Script v1.4.4.0
- Handtools
- Events
- Objects
- Placeables
- Triggers
- Utils
- Vehicles
- Specializations
- AIVehicle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BuiltInCutterTrailer
- BunkerSiloCompacter
- Combine
- ConveyorBelt
- Cover
- CrabSteering
- Crawler
- Cultivator
- Cutter
- Cylindered
- Drivable
- DynamicMountAttacher
- Fillable
- FillActivatable
- FillVolume
- Foldable
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- FuelTrailer
- Honk
- HookLiftContainer
- HookLiftTrailer
- Leveler
- Lights
- LivestockTrailer
- ManureBarrel
- ManureSpreader
- MixerWagon
- Motorized
- Mountable
- Mower
- NonTabbable
- Overloading
- Pickup
- Pipe
- Plough
- PowerConsumer
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- RidgeMarker
- Roller
- Ropes
- RotorSpreader
- SemiTrailerFront
- Shovel
- SowingMachine
- SpeedRotatingParts
- Sprayer
- Steerable
- StrawBlower
- StumpCutter
- Tedder
- TensionBelts
- Trailer
- TreePlanter
- TreePlanterActivatable
- TreeSaw
- TurnOnVehicle
- Washable
- WaterTrailer
- Weeder
- WheelRotations
- Windrower
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkParticles
Engine v7.0.0.2
- General
- Entity
- Node
- Scenegraph
- Lighting
- Camera
- Shape
- Particle System
- Physics
- Spline
- Animation
- Overlays
- Sound
- Input
- XML
- Network
- Callbacks
- Text Rendering
- Terrain Detail
- Tire Track
- Editor
- Rendering
- String
- Math
- I3D
- Fillplanes
Foundation Reference
Steerable
DescriptionSpecialization class for steerablesFunctions
- prerequisitesPresent
- preLoad
- load
- postLoad
- loadSettingsFromXML
- delete
- readStream
- writeStream
- getXMLStatsAttributes
- mouseEvent
- update
- draw
- drawUIInfo
- enterVehicle
- leaveVehicle
- onEnter
- getSaveAttributesAndNodes
- setNextLightsState
- getDistanceToObject
- getInteractionHelp
- interact
- getIsActiveForInput
- setActiveCameraIndex
- addToolCameras
- removeToolCameras
prerequisitesPresent
DescriptionChecks if all prerequisite specializations are loadedDefinition
prerequisitesPresent(table specializations)Arguments
table | specializations | specializations |
boolean | hasPrerequisite | true if all prerequisite specializations are loaded |
17 | function Steerable.prerequisitesPresent(specializations) |
18 | return SpecializationUtil.hasSpecialization(Lights, specializations); |
19 | end |
preLoad
DescriptionCalled before loadingDefinition
preLoad(table savegame)Arguments
table | savegame | savegame |
24 | function Steerable:preLoad(savegame) |
25 | Vehicle.registerInteractionFlag("steerable") |
26 | |
27 | self.enterVehicle = Steerable.enterVehicle |
28 | self.leaveVehicle = Steerable.leaveVehicle |
29 | self.drawUIInfo = Utils.overwrittenFunction(self.drawUIInfo, Steerable.drawUIInfo); |
30 | self.getIsActiveForInput = Utils.overwrittenFunction(self.getIsActiveForInput, Steerable.getIsActiveForInput); |
31 | self.getDistanceToObject = Utils.overwrittenFunction(self.getDistanceToObject, Steerable.getDistanceToObject); |
32 | self.getInteractionHelp = Utils.overwrittenFunction(self.getInteractionHelp, Steerable.getInteractionHelp); |
33 | self.interact = Utils.overwrittenFunction(self.interact, Steerable.interact); |
34 | self.setActiveCameraIndex = Steerable.setActiveCameraIndex; |
35 | self.addToolCameras = Steerable.addToolCameras; |
36 | self.removeToolCameras = Steerable.removeToolCameras; |
37 | |
38 | self.onEnter = SpecializationUtil.callSpecializationsFunction("onEnter"); |
39 | self.onLeave = SpecializationUtil.callSpecializationsFunction("onLeave"); |
40 | self.onCameraChanged = SpecializationUtil.callSpecializationsFunction("onCameraChanged"); |
41 | end |
load
DescriptionCalled on loadingDefinition
load(table savegame)Arguments
table | savegame | savegame |
46 | function Steerable:load(savegame) |
47 | |
48 | self.isSteerable = true; |
49 | self.isAttachable = SpecializationUtil.hasSpecialization(Attachable, self.specializations); |
50 | self.isControlled = false; |
51 | |
52 | self.steering = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.steering#index")); |
53 | |
54 | Steerable.loadSettingsFromXML(self, self.xmlFile); |
55 | |
56 | self.numCameras = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.cameras#count"), 0); |
57 | self.cameras = {}; |
58 | for i=1, self.numCameras do |
59 | local cameraKey = string.format("vehicle.cameras.camera%d", i); |
60 | local camera = VehicleCamera:new(self); |
61 | if camera:loadFromXML(self.xmlFile, cameraKey) then |
62 | table.insert(self.cameras, camera); |
63 | end |
64 | end |
65 | self.numCameras = table.getn(self.cameras); |
66 | if self.numCameras == 0 then |
67 | print("Error: No cameras in xml file: ".. self.configFileName); |
68 | end |
69 | |
70 | self.camIndex = 1; |
71 | |
72 | self.isEntered = false; |
73 | |
74 | self.controllerName = "Unknown"; |
75 | |
76 | self.disableCharacterOnLeave = true; |
77 | |
78 | self.deactivateLightsOnLeave = true; |
79 | |
80 | self.steerableNeedsAttacherVehicle = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.steerableNeedsAttacherVehicle"), true); |
81 | |
82 | self.forceSelectionOnEnter = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.forceSelectionOnEnter"), false); |
83 | |
84 | self.currentLightState = 0; |
85 | if self.lightStates == nil or #self.lightStates == 0 then |
86 | table.insert(self.lightStates, {0}); |
87 | table.insert(self.lightStates, {0, 1}); |
88 | table.insert(self.lightStates, {0, 1, 2}); |
89 | end |
90 | |
91 | local useDefaultSample = true; |
92 | if hasXMLProperty(self.xmlFile, "vehicle.toggleLightsSound") then |
93 | useDefaultSample = false; |
94 | local customFile = getXMLString(self.xmlFile, "vehicle.toggleLightsSound#file"); |
95 | local customFilename = Utils.getFilename(customFile, self.baseDirectory); |
96 | useDefaultSample = g_currentMission.defaultVehicleSounds[customFilename] ~= nil; |
97 | end |
98 | if not useDefaultSample then |
99 | self.sampleToggleLights = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.toggleLightsSound", nil, self.baseDirectory); |
100 | end |
101 | |
102 | self.steerableGroundFlag = self:getNextDirtyFlag(); |
103 | |
104 | g_currentMission:addInteractiveVehicle(self); |
105 | end |
postLoad
DescriptionCalled after loadingDefinition
postLoad(table savegame)Arguments
table | savegame | savegame |
110 | function Steerable:postLoad(savegame) |
111 | if self.steering ~= nil then |
112 | self.steeringSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.steering#rotationSpeed"), 0); |
113 | local indoorRotation = getXMLFloat(self.xmlFile, "vehicle.steering#indoorRotation"); |
114 | if indoorRotation ~= nil then |
115 | self.steeringIndoorRotation = math.rad(indoorRotation); |
116 | end |
117 | local outdoorRotation = getXMLFloat(self.xmlFile, "vehicle.steering#outdoorRotation"); |
118 | if outdoorRotation ~= nil then |
119 | self.steeringOutdoorRotation = math.rad(outdoorRotation); |
120 | end |
121 | _, self.steeringLastRotation, _ = getRotation(self.steering); |
122 | end |
123 | end |
loadSettingsFromXML
DescriptionCalled on loadingDefinition
loadSettingsFromXML(table savegame)Arguments
table | savegame | savegame |
128 | function Steerable:loadSettingsFromXML(xmlFile) |
129 | self.enterReferenceNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.enterReferenceNode#index")); |
130 | self.exitPoint = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.exitPoint#index")); |
131 | |
132 | self.interactionRadius = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.enterReferenceNode#interactionRadius"), 6.0) |
133 | |
134 | self.vehicleCharacter = VehicleCharacter:new(self); |
135 | if not self.vehicleCharacter:load(xmlFile, "vehicle.characterNode") then |
136 | self.vehicleCharacter = nil |
137 | end |
138 | |
139 | self.nicknameRenderNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.nicknameRenderNode#index")); |
140 | self.nicknameRenderNodeOffset = Utils.getVectorNFromString(getXMLString(xmlFile, "vehicle.nicknameRenderNode#offset"), 3); |
141 | if self.nicknameRenderNode == nil then |
142 | if self.vehicleCharacter ~= nil and self.vehicleCharacter.characterDistanceRefNode ~= nil then |
143 | self.nicknameRenderNode = self.vehicleCharacter.characterDistanceRefNode; |
144 | if self.nicknameRenderNodeOffset == nil then |
145 | self.nicknameRenderNodeOffset = {0,1.5,0}; |
146 | end |
147 | else |
148 | self.nicknameRenderNode = self.components[1].node; |
149 | end |
150 | end |
151 | if self.nicknameRenderNodeOffset == nil then |
152 | self.nicknameRenderNodeOffset = {0,4,0}; |
153 | end |
154 | |
155 | self.enterAnimation = getXMLString(xmlFile, "vehicle.enterAnimation#name"); |
156 | end |
delete
DescriptionCalled on deletingDefinition
delete()Code
160 | function Steerable:delete() |
161 | g_currentMission:removeInteractiveVehicle(self); |
162 | if self.vehicleCharacter ~= nil then |
163 | self.vehicleCharacter:delete(); |
164 | end |
165 | for _, camera in ipairs(self.cameras) do |
166 | camera:delete(); |
167 | end |
168 | if self.sampleToggleLights ~= nil then |
169 | SoundUtil.deleteSample(self.sampleToggleLights); |
170 | end |
171 | end |
readStream
DescriptionCalled on client side on joinDefinition
readStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
177 | function Steerable:readStream(streamId, connection) |
178 | local isControlled = streamReadBool(streamId); |
179 | if isControlled then |
180 | self.controllerName = streamReadString(streamId); |
181 | local playerIndex = streamReadUIntN(streamId, PlayerUtil.sendNumBits) |
182 | local playerColorIndex = streamReadUInt8(streamId) |
183 | self:enterVehicle(false, playerIndex, playerColorIndex); |
184 | end |
185 | end |
writeStream
DescriptionCalled on server side on joinDefinition
writeStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
191 | function Steerable:writeStream(streamId, connection) |
192 | if streamWriteBool(streamId, self.isControlled) then |
193 | streamWriteString(streamId, self.controllerName); |
194 | streamWriteUIntN(streamId, self.playerIndex, PlayerUtil.sendNumBits) |
195 | streamWriteUInt8(streamId, self.playerColorIndex) |
196 | end |
197 | end |
getXMLStatsAttributes
DescriptionReturns string with name of controller for game stats xmlDefinition
getXMLStatsAttributes()Return Values
string | statesAttributes | states attributes |
208 | function Steerable:getXMLStatsAttributes() |
209 | if self.isControlled and self.controllerName ~= nil then |
210 | return string.format('controller="%s"', Utils.encodeToHTML(tostring(self.controllerName))); |
211 | end |
212 | return nil; |
213 | end |
mouseEvent
DescriptionCalled on mouse eventDefinition
mouseEvent(float posX, float posY, boolean isDown, boolean isUp, integer button)Arguments
float | posX | x position |
float | posY | y position |
boolean | isDown | is mouse button down |
boolean | isUp | is mouse button up |
integer | button | mouse button |
222 | function Steerable:mouseEvent(posX, posY, isDown, isUp, button) |
223 | if self.activeCamera ~= nil and self.isEntered then |
224 | self.activeCamera:mouseEvent(posX, posY, isDown, isUp, button); |
225 | end |
226 | end |
update
DescriptionCalled on updateDefinition
update(float dt)Arguments
float | dt | time since last call in ms |
234 | function Steerable:update(dt) |
235 | if self:getIsActive() then |
236 | |
237 | if InputBinding.hasEvent(InputBinding.ENTER) and self.isEntered and not g_gui:getIsGuiVisible() then |
238 | g_currentMission:onLeaveVehicle(); |
239 | end |
240 | |
241 | if InputBinding.hasEvent(InputBinding.RESET_HEAD_TRACKING) then |
242 | centerHeadTracking(); |
243 | end |
244 | |
245 | if self.isClient then |
246 | if self.steering ~= nil then |
247 | local rotTime = self.rotatedTime; |
248 | local baseRotation = self.steeringSpeed; |
249 | |
250 | if g_currentMission.controlledVehicle ~= self or not self.activeCamera.isInside then |
251 | baseRotation = Utils.getNoNil(self.steeringOutdoorRotation, self.steeringSpeed); |
252 | else |
253 | baseRotation = Utils.getNoNil(self.steeringIndoorRotation, self.steeringSpeed); |
254 | end |
255 | |
256 | if self.steeringOutdoorRotation ~= nil or self.steeringIndoorRotation ~= nil then |
257 | if self.rotatedTime > 0 then |
258 | rotTime = self.rotatedTime/math.abs(self.maxRotTime); |
259 | else |
260 | rotTime = self.rotatedTime/math.abs(self.minRotTime); |
261 | end |
262 | end |
263 | |
264 | local rotation = baseRotation * rotTime; |
265 | |
266 | if self.steeringLastRotation ~= rotation then |
267 | self.steeringLastRotation = rotation; |
268 | setRotation(self.steering, 0, rotation*Utils.getNoNil(self.reverserDirection, 1), 0); |
269 | |
270 | if self.vehicleCharacter ~= nil then |
271 | self.vehicleCharacter:setDirty(); |
272 | end |
273 | end |
274 | end |
275 | |
276 | if self.isEntered and self.vehicleCharacter ~= nil then |
277 | if self.vehicleCharacter.characterSpineNode ~= nil and self.vehicleCharacter.characterSpineSpeedDepended then |
278 | self.vehicleCharacter:setSpineDirty(self.lastSpeedAcceleration); |
279 | end |
280 | end |
281 | end |
282 | end |
283 | |
284 | if self.isEntered and self.isClient then |
285 | if not g_currentMission.hasSpecialCamera then |
286 | setCamera(self.activeCamera.cameraNode); |
287 | end |
288 | self.activeCamera:update(dt); |
289 | |
290 | -- do all the input handling |
291 | local activeForInput = true; |
292 | if g_gui:getIsGuiVisible() or g_currentMission.isPlayerFrozen then |
293 | activeForInput = false; |
294 | end |
295 | |
296 | if activeForInput then |
297 | |
298 | if InputBinding.hasEvent(InputBinding.CAMERA_SWITCH) then |
299 | self:setActiveCameraIndex(self.camIndex + 1); |
300 | end |
301 | |
302 | -- camera zoom is handled here, otherwise the controls are laggy or don't work at all |
303 | if self.activeCamera.allowTranslation then |
304 | if InputBinding.isPressed(InputBinding.CAMERA_ZOOM_IN) then |
305 | if InputBinding.getInputTypeOfDigitalAction(InputBinding.CAMERA_ZOOM_IN) == InputBinding.INPUTTYPE_MOUSE_WHEEL then |
306 | self.activeCamera:zoomSmoothly(-0.6); |
307 | else |
308 | self.activeCamera:zoomSmoothly(-0.005*dt); |
309 | end |
310 | elseif InputBinding.isPressed(InputBinding.CAMERA_ZOOM_OUT) then |
311 | if InputBinding.getInputTypeOfDigitalAction(InputBinding.CAMERA_ZOOM_OUT) == InputBinding.INPUTTYPE_MOUSE_WHEEL then |
312 | self.activeCamera:zoomSmoothly(0.6); |
313 | else |
314 | self.activeCamera:zoomSmoothly(0.005*dt); |
315 | end |
316 | end |
317 | end |
318 | |
319 | if self:canToggleLight() then |
320 | |
321 | local playSound = false; |
322 | |
323 | if self.numLightTypes >= 1 and InputBinding.hasEvent(InputBinding.TOGGLE_LIGHT_FRONT) then |
324 | playSound = true; |
325 | local lightsTypesMask = bitXOR(self.lightsTypesMask, 2^0); |
326 | self:setLightsTypesMask(lightsTypesMask); |
327 | elseif InputBinding.hasEvent(InputBinding.TOGGLE_LIGHTS) then |
328 | Steerable.setNextLightsState(self); |
329 | end |
330 | |
331 | if self.numLightTypes >= 2 then |
332 | -- work light back has light type 1 |
333 | if InputBinding.hasEvent(InputBinding.TOGGLE_WORK_LIGHT_BACK) then |
334 | playSound = true; |
335 | local lightsTypesMask = bitXOR(self.lightsTypesMask, 2^1); |
336 | self:setLightsTypesMask(lightsTypesMask); |
337 | end |
338 | |
339 | if self.numLightTypes >= 3 then |
340 | -- work light front has light type 2 |
341 | if InputBinding.hasEvent(InputBinding.TOGGLE_WORK_LIGHT_FRONT) then |
342 | playSound = true; |
343 | local lightsTypesMask = bitXOR(self.lightsTypesMask, 2^2); |
344 | self:setLightsTypesMask(lightsTypesMask); |
345 | end |
346 | |
347 | if self.numLightTypes >= 4 then |
348 | -- work light has light type 3 |
349 | if InputBinding.hasEvent(InputBinding.TOGGLE_HIGH_BEAM_LIGHT) then |
350 | playSound = true; |
351 | local lightsTypesMask = bitXOR(self.lightsTypesMask, 2^3); |
352 | self:setLightsTypesMask(lightsTypesMask); |
353 | end |
354 | end |
355 | end |
356 | end |
357 | |
358 | if playSound then |
359 | if self.sampleToggleLights ~= nil then |
360 | SoundUtil.playSample(self.sampleToggleLights, 1, 0, 1); |
361 | else |
362 | SoundUtil.playSample(g_currentMission.sampleToggleLights, 1, 0, 1); |
363 | end |
364 | end |
365 | |
366 | end |
367 | |
368 | end |
369 | |
370 | -- update character visiblity |
371 | if self.vehicleCharacter ~= nil then |
372 | self.vehicleCharacter:updateVisibility(); |
373 | end |
374 | end |
375 | end |
draw
DescriptionCalled on drawDefinition
draw()Code
382 | function Steerable:draw() |
383 | if not self.isEntered then |
384 | return; |
385 | end |
386 | |
387 | g_currentMission:addHelpButtonText(g_i18n:getText("action_exitVehicle"), InputBinding.ENTER, nil, GS_PRIO_LOW); |
388 | |
389 | if self:canToggleLight() and not self.isAttachable then |
390 | if g_currentMission.environment.currentHour > 20 or g_currentMission.environment.currentHour < 7 then |
391 | g_currentMission:addHelpButtonText(g_i18n:getText("input_TOGGLE_LIGHTS"), InputBinding.TOGGLE_LIGHTS, nil, GS_PRIO_LOW); |
392 | end |
393 | end |
394 | end |
drawUIInfo
DescriptionCalled on ui info draw, renders nicknames in multiplayerDefinition
drawUIInfo()Code
398 | function Steerable:drawUIInfo(superFunc) |
399 | if superFunc ~= nil then |
400 | superFunc(self); |
401 | end |
402 | |
403 | if not self.isEntered and self.isClient and self:getIsActive() and self.isControlled and not g_gui:getIsGuiVisible() and g_currentMission.showHudEnv then |
404 | local x,y,z = getWorldTranslation(self.nicknameRenderNode); |
405 | local x1,y1,z1 = getWorldTranslation(getCamera()) |
406 | local distSq = Utils.vector3LengthSq(x-x1,y-y1,z-z1); |
407 | if distSq <= 100*100 then |
408 | x = x + self.nicknameRenderNodeOffset[1]; |
409 | y = y + self.nicknameRenderNodeOffset[2]; |
410 | z = z + self.nicknameRenderNodeOffset[3]; |
411 | |
412 | Utils.renderTextAtWorldPosition(x,y,z, self.controllerName, getCorrectTextSize(0.02), 0) |
413 | end |
414 | end |
415 | end |
enterVehicle
DescriptionEnter vehicleDefinition
enterVehicle(boolean isControlling, integer playerIndex, integer playerColorIndex)Arguments
boolean | isControlling | is controlling vehicle |
integer | playerIndex | index of player who enters the vehicle |
integer | playerColorIndex | index of player color |
422 | function Steerable:enterVehicle(isControlling, playerIndex, playerColorIndex) |
423 | self.isControlled = true; |
424 | if isControlling then |
425 | self.isEntered = true; |
426 | |
427 | -- if head tracking is available we want to use the first indoor camera |
428 | if g_gameSettings:getValue("isHeadTrackingEnabled") and isHeadTrackingAvailable() then |
429 | for i,camera in pairs(self.cameras) do |
430 | if camera.isInside then |
431 | self.camIndex = i; |
432 | break; |
433 | end |
434 | end |
435 | end |
436 | |
437 | if g_gameSettings:getValue("resetCamera") then |
438 | self.camIndex = 1 |
439 | end |
440 | self:setActiveCameraIndex(self.camIndex); |
441 | end |
442 | |
443 | if self.vehicleCharacter ~= nil and not self:getIsHired() then |
444 | self.vehicleCharacter:loadCharacter(PlayerUtil.playerIndexToDesc[playerIndex].xmlFilename, playerColorIndex) |
445 | end |
446 | |
447 | if self.enterAnimation ~= nil and self.playAnimation ~= nil then |
448 | self:playAnimation(self.enterAnimation, 1, nil, true); |
449 | end |
450 | |
451 | self.playerIndex = playerIndex |
452 | self.playerColorIndex = playerColorIndex |
453 | |
454 | g_currentMission.controlledVehicles[self] = self; |
455 | self:onEnter(isControlling) |
456 | |
457 | if self.isServer and not isControlling and g_currentMission.trafficSystem ~= nil and g_currentMission.trafficSystem.trafficSystemId ~= 0 then |
458 | addTrafficSystemPlayer(g_currentMission.trafficSystem.trafficSystemId, self.components[1].node); |
459 | end |
460 | end |
leaveVehicle
DescriptionLeave vehicleDefinition
leaveVehicle()Code
464 | function Steerable:leaveVehicle() |
465 | if self.isServer and not self.isEntered and g_currentMission.trafficSystem ~= nil and g_currentMission.trafficSystem.trafficSystemId ~= 0 then |
466 | removeTrafficSystemPlayer(g_currentMission.trafficSystem.trafficSystemId, self.components[1].node); |
467 | end |
468 | |
469 | g_currentMission.interactionBlockTimer = 500 |
470 | self:onLeave() |
471 | |
472 | self.isControlled = false; |
473 | if self.activeCamera ~= nil and self.isEntered then |
474 | self.activeCamera:onDeactivate(); |
475 | SoundUtil.onCameraSwitched(false); |
476 | end |
477 | if self.vehicleCharacter ~= nil and self.disableCharacterOnLeave then |
478 | self.vehicleCharacter:delete() |
479 | end |
480 | |
481 | if self:getDeactivateOnLeave() then |
482 | self:onDeactivate(); |
483 | else |
484 | self:onDeactivateSounds(); |
485 | end |
486 | |
487 | if self.enterAnimation ~= nil and self.playAnimation ~= nil then |
488 | self:playAnimation(self.enterAnimation, -1, nil, true); |
489 | end |
490 | |
491 | self.currentLightState = 0 |
492 | |
493 | self.isEntered = false; |
494 | g_currentMission.controlledVehicles[self] = nil; |
495 | end |
onEnter
DescriptionCalled on enter vehicleDefinition
onEnter(boolean isControlling)Arguments
boolean | isControlling | is player controlling the vehicle |
500 | function Steerable:onEnter(isControlling) |
501 | if self.forceSelectionOnEnter then |
502 | local rootAttacherVehicle = self:getRootAttacherVehicle(); |
503 | rootAttacherVehicle:setSelectedImplement(rootAttacherVehicle:getImplementByObject(self)); |
504 | |
505 | end; |
506 | end |
getSaveAttributesAndNodes
DescriptionReturns attributes and nodes to saveDefinition
getSaveAttributesAndNodes(table nodeIdent)Arguments
table | nodeIdent | node ident |
string | attributes | attributes |
string | nodes | nodes |
516 | function Steerable:getSaveAttributesAndNodes(nodeIdent) |
517 | local attributes = ""; |
518 | local nodes = ""; |
519 | return attributes, nodes; |
520 | end |
setNextLightsState
DescriptionToggle next light stateDefinition
setNextLightsState()Code
524 | function Steerable.setNextLightsState(self) |
525 | if self.lightStates ~= nil and #self.lightStates > 0 then |
526 | if self.sampleToggleLights ~= nil then |
527 | SoundUtil.playSample(self.sampleToggleLights, 1, 0, 1); |
528 | else |
529 | SoundUtil.playSample(g_currentMission.sampleToggleLights, 1, 0, 1); |
530 | end |
531 | |
532 | local currentLightState = self.currentLightState + 1; |
533 | if currentLightState > #self.lightStates or (self.currentLightState == 0 and self.lightsTypesMask > 0) then |
534 | currentLightState = 0; |
535 | end |
536 | |
537 | local lightsTypesMask = 0; |
538 | if currentLightState > 0 then |
539 | for _, lightType in pairs(self.lightStates[currentLightState]) do |
540 | lightsTypesMask = bitOR(lightsTypesMask, 2^lightType); |
541 | end |
542 | end |
543 | |
544 | self:setLightsTypesMask(lightsTypesMask); |
545 | self.currentLightState = currentLightState; |
546 | end |
547 | end |
getDistanceToObject
DescriptionReturns distance between given object and enterReferenceNodeDefinition
getDistanceToObject(integer object)Arguments
integer | object | id of object |
float | distance | distance |
553 | function Steerable:getDistanceToObject(superFunc, object) |
554 | local px, _, pz = getWorldTranslation(object); |
555 | local vx, _, vz = getWorldTranslation(self.enterReferenceNode); |
556 | local distance = Utils.vector2Length(px-vx, pz-vz); |
557 | |
558 | local superDistance = math.huge |
559 | if superFunc ~= nil then |
560 | superDistance = superFunc(self, object) |
561 | end |
562 | |
563 | if distance < self.interactionRadius and distance < superDistance then |
564 | self.interactionFlag = Vehicle.INTERACTION_FLAG_STEERABLE |
565 | return distance |
566 | end |
567 | |
568 | return superDistance; |
569 | end |
getInteractionHelp
DescriptionReturns interaction help textDefinition
getInteractionHelp()Return Values
string | text | text |
574 | function Steerable:getInteractionHelp(superFunc) |
575 | if self.interactionFlag == Vehicle.INTERACTION_FLAG_STEERABLE then |
576 | return g_i18n:getText("action_enter"); |
577 | else |
578 | if superFunc ~= nil then |
579 | return superFunc(self) |
580 | else |
581 | return "" |
582 | end |
583 | end |
584 | end |
interact
DescriptionInteractDefinition
interact()Code
588 | function Steerable:interact(superFunc) |
589 | if self.interactionFlag == Vehicle.INTERACTION_FLAG_STEERABLE then |
590 | g_currentMission:requestToEnterVehicle(self) |
591 | else |
592 | if superFunc ~= nil then |
593 | return superFunc(self) |
594 | end |
595 | end |
596 | end |
getIsActiveForInput
DescriptionReturns if vehicle is active for inputDefinition
getIsActiveForInput(boolean onlyTrueIfSelected, boolean activeIfIngameMessageShown)Arguments
boolean | onlyTrueIfSelected | only true if selected |
boolean | activeIfIngameMessageShown | active if ingame message is shown |
boolean | isActive | is active for input |
603 | function Steerable:getIsActiveForInput(superFunc, onlyTrueIfSelected, activeIfIngameMessageShown) |
604 | if not self.isAttachable then |
605 | return superFunc(self, onlyTrueIfSelected, activeIfIngameMessageShown); |
606 | else |
607 | if g_gui:getIsGuiVisible() or g_currentMission.isPlayerFrozen then |
608 | return false; |
609 | end |
610 | if self.isEntered then |
611 | if self.attacherVehicle ~= nil then |
612 | return true; |
613 | else |
614 | return (not self.steerableNeedsAttacherVehicle) and (not self.isHired); |
615 | end |
616 | end |
617 | return false; |
618 | end |
619 | end |
setActiveCameraIndex
DescriptionChange active camera indexDefinition
setActiveCameraIndex(integer index)Arguments
integer | index | index of camera to set |
624 | function Steerable:setActiveCameraIndex(index) |
625 | if self.activeCamera ~= nil then |
626 | self.activeCamera:onDeactivate(); |
627 | end |
628 | self.camIndex = index; |
629 | if self.camIndex > self.numCameras then |
630 | self.camIndex = 1; |
631 | end |
632 | self.activeCamera = self.cameras[self.camIndex]; |
633 | self.activeCamera:onActivate(); |
634 | self:onCameraChanged(self.activeCamera, self.camIndex) |
635 | |
636 | -- |
637 | SoundUtil.onCameraSwitched(self.activeCamera.isInside); |
638 | end |
addToolCameras
DescriptionAdd cameras from toolDefinition
addToolCameras(table cameras)Arguments
table | cameras | cameras to add |
643 | function Steerable:addToolCameras(cameras) |
644 | for _,toolCamera in pairs(cameras) do |
645 | table.insert(self.cameras, toolCamera); |
646 | end |
647 | self.numCameras = #self.cameras; |
648 | end |
removeToolCameras
DescriptionRemove cameras from toolDefinition
removeToolCameras(table cameras)Arguments
table | cameras | cameras to remove |
653 | function Steerable:removeToolCameras(cameras) |
654 | for _,toolCamera in pairs(cameras) do |
655 | for j,camera in pairs(self.cameras) do |
656 | if toolCamera == camera then |
657 | table.remove(self.cameras, j); |
658 | break; |
659 | end |
660 | end |
661 | end |
662 | self.numCameras = #self.cameras; |
663 | if self.activeCamera ~= nil then |
664 | self.activeCamera:onDeactivate(); |
665 | end |
666 | if self.camIndex > self.numCameras then |
667 | self.camIndex = 1; |
668 | end |
669 | local cameraId = getCamera(); |
670 | self:setActiveCameraIndex(self.camIndex); |
671 | setCamera(cameraId); |
672 | end |