LUADOC - Farming Simulator 19

Drivable

Description
Specialization for cruise control, steering wheel; required Enterable and Motorized specialization
Functions

actionEventAccelerate

Description
Definition
actionEventAccelerate()
Code
798function Drivable.actionEventAccelerate(self, actionName, inputValue, callbackState, isAnalog)
799 local spec = self.spec_drivable
800 spec.lastInputValues.axisAccelerate = MathUtil.clamp(inputValue, 0, 1)
801end

actionEventBrake

Description
Definition
actionEventBrake()
Code
805function Drivable.actionEventBrake(self, actionName, inputValue, callbackState, isAnalog)
806 local spec = self.spec_drivable
807 spec.lastInputValues.axisBrake = MathUtil.clamp(inputValue, 0, 1)
808end

actionEventCruiseControlState

Description
Definition
actionEventCruiseControlState()
Code
823function Drivable.actionEventCruiseControlState(self, actionName, inputValue, callbackState, isAnalog)
824 local spec = self.spec_drivable
825 spec.lastInputValues.cruiseControlState = 1
826end

actionEventCruiseControlValue

Description
Definition
actionEventCruiseControlValue()
Code
830function Drivable.actionEventCruiseControlValue(self, actionName, inputValue, callbackState, isAnalog)
831 local spec = self.spec_drivable
832 spec.lastInputValues.cruiseControlValue = inputValue
833end

actionEventSteer

Description
Definition
actionEventSteer()
Code
812function Drivable.actionEventSteer(self, actionName, inputValue, callbackState, isAnalog, isMouse, deviceCategory)
813 local spec = self.spec_drivable
814 spec.lastInputValues.axisSteer = inputValue
815 if inputValue ~= 0 then
816 spec.lastInputValues.axisSteerIsAnalog = isAnalog
817 spec.lastInputValues.axisSteerDeviceCategory = deviceCategory
818 end
819end

getAccelerationAxis

Description
Definition
getAccelerationAxis()
Code
575function Drivable:getAccelerationAxis()
576 if self.lastSpeedReal > 0.0001 then
577 return math.max(self.spec_drivable.axisForward*self.movingDirection*self:getReverserDirection(), 0)
578 end
579
580 return 0
581end

getAcDecelerationAxis

Description
Definition
getAcDecelerationAxis()
Code
605function Drivable:getAcDecelerationAxis()
606 return self.spec_drivable.axisForward*self:getReverserDirection()
607end

getAxisForward

Description
Definition
getAxisForward()
Code
569function Drivable:getAxisForward()
570 return self.spec_drivable.axisForward
571end

getCruiseControlAxis

Description
Definition
getCruiseControlAxis()
Code
598function Drivable:getCruiseControlAxis()
599 return self.spec_drivable.cruiseControl.state ~= Drivable.CRUISECONTROL_STATE_OFF and 1 or 0
600end

getCruiseControlMaxSpeed

Description
Definition
getCruiseControlMaxSpeed()
Code
563function Drivable:getCruiseControlMaxSpeed()
564 return self.spec_drivable.cruiseControl.maxSpeed
565end

getCruiseControlSpeed

Description
Definition
getCruiseControlSpeed()
Code
552function Drivable:getCruiseControlSpeed()
553 local spec = self.spec_drivable
554 if spec.cruiseControl.state == Drivable.CRUISECONTROL_STATE_FULL then
555 return spec.cruiseControl.maxSpeed
556 end
557
558 return spec.cruiseControl.speed
559end

getCruiseControlState

Description
Definition
getCruiseControlState()
Code
546function Drivable:getCruiseControlState()
547 return self.spec_drivable.cruiseControl.state
548end

getDashboardSteeringAxis

Description
Definition
getDashboardSteeringAxis()
Code
611function Drivable:getDashboardSteeringAxis()
612 return self.rotatedTime * self:getReverserDirection()
613end

getDecelerationAxis

Description
Definition
getDecelerationAxis()
Code
586function Drivable:getDecelerationAxis()
587 -- if moving backward and accelrating forward the threshold for the brake pedal is at 7.2km/h to avoid quick brake and gas pedal switches
588 if self.lastSpeedReal > 0.0001 and (self.movingDirection == MathUtil.sign(self.spec_drivable.axisForward) or self.lastSpeedReal > 0.002) then
589 return math.abs(math.min(self.spec_drivable.axisForward*self.movingDirection*self:getReverserDirection(), 0))
590 end
591
592 return 0
593end

getDrivingDirection

Description
Definition
getDrivingDirection()
Code
647function Drivable:getDrivingDirection()
648 if self:getLastSpeed() < 0.2 then
649 return 0
650 end
651
652 return self.movingDirection
653end

getIsDrivingBackward

Description
Definition
getIsDrivingBackward()
Code
641function Drivable:getIsDrivingBackward()
642 return self:getDrivingDirection() < 0
643end

getIsDrivingForward

Description
Definition
getIsDrivingForward()
Code
635function Drivable:getIsDrivingForward()
636 return self:getDrivingDirection() >= 0
637end

getIsVehicleControlledByPlayer

Description
Definition
getIsVehicleControlledByPlayer()
Code
657function Drivable:getIsVehicleControlledByPlayer()
658 return true
659end

getReverserDirection

Description
Definition
getReverserDirection()
Code
623function Drivable:getReverserDirection()
624 return self.spec_drivable.reverserDirection
625end

getSteeringDirection

Description
Definition
getSteeringDirection()
Code
629function Drivable:getSteeringDirection()
630 return 1
631end

onCameraChanged

Description
Called on camera change
Definition
onCameraChanged(table camera, integer camIndex)
Arguments
tablecameranew camera
integercamIndexindex of new camera
Code
666function Drivable:onCameraChanged(camera, camIndex)
667end

onDelete

Description
Called on deleting
Definition
onDelete()
Code
199function Drivable:onDelete()
200 if self.isClient then
201 local spec = self.spec_drivable
202 for _,sample in pairs(spec.samples) do
203 g_soundManager:deleteSample(sample)
204 end
205 end
206end

onLeaveVehicle

Description
Definition
onLeaveVehicle()
Code
723function Drivable:onLeaveVehicle()
724 self:setCruiseControlState(Drivable.CRUISECONTROL_STATE_OFF)
725
726 if self.brake ~= nil then
727 self:brake(1)
728 end
729end

onLoad

Description
Called on loading
Definition
onLoad(table savegame)
Arguments
tablesavegamesavegame
Code
73function Drivable:onLoad(savegame)
74 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.steering#index", "vehicle.drivable.steeringWheel#node") --FS17 to FS19
75 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.steering#node", "vehicle.drivable.steeringWheel#node") --FS17 to FS19
76 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.cruiseControl", "vehicle.drivable.cruiseControl") --FS17 to FS19
77 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.indoorHud.cruiseControl", "vehicle.drivable.dashboards.dashboard with valueType 'cruiseControl'") --FS17 to FS19
78 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.showChangeToolSelectionHelp") --FS17 to FS19
79 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.maxRotatedTimeSpeed#value") --FS17 to FS19
80 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.speedRotScale#scale", "vehicle.drivable.speedRotScale#scale") --FS17 to FS19
81 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.speedRotScale#offset", "vehicle.drivable.speedRotScale#offset") --FS17 to FS19
82
83 local spec = self.spec_drivable
84
85 spec.showToolSelectionHud = true
86
87 spec.doHandbrake = false
88 spec.doHandbrakeSend = false
89 spec.reverserDirection = 1
90
91 -- attributes set by action events
92 spec.lastInputValues = {}
93 spec.lastInputValues.axisAccelerate = 0
94 spec.lastInputValues.axisBrake = 0
95 spec.lastInputValues.axisSteer = 0
96 spec.lastInputValues.axisSteerIsAnalog = false
97 spec.lastInputValues.axisSteerDeviceCategory = InputDevice.CATEGORY.UNKNOWN
98 spec.lastInputValues.cruiseControlValue = 0
99 spec.lastInputValues.cruiseControlState = 0
100
101 -- 'final' attrbutes calculated
102 spec.axisForward = 0
103 spec.axisForwardSend = 0
104
105 spec.axisSide = 0
106 spec.axisSideSend = 0
107 spec.axisSideLast = 0
108
109 spec.speedRotScale = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.drivable.speedRotScale#scale"), 80)
110 spec.speedRotScaleOffset = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.drivable.speedRotScale#offset"), 0.7)
111
112 local motor = self:getMotor()
113 spec.cruiseControl = {}
114 spec.cruiseControl.maxSpeed = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.drivable.cruiseControl#maxSpeed"), math.ceil(motor:getMaximumForwardSpeed()*3.6))
115 spec.cruiseControl.minSpeed = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.drivable.cruiseControl#minSpeed"), math.min(1, spec.cruiseControl.maxSpeed))
116 spec.cruiseControl.speed = spec.cruiseControl.maxSpeed
117 spec.cruiseControl.isActive = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.drivable.cruiseControl#enabled"), true)
118 spec.cruiseControl.state = Drivable.CRUISECONTROL_STATE_OFF
119 spec.cruiseControl.topSpeedTime = 2000
120 spec.cruiseControl.changeDelay = 250
121 spec.cruiseControl.changeCurrentDelay = 0
122 spec.cruiseControl.changeMultiplier = 1
123 spec.cruiseControl.speedSent = spec.cruiseControl.speed
124
125 local node = I3DUtil.indexToObject( self.components, getXMLString(self.xmlFile, "vehicle.drivable.steeringWheel#node"), self.i3dMappings)
126 if node ~= nil then
127 spec.steeringWheel = {}
128 spec.steeringWheel.node = node
129 local _,ry,_ = getRotation(spec.steeringWheel.node)
130 spec.steeringWheel.lastRotation = ry
131 spec.steeringWheel.indoorRotation = math.rad( Utils.getNoNil( getXMLFloat(self.xmlFile, "vehicle.drivable.steeringWheel#indoorRotation"), 0 ) )
132 spec.steeringWheel.outdoorRotation = math.rad( Utils.getNoNil( getXMLFloat(self.xmlFile, "vehicle.drivable.steeringWheel#outdoorRotation"), 0 ) )
133 end
134
135 if self.loadDashboardsFromXML ~= nil then
136 local dashKey = "vehicle.drivable.dashboards"
137 self:loadDashboardsFromXML(self.xmlFile, dashKey, {valueTypeToLoad = "cruiseControl",
138 valueObject = spec.cruiseControl,
139 valueFunc = "speed"})
140
141 self:loadDashboardsFromXML(self.xmlFile, dashKey, {valueTypeToLoad = "directionForward",
142 valueObject = self,
143 valueFunc = "getIsDrivingForward"})
144
145 self:loadDashboardsFromXML(self.xmlFile, dashKey, {valueTypeToLoad = "directionBackward",
146 valueObject = self,
147 valueFunc = "getIsDrivingBackward"})
148
149 self:loadDashboardsFromXML(self.xmlFile, dashKey, {valueTypeToLoad = "movingDirection",
150 valueObject = self,
151 valueFunc = "getDrivingDirection",
152 minFunc = -1,
153 maxFunc = 1})
154
155 self:loadDashboardsFromXML(self.xmlFile, dashKey, {valueTypeToLoad = "cruiseControlActive",
156 valueObject = spec.cruiseControl,
157 valueFunc = "state",
158 valueCompare = Drivable.CRUISECONTROL_STATE_ACTIVE})
159
160 self:loadDashboardsFromXML(self.xmlFile, dashKey, {valueTypeToLoad = "accelerationAxis",
161 valueObject = self,
162 valueFunc = "getAccelerationAxis"})
163
164 self:loadDashboardsFromXML(self.xmlFile, dashKey, {valueTypeToLoad = "decelerationAxis",
165 valueObject = self,
166 valueFunc = "getDecelerationAxis"})
167
168 self:loadDashboardsFromXML(self.xmlFile, dashKey, {valueTypeToLoad = "ac_decelerationAxis",
169 valueObject = self,
170 valueFunc = "getAcDecelerationAxis"})
171
172 self:loadDashboardsFromXML(self.xmlFile, dashKey, {valueTypeToLoad = "steeringAngle",
173 valueObject = self,
174 valueFunc = "getDashboardSteeringAxis",
175 minFunc = -1,
176 maxFunc = 1})
177 end
178
179 if self.isClient then
180 spec.samples = {}
181 spec.samples.waterSplash = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.drivable.sounds", "waterSplash", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self)
182 if self.isClient and g_isDevelopmentVersion then
183 if spec.samples.waterSplash == nil then
184 g_logManager:xmlDevWarning(self.configFileName, "Missing drivable waterSplash sound")
185 end
186 end
187 end
188
189 if savegame ~= nil then
190 local maxSpeed = getXMLInt(savegame.xmlFile, savegame.key..".drivable#cruiseControl")
191 self:setCruiseControlMaxSpeed(maxSpeed)
192 end
193
194 spec.dirtyFlag = self:getNextDirtyFlag()
195end

onReadStream

Description
Called on client side on join
Definition
onReadStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
219function Drivable:onReadStream(streamId, connection)
220 local spec = self.spec_drivable
221
222 if spec.cruiseControl.isActive then
223 self:setCruiseControlState(streamReadUIntN(streamId, 2), true)
224 local speed = streamReadUInt8(streamId)
225 self:setCruiseControlMaxSpeed(speed)
226 spec.cruiseControl.speedSent = speed
227 end
228end

onReadUpdateStream

Description
Called on on update
Definition
onReadUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdstream ID
integertimestamptimestamp
tableconnectionconnection
Code
248function Drivable:onReadUpdateStream(streamId, timestamp, connection)
249 local spec = self.spec_drivable
250
251 if streamReadBool(streamId) then
252 spec.axisForward = streamReadUIntN(streamId, 10) / 1023 * 2 - 1
253 if math.abs(spec.axisForward) < 0.00099 then
254 spec.axisForward = 0 -- set to 0 to avoid noise caused by compression
255 end
256
257 spec.axisSide = streamReadUIntN(streamId, 10) / 1023 * 2 - 1
258 if math.abs(spec.axisSide) < 0.00099 then
259 spec.axisSide = 0 -- set to 0 to avoid noise caused by compression
260 end
261
262 spec.doHandbrake = streamReadBool(streamId)
263 end
264end

onRegisterActionEvents

Description
Definition
onRegisterActionEvents()
Code
678function Drivable:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
679 if self.isClient then
680 local spec = self.spec_drivable
681
682 spec.toggleCruiseControlEvent = nil
683 self:clearActionEventsTable(spec.actionEvents)
684
685 local entered = true
686 if self.getIsEntered ~= nil then
687 entered = self:getIsEntered()
688 end
689
690 local _, actionEventId
691
692 local levelVery = g_isPresentationVersionShowDrivingHelp and GS_PRIO_VERY_HIGHT or GS_PRIO_VERY_LOW
693 local level = g_isPresentationVersionShowDrivingHelp and GS_PRIO_HIGH or GS_PRIO_LOW
694 local visibility = g_isPresentationVersionShowDrivingHelp
695
696 if self:getIsActiveForInput(true, true) and entered then
697 if not self:getIsAIActive() then
698 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.AXIS_ACCELERATE_VEHICLE, self, Drivable.actionEventAccelerate, false, false, true, true, nil)
699 g_inputBinding:setActionEventTextPriority(actionEventId, levelVery)
700 g_inputBinding:setActionEventTextVisibility(actionEventId, visibility)
701 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.AXIS_BRAKE_VEHICLE, self, Drivable.actionEventBrake, false, false, true, true, nil)
702 g_inputBinding:setActionEventTextPriority(actionEventId, levelVery)
703 g_inputBinding:setActionEventTextVisibility(actionEventId, visibility)
704 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.AXIS_MOVE_SIDE_VEHICLE, self, Drivable.actionEventSteer, false, false, true, true, nil)
705 g_inputBinding:setActionEventTextPriority(actionEventId, levelVery)
706 g_inputBinding:setActionEventTextVisibility(actionEventId, visibility)
707 g_inputBinding:setActionEventText(actionEventId, g_i18n:getText("action_steer"))
708
709 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.TOGGLE_CRUISE_CONTROL, self, Drivable.actionEventCruiseControlState, false, true, true, true, nil)
710 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_LOW)
711 spec.toggleCruiseControlEvent = actionEventId
712 end
713
714 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.AXIS_CRUISE_CONTROL, self, Drivable.actionEventCruiseControlValue, false, true, true, true, nil)
715 g_inputBinding:setActionEventText(actionEventId, g_i18n:getText("action_changeCruiseControlLevel"))
716 g_inputBinding:setActionEventTextPriority(actionEventId, level)
717 end
718 end
719end

onSetBroken

Description
Definition
onSetBroken()
Code
733function Drivable:onSetBroken()
734 if self.isClient then
735 local spec = self.spec_drivable
736 g_soundManager:playSample(spec.samples.waterSplash)
737 end
738end

onUpdate

Description
Definition
onUpdate()
Code
287function Drivable:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
288 local spec = self.spec_drivable
289
290 -- update inputs on client side for basic controls
291 if self.isClient then
292 if self.getIsEntered ~= nil and self:getIsEntered() then
293 if self:getIsActiveForInput(true, true) then
294 if self:getIsVehicleControlledByPlayer() then
295 spec.doHandbrake = false
296
297 -- gas and brake pedal
298 local axisForward = MathUtil.clamp((spec.lastInputValues.axisAccelerate - spec.lastInputValues.axisBrake), -1, 1)
299 spec.axisForward = axisForward
300
301 -- steering
302 local speedFactor = 1.0
303 local sensitivitySetting = g_gameSettings:getValue(GameSettings.SETTING.STEERING_SENSITIVITY)
304
305 if spec.lastInputValues.axisSteerIsAnalog then
306 local isArticulatedSteering = self.spec_articulatedAxis ~= nil and self.spec_articulatedAxis.componentJoint ~= nil
307 if isArticulatedSteering then
308 speedFactor = 1.5
309 else
310 speedFactor = 2.5
311 end
312
313 -- only use steering speed for gamepads
314 if spec.lastInputValues.axisSteerDeviceCategory == InputDevice.CATEGORY.GAMEPAD then
315 speedFactor = speedFactor * sensitivitySetting
316 end
317 else
318 if spec.lastInputValues.axisSteer == 0 then
319 local rotateBackSpeedSetting = g_gameSettings:getValue(GameSettings.SETTING.STEERING_BACK_SPEED) / 10
320
321 -- if the setting is '1' we use the same speed as we use for steering
322 -- if the setting is smaller '1' we reduce the steering angle depending on the driving speed
323 if rotateBackSpeedSetting < 1 and self.speedDependentRotateBack then
324 local speed = self:getLastSpeed() / 36
325 local setting = rotateBackSpeedSetting / 0.5
326 speedFactor = speedFactor * math.min(speed * setting, 1)
327 end
328
329 speedFactor = speedFactor * (self.autoRotateBackSpeed or 1) / 1.5
330 else
331 speedFactor = math.min(1.0/(self.lastSpeed*spec.speedRotScale+spec.speedRotScaleOffset), 1);
332 speedFactor = speedFactor * sensitivitySetting
333 end
334 end
335
336 local steeringDuration = (self.wheelSteeringDuration or 1) * 1000
337 local rotDelta = (dt / steeringDuration) * speedFactor
338
339 if spec.lastInputValues.axisSteer > spec.axisSide then
340 spec.axisSide = math.min(spec.lastInputValues.axisSteer, spec.axisSide + rotDelta)
341 elseif spec.lastInputValues.axisSteer < spec.axisSide then
342 spec.axisSide = math.max(spec.lastInputValues.axisSteer, spec.axisSide - rotDelta)
343 end
344 else
345 spec.axisForward = 0
346 if self.rotatedTime < 0 then
347 spec.axisSide = self.rotatedTime / -self.maxRotTime / self:getSteeringDirection()
348 else
349 spec.axisSide = self.rotatedTime / self.minRotTime / self:getSteeringDirection()
350 end
351 end
352 else
353 spec.doHandbrake = true
354 spec.axisForward = 0
355 end
356
357 -- prepare for next frame
358 spec.lastInputValues.axisAccelerate = 0
359 spec.lastInputValues.axisBrake = 0
360 spec.lastInputValues.axisSteer = 0
361
362 -- prepare network update
363 if spec.axisForward ~= spec.axisForwardSend or spec.axisSide ~= spec.axisSideSend or spec.doHandbrake ~= spec.doHandbrakeSend then
364 spec.axisForwardSend = spec.axisForward
365 spec.axisSideSend = spec.axisSide
366 spec.doHandbrakeSend = spec.doHandbrake
367 self:raiseDirtyFlags(spec.dirtyFlag)
368 end
369 end
370 end
371
372 -- update inputs on client side for cruise control
373 if self.isClient then
374 if self.getIsEntered ~= nil and self:getIsEntered() then
375 -- cruise control state
376 local inputValue = spec.lastInputValues.cruiseControlState
377 spec.lastInputValues.cruiseControlState = 0
378
379 if inputValue == 1 then
380 if spec.cruiseControl.topSpeedTime == Drivable.CRUISECONTROL_FULL_TOGGLE_TIME then
381 if spec.cruiseControl.state == Drivable.CRUISECONTROL_STATE_OFF then
382 self:setCruiseControlState(Drivable.CRUISECONTROL_STATE_ACTIVE)
383 else
384 self:setCruiseControlState(Drivable.CRUISECONTROL_STATE_OFF)
385 end
386 end
387
388 if spec.cruiseControl.topSpeedTime > 0 then
389 spec.cruiseControl.topSpeedTime = spec.cruiseControl.topSpeedTime - dt
390 if spec.cruiseControl.topSpeedTime < 0 then
391 self:setCruiseControlState(Drivable.CRUISECONTROL_STATE_FULL)
392 end
393 end
394 else
395 spec.cruiseControl.topSpeedTime = Drivable.CRUISECONTROL_FULL_TOGGLE_TIME
396 end
397
398 -- cruise control value
399 local lastCruiseControlValue = spec.lastInputValues.cruiseControlValue
400 spec.lastInputValues.cruiseControlValue = 0
401
402 if lastCruiseControlValue ~= 0 then
403 spec.cruiseControl.changeCurrentDelay = spec.cruiseControl.changeCurrentDelay - (dt * spec.cruiseControl.changeMultiplier)
404 spec.cruiseControl.changeMultiplier = math.min(spec.cruiseControl.changeMultiplier + (dt * 0.003), 10)
405
406 if spec.cruiseControl.changeCurrentDelay < 0 then
407 spec.cruiseControl.changeCurrentDelay = spec.cruiseControl.changeDelay
408
409 local dir = MathUtil.sign(lastCruiseControlValue)
410
411 local speed = spec.cruiseControl.speed + dir
412 self:setCruiseControlMaxSpeed(speed)
413
414 if spec.cruiseControl.speed ~= spec.cruiseControl.speedSent then
415 if g_server ~= nil then
416 g_server:broadcastEvent(SetCruiseControlSpeedEvent:new(self, spec.cruiseControl.speed), nil, nil, self)
417 else
418 g_client:getServerConnection():sendEvent(SetCruiseControlSpeedEvent:new(self, spec.cruiseControl.speed))
419 end
420 spec.cruiseControl.speedSent = spec.cruiseControl.speed
421 end
422 end
423 else
424 spec.cruiseControl.changeCurrentDelay = 0
425 spec.cruiseControl.changeMultiplier = 1
426 end
427
428 end
429 end
430
431 local isControlled = self.getIsControlled ~= nil and self:getIsControlled()
432
433 -- update vehicle physics on server side
434 if self:getIsVehicleControlledByPlayer() then
435 if self.isServer then
436 if isControlled then
437 -- lock max speed to working tool
438 local speed,_ = self:getSpeedLimit(true)
439 if spec.cruiseControl.state == Drivable.CRUISECONTROL_STATE_ACTIVE then
440 speed = math.min(speed, spec.cruiseControl.speed)
441 end
442 self:getMotor():setSpeedLimit(speed)
443
444 self:updateVehiclePhysics(spec.axisForward, spec.axisSide, spec.doHandbrake, dt)
445 end
446 end
447 end
448
449 -- just a visual update of the steering wheel
450 if self.isClient and isControlled then
451 self:updateSteeringWheel(spec.steeringWheel, dt, 1)
452 end
453end

onWriteStream

Description
Called on server side on join
Definition
onWriteStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
234function Drivable:onWriteStream(streamId, connection)
235 local spec = self.spec_drivable
236
237 if spec.cruiseControl.isActive then
238 streamWriteUIntN(streamId, spec.cruiseControl.state, 2)
239 streamWriteUInt8(streamId, spec.cruiseControl.speed)
240 end
241end

onWriteUpdateStream

Description
Called on on update
Definition
onWriteUpdateStream(integer streamId, table connection, integer dirtyMask)
Arguments
integerstreamIdstream ID
tableconnectionconnection
integerdirtyMaskdirty mask
Code
271function Drivable:onWriteUpdateStream(streamId, connection, dirtyMask)
272 local spec = self.spec_drivable
273
274 if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlag) ~= 0) then
275 local axisForward = (spec.axisForward + 1) / 2 * 1023
276 streamWriteUIntN(streamId, axisForward, 10)
277
278 local axisSide = (spec.axisSide + 1) / 2 * 1023
279 streamWriteUIntN(streamId, axisSide, 10)
280
281 streamWriteBool(streamId, spec.doHandbrake)
282 end
283end

prerequisitesPresent

Description
Checks if all prerequisite specializations are loaded
Definition
prerequisitesPresent(table specializations)
Arguments
tablespecializationsspecializations
Return Values
booleanhasPrerequisitetrue if all prerequisite specializations are loaded
Code
26function Drivable.prerequisitesPresent(specializations)
27 return SpecializationUtil.hasSpecialization(Enterable, specializations) and SpecializationUtil.hasSpecialization(Motorized, specializations)
28end

registerEventListeners

Description
Definition
registerEventListeners()
Code
57function Drivable.registerEventListeners(vehicleType)
58 SpecializationUtil.registerEventListener(vehicleType, "onLoad", Drivable)
59 SpecializationUtil.registerEventListener(vehicleType, "onDelete", Drivable)
60 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Drivable)
61 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Drivable)
62 SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", Drivable)
63 SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", Drivable)
64 SpecializationUtil.registerEventListener(vehicleType, "onUpdate", Drivable)
65 SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", Drivable)
66 SpecializationUtil.registerEventListener(vehicleType, "onLeaveVehicle", Drivable)
67 SpecializationUtil.registerEventListener(vehicleType, "onSetBroken", Drivable)
68end

registerFunctions

Description
Definition
registerFunctions()
Code
32function Drivable.registerFunctions(vehicleType)
33 SpecializationUtil.registerFunction(vehicleType, "updateSteeringWheel", Drivable.updateSteeringWheel)
34 SpecializationUtil.registerFunction(vehicleType, "setCruiseControlState", Drivable.setCruiseControlState)
35 SpecializationUtil.registerFunction(vehicleType, "setCruiseControlMaxSpeed", Drivable.setCruiseControlMaxSpeed)
36 SpecializationUtil.registerFunction(vehicleType, "getCruiseControlState", Drivable.getCruiseControlState)
37 SpecializationUtil.registerFunction(vehicleType, "getCruiseControlSpeed", Drivable.getCruiseControlSpeed)
38 SpecializationUtil.registerFunction(vehicleType, "getCruiseControlMaxSpeed", Drivable.getCruiseControlMaxSpeed)
39 SpecializationUtil.registerFunction(vehicleType, "getAxisForward", Drivable.getAxisForward)
40 SpecializationUtil.registerFunction(vehicleType, "getAccelerationAxis", Drivable.getAccelerationAxis)
41 SpecializationUtil.registerFunction(vehicleType, "getDecelerationAxis", Drivable.getDecelerationAxis)
42 SpecializationUtil.registerFunction(vehicleType, "getCruiseControlAxis", Drivable.getCruiseControlAxis)
43 SpecializationUtil.registerFunction(vehicleType, "getAcDecelerationAxis", Drivable.getAcDecelerationAxis)
44 SpecializationUtil.registerFunction(vehicleType, "getDashboardSteeringAxis", Drivable.getDashboardSteeringAxis)
45 SpecializationUtil.registerFunction(vehicleType, "setReverserDirection", Drivable.setReverserDirection)
46 SpecializationUtil.registerFunction(vehicleType, "getReverserDirection", Drivable.getReverserDirection)
47 SpecializationUtil.registerFunction(vehicleType, "getSteeringDirection", Drivable.getSteeringDirection)
48 SpecializationUtil.registerFunction(vehicleType, "getIsDrivingForward", Drivable.getIsDrivingForward)
49 SpecializationUtil.registerFunction(vehicleType, "getIsDrivingBackward", Drivable.getIsDrivingBackward)
50 SpecializationUtil.registerFunction(vehicleType, "getDrivingDirection", Drivable.getDrivingDirection)
51 SpecializationUtil.registerFunction(vehicleType, "getIsVehicleControlledByPlayer", Drivable.getIsVehicleControlledByPlayer)
52 SpecializationUtil.registerFunction(vehicleType, "updateVehiclePhysics", Drivable.updateVehiclePhysics)
53end

saveToXMLFile

Description
Definition
saveToXMLFile()
Code
210function Drivable:saveToXMLFile(xmlFile, key, usedModNames)
211 local spec = self.spec_drivable
212 setXMLFloat(xmlFile, key.."#cruiseControl", spec.cruiseControl.speed)
213end

setCruiseControlMaxSpeed

Description
Sets cruise control max speed
Definition
setCruiseControlMaxSpeed(float speed)
Arguments
floatspeednew max speed
Code
489function Drivable:setCruiseControlMaxSpeed(speed)
490 local spec = self.spec_drivable
491
492 if speed ~= nil then
493 speed = MathUtil.clamp(speed, spec.cruiseControl.minSpeed, spec.cruiseControl.maxSpeed)
494 if spec.cruiseControl.speed ~= speed then
495 spec.cruiseControl.speed = speed
496 if spec.cruiseControl.state == Drivable.CRUISECONTROL_STATE_FULL then
497 spec.cruiseControl.state = Drivable.CRUISECONTROL_STATE_ACTIVE
498 end
499 end
500
501 if spec.cruiseControl.state ~= Drivable.CRUISECONTROL_STATE_OFF then
502 if spec.cruiseControl.state == Drivable.CRUISECONTROL_STATE_ACTIVE then
503 local speed,_ = self:getSpeedLimit(true)
504 speed = math.min(speed, spec.cruiseControl.speed)
505 self:getMotor():setSpeedLimit(speed)
506 else
507 self:getMotor():setSpeedLimit(math.huge)
508 end
509 end
510 end
511end

setCruiseControlState

Description
Changes cruise control state
Definition
setCruiseControlState(integer state, boolean noEventSend)
Arguments
integerstatenew state
booleannoEventSendno event send
Code
459function Drivable:setCruiseControlState(state, noEventSend)
460 local spec = self.spec_drivable
461 if spec.cruiseControl.state ~= state then
462 spec.cruiseControl.state = state
463 if noEventSend == nil or not noEventSend then
464 if not self.isServer then
465 g_client:getServerConnection():sendEvent(SetCruiseControlStateEvent:new(self, state))
466 else
467 local owner = self:getOwner()
468 if owner ~= nil then
469 owner:sendEvent(SetCruiseControlStateEvent:new(self, state))
470 end
471 end
472 end
473
474 if spec.toggleCruiseControlEvent ~= nil then
475 local text
476 if state ~= Drivable.CRUISECONTROL_STATE_ACTIVE then
477 text = g_i18n:getText("action_activateCruiseControl")
478 else
479 text = g_i18n:getText("action_deactivateCruiseControl")
480 end
481 g_inputBinding:setActionEventText(spec.toggleCruiseControlEvent, text)
482 end
483 end
484end

setReverserDirection

Description
Definition
setReverserDirection()
Code
617function Drivable:setReverserDirection(reverserDirection)
618 self.spec_drivable.reverserDirection = reverserDirection
619end

stopMotor

Description
Called on motor stop
Definition
stopMotor(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
672function Drivable:stopMotor(noEventSend)
673 self:setCruiseControlState(Drivable.CRUISECONTROL_STATE_OFF, true)
674end

updateSteeringWheel

Description
Definition
updateSteeringWheel()
Code
515function Drivable:updateSteeringWheel(steeringWheel, dt, direction)
516 if steeringWheel ~= nil then
517 local maxRotation = steeringWheel.outdoorRotation
518 if g_currentMission.controlledVehicle == self then
519 if self.getActiveCamera ~= nil then
520 local activeCamera = self:getActiveCamera()
521 if activeCamera ~= nil and activeCamera.isInside then
522 maxRotation = steeringWheel.indoorRotation
523 end
524 end
525 end
526
527 local rotation = self.rotatedTime * maxRotation
528
529 if steeringWheel.lastRotation ~= rotation then
530 steeringWheel.lastRotation = rotation
531
532 setRotation(steeringWheel.node, 0, rotation * direction, 0)
533
534 if self.getVehicleCharacter ~= nil then
535 local vehicleCharacter = self:getVehicleCharacter()
536 if vehicleCharacter ~= nil then
537 vehicleCharacter:setDirty(true)
538 end
539 end
540 end
541 end
542end

updateVehiclePhysics

Description
Update vehicle physics
Definition
updateVehiclePhysics(float axisForward, boolean axisForwardIsAnalog, float axisSide, boolean axisSideIsAnalog, boolean doHandbrake, float dt)
Arguments
floataxisForwardaxis forward value
booleanaxisForwardIsAnalogforward axis is analog
floataxisSideside axis
booleanaxisSideIsAnalogside axis is analog
booleandoHandbrakedo handbrake
floatdttime since lsat call in ms
Code
748function Drivable:updateVehiclePhysics(axisForward, axisSide, doHandbrake, dt)
749 local spec = self.spec_drivable
750
751 axisForward = axisForward
752 axisSide = self:getSteeringDirection() * axisSide
753
754 local acceleration = 0
755
756 if self:getIsMotorStarted() and self:getMotorStartTime() <= g_currentMission.time then
757 acceleration = axisForward
758 if math.abs(acceleration) > 0 then
759 self:setCruiseControlState(Drivable.CRUISECONTROL_STATE_OFF)
760 end
761 if spec.cruiseControl.state ~= Drivable.CRUISECONTROL_STATE_OFF then
762 acceleration = 1.0
763 end
764 end
765 if not self:getCanMotorRun() then
766 acceleration = 0
767 if self:getIsMotorStarted() then
768 self:stopMotor()
769 end
770 end
771
772 -- only update steering if a player is in the vehicle
773 if self.getIsControlled ~= nil and self:getIsControlled() then
774 local targetRotatedTime = 0
775 if self.maxRotTime ~= nil and self.minRotTime ~= nil then
776 if axisSide < 0 then
777 -- 0 to maxRotTime
778 targetRotatedTime = math.min(-self.maxRotTime * axisSide, self.maxRotTime)
779 else
780 -- 0 to minRotTime
781 targetRotatedTime = math.max(self.minRotTime * axisSide, self.minRotTime)
782 end
783 end
784 self.rotatedTime = targetRotatedTime
785 end
786
787 if self.firstTimeRun then
788 if self.spec_wheels ~= nil then
789 WheelsUtil.updateWheelsPhysics(self, dt, self.lastSpeedReal*self.movingDirection, acceleration, doHandbrake, g_currentMission.missionInfo.stopAndGoBraking)
790 end
791 end
792
793 return acceleration
794end