LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

Motorized

Description
Specialization for all vehicles with motors/engines. Simulates engine, transmission/gears, fuel usage, air brakes
Functions

actionEventClutch

Description
Definition
actionEventClutch()
Code
2606function Motorized.actionEventClutch(self, actionName, inputValue, callbackState, isAnalog)
2607 local spec = self.spec_motorized
2608 spec.clutchState = inputValue
2609
2610 if self.isServer then
2611 spec.motor:onManualClutchChanged(spec.clutchState)
2612
2613 if inputValue > 0 then
2614 self:raiseActive()
2615 end
2616 else
2617 self:raiseDirtyFlags(spec.inputDirtyFlag)
2618 end
2619end

actionEventDirectionChange

Description
Definition
actionEventDirectionChange()
Code
2594function Motorized.actionEventDirectionChange(self, actionName, inputValue, callbackState, isAnalog)
2595 if actionName == InputAction.DIRECTION_CHANGE_POS then
2596 MotorGearShiftEvent.sendEvent(self, MotorGearShiftEvent.TYPE_DIRECTION_CHANGE_POS)
2597 elseif actionName == InputAction.DIRECTION_CHANGE_NEG then
2598 MotorGearShiftEvent.sendEvent(self, MotorGearShiftEvent.TYPE_DIRECTION_CHANGE_NEG)
2599 else
2600 MotorGearShiftEvent.sendEvent(self, MotorGearShiftEvent.TYPE_DIRECTION_CHANGE)
2601 end
2602end

actionEventSelectGear

Description
Definition
actionEventSelectGear()
Code
2548function Motorized.actionEventSelectGear(self, actionName, inputValue, callbackState, isAnalog)
2549 local spec = self.spec_motorized
2550 local gears = spec.motor.currentGears
2551 if gears ~= nil then
2552 for i=1, #gears do
2553 local gear = gears[i]
2554 if gear.inputAction == InputAction[actionName] then
2555 MotorGearShiftEvent.sendEvent(self, MotorGearShiftEvent.TYPE_SELECT_GEAR, inputValue == 1 and i or 0)
2556 return
2557 end
2558 end
2559 end
2560
2561 return MotorGearShiftEvent.sendEvent(self, MotorGearShiftEvent.TYPE_SELECT_GEAR, inputValue == 1 and callbackState or 0)
2562end

actionEventSelectGroup

Description
Definition
actionEventSelectGroup()
Code
2576function Motorized.actionEventSelectGroup(self, actionName, inputValue, callbackState, isAnalog)
2577 local spec = self.spec_motorized
2578 local groups = spec.motor.gearGroups
2579 if groups ~= nil then
2580 for i=1, #groups do
2581 local group = groups[i]
2582 if group.inputAction == InputAction[actionName] then
2583 MotorGearShiftEvent.sendEvent(self, MotorGearShiftEvent.TYPE_SELECT_GROUP, inputValue == 1 and i or 0)
2584 return
2585 end
2586 end
2587 end
2588
2589 return MotorGearShiftEvent.sendEvent(self, MotorGearShiftEvent.TYPE_SELECT_GROUP, inputValue == 1 and callbackState or 0)
2590end

actionEventShiftGear

Description
Definition
actionEventShiftGear()
Code
2538function Motorized.actionEventShiftGear(self, actionName, inputValue, callbackState, isAnalog)
2539 if actionName == InputAction.SHIFT_GEAR_UP then
2540 MotorGearShiftEvent.sendEvent(self, MotorGearShiftEvent.TYPE_SHIFT_UP)
2541 else
2542 MotorGearShiftEvent.sendEvent(self, MotorGearShiftEvent.TYPE_SHIFT_DOWN)
2543 end
2544end

actionEventShiftGroup

Description
Definition
actionEventShiftGroup()
Code
2566function Motorized.actionEventShiftGroup(self, actionName, inputValue, callbackState, isAnalog)
2567 if actionName == InputAction.SHIFT_GROUP_UP then
2568 MotorGearShiftEvent.sendEvent(self, MotorGearShiftEvent.TYPE_SHIFT_GROUP_UP)
2569 else
2570 MotorGearShiftEvent.sendEvent(self, MotorGearShiftEvent.TYPE_SHIFT_GROUP_DOWN)
2571 end
2572end

actionEventToggleMotorState

Description
Definition
actionEventToggleMotorState()
Code
2960function Motorized.actionEventToggleMotorState(self, actionName, inputValue, callbackState, isAnalog)
2961 if not self:getIsAIActive() then
2962 local spec = self.spec_motorized
2963 if spec.isMotorStarted then
2964 self:stopMotor()
2965 else
2966 if self:getCanMotorRun() then
2967 self:startMotor()
2968 else
2969 local warning = self:getMotorNotAllowedWarning()
2970 if warning ~= nil then
2971 g_currentMission:showBlinkingWarning(warning, 2000)
2972 end
2973 end
2974 end
2975 end
2976end

addToPhysics

Description
Add to physics
Definition
addToPhysics()
Return Values
booleansuccesssuccess
Code
2333function Motorized:addToPhysics(superFunc)
2334 if not superFunc(self) then
2335 return false
2336 end
2337
2338 if self.isServer then
2339 local spec = self.spec_motorized
2340
2341 if spec.motorizedNode ~= nil then
2342 if next(spec.differentials) ~= nil then
2343
2344 for _, differential in pairs(spec.differentials) do
2345 local diffIndex1 = differential.diffIndex1
2346 local diffIndex2 = differential.diffIndex2
2347
2348 if differential.diffIndex1IsWheel then
2349 diffIndex1 = self:getWheelFromWheelIndex(diffIndex1).wheelShape
2350 end
2351 if differential.diffIndex2IsWheel then
2352 diffIndex2 = self:getWheelFromWheelIndex(diffIndex2).wheelShape
2353 end
2354
2355 addDifferential( spec.motorizedNode,
2356 diffIndex1,
2357 differential.diffIndex1IsWheel,
2358 diffIndex2,
2359 differential.diffIndex2IsWheel,
2360 differential.torqueRatio,
2361 differential.maxSpeedRatio )
2362 end
2363
2364 self:updateMotorProperties()
2365
2366 self:controlVehicle(0.0, 0.0, 0.0, 0.0, math.huge, 0.0, 0.0, 0.0, 0.0, 0.0)
2367 end
2368 end
2369 end
2370
2371 return true
2372end

controlVehicle

Description
Update the motor properties based on script motor state
Definition
controlVehicle()
Code
2406function Motorized:controlVehicle(acceleratorPedal, maxSpeed, maxAcceleration, minMotorRotSpeed, maxMotorRotSpeed, maxMotorRotAcceleration, minGearRatio, maxGearRatio, maxClutchTorque, neededPtoTorque)
2407 local spec = self.spec_motorized
2408
2409 controlVehicle(spec.motorizedNode, acceleratorPedal, maxSpeed, maxAcceleration, minMotorRotSpeed, maxMotorRotSpeed, maxMotorRotAcceleration, minGearRatio, maxGearRatio, maxClutchTorque, neededPtoTorque)
2410
2411 -- wake up the phyiscs if the value change while the motorized node is sleeping to force an update
2412 local lastParameters = spec.lastControlParameters
2413 if getIsSleeping(spec.motorizedNode) then
2414 if acceleratorPedal ~= lastParameters.acceleratorPedal
2415 or maxSpeed ~= lastParameters.maxSpeed
2416 or maxAcceleration ~= lastParameters.maxAcceleration
2417 or minMotorRotSpeed ~= lastParameters.minMotorRotSpeed
2418 or maxMotorRotSpeed ~= lastParameters.maxMotorRotSpeed
2419 or maxMotorRotAcceleration ~= lastParameters.maxMotorRotAcceleration
2420 or minGearRatio ~= lastParameters.minGearRatio
2421 or maxGearRatio ~= lastParameters.maxGearRatio
2422 or maxClutchTorque ~= lastParameters.maxClutchTorque
2423 or neededPtoTorque ~= lastParameters.neededPtoTorque then
2424 I3DUtil.wakeUpObject(spec.motorizedNode)
2425 end
2426 end
2427
2428 lastParameters.acceleratorPedal = acceleratorPedal
2429 lastParameters.maxSpeed = maxSpeed
2430 lastParameters.maxAcceleration = maxAcceleration
2431 lastParameters.minMotorRotSpeed = minMotorRotSpeed
2432 lastParameters.maxMotorRotSpeed = maxMotorRotSpeed
2433 lastParameters.maxMotorRotAcceleration = maxMotorRotAcceleration
2434 lastParameters.minGearRatio = minGearRatio
2435 lastParameters.maxGearRatio = maxGearRatio
2436 lastParameters.maxClutchTorque = maxClutchTorque
2437 lastParameters.neededPtoTorque = neededPtoTorque
2438end

generateShiftAnimation

Description
Definition
generateShiftAnimation()
Code
2669function Motorized:generateShiftAnimation(gearLever, state, time, isResetPosition)
2670 local gearLeverInterpolator = {}
2671 gearLeverInterpolator.interpolations = {}
2672
2673 state.curRotation[1], state.curRotation[2], state.curRotation[3] = getRotation(gearLever.node)
2674
2675 -- check if the current rotation is already the target rotation
2676 local requiresChange = false
2677 for axis=1, 3 do
2678 if math.abs(state.curRotation[axis]-state.rotation[axis]) > 0.00001 then
2679 requiresChange = true
2680 break
2681 end
2682 end
2683
2684 -- check if the current target direction is already the target direction
2685 local alreadyMovingToTarget = true
2686 for axis=1, 3 do
2687 if math.abs(gearLever.curTarget[axis]-state.rotation[axis]) > 0.00001 then
2688 alreadyMovingToTarget = false
2689 break
2690 end
2691 end
2692
2693 if not requiresChange or alreadyMovingToTarget then
2694 return false
2695 end
2696
2697 gearLever.curTarget[1], gearLever.curTarget[2], gearLever.curTarget[3] = state.curRotation[1], state.curRotation[2], state.curRotation[3]
2698
2699 local requiresMoveToCenter = false
2700 if gearLever.centerAxis ~= nil then
2701 local curCenter = state.curRotation[gearLever.centerAxis]
2702 local tarCenter = state.rotation[gearLever.centerAxis]
2703 requiresMoveToCenter = math.abs(curCenter-tarCenter) > 0.00001
2704 end
2705
2706 -- move to center on non center axis
2707 if requiresMoveToCenter then
2708 for axis=1, 3 do
2709 if axis ~= gearLever.centerAxis then
2710 local cur = state.curRotation[axis]
2711 local tar = state.rotation[axis]
2712 if gearLever.centerAxis ~= nil then
2713 tar = 0
2714 end
2715
2716 local allowed = math.abs(cur-tar) > 0.00001
2717 local goToCenter = false
2718 if gearLever.centerAxis ~= nil and not allowed then
2719 allowed = state.useRotation[axis] and math.abs(state.curRotation[gearLever.centerAxis]-state.rotation[gearLever.centerAxis]) > 0.00001
2720 goToCenter = allowed
2721 end
2722
2723 if allowed then
2724 table.insert(gearLeverInterpolator.interpolations, {axis=axis, cur=cur, tar=(goToCenter and 0 or tar)})
2725 gearLever.curTarget[axis] = tar
2726 end
2727 end
2728 end
2729 end
2730
2731 if gearLever.centerAxis ~= nil then
2732 -- align center axis to new state
2733 if requiresMoveToCenter then
2734 local curCenter = state.curRotation[gearLever.centerAxis]
2735 local tarCenter = state.rotation[gearLever.centerAxis]
2736 table.insert(gearLeverInterpolator.interpolations, {axis=gearLever.centerAxis, cur=curCenter, tar=tarCenter})
2737 gearLever.curTarget[gearLever.centerAxis] = tarCenter
2738 end
2739
2740 -- move non center axis to final position
2741 for axis=1, 3 do
2742 if axis ~= gearLever.centerAxis then
2743 local cur = state.curRotation[axis]
2744 local tar = state.rotation[axis]
2745 local allowed = math.abs(cur-tar) > 0.00001
2746 if gearLever.centerAxis ~= nil and not allowed then
2747 allowed = state.useRotation[axis] and math.abs(state.curRotation[gearLever.centerAxis]-state.rotation[gearLever.centerAxis]) > 0.00001
2748 end
2749
2750 if allowed then
2751 table.insert(gearLeverInterpolator.interpolations, {axis=axis, cur=requiresMoveToCenter and 0 or cur, tar=tar})
2752 gearLever.curTarget[axis] = tar
2753 end
2754 end
2755 end
2756 end
2757
2758 for intState, _ in pairs(self.spec_motorized.activeGearLeverInterpolators) do
2759 if intState.gearLever == state.gearLever then
2760 self.spec_motorized.activeGearLeverInterpolators[intState] = nil
2761 end
2762 end
2763
2764 if self.spec_motorized.activeGearLeverInterpolators[state] == nil then
2765 local numInterpolations = #gearLeverInterpolator.interpolations
2766 if numInterpolations > 0 then
2767 local timePerInterpolation = math.max(gearLever.changeTime, 0.001) / numInterpolations
2768
2769 for ii=1, numInterpolations do
2770 local interpolation = gearLeverInterpolator.interpolations[ii]
2771 interpolation.speed = (interpolation.tar - interpolation.cur) / timePerInterpolation
2772 end
2773
2774 gearLeverInterpolator.currentInterpolation = 1
2775 gearLeverInterpolator.isResetPosition = (isResetPosition == nil or isResetPosition == true)
2776 gearLeverInterpolator.handsOnDelay = gearLever.handsOnDelay
2777 gearLeverInterpolator.isGear = state.gear ~= nil
2778 self.spec_motorized.activeGearLeverInterpolators[state] = gearLeverInterpolator
2779 end
2780 end
2781end

getAirConsumerUsage

Description
Definition
getAirConsumerUsage()
Code
2247function Motorized:getAirConsumerUsage()
2248 local spec = self.spec_motorized
2249 local consumer = spec.consumersByFillTypeName["AIR"]
2250 return (consumer and consumer.usage) or 0
2251end

getBrakeForce

Description
Definition
getBrakeForce()
Code
2256function Motorized:getBrakeForce(superFunc)
2257 local brakeForce = superFunc(self)
2258 return math.max(brakeForce, self.spec_motorized.motor:getBrakeForce())
2259end

getCanBeSelected

Description
Definition
getCanBeSelected()
Code
2910function Motorized:getCanBeSelected(superFunc)
2911 -- if automatic motor start is disabled we need to choose which vehicle we need to turn on/off
2912 if not g_currentMission.missionInfo.automaticMotorStartEnabled then
2913 local vehicles = self.rootVehicle:getChildVehicles()
2914 for _, vehicle in pairs(vehicles) do
2915 if vehicle.spec_motorized ~= nil then
2916 return true
2917 end
2918 end
2919 end
2920
2921 return superFunc(self)
2922end

getCanMotorRun

Description
Definition
getCanMotorRun()
Code
1716function Motorized:getCanMotorRun()
1717 local spec = self.spec_motorized
1718
1719 for _, fillUnitIndex in ipairs(spec.propellantFillUnitIndices) do
1720 if self:getFillUnitFillLevel(fillUnitIndex) == 0 then
1721 return false
1722 end
1723 end
1724
1725 if not spec.motor:getCanMotorRun() then
1726 return false
1727 end
1728
1729 return true
1730end

getConsumerFillUnitIndex

Description
Definition
getConsumerFillUnitIndex()
Code
2235function Motorized:getConsumerFillUnitIndex(fillTypeIndex)
2236 local spec = self.spec_motorized
2237 local consumer = spec.consumersByFillType[fillTypeIndex]
2238 if consumer ~= nil then
2239 return consumer.fillUnitIndex
2240 end
2241
2242 return nil
2243end

getDashboardSpeedDir

Description
Definition
getDashboardSpeedDir()
Code
2954function Motorized:getDashboardSpeedDir()
2955 return self:getLastSpeed() * self.movingDirection
2956end

getDeactivateLightsOnLeave

Description
Returns if vehicle deactivates lights on leave
Definition
getDeactivateLightsOnLeave()
Return Values
booleandeactivatevehicle deactivates on leave
Code
2457function Motorized:getDeactivateLightsOnLeave(superFunc)
2458 return superFunc(self) and g_currentMission.missionInfo.automaticMotorStartEnabled
2459end

getDeactivateOnLeave

Description
Returns if vehicle deactivates on leave
Definition
getDeactivateOnLeave()
Return Values
booleandeactivatevehicle deactivates on leave
Code
2450function Motorized:getDeactivateOnLeave(superFunc)
2451 return superFunc(self) and g_currentMission.missionInfo.automaticMotorStartEnabled
2452end

getDirectionChangeMode

Description
Returns current direction change mode for vehicle
Definition
getDirectionChangeMode()
Return Values
directionChangeModedirectionchange mode [1: auto, 2: manual]
Code
2824function Motorized:getDirectionChangeMode()
2825 return self.spec_motorized.directionChangeMode
2826end

getGearInfoToDisplay

Description
Returns gear information to display
Definition
getGearInfoToDisplay()
Return Values
stringgeargear name to display
stringgearGroupgear group name to display
Code
2787function Motorized:getGearInfoToDisplay()
2788 local gear, gearGroup, gearsAvailable, groupsAvailable
2789 local isAutomatic, prevGearName, nextGearName, prevPrevGearName, nextNextGearName, isGearChanging
2790 local showNeutralWarning = false
2791
2792 local motor = self.spec_motorized.motor
2793 if motor ~= nil then
2794 gear, gearsAvailable, isAutomatic, prevGearName, nextGearName, prevPrevGearName, nextNextGearName, isGearChanging = motor:getGearToDisplay()
2795
2796 gearGroup, groupsAvailable = motor:getGearGroupToDisplay()
2797 if not groupsAvailable then
2798 gearGroup = nil
2799 end
2800
2801 if self.getAcDecelerationAxis ~= nil then
2802 if math.abs(self:getAcDecelerationAxis()) > 0 then
2803 showNeutralWarning = self:getIsMotorInNeutral()
2804 end
2805 end
2806 end
2807
2808 return gear, gearGroup, gearsAvailable, isAutomatic, prevGearName, nextGearName, prevPrevGearName, nextNextGearName, isGearChanging, showNeutralWarning
2809end

getGearShiftMode

Description
Returns current gear shift mode for vehicle
Definition
getGearShiftMode()
Return Values
gearShiftModegearshift mode [1: auto, 2: manual, 3: manual with clutch]
Code
2838function Motorized:getGearShiftMode()
2839 return self.spec_motorized.gearShiftMode
2840end

getIsActiveForInteriorLights

Description
Definition
getIsActiveForInteriorLights()
Code
2302function Motorized:getIsActiveForInteriorLights(superFunc)
2303 if self.spec_motorized.isMotorStarted then
2304 return true
2305 end
2306
2307 return superFunc(self)
2308end

getIsActiveForWipers

Description
Definition
getIsActiveForWipers()
Code
2312function Motorized:getIsActiveForWipers(superFunc)
2313 if not self.spec_motorized.isMotorStarted then
2314 return false
2315 end
2316
2317 return superFunc(self)
2318end

getIsDashboardGroupActive

Description
Definition
getIsDashboardGroupActive()
Code
2276function Motorized:getIsDashboardGroupActive(superFunc, group)
2277 local spec = self.spec_motorized
2278
2279 if group.isMotorRunning and group.isMotorStarting then
2280 if not spec.isMotorStarted then
2281 return false
2282 end
2283 end
2284
2285 if group.isMotorStarting and not group.isMotorRunning then
2286 if not spec.isMotorStarted or spec.motorStartTime < g_currentMission.time then
2287 return false
2288 end
2289 end
2290
2291 if group.isMotorRunning and not group.isMotorStarting then
2292 if not spec.isMotorStarted or spec.motorStartTime > g_currentMission.time then
2293 return false
2294 end
2295 end
2296
2297 return superFunc(self, group)
2298end

getIsManualDirectionChangeAllowed

Description
Returns if the manual direction change is currently allowed
Definition
getIsManualDirectionChangeAllowed()
Return Values
booleanisAllowedisAllowed
Code
2831function Motorized:getIsManualDirectionChangeAllowed()
2832 return not self:getIsAIActive()
2833end

getIsMotorInNeutral

Description
Returns if motor is in neutral state
Definition
getIsMotorInNeutral()
Return Values
booleanisNeutralis neutral
Code
1703function Motorized:getIsMotorInNeutral()
1704 return self.spec_motorized.motor:getIsInNeutral()
1705end

getIsMotorStarted

Description
Returns if motor is stated
Definition
getIsMotorStarted()
Return Values
booleanisStartedmotor is started
Code
1696function Motorized:getIsMotorStarted(isRunning)
1697 return self.spec_motorized.isMotorStarted and (not isRunning or self.spec_motorized.motorStartTime < g_currentMission.time)
1698end

getIsOperating

Description
Returns if vehicle is operating
Definition
getIsOperating()
Return Values
booleanisOperatingis operating
Code
2443function Motorized:getIsOperating(superFunc)
2444 return superFunc(self) or self:getIsMotorStarted()
2445end

getIsPowered

Description
Definition
getIsPowered()
Code
2926function Motorized:getIsPowered(superFunc)
2927 local ret = superFunc(self)
2928 if ret then
2929 if not self.spec_motorized.isMotorStarted then
2930 local vehicles = self.rootVehicle:getChildVehicles()
2931 for _, vehicle in pairs(vehicles) do
2932 if vehicle ~= self then
2933 if vehicle.spec_motorized ~= nil then
2934 if vehicle.spec_motorized.isMotorStarted then
2935 return true
2936 end
2937 end
2938 end
2939 end
2940
2941 if self:getCanMotorRun() then
2942 return false, g_i18n:getText("warning_motorNotStarted")
2943 else
2944 return false, self:getMotorNotAllowedWarning()
2945 end
2946 end
2947 end
2948
2949 return ret
2950end

getMotor

Description
Definition
getMotor()
Code
2165function Motorized:getMotor()
2166 return self.spec_motorized.motor
2167end

getMotorBlowOffValveState

Description
Definition
getMotorBlowOffValveState()
Code
2217function Motorized:getMotorBlowOffValveState()
2218 return self.spec_motorized.motor.blowOffValveState
2219end

getMotorBrakeTime

Description
Definition
getMotorBrakeTime()
Code
2205function Motorized:getMotorBrakeTime()
2206 local sample = self.spec_motorized.samples.compressedAir
2207 if sample ~= nil then
2208 return sample.lastBrakeTime / 1000
2209 end
2210
2211 return 0
2212end

getMotorDifferentialSpeed

Description
Definition
getMotorDifferentialSpeed()
Code
2224function Motorized:getMotorDifferentialSpeed()
2225 if self.spec_motorized == nil then
2226 Logging.error("Sound modifier 'DIFFERENTIAL_SPEED' used on non motorized vehicle '%s'", self.configFileName)
2227 return 0
2228 end
2229 return math.abs(self.spec_motorized.motor.differentialRotSpeed * 3.6)
2230end

getMotorIgnitionState

Description
Returns motor ignition state (Off: 0, Turning on: 1 Turned on: 2)
Definition
getMotorIgnitionState()
Return Values
booleanisNeutralis neutral
Code
1710function Motorized:getMotorIgnitionState()
1711 return self.spec_motorized.isMotorStarted and (self.spec_motorized.motorStartTime > g_currentMission.time and 1 or 2) or 0
1712end

getMotorLoadPercentage

Description
Definition
getMotorLoadPercentage()
Code
2198function Motorized:getMotorLoadPercentage()
2199 return self.spec_motorized.smoothedLoadPercentage
2200end

getMotorNotAllowedWarning

Description
Definition
getMotorNotAllowedWarning()
Code
1746function Motorized:getMotorNotAllowedWarning()
1747 local spec = self.spec_motorized
1748
1749 for _, fillUnit in pairs(spec.propellantFillUnitIndices) do
1750 if self:getFillUnitFillLevel(fillUnit) == 0 then
1751 return spec.consumersEmptyWarning
1752 end
1753 end
1754
1755 local canMotorRun, reason = spec.motor:getCanMotorRun()
1756 if not canMotorRun then
1757 if reason == VehicleMotor.REASON_CLUTCH_NOT_ENGAGED then
1758 return spec.clutchNoEngagedWarning
1759 end
1760 end
1761
1762 return nil
1763end

getMotorRpmPercentage

Description
Definition
getMotorRpmPercentage()
Code
2183function Motorized:getMotorRpmPercentage()
2184 local motor = self.spec_motorized.motor
2185 return (motor:getLastModulatedMotorRpm() - motor:getMinRpm()) / (motor:getMaxRpm() - motor:getMinRpm())
2186end

getMotorRpmReal

Description
Definition
getMotorRpmReal()
Code
2191function Motorized:getMotorRpmReal()
2192 return self.spec_motorized.motor:getLastModulatedMotorRpm()
2193end

getMotorStartTime

Description
Definition
getMotorStartTime()
Code
2171function Motorized:getMotorStartTime()
2172 return self.spec_motorized.motorStartTime
2173end

getMotorType

Description
Definition
getMotorType()
Code
2177function Motorized:getMotorType()
2178 return self.spec_motorized.motorType
2179end

getName

Description
Definition
getName()
Code
2893function Motorized:getName(superFunc)
2894 local name = superFunc(self)
2895
2896 local item = g_storeManager:getItemByXMLFilename(self.configFileName)
2897 if item ~= nil and item.configurations ~= nil then
2898 local configId = self.configurations["motor"]
2899 local config = item.configurations["motor"][configId]
2900 if config.name and config.name ~= "" then
2901 name = config.name
2902 end
2903 end
2904
2905 return name
2906end

getSpecValueFuel

Description
Definition
getSpecValueFuel()
Code
3076function Motorized.getSpecValueFuel(storeItem, realItem, configurations, fillTypeFilter)
3077 local consumerIndex = 1
3078 if realItem ~= nil and storeItem.configurations ~= nil and realItem.configurations["motor"] ~= nil and storeItem.configurations["motor"] ~= nil then
3079 local motorConfigId = realItem.configurations["motor"]
3080 consumerIndex = Utils.getNoNil(storeItem.configurations["motor"][motorConfigId].consumerConfigurationIndex, consumerIndex)
3081 elseif configurations ~= nil then
3082 local motorConfigId = configurations["motor"]
3083 if motorConfigId ~= nil then
3084 consumerIndex = Utils.getNoNil(storeItem.configurations["motor"][motorConfigId].consumerConfigurationIndex, consumerIndex)
3085 end
3086 end
3087
3088 local fuel, def, electricCharge, methane
3089
3090 local fuelFillUnitIndex, defFillUnitIndex, electricFillUnitIndex, methaneFillUnitIndex = 0, 0, 0, 0
3091
3092 --#debug if storeItem.specs.fuel == nil then printCallstack() end
3093
3094 local consumerConfiguration = storeItem.specs.fuel and storeItem.specs.fuel.consumers[consumerIndex]
3095 if consumerConfiguration ~= nil then
3096 for _, unitConsumers in ipairs(consumerConfiguration) do
3097 local fillType = g_fillTypeManager:getFillTypeIndexByName(unitConsumers.fillType)
3098
3099 if fillTypeFilter == nil or fillType == fillTypeFilter then
3100 if fillType == FillType.DIESEL then
3101 fuelFillUnitIndex = unitConsumers.fillUnitIndex
3102 fuel = unitConsumers.capacity
3103
3104 if fillType == FillType.DEF then
3105 defFillUnitIndex = unitConsumers.fillUnitIndex
3106 def = unitConsumers.capacity
3107 end
3108 elseif fillType == FillType.ELECTRICCHARGE then
3109 electricFillUnitIndex = unitConsumers.fillUnitIndex
3110 electricCharge = unitConsumers.capacity
3111 elseif fillType == FillType.METHANE then
3112 methaneFillUnitIndex = unitConsumers.fillUnitIndex
3113 methane = unitConsumers.capacity
3114 end
3115 end
3116 end
3117 end
3118
3119 local fuelConfigIndex = 1
3120 if realItem ~= nil and storeItem.configurations ~= nil and realItem.configurations["fillUnit"] ~= nil and storeItem.configurations["fillUnit"] ~= nil then
3121 fuelConfigIndex = realItem.configurations["fillUnit"]
3122 end
3123
3124 if storeItem.specs.fuel and storeItem.specs.fuel.fillUnits[fuelConfigIndex] ~= nil then
3125 local fuelFillUnit = storeItem.specs.fuel.fillUnits[fuelConfigIndex][fuelFillUnitIndex]
3126 if fuelFillUnit ~= nil and fuel == nil then
3127 fuel = math.max(fuelFillUnit.capacity, fuel or 0)
3128 end
3129
3130 local defFillUnit = storeItem.specs.fuel.fillUnits[fuelConfigIndex][defFillUnitIndex]
3131 if defFillUnit ~= nil and def == nil then
3132 def = math.max(defFillUnit.capacity, def or 0)
3133 end
3134
3135 local electricFillUnit = storeItem.specs.fuel.fillUnits[fuelConfigIndex][electricFillUnitIndex]
3136 if electricFillUnit ~= nil and electricCharge == nil then
3137 electricCharge = math.max(electricFillUnit.capacity, electricCharge or 0)
3138 end
3139
3140 local methaneFillUnit = storeItem.specs.fuel.fillUnits[fuelConfigIndex][methaneFillUnitIndex]
3141 if methaneFillUnit ~= nil and methane == nil then
3142 methane = math.max(methaneFillUnit.capacity, methane or 0)
3143 end
3144
3145 end
3146
3147 if fuel ~= nil then
3148 if def ~= nil and def > 0 then
3149 return string.format(g_i18n:getText("shop_fuelDefValue"), fuel, g_i18n:getText("unit_literShort"), def, g_i18n:getText("unit_literShort"), g_i18n:getText("fillType_def_short"))
3150 else
3151 return string.format(g_i18n:getText("shop_fuelValue"), fuel, g_i18n:getText("unit_literShort"))
3152 end
3153 elseif electricCharge ~= nil then
3154 return string.format(g_i18n:getText("shop_fuelValue"), electricCharge, g_i18n:getText("unit_kw"))
3155 elseif methane ~= nil then
3156 return string.format(g_i18n:getText("shop_fuelValue"), methane, g_i18n:getText("unit_kg"))
3157 end
3158
3159 return nil
3160end

getSpecValueFuelDiesel

Description
Definition
getSpecValueFuelDiesel()
Code
3058function Motorized.getSpecValueFuelDiesel(storeItem, realItem, configurations)
3059 return Motorized.getSpecValueFuel(storeItem, realItem, configurations, FillType.DIESEL)
3060end

getSpecValueFuelElectricCharge

Description
Definition
getSpecValueFuelElectricCharge()
Code
3064function Motorized.getSpecValueFuelElectricCharge(storeItem, realItem, configurations)
3065 return Motorized.getSpecValueFuel(storeItem, realItem, configurations, FillType.ELECTRICCHARGE)
3066end

getSpecValueFuelMethane

Description
Definition
getSpecValueFuelMethane()
Code
3070function Motorized.getSpecValueFuelMethane(storeItem, realItem, configurations)
3071 return Motorized.getSpecValueFuel(storeItem, realItem, configurations, FillType.METHANE)
3072end

getSpecValueMaxSpeed

Description
Definition
getSpecValueMaxSpeed()
Code
3198function Motorized.getSpecValueMaxSpeed(storeItem, realItem)
3199 local maxSpeed = nil
3200 if realItem ~= nil and storeItem.configurations ~= nil and realItem.configurations["motor"] ~= nil and storeItem.configurations["motor"] ~= nil then
3201 local configId = realItem.configurations["motor"]
3202 maxSpeed = Utils.getNoNil(storeItem.configurations["motor"][configId].maxSpeed, maxSpeed)
3203 end
3204 if maxSpeed == nil then
3205 maxSpeed = storeItem.specs.maxSpeed
3206 end
3207 if maxSpeed ~= nil then
3208 return string.format(g_i18n:getText("shop_maxSpeed"), string.format("%1d", g_i18n:getSpeed(maxSpeed)), g_i18n:getSpeedMeasuringUnit())
3209 end
3210 return nil
3211end

getSpecValuePower

Description
Definition
getSpecValuePower()
Code
3221function Motorized.getSpecValuePower(storeItem, realItem, configurations, saleItem, returnValues, returnRange)
3222 local minPower = nil
3223 local maxPower = nil
3224 if realItem ~= nil and storeItem.configurations ~= nil and realItem.configurations["motor"] ~= nil and storeItem.configurations["motor"] ~= nil then
3225 local configId = realItem.configurations["motor"]
3226 minPower = storeItem.configurations["motor"][configId].power
3227 maxPower = minPower
3228 elseif realItem == nil and storeItem.configurations ~= nil and storeItem.configurations["motor"] ~= nil then
3229 for configId=1, #storeItem.configurations["motor"] do
3230 local configItem = storeItem.configurations["motor"][configId]
3231 if configItem.power ~= nil then
3232 minPower = math.min(minPower or math.huge, configItem.power)
3233 maxPower = math.max(maxPower or 0, configItem.power)
3234 end
3235 end
3236 end
3237
3238 if minPower == nil then
3239 minPower = storeItem.specs.power
3240 maxPower = minPower
3241 end
3242
3243 if minPower ~= nil then
3244 if returnValues == nil or returnValues == false then
3245 if minPower ~= maxPower then
3246 return string.format(g_i18n:getText("shop_maxPowerValueRange"), MathUtil.round(minPower), MathUtil.round(maxPower))
3247 else
3248 return string.format(g_i18n:getText("shop_maxPowerValueSingle"), MathUtil.round(minPower))
3249 end
3250 else
3251 return MathUtil.round(minPower), MathUtil.round(maxPower)
3252 end
3253 end
3254
3255 return nil
3256end

getSpecValueTransmission

Description
Definition
getSpecValueTransmission()
Code
3361function Motorized.getSpecValueTransmission(storeItem, realItem, configurations, saleItem, returnValues, returnRange)
3362 local name
3363 if realItem ~= nil and storeItem.configurations ~= nil and realItem.configurations["motor"] ~= nil and storeItem.configurations["motor"] ~= nil then
3364 name = storeItem.specs.transmission[realItem.configurations["motor"]]
3365 if name == nil then
3366 name = storeItem.specs.transmission[1]
3367 end
3368 else
3369 name = storeItem.specs.transmission[1]
3370 end
3371
3372 return name
3373end

getStopMotorOnLeave

Description
Definition
getStopMotorOnLeave()
Code
1734function Motorized:getStopMotorOnLeave()
1735 if GS_IS_MOBILE_VERSION then
1736 if self.rootVehicle:getActionControllerDirection() == -1 then
1737 return false
1738 end
1739 end
1740
1741 return self.spec_motorized.stopMotorOnLeave
1742end

getStoreAdditionalConfigData

Description
Definition
getStoreAdditionalConfigData()
Code
2980function Motorized.getStoreAdditionalConfigData(xmlFile, baseXMLName, baseDir, customEnvironment, isMod, configItem)
2981 configItem.power = xmlFile:getValue(baseXMLName.."#hp")
2982 configItem.maxSpeed = xmlFile:getValue(baseXMLName.."#maxSpeed")
2983 configItem.consumerConfigurationIndex = xmlFile:getValue(baseXMLName.."#consumerConfigurationIndex")
2984end

getTraveledDistanceStatsActive

Description
Definition
getTraveledDistanceStatsActive()
Code
2649function Motorized:getTraveledDistanceStatsActive()
2650 return true
2651end

getUsageCausesDamage

Description
Definition
getUsageCausesDamage()
Code
2322function Motorized:getUsageCausesDamage(superFunc)
2323 if not self.spec_motorized.isMotorStarted then
2324 return false
2325 end
2326
2327 return superFunc(self)
2328end

initSpecialization

Description
Definition
initSpecialization()
Code
19function Motorized.initSpecialization()
20 g_configurationManager:addConfigurationType("motor", g_i18n:getText("configuration_motorSetup"), "motorized", nil, Motorized.getStoreAdditionalConfigData, nil, ConfigurationUtil.SELECTOR_MULTIOPTION)
21
22 g_storeManager:addSpecType("fuel", "shopListAttributeIconFuel", Motorized.loadSpecValueFuel, Motorized.getSpecValueFuelDiesel, "vehicle")
23 g_storeManager:addSpecType("electricCharge", "shopListAttributeIconElectricCharge", Motorized.loadSpecValueFuel, Motorized.getSpecValueFuelElectricCharge, "vehicle")
24 g_storeManager:addSpecType("methane", "shopListAttributeIconMethane", Motorized.loadSpecValueFuel, Motorized.getSpecValueFuelMethane, "vehicle")
25 g_storeManager:addSpecType("maxSpeed", "shopListAttributeIconMaxSpeed", Motorized.loadSpecValueMaxSpeed, Motorized.getSpecValueMaxSpeed, "vehicle")
26 g_storeManager:addSpecType("power", "shopListAttributeIconPower", Motorized.loadSpecValuePower, Motorized.getSpecValuePower, "vehicle")
27 g_storeManager:addSpecType("powerConfig", "shopListAttributeIconPower", Motorized.loadSpecValuePowerConfig, Motorized.getSpecValuePowerConfig, "vehicle") -- used for export only
28 g_storeManager:addSpecType("transmission", "shopListAttributeIconTransmission", Motorized.loadSpecValueTransmission, Motorized.getSpecValueTransmission, "vehicle")
29
30 Vehicle.registerStateChange("MOTOR_TURN_ON")
31 Vehicle.registerStateChange("MOTOR_TURN_OFF")
32
33 local schema = Vehicle.xmlSchema
34 schema:setXMLSpecializationType("Motorized")
35
36 Motorized.registerDifferentialXMLPaths(schema, "vehicle.motorized.differentialConfigurations.differentialConfiguration(?)")
37 Motorized.registerDifferentialXMLPaths(schema, "vehicle.motorized.differentials")
38
39 Motorized.registerMotorXMLPaths(schema, "vehicle.motorized.motorConfigurations.motorConfiguration(?)")
40
41 ObjectChangeUtil.registerObjectChangeXMLPaths(schema, "vehicle.motorized.motorConfigurations.motorConfiguration(?)")
42
43 Motorized.registerConsumerXMLPaths(schema, "vehicle.motorized.consumerConfigurations.consumerConfiguration(?)")
44 Motorized.registerConsumerXMLPaths(schema, "vehicle.motorized.consumers")
45
46 schema:register(XMLValueType.FLOAT, "vehicle.wheels.wheelConfigurations.wheelConfiguration(?).wheels#maxForwardSpeed", "Max. forward speed")
47 schema:register(XMLValueType.FLOAT, "vehicle.wheels#maxForwardSpeed", "Max. forward speed")
48
49 Motorized.registerSoundXMLPaths(schema, "vehicle.motorized.sounds")
50 Motorized.registerSoundXMLPaths(schema, "vehicle.motorized.motorConfigurations.motorConfiguration(?).sounds")
51
52 schema:register(XMLValueType.FLOAT, "vehicle.motorized.reverseDriveSound#threshold", "Reverse drive sound turn on speed threshold", 4)
53 schema:register(XMLValueType.FLOAT, "vehicle.motorized.brakeCompressor#capacity", "Brake compressor capacity", 6)
54 schema:register(XMLValueType.FLOAT, "vehicle.motorized.brakeCompressor#refillFillLevel", "Brake compressor refill threshold", "half of capacity")
55 schema:register(XMLValueType.FLOAT, "vehicle.motorized.brakeCompressor#fillSpeed", "Brake compressor fill speed", 0.6)
56
57 ParticleUtil.registerParticleXMLPaths(schema, "vehicle.motorized.exhaustParticleSystems", "exhaustParticleSystem(?)")
58
59 schema:register(XMLValueType.FLOAT, "vehicle.motorized.exhaustParticleSystems#minScale", "Min. scale", 0.5)
60 schema:register(XMLValueType.FLOAT, "vehicle.motorized.exhaustParticleSystems#maxScale", "Max. scale", 1)
61
62 schema:register(XMLValueType.NODE_INDEX, "vehicle.motorized.exhaustFlap#node", "Exhaust Flap Node")
63 schema:register(XMLValueType.ANGLE, "vehicle.motorized.exhaustFlap#maxRot", "Max. rotation", 0)
64 schema:register(XMLValueType.INT, "vehicle.motorized.exhaustFlap#rotationAxis", "Rotation Axis", 1)
65
66 schema:register(XMLValueType.NODE_INDEX, "vehicle.motorized.exhaustEffects.exhaustEffect(?)#node", "Effect link node")
67 schema:register(XMLValueType.STRING, "vehicle.motorized.exhaustEffects.exhaustEffect(?)#filename", "Effect i3d filename")
68
69 schema:register(XMLValueType.VECTOR_4, "vehicle.motorized.exhaustEffects.exhaustEffect(?)#minRpmColor", "Min. rpm color", "0 0 0 1")
70 schema:register(XMLValueType.VECTOR_4, "vehicle.motorized.exhaustEffects.exhaustEffect(?)#maxRpmColor", "Max. rpm color", "0.0384 0.0359 0.0627 2.0")
71 schema:register(XMLValueType.FLOAT, "vehicle.motorized.exhaustEffects.exhaustEffect(?)#minRpmScale", "Min. rpm scale", 0.25)
72 schema:register(XMLValueType.FLOAT, "vehicle.motorized.exhaustEffects.exhaustEffect(?)#maxRpmScale", "Max. rpm scale", 0.95)
73 schema:register(XMLValueType.FLOAT, "vehicle.motorized.exhaustEffects.exhaustEffect(?)#upFactor", "Defines how far the effect goes up in the air in meter", 0.75)
74
75 schema:register(XMLValueType.FLOAT, "vehicle.motorized.motorStartDuration", "Motor start duration", "Duration motor takes to start. After this time player can start to drive")
76
77 schema:register(XMLValueType.L10N_STRING, "vehicle.motorized#clutchNoEngagedWarning", "Warning to be displayed if try to start the engine but clutch not engaged", "warning_motorClutchNoEngaged")
78 schema:register(XMLValueType.L10N_STRING, "vehicle.motorized#clutchCrackingGearWarning", "Warning to be display if user trys to select a gear without pressing clutch pedal", "action_clutchCrackingGear")
79 schema:register(XMLValueType.L10N_STRING, "vehicle.motorized#clutchCrackingGroupWarning", "Warning to be display if user trys to select a gear without pressing clutch pedal", "action_clutchCrackingGroup")
80
81 schema:register(XMLValueType.L10N_STRING, "vehicle.motorized#turnOnText", "Motor start text", "action_startMotor")
82 schema:register(XMLValueType.L10N_STRING, "vehicle.motorized#turnOffText", "Motor stop text", "action_stopMotor")
83
84 schema:register(XMLValueType.NODE_INDEX, "vehicle.motorized.gearLevers.gearLever(?)#node", "Gear lever node")
85 schema:register(XMLValueType.INT, "vehicle.motorized.gearLevers.gearLever(?)#centerAxis", "Axis of center bay")
86 schema:register(XMLValueType.TIME, "vehicle.motorized.gearLevers.gearLever(?)#changeTime", "Time to move lever from one state to another", 0.5)
87 schema:register(XMLValueType.TIME, "vehicle.motorized.gearLevers.gearLever(?)#handsOnDelay", "The animation is delayed by this time to have time to put the hand on the lever", 0)
88 schema:register(XMLValueType.INT, "vehicle.motorized.gearLevers.gearLever(?).state(?)#gear", "Gear index")
89 schema:register(XMLValueType.INT, "vehicle.motorized.gearLevers.gearLever(?).state(?)#group", "Group index")
90 schema:register(XMLValueType.ANGLE, "vehicle.motorized.gearLevers.gearLever(?).state(?)#xRot", "X rotation")
91 schema:register(XMLValueType.ANGLE, "vehicle.motorized.gearLevers.gearLever(?).state(?)#yRot", "Y rotation")
92 schema:register(XMLValueType.ANGLE, "vehicle.motorized.gearLevers.gearLever(?).state(?)#zRot", "Z rotation")
93
94 schema:register(XMLValueType.FLOAT, "vehicle.storeData.specs.power", "Power")
95 schema:register(XMLValueType.FLOAT, "vehicle.storeData.specs.maxSpeed", "Max speed")
96 schema:register(XMLValueType.FLOAT, "vehicle.motorized.motorConfigurations.motorConfiguration(?)#maxSpeed", "Max speed for shop")
97 schema:register(XMLValueType.FLOAT, "vehicle.motorized.motorConfigurations.motorConfiguration(?)#hp", "HP for shop")
98
99 schema:register(XMLValueType.STRING, "vehicle.motorized#statsType", "Statistic type", "tractor")
100
101 schema:register(XMLValueType.BOOL, "vehicle.motorized#forceSpeedHudDisplay", "Force usage of vehicle speed display in hud independent of setting", false)
102 schema:register(XMLValueType.BOOL, "vehicle.motorized#forceRpmHudDisplay", "Force usage of motor speed display in hud independent of setting", false)
103
104 Dashboard.registerDashboardXMLPaths(schema, "vehicle.motorized.dashboards", "rpm | load | speed | speedDir | fuelUsage | motorTemperature | motorTemperatureWarning | clutchPedal | gear | gearGroup | movingDirection | directionForward | directionForwardExclusive | directionBackward | movingDirectionLetter | ignitionState")
105 Dashboard.registerDashboardWarningXMLPaths(schema, "vehicle.motorized.dashboards")
106
107 AnimationManager.registerAnimationNodesXMLPaths(schema, "vehicle.motorized.animationNodes")
108
109 schema:register(XMLValueType.BOOL, Dashboard.GROUP_XML_KEY .. "#isMotorStarting", "Is motor starting")
110 schema:register(XMLValueType.BOOL, Dashboard.GROUP_XML_KEY .. "#isMotorRunning", "Is motor running")
111
112 schema:setXMLSpecializationType()
113end

loadConsumerConfiguration

Description
Definition
loadConsumerConfiguration()
Code
1628function Motorized:loadConsumerConfiguration(xmlFile, consumerIndex)
1629 local key = string.format("vehicle.motorized.consumerConfigurations.consumerConfiguration(%d)", consumerIndex-1)
1630
1631 local spec = self.spec_motorized
1632
1633 local fallbackConfigKey = "vehicle.motorized.consumers"
1634
1635 spec.consumersEmptyWarning = self.xmlFile:getValue(key .. "#consumersEmptyWarning", "warning_motorFuelEmpty", self.customEnvironment)
1636
1637 spec.consumers = {}
1638 spec.consumersByFillTypeName = {}
1639 spec.consumersByFillType = {}
1640
1641 if not xmlFile:hasProperty(key) then
1642 return
1643 end
1644
1645 local i = 0
1646 while true do
1647 local consumerKey = string.format(".consumer(%d)", i)
1648 if not xmlFile:hasProperty(key..consumerKey) then
1649 break
1650 end
1651 local consumer = {}
1652 consumer.fillUnitIndex = ConfigurationUtil.getConfigurationValue(xmlFile, key, consumerKey, "#fillUnitIndex", 1, fallbackConfigKey)
1653
1654 local fillTypeName = ConfigurationUtil.getConfigurationValue(xmlFile, key, consumerKey, "#fillType", "consumer", fallbackConfigKey)
1655 consumer.fillType = g_fillTypeManager:getFillTypeIndexByName(fillTypeName)
1656
1657 consumer.capacity = ConfigurationUtil.getConfigurationValue(xmlFile, key, consumerKey, "#capacity", nil, fallbackConfigKey)
1658
1659 local fillUnit = self:getFillUnitByIndex(consumer.fillUnitIndex)
1660 if fillUnit ~= nil then
1661 if fillUnit.supportedFillTypes[consumer.fillType] ~= nil then
1662 fillUnit.capacity = consumer.capacity or fillUnit.capacity
1663
1664 --fill fillUnit on start
1665 fillUnit.startFillLevel = fillUnit.capacity
1666 fillUnit.startFillTypeIndex = consumer.fillType
1667
1668 local usage = ConfigurationUtil.getConfigurationValue(xmlFile, key, consumerKey, "#usage", 1.0, fallbackConfigKey)
1669 consumer.permanentConsumption = ConfigurationUtil.getConfigurationValue(xmlFile, key, consumerKey, "#permanentConsumption", true, fallbackConfigKey)
1670 if consumer.permanentConsumption then
1671 consumer.usage = usage / (60*60*1000) -- from l/h to l/ms
1672 else
1673 consumer.usage = usage
1674 end
1675 consumer.refillLitersPerSecond = ConfigurationUtil.getConfigurationValue(xmlFile, key, consumerKey, "#refillLitersPerSecond", 0, fallbackConfigKey)
1676 consumer.refillCapacityPercentage = ConfigurationUtil.getConfigurationValue(xmlFile, key, consumerKey, "#refillCapacityPercentage", 0, fallbackConfigKey)
1677
1678 consumer.fillLevelToChange = 0
1679
1680 table.insert(spec.consumers, consumer)
1681 spec.consumersByFillTypeName[fillTypeName:upper()] = consumer
1682 spec.consumersByFillType[consumer.fillType] = consumer
1683 else
1684 Logging.xmlWarning(self.xmlFile, "FillUnit '%d' does not support fillType '%s' for consumer '%s'", consumer.fillUnitIndex, fillTypeName, key..consumerKey)
1685 end
1686 else
1687 Logging.xmlWarning(self.xmlFile, "Unknown fillUnit '%d' for consumer '%s'", consumer.fillUnitIndex, key..consumerKey)
1688 end
1689 i = i + 1
1690 end
1691end

loadDashboardGroupFromXML

Description
Definition
loadDashboardGroupFromXML()
Code
2263function Motorized:loadDashboardGroupFromXML(superFunc, xmlFile, key, group)
2264 if not superFunc(self, xmlFile, key, group) then
2265 return false
2266 end
2267
2268 group.isMotorStarting = xmlFile:getValue(key .. "#isMotorStarting")
2269 group.isMotorRunning = xmlFile:getValue(key .. "#isMotorRunning")
2270
2271 return true
2272end

loadDifferentials

Description
Load differentials from xml
Definition
loadDifferentials(integer xmlFile, integer configDifferentialIndex)
Arguments
integerxmlFileid of xml object
integerconfigDifferentialIndexindex of differential config
Code
1175function Motorized:loadDifferentials(xmlFile, configDifferentialIndex)
1176 local key,_ = ConfigurationUtil.getXMLConfigurationKey(xmlFile, configDifferentialIndex, "vehicle.motorized.differentialConfigurations.differentialConfiguration", "vehicle.motorized.differentials", "differentials")
1177
1178 local spec = self.spec_motorized
1179
1180 spec.differentials = {}
1181 if self.isServer and spec.motorizedNode ~= nil then
1182 xmlFile:iterate(key..".differentials.differential", function(_, differentialKey)
1183 local torqueRatio = xmlFile:getValue(differentialKey.."#torqueRatio", 0.5)
1184 local maxSpeedRatio = xmlFile:getValue(differentialKey.."#maxSpeedRatio", 1.3)
1185
1186 local indices = {-1, -1}
1187 local indexIsWheel = {false, false}
1188 for j=1,2 do
1189 local wheelIndex = xmlFile:getValue(differentialKey .. string.format("#wheelIndex%d", j))
1190 if wheelIndex ~= nil then
1191 if self:getWheelFromWheelIndex(wheelIndex) ~= nil then
1192 indices[j] = wheelIndex
1193 indexIsWheel[j] = true
1194 else
1195 Logging.xmlWarning(self.xmlFile, "Unable to find wheelIndex '%d' for differential '%s' (Indices start at 1)", wheelIndex, differentialKey)
1196 end
1197 else
1198 local diffIndex = xmlFile:getValue(differentialKey .. string.format("#differentialIndex%d", j))
1199 if diffIndex ~= nil then
1200 indices[j] = diffIndex - 1
1201 indexIsWheel[j] = false
1202
1203 if diffIndex == 0 then
1204 Logging.xmlWarning(self.xmlFile, "Unable to find differentialIndex '0' for differential '%s' (Indices start at 1)", differentialKey)
1205 end
1206 end
1207 end
1208 end
1209
1210 if indices[1] ~= -1 and indices[2] ~= -1 then
1211 table.insert(spec.differentials, {
1212 torqueRatio = torqueRatio,
1213 maxSpeedRatio = maxSpeedRatio,
1214 diffIndex1 = indices[1],
1215 diffIndex1IsWheel = indexIsWheel[1],
1216 diffIndex2 = indices[2],
1217 diffIndex2IsWheel = indexIsWheel[2] } )
1218 end
1219 end)
1220
1221 if #spec.differentials == 0 then
1222 Logging.xmlWarning(self.xmlFile, "No differentials defined")
1223 end
1224 end
1225end

loadExhaustEffects

Description
Loading of exhaust effects from xml file
Definition
loadExhaustEffects(integer xmlFile, table exhaustEffects)
Arguments
integerxmlFileid of xml object
tableexhaustEffectstable to ass exhaustEffects
Code
1476function Motorized:loadExhaustEffects(xmlFile)
1477 local spec = self.spec_motorized
1478
1479 local minScale = xmlFile:getValue("vehicle.motorized.exhaustParticleSystems#minScale", 0.5)
1480 local maxScale = xmlFile:getValue("vehicle.motorized.exhaustParticleSystems#maxScale", 1)
1481
1482 spec.exhaustParticleSystems = {}
1483 local i = 0
1484 while true do
1485 local baseKey = string.format("vehicle.motorized.exhaustParticleSystems.exhaustParticleSystem(%d)", i)
1486 if not xmlFile:hasProperty(baseKey) then
1487 break
1488 end
1489
1490 local particleSystem = {}
1491 ParticleUtil.loadParticleSystem(xmlFile, particleSystem, baseKey, self.components, false, nil, self.baseDirectory)
1492 particleSystem.minScale = minScale
1493 particleSystem.maxScale = maxScale
1494
1495 table.insert(spec.exhaustParticleSystems, particleSystem)
1496
1497 i = i + 1
1498 end
1499
1500 if #spec.exhaustParticleSystems == 0 then
1501 spec.exhaustParticleSystems = nil
1502 end
1503
1504 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, "vehicle.motorized.exhaustFlap#index", "vehicle.motorized.exhaustFlap#node") --FS17 to FS19
1505
1506 local exhaustFlapNode = xmlFile:getValue("vehicle.motorized.exhaustFlap#node", nil, self.components, self.i3dMappings)
1507 if exhaustFlapNode ~= nil then
1508 spec.exhaustFlap = {}
1509 spec.exhaustFlap.node = exhaustFlapNode
1510 spec.exhaustFlap.maxRot = xmlFile:getValue("vehicle.motorized.exhaustFlap#maxRot", 0)
1511 spec.exhaustFlap.rotationAxis = xmlFile:getValue("vehicle.motorized.exhaustFlap#rotationAxis", 1)
1512 end
1513
1514 spec.exhaustEffects = {}
1515 spec.sharedLoadRequestIds = {}
1516 xmlFile:iterate("vehicle.motorized.exhaustEffects.exhaustEffect", function(index, key)
1517 XMLUtil.checkDeprecatedXMLElements(xmlFile, self.configFileName, key.."#index", key.."#node") --FS17 to FS19
1518
1519 local linkNode = xmlFile:getValue(key.."#node", nil, self.components, self.i3dMappings)
1520 local filename = xmlFile:getValue(key .. "#filename")
1521 if filename ~= nil and linkNode ~= nil then
1522 filename = Utils.getFilename(filename, self.baseDirectory)
1523 local arguments = {
1524 xmlFile = xmlFile,
1525 key = key,
1526 linkNode = linkNode,
1527 filename = filename
1528 }
1529 local sharedLoadRequestId = self:loadSubSharedI3DFile(filename, false, false, self.onExhaustEffectI3DLoaded, self, arguments)
1530 table.insert(spec.sharedLoadRequestIds, sharedLoadRequestId)
1531 end
1532 end)
1533
1534 spec.exhaustEffectMaxSteeringSpeed = 0.001
1535end

loadGearGroups

Description
Definition
loadGearGroups()
Code
1434function Motorized:loadGearGroups(xmlFile, key, motorMaxRpm, axleRatio)
1435 local groups = {}
1436 local i = 0
1437 while true do
1438 local groupKey = string.format(key..".group(%d)", i)
1439 if not xmlFile:hasProperty(groupKey) then
1440 break
1441 end
1442
1443 local ratio = xmlFile:getValue(groupKey.."#ratio")
1444 if ratio ~= nil then
1445 local groupEntry = {}
1446 groupEntry.ratio = 1 / ratio
1447 groupEntry.isDefault = xmlFile:getValue(groupKey.."#isDefault", false)
1448 groupEntry.name = xmlFile:getValue(groupKey.."#name", tostring(i + 1))
1449
1450 groupEntry.actionName = xmlFile:getValue(groupKey.."#actionName")
1451 if (i < 4 or groupEntry.actionName ~= nil) and groupEntry.actionName ~= "-" then
1452 groupEntry.actionName = groupEntry.actionName or string.format("SHIFT_GROUP_SELECT_%d", i + 1)
1453 groupEntry.inputAction = InputAction[groupEntry.actionName]
1454 if groupEntry.inputAction == nil then
1455 Logging.xmlWarning(xmlFile, "Invalid actionName '%s' found for gear group '%s'", groupEntry.actionName, groupKey)
1456 groupEntry.inputAction = InputAction[string.format("SHIFT_GROUP_SELECT_%d", i + 1)]
1457 end
1458 end
1459
1460 table.insert(groups, groupEntry)
1461 end
1462
1463 i = i + 1
1464 end
1465
1466 if #groups > 0 then
1467 return groups
1468 end
1469end

loadGears

Description
Definition
loadGears()
Code
1387function Motorized:loadGears(xmlFile, gearName, key, motorMaxRpm, axleRatio, direction)
1388 local gears = {}
1389 local gearI = 0
1390 while true do
1391 local gearKey = string.format(key..".%s(%d)", gearName, gearI)
1392 if not xmlFile:hasProperty(gearKey) then
1393 break
1394 end
1395
1396 local gearRatio = xmlFile:getValue(gearKey.."#gearRatio")
1397 local maxSpeed = xmlFile:getValue(gearKey.."#maxSpeed")
1398
1399 if maxSpeed ~= nil then
1400 gearRatio = (motorMaxRpm * math.pi) / (maxSpeed / 3.6 * 30)
1401 end
1402
1403 if gearRatio ~= nil then
1404 local gearEntry = {}
1405 gearEntry.ratio = gearRatio * axleRatio
1406 gearEntry.default = xmlFile:getValue(gearKey.."#defaultGear", false)
1407 gearEntry.name = xmlFile:getValue(gearKey.."#name", tostring((gearI + 1) * direction))
1408 gearEntry.reverseName = xmlFile:getValue(gearKey.."#reverseName", tostring((gearI + 1) * direction * -1))
1409
1410 gearEntry.actionName = xmlFile:getValue(gearKey.."#actionName")
1411 if (gearI < 8 or gearEntry.actionName ~= nil) and gearEntry.actionName ~= "-" then
1412 gearEntry.actionName = gearEntry.actionName or string.format("SHIFT_GEAR_SELECT_%d", gearI + 1)
1413
1414 gearEntry.inputAction = InputAction[gearEntry.actionName]
1415 if gearEntry.inputAction == nil then
1416 Logging.xmlWarning(xmlFile, "Invalid actionName '%s' found for gear '%s'", gearEntry.actionName, gearKey)
1417 gearEntry.inputAction = InputAction[string.format("SHIFT_GEAR_SELECT_%d", gearI + 1)]
1418 end
1419 end
1420
1421 table.insert(gears, gearEntry)
1422 end
1423
1424 gearI = gearI + 1
1425 end
1426
1427 if #gears > 0 then
1428 return gears
1429 end
1430end

loadMotor

Description
Load motor from xml file
Definition
loadMotor(integer xmlFile, integer motorId)
Arguments
integerxmlFileid of xml object
integermotorIdindex of motor configuration
Code
1231function Motorized:loadMotor(xmlFile, motorId)
1232 local key
1233 -- Sets motorId to default 1 if motor cannot be found.
1234 key, motorId = ConfigurationUtil.getXMLConfigurationKey(xmlFile, motorId, "vehicle.motorized.motorConfigurations.motorConfiguration", "vehicle.motorized", "motor")
1235
1236 local spec = self.spec_motorized
1237
1238 local fallbackConfigKey = "vehicle.motorized.motorConfigurations.motorConfiguration(0)"
1239
1240 spec.motorType = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#type", "vehicle", fallbackConfigKey)
1241 spec.motorStartAnimation = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#startAnimationName", "vehicle", fallbackConfigKey)
1242
1243 spec.consumerConfigurationIndex = ConfigurationUtil.getConfigurationValue(xmlFile, key, "#consumerConfigurationIndex", "", 1, fallbackConfigKey)
1244
1245 local wheelKey, _ = ConfigurationUtil.getXMLConfigurationKey(xmlFile, self.configurations["wheel"], "vehicle.wheels.wheelConfigurations.wheelConfiguration", "vehicle.wheels", "wheels")
1246
1247 ObjectChangeUtil.updateObjectChanges(xmlFile, "vehicle.motorized.motorConfigurations.motorConfiguration", motorId, self.components, self)
1248
1249 local motorMinRpm = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#minRpm", 1000, fallbackConfigKey)
1250 local motorMaxRpm = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#maxRpm", 1800, fallbackConfigKey)
1251 local minSpeed = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#minSpeed", 1, fallbackConfigKey)
1252 local maxForwardSpeed = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#maxForwardSpeed", nil, fallbackConfigKey)
1253 local maxBackwardSpeed = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#maxBackwardSpeed", nil, fallbackConfigKey)
1254 if maxForwardSpeed ~= nil then
1255 maxForwardSpeed = maxForwardSpeed/3.6
1256 end
1257 if maxBackwardSpeed ~= nil then
1258 maxBackwardSpeed = maxBackwardSpeed/3.6
1259 end
1260
1261 local maxWheelSpeed = ConfigurationUtil.getConfigurationValue(xmlFile, wheelKey, ".wheels", "#maxForwardSpeed", nil, nil)
1262 if maxWheelSpeed ~= nil then
1263 maxForwardSpeed = maxWheelSpeed/3.6
1264 end
1265 local accelerationLimit = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#accelerationLimit", 2.0, fallbackConfigKey) -- m/s^2
1266
1267 local brakeForce = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#brakeForce", 10, fallbackConfigKey) * 2
1268 local lowBrakeForceScale = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#lowBrakeForceScale", 0.5, fallbackConfigKey)
1269 local lowBrakeForceSpeedLimit = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#lowBrakeForceSpeedLimit", 1, fallbackConfigKey) / 3600
1270 local torqueScale = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#torqueScale", 1, fallbackConfigKey)
1271 local ptoMotorRpmRatio = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#ptoMotorRpmRatio", 4, fallbackConfigKey)
1272
1273 -- transmission settings can only be fully overwritten, not only single attributes
1274 local transmissionKey = key .. ".transmission"
1275 if not xmlFile:hasProperty(transmissionKey) then
1276 transmissionKey = fallbackConfigKey .. ".transmission"
1277 end
1278
1279 local minForwardGearRatio = xmlFile:getValue(transmissionKey .. "#minForwardGearRatio")
1280 local maxForwardGearRatio = xmlFile:getValue(transmissionKey .. "#maxForwardGearRatio")
1281 local minBackwardGearRatio = xmlFile:getValue(transmissionKey .. "#minBackwardGearRatio")
1282 local maxBackwardGearRatio = xmlFile:getValue(transmissionKey .. "#maxBackwardGearRatio")
1283 local gearChangeTime = xmlFile:getValue(transmissionKey .. "#gearChangeTime")
1284 local autoGearChangeTime = xmlFile:getValue(transmissionKey .. "#autoGearChangeTime")
1285 local axleRatio = xmlFile:getValue(transmissionKey .. "#axleRatio", 1.0)
1286 local startGearThreshold = xmlFile:getValue(transmissionKey .. "#startGearThreshold", VehicleMotor.GEAR_START_THRESHOLD)
1287
1288
1289 if maxForwardGearRatio == nil or minForwardGearRatio == nil then
1290 minForwardGearRatio = nil
1291 maxForwardGearRatio = nil
1292 else
1293 minForwardGearRatio = minForwardGearRatio * axleRatio
1294 maxForwardGearRatio = maxForwardGearRatio * axleRatio
1295 end
1296 if minBackwardGearRatio == nil or maxBackwardGearRatio == nil then
1297 minBackwardGearRatio = nil
1298 maxBackwardGearRatio = nil
1299 else
1300 minBackwardGearRatio = minBackwardGearRatio * axleRatio
1301 maxBackwardGearRatio = maxBackwardGearRatio * axleRatio
1302 end
1303
1304 -- Read forward gear ratios
1305 local forwardGears
1306 if minForwardGearRatio == nil then
1307 forwardGears = self:loadGears(xmlFile, "forwardGear", transmissionKey, motorMaxRpm, axleRatio, 1)
1308 if forwardGears == nil then
1309 print("Warning: Missing forward gear ratios for motor in '"..self.configFileName.."'!")
1310 forwardGears = {{ratio=1, default=false}}
1311 end
1312 end
1313 -- Read backward gear ratios
1314 local backwardGears
1315 if minBackwardGearRatio == nil then
1316 backwardGears = self:loadGears(xmlFile, "backwardGear", transmissionKey, motorMaxRpm, axleRatio, -1)
1317 end
1318
1319 local gearGroups = self:loadGearGroups(xmlFile, transmissionKey .. ".groups", motorMaxRpm, axleRatio)
1320 local groupsType = xmlFile:getValue(transmissionKey .. ".groups#type", "default")
1321 local groupChangeTime = xmlFile:getValue(transmissionKey .. ".groups#changeTime", 0.5)
1322
1323 local directionChangeUseGear = xmlFile:getValue(transmissionKey .. ".directionChange#useGear", false)
1324 local directionChangeGearIndex = xmlFile:getValue(transmissionKey .. ".directionChange#reverseGearIndex", 1)
1325 local directionChangeUseGroup = xmlFile:getValue(transmissionKey .. ".directionChange#useGroup", false)
1326 local directionChangeGroupIndex = xmlFile:getValue(transmissionKey .. ".directionChange#reverseGroupIndex", 1)
1327 local directionChangeTime = xmlFile:getValue(transmissionKey .. ".directionChange#changeTime", 0.5)
1328
1329 local manualShiftGears = xmlFile:getValue(transmissionKey .. ".manualShift#gears", true)
1330 local manualShiftGroups = xmlFile:getValue(transmissionKey .. ".manualShift#groups", true)
1331
1332 --local maxTorque = 0
1333 local torqueCurve = AnimCurve.new(linearInterpolator1)
1334 local torqueI = 0
1335 local torqueBase = fallbackConfigKey..".motor.torque"
1336 if key ~= nil and xmlFile:hasProperty(key..".motor.torque(0)") then -- using selected motor configuration
1337 torqueBase = key..".motor.torque"
1338 end
1339
1340 while true do
1341 local torqueKey = string.format(torqueBase.."(%d)", torqueI)
1342 local normRpm = xmlFile:getValue(torqueKey.."#normRpm")
1343 local rpm
1344 if normRpm == nil then
1345 rpm = xmlFile:getValue(torqueKey.."#rpm")
1346 else
1347 rpm = normRpm * motorMaxRpm
1348 end
1349 local torque = xmlFile:getValue(torqueKey.."#torque")
1350 if torque == nil or rpm == nil then
1351 break
1352 end
1353 torqueCurve:addKeyframe({torque*torqueScale, time = rpm})
1354 torqueI = torqueI +1
1355 end
1356
1357 spec.motor = VehicleMotor.new(self, motorMinRpm, motorMaxRpm, maxForwardSpeed, maxBackwardSpeed, torqueCurve, brakeForce, forwardGears, backwardGears, minForwardGearRatio, maxForwardGearRatio, minBackwardGearRatio, maxBackwardGearRatio, ptoMotorRpmRatio, minSpeed)
1358 spec.motor:setGearGroups(gearGroups, groupsType, groupChangeTime)
1359 spec.motor:setDirectionChange(directionChangeUseGear, directionChangeGearIndex, directionChangeUseGroup, directionChangeGroupIndex, directionChangeTime)
1360 spec.motor:setManualShift(manualShiftGears, manualShiftGroups)
1361 spec.motor:setStartGearThreshold(startGearThreshold)
1362
1363 local rotInertia = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#rotInertia", spec.motor:getRotInertia(), fallbackConfigKey)
1364 local dampingRateScale = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#dampingRateScale", 1, fallbackConfigKey)
1365 spec.motor:setRotInertia(rotInertia)
1366 spec.motor:setDampingRateScale(dampingRateScale)
1367 spec.motor:setLowBrakeForce(lowBrakeForceScale, lowBrakeForceSpeedLimit)
1368 spec.motor:setAccelerationLimit(accelerationLimit)
1369
1370 local motorRotationAccelerationLimit = ConfigurationUtil.getConfigurationValue(xmlFile, key, ".motor", "#rpmSpeedLimit", nil, fallbackConfigKey) -- xml: rpm/s -> converted to rad/s^2
1371 if motorRotationAccelerationLimit ~= nil then
1372 motorRotationAccelerationLimit = motorRotationAccelerationLimit * math.pi/30
1373 spec.motor:setMotorRotationAccelerationLimit(motorRotationAccelerationLimit)
1374 end
1375
1376 if gearChangeTime ~= nil then
1377 spec.motor:setGearChangeTime(gearChangeTime)
1378 end
1379 if autoGearChangeTime ~= nil then
1380 spec.motor:setAutoGearChangeTime(autoGearChangeTime)
1381 end
1382end

loadSounds

Description
Load sounds from xml file
Definition
loadSounds(integer xmlFile)
Arguments
integerxmlFileid of xml object
Code
1575function Motorized:loadSounds(xmlFile, baseString)
1576 if self.isClient then
1577 local spec = self.spec_motorized
1578
1579 spec.samples = spec.samples or {}
1580
1581 spec.samples.motorStart = g_soundManager:loadSampleFromXML(xmlFile, baseString, "motorStart", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.motorStart
1582 spec.samples.motorStop = g_soundManager:loadSampleFromXML(xmlFile, baseString, "motorStop", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.motorStop
1583 spec.samples.clutchCracking = g_soundManager:loadSampleFromXML(xmlFile, baseString, "clutchCracking", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.clutchCracking
1584 spec.samples.gearEngaged = g_soundManager:loadSampleFromXML(xmlFile, baseString, "gearEngaged", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.gearEngaged
1585 spec.samples.gearDisengaged = g_soundManager:loadSampleFromXML(xmlFile, baseString, "gearDisengaged", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.gearDisengaged
1586 spec.samples.gearGroupChange = g_soundManager:loadSampleFromXML(xmlFile, baseString, "gearGroupChange", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.gearGroupChange
1587 spec.samples.gearLeverStart = g_soundManager:loadSampleFromXML(xmlFile, baseString, "gearLeverStart", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.gearLeverStart
1588 spec.samples.gearLeverEnd = g_soundManager:loadSampleFromXML(xmlFile, baseString, "gearLeverEnd", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.gearLeverEnd
1589 spec.samples.gearGroupLeverStart = g_soundManager:loadSampleFromXML(xmlFile, baseString, "gearGroupLeverStart", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.gearGroupLeverStart
1590 spec.samples.gearGroupLeverEnd = g_soundManager:loadSampleFromXML(xmlFile, baseString, "gearGroupLeverEnd", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.gearGroupLeverEnd
1591 spec.samples.blowOffValve = g_soundManager:loadSampleFromXML(xmlFile, baseString, "blowOffValve", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.blowOffValve
1592 spec.samples.retarder = g_soundManager:loadSampleFromXML(xmlFile, baseString, "retarder", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.retarder
1593
1594 spec.gearboxSamples = g_soundManager:loadSamplesFromXML(xmlFile, baseString, "gearbox", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self, spec.gearboxSamples)
1595 spec.motorSamples = g_soundManager:loadSamplesFromXML(xmlFile, baseString, "motor", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self, spec.motorSamples)
1596
1597 spec.samples.airCompressorStart = g_soundManager:loadSampleFromXML(xmlFile, baseString, "airCompressorStart", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.airCompressorStart
1598 spec.samples.airCompressorStop = g_soundManager:loadSampleFromXML(xmlFile, baseString, "airCompressorStop", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.airCompressorStop
1599 spec.samples.airCompressorRun = g_soundManager:loadSampleFromXML(xmlFile, baseString, "airCompressorRun", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.airCompressorRun
1600
1601 spec.samples.compressedAir = g_soundManager:loadSampleFromXML(xmlFile, baseString, "compressedAir", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.compressedAir
1602 if spec.samples.compressedAir ~= nil then
1603 spec.samples.compressedAir.brakeTime = 0
1604 spec.samples.compressedAir.lastBrakeTime = 0
1605 end
1606
1607 spec.samples.airRelease = g_soundManager:loadSampleFromXML(xmlFile, baseString, "airRelease", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.airRelease
1608
1609 spec.samples.reverseDrive = g_soundManager:loadSampleFromXML(xmlFile, baseString, "reverseDrive", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.reverseDrive
1610 spec.reverseDriveThreshold = xmlFile:getValue("vehicle.motorized.reverseDriveSound#threshold", 4)
1611
1612 spec.brakeCompressor = {}
1613 spec.brakeCompressor.capacity = xmlFile:getValue("vehicle.motorized.brakeCompressor#capacity", 6)
1614 spec.brakeCompressor.refillFilllevel = math.min(spec.brakeCompressor.capacity, xmlFile:getValue("vehicle.motorized.brakeCompressor#refillFillLevel", spec.brakeCompressor.capacity / 2))
1615 spec.brakeCompressor.fillSpeed = xmlFile:getValue("vehicle.motorized.brakeCompressor#fillSpeed", 0.6) / 1000
1616 spec.brakeCompressor.fillLevel = 0
1617 spec.brakeCompressor.doFill = true
1618
1619 spec.isBrakeSamplePlaying = false
1620 spec.samples.brake = g_soundManager:loadSampleFromXML(xmlFile, baseString, "brake", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) or spec.samples.brake
1621
1622 spec.compressionSoundTime = 0
1623 end
1624end

loadSpecValueFuel

Description
Definition
loadSpecValueFuel()
Code
2988function Motorized.loadSpecValueFuel(xmlFile, customEnvironment, baseDir)
2989 local rootName = xmlFile:getRootName()
2990
2991 local fillUnits = {}
2992
2993 local i = 0
2994 while true do
2995 local configKey = string.format(rootName..".fillUnit.fillUnitConfigurations.fillUnitConfiguration(%d)", i)
2996 if not xmlFile:hasProperty(configKey) then
2997 break
2998 end
2999
3000 local configFillUnits = {}
3001
3002 local j = 0
3003 while true do
3004 local fillUnitKey = string.format(configKey .. ".fillUnits.fillUnit(%d)", j)
3005 if not xmlFile:hasProperty(fillUnitKey) then
3006 break
3007 end
3008
3009 local fillTypes = xmlFile:getValue(fillUnitKey .. "#fillTypes")
3010 local capacity = xmlFile:getValue(fillUnitKey .. "#capacity")
3011
3012 table.insert(configFillUnits, {fillTypes=fillTypes, capacity=capacity})
3013 j = j + 1
3014 end
3015
3016 table.insert(fillUnits, configFillUnits)
3017
3018 i = i + 1
3019 end
3020
3021 local consumers = {}
3022
3023 i = 0
3024 while true do
3025 local key = string.format(rootName..".motorized.consumerConfigurations.consumerConfiguration(%d)", i)
3026 if not xmlFile:hasProperty(key) then
3027 break
3028 end
3029
3030 local consumer = {}
3031
3032 local j = 0
3033 while true do
3034 local consumerKey = string.format(key..".consumer(%d)", j)
3035 if not xmlFile:hasProperty(consumerKey) then
3036 break
3037 end
3038
3039 local fillType = xmlFile:getValue(consumerKey .. "#fillType")
3040 local fillUnitIndex = xmlFile:getValue(consumerKey .. "#fillUnitIndex")
3041 local capacity = xmlFile:getValue(consumerKey .. "#capacity")
3042
3043 table.insert(consumer, {fillType=fillType, fillUnitIndex=fillUnitIndex, capacity=capacity})
3044
3045 j = j + 1
3046 end
3047
3048 table.insert(consumers, consumer)
3049
3050 i = i + 1
3051 end
3052
3053 return {fillUnits=fillUnits, consumers=consumers}
3054end

loadSpecValueMaxSpeed

Description
Definition
loadSpecValueMaxSpeed()
Code
3164function Motorized.loadSpecValueMaxSpeed(xmlFile, customEnvironment, baseDir)
3165 local motorKey = nil
3166 if xmlFile:hasProperty("vehicle.motorized.motorConfigurations.motorConfiguration(0)") then
3167 motorKey = "vehicle.motorized.motorConfigurations.motorConfiguration(0)"
3168 elseif xmlFile:hasProperty("vehicle.motor") then
3169 motorKey = "vehicle"
3170 end
3171 if motorKey ~= nil then
3172 local maxRpm = xmlFile:getValue(motorKey..".motor#maxRpm", 1800)
3173 local minForwardGearRatio = xmlFile:getValue(motorKey..".transmission#minForwardGearRatio", nil)
3174
3175 local axleRatio = xmlFile:getValue(motorKey..".transmission#axleRatio", 1.0)
3176 local forwardGears = Motorized.loadGears(nil, xmlFile, "forwardGear", motorKey..".transmission", maxRpm, axleRatio, 1)
3177 local calculatedMaxSpeed = math.ceil(VehicleMotor.calculatePhysicalMaximumSpeed(minForwardGearRatio, forwardGears, maxRpm)*3.6)
3178
3179 local storeDataMaxSpeed = xmlFile:getValue("vehicle.storeData.specs.maxSpeed")
3180 local maxSpeed = xmlFile:getValue("vehicle.motorized.motorConfigurations.motorConfiguration(0)#maxSpeed")
3181 local maxForwardSpeed = xmlFile:getValue(motorKey..".motor#maxForwardSpeed")
3182
3183 if storeDataMaxSpeed ~= nil then
3184 return storeDataMaxSpeed
3185 elseif maxSpeed ~= nil then
3186 return maxSpeed
3187 elseif maxForwardSpeed ~= nil then
3188 return math.min(maxForwardSpeed, calculatedMaxSpeed)
3189 else
3190 return calculatedMaxSpeed
3191 end
3192 end
3193 return nil
3194end

loadSpecValuePower

Description
Definition
loadSpecValuePower()
Code
3215function Motorized.loadSpecValuePower(xmlFile, customEnvironment, baseDir)
3216 return xmlFile:getValue("vehicle.storeData.specs.power")
3217end

loadSpecValueTransmission

Description
Definition
loadSpecValueTransmission()
Code
3345function Motorized.loadSpecValueTransmission(xmlFile, customEnvironment, baseDir)
3346 local nameByConfigIndex = {}
3347 xmlFile:iterate("vehicle.motorized.motorConfigurations.motorConfiguration", function(index, key)
3348 nameByConfigIndex[index] = xmlFile:getValue(key .. ".transmission#name", nil, customEnvironment, false)
3349 local param = xmlFile:getValue(key .. ".transmission#param")
3350 if param ~= nil then
3351 param = g_i18n:convertText(param, customEnvironment)
3352 nameByConfigIndex[index] = string.format(nameByConfigIndex[index], param)
3353 end
3354 end)
3355
3356 return nameByConfigIndex
3357end

onAIJobFinished

Description
Definition
onAIJobFinished()
Code
2151function Motorized:onAIJobFinished(job)
2152 -- only stop motor if no player is inside
2153 if self.getIsControlled == nil or not self:getIsControlled() then
2154 self:stopMotor(true)
2155 end
2156
2157 local spec = self.spec_motorized
2158 if spec.motor ~= nil then
2159 spec.motor:setGearShiftMode(spec.gearShiftMode)
2160 end
2161end

onAIJobStarted

Description
Definition
onAIJobStarted()
Code
2140function Motorized:onAIJobStarted(job)
2141 local spec = self.spec_motorized
2142 self:startMotor(true)
2143
2144 if spec.motor ~= nil then
2145 spec.motor:setGearShiftMode(VehicleMotor.SHIFT_MODE_AUTOMATIC)
2146 end
2147end

onClutchCreaking

Description
Definition
onClutchCreaking()
Code
2078function Motorized:onClutchCreaking(isEvent, groupTransmission, gearIndex, groupIndex)
2079 local spec = self.spec_motorized
2080 if groupTransmission then
2081 g_currentMission:showBlinkingWarning(spec.clutchCrackingGroupWarning, 2000)
2082 else
2083 g_currentMission:showBlinkingWarning(spec.clutchCrackingGearWarning, 2000)
2084 end
2085
2086 if not g_soundManager:getIsSamplePlaying(spec.samples.clutchCracking) then
2087 g_soundManager:playSample(spec.samples.clutchCracking)
2088 end
2089
2090 if gearIndex ~= nil then
2091 self:setGearLeversState(gearIndex, nil, 500, false)
2092 spec.clutchCrackingGearIndex = gearIndex
2093 end
2094
2095 if groupIndex ~= nil then
2096 self:setGearLeversState(nil, groupIndex, 500, false)
2097 spec.clutchCrackingGroupIndex = groupIndex
2098 end
2099
2100 spec.clutchCrackingTimeOut = g_time + (isEvent and 750 or 100)
2101end

onDelete

Description
Definition
onDelete()
Code
675function Motorized:onDelete()
676 local spec = self.spec_motorized
677
678 if spec.motor ~= nil then
679 spec.motor:delete()
680 end
681
682 if spec.sharedLoadRequestIds ~= nil then
683 for _, sharedLoadRequestId in ipairs(spec.sharedLoadRequestIds) do
684 g_i3DManager:releaseSharedI3DFile(sharedLoadRequestId)
685 end
686 spec.sharedLoadRequestIds = nil
687 end
688
689 ParticleUtil.deleteParticleSystems(spec.exhaustParticleSystems)
690 g_soundManager:deleteSamples(spec.samples)
691 g_soundManager:deleteSamples(spec.motorSamples)
692 g_soundManager:deleteSamples(spec.gearboxSamples)
693 g_animationManager:deleteAnimations(spec.animationNodes)
694end

onExhaustEffectI3DLoaded

Description
Definition
onExhaustEffectI3DLoaded()
Code
1539function Motorized:onExhaustEffectI3DLoaded(i3dNode, failedReason, args)
1540 local spec = self.spec_motorized
1541
1542 if i3dNode ~= 0 then
1543 local node = getChildAt(i3dNode, 0)
1544 if getHasShaderParameter(node, "param") then
1545 local xmlFile = args.xmlFile
1546 local key = args.key
1547 local effect = {}
1548 effect.effectNode = node
1549 effect.node = args.linkNode
1550 effect.filename = args.filename
1551 link(effect.node, effect.effectNode)
1552 setVisibility(effect.effectNode, false)
1553 delete(i3dNode)
1554
1555 effect.minRpmColor = xmlFile:getValue(key.."#minRpmColor", "0 0 0 1", true)
1556 effect.maxRpmColor = xmlFile:getValue(key.."#maxRpmColor", "0.0384 0.0359 0.0627 2.0", true)
1557 effect.minRpmScale = xmlFile:getValue(key.."#minRpmScale", 0.25)
1558 effect.maxRpmScale = xmlFile:getValue(key.."#maxRpmScale", 0.95)
1559
1560 effect.upFactor = xmlFile:getValue(key.."#upFactor", 0.75)
1561
1562 effect.lastPosition = nil
1563
1564 effect.xRot = 0
1565 effect.zRot = 0
1566
1567 table.insert(spec.exhaustEffects, effect)
1568 end
1569 end
1570end

onFillUnitFillLevelChanged

Description
Definition
onFillUnitFillLevelChanged()
Code
2873function Motorized:onFillUnitFillLevelChanged(fillUnitIndex, fillLevelDelta, fillType, toolType, fillPositionData, appliedDelta)
2874 -- refill def if diesel is refilled
2875 if fillLevelDelta > 0 and fillType == FillType.DIESEL then
2876 local factor = self:getFillUnitFillLevel(fillUnitIndex) / self:getFillUnitCapacity(fillUnitIndex)
2877 local defFillUnitIndex = self:getConsumerFillUnitIndex(FillType.DEF)
2878 if defFillUnitIndex ~= nil then
2879 local delta = (self:getFillUnitCapacity(defFillUnitIndex) * factor) - self:getFillUnitFillLevel(defFillUnitIndex)
2880 self:addFillUnitFillLevel(self:getOwnerFarmId(), defFillUnitIndex, delta, FillType.DEF, ToolType.UNDEFINED, nil)
2881 end
2882 end
2883end

onGearChanged

Description
Definition
onGearChanged()
Code
2038function Motorized:onGearChanged(gear, targetGear, changeTime)
2039 self:setGearLeversState(targetGear, nil, changeTime)
2040
2041 local spec = self.spec_motorized
2042 if self.isClient then
2043 if gear == 0 then
2044 if not g_soundManager:getIsSamplePlaying(spec.samples.gearDisengaged) then
2045 g_soundManager:playSample(spec.samples.gearDisengaged)
2046 end
2047 else
2048 if not g_soundManager:getIsSamplePlaying(spec.samples.gearEngaged) then
2049 g_soundManager:playSample(spec.samples.gearEngaged)
2050 end
2051 end
2052 end
2053
2054 if self.isServer then
2055 self:raiseDirtyFlags(spec.dirtyFlag)
2056 end
2057end

onGearDirectionChanged

Description
Definition
onGearDirectionChanged()
Code
2030function Motorized:onGearDirectionChanged(direction)
2031 if self.isServer then
2032 self:raiseDirtyFlags(self.spec_motorized.dirtyFlag)
2033 end
2034end

onGearGroupChanged

Description
Definition
onGearGroupChanged()
Code
2061function Motorized:onGearGroupChanged(targetGroup, changeTime)
2062 self:setGearLeversState(nil, targetGroup, changeTime)
2063
2064 local spec = self.spec_motorized
2065 if self.isClient then
2066 if not g_soundManager:getIsSamplePlaying(spec.samples.gearGroupChange) then
2067 g_soundManager:playSample(spec.samples.gearGroupChange)
2068 end
2069 end
2070
2071 if self.isServer then
2072 self:raiseDirtyFlags(spec.dirtyFlag)
2073 end
2074end

onLoad

Description
Called on loading
Definition
onLoad(table savegame)
Arguments
tablesavegamesavegame
Code
347function Motorized:onLoad(savegame)
348 local spec = self.spec_motorized
349
350 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.turnedOnRotationNodes.turnedOnRotationNode#type", "vehicle.motor.animationNodes.animationNode", "motor") --FS17 to FS19
351 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.differentialConfigurations", "vehicle.motorized.differentialConfigurations") --FS17 to FS19
352 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.motorConfigurations", "vehicle.motorized.motorConfigurations") --FS17 to FS19
353 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.maximalAirConsumptionPerFullStop", "vehicle.motorized.consumerConfigurations.consumerConfiguration.consumer(with fill type 'air')#usage (is now in usage per second at full brake power)") --FS17 to FS19
354 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.indoorHud.rpm", "vehicle.motorized.dashboards.dashboard with valueType 'rpm'") --FS17 to FS19
355 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.indoorHud.speed", "vehicle.motorized.dashboards.dashboard with valueType 'speed'") --FS17 to FS19
356 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.indoorHud.fuelUsage", "vehicle.motorized.dashboards.dashboard with valueType 'fuelUsage'") --FS17 to FS19
357 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.indoorHud.fuel", "fillUnit.dashboard with valueType 'fillLevel'") --FS17 to FS19
358
359 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.motor", "vehicle.motorized.motorConfigurations.motorConfiguration(?).motor") --FS19 to FS22
360 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.transmission", "vehicle.motorized.motorConfigurations.motorConfiguration(?).transmission") --FS19 to FS22
361 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.fuelCapacity", "vehicle.motorized.consumerConfigurations.consumerConfiguration.consumer#capacity") --FS19 to FS22
362 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.motorized.motorConfigurations.motorConfiguration(?).fuelCapacity", "vehicle.motorized.consumerConfigurations.consumerConfiguration.consumer#capacity") --FS19 to FS22
363 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle#consumerConfigurationIndex", "vehicle.motorized.motorConfigurations.motorConfiguration(?)#consumerConfigurationIndex'") --FS19 to FS22
364
365 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.motorized.exhaustParticleSystems#count") --FS19 to FS22
366 XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.motorized.exhaustParticleSystems.exhaustParticleSystem1", "vehicle.motorized.exhaustParticleSystems.exhaustParticleSystem") --FS19 to FS22
367
368 spec.motorizedNode = nil
369 for _, component in pairs(self.components) do
370 if component.motorized then
371 spec.motorizedNode = component.node
372 break
373 end
374 end
375
376 spec.directionChangeMode = VehicleMotor.DIRECTION_CHANGE_MODE_AUTOMATIC
377 spec.gearShiftMode = VehicleMotor.SHIFT_MODE_AUTOMATIC
378
379 local configKey = string.format("vehicle.motorized.motorConfigurations.motorConfiguration(%d)", self.configurations["motor"] - 1)
380
381 self:loadDifferentials(self.xmlFile, self.differentialIndex)
382 self:loadMotor(self.xmlFile, self.configurations["motor"])
383
384 self:loadSounds(self.xmlFile, "vehicle.motorized.sounds")
385 if self.xmlFile:hasProperty(configKey) then
386 self:loadSounds(self.xmlFile, configKey .. ".sounds")
387 end
388
389 self:loadConsumerConfiguration(self.xmlFile, spec.consumerConfigurationIndex)
390
391 if self.isClient then
392 self:loadExhaustEffects(self.xmlFile)
393 end
394
395 spec.gearLevers = {}
396 spec.activeGearLeverInterpolators = {}
397 self.xmlFile:iterate("vehicle.motorized.gearLevers.gearLever", function(index, key)
398 local entry = {}
399 entry.node = self.xmlFile:getValue(key .. "#node", nil, self.components, self.i3dMappings)
400 if entry.node ~= nil then
401 entry.centerAxis = self.xmlFile:getValue(key .. "#centerAxis")
402
403 entry.changeTime = self.xmlFile:getValue(key .. "#changeTime", 500)
404 entry.handsOnDelay = self.xmlFile:getValue(key .. "#handsOnDelay", 0)
405
406 entry.curTarget = {getRotation(entry.node)}
407
408 entry.states = {}
409 self.xmlFile:iterate(key .. ".state", function(stateIndex, stateKey)
410 local state = {}
411
412 state.gear = self.xmlFile:getValue(stateKey .. "#gear")
413 state.group = self.xmlFile:getValue(stateKey .. "#group")
414
415 if state.gear ~= nil or state.group ~= nil then
416 state.node = entry.node
417 state.gearLever = entry
418
419 local x, y, z = getRotation(entry.node)
420 local xRot = self.xmlFile:getValue(stateKey .. "#xRot", x)
421 local yRot = self.xmlFile:getValue(stateKey .. "#yRot", y)
422 local zRot = self.xmlFile:getValue(stateKey .. "#zRot", z)
423
424 state.rotation = {xRot, yRot, zRot}
425 state.useRotation = {self.xmlFile:getValue(stateKey .. "#xRot") ~= nil,
426 self.xmlFile:getValue(stateKey .. "#yRot") ~= nil,
427 self.xmlFile:getValue(stateKey .. "#zRot") ~= nil}
428 state.curRotation = {xRot, yRot, zRot}
429
430 table.insert(entry.states, state)
431 else
432 Logging.xmlWarning(self.xmlFile, "Unable to load gear lever state. Missing gear or group! '%s'", stateKey)
433 end
434 end)
435
436 table.insert(spec.gearLevers, entry)
437 else
438 Logging.xmlWarning(self.xmlFile, "Unable to load gear lever. Missing node! '%s'", key)
439 end
440 end)
441
442 spec.stopMotorOnLeave = true
443
444 spec.motorStartDuration = 0
445 if spec.samples ~= nil and spec.samples.motorStart ~= nil then
446 spec.motorStartDuration = spec.samples.motorStart.duration
447 end
448 spec.motorStartDuration = self.xmlFile:getValue("vehicle.motorized.motorStartDuration", spec.motorStartDuration) or 0
449 if self.xmlFile:hasProperty(configKey) then
450 spec.motorStartDuration = self.xmlFile:getValue(configKey .. ".motorStartDuration", spec.motorStartDuration)
451 end
452
453 spec.clutchNoEngagedWarning = self.xmlFile:getValue("vehicle.motorized#clutchNoEngagedWarning", "warning_motorClutchNoEngaged", self.customEnvironment)
454 spec.clutchCrackingGearWarning = self.xmlFile:getValue("vehicle.motorized#clutchCrackingGearWarning", "action_clutchCrackingGear", self.customEnvironment)
455 spec.clutchCrackingGroupWarning = self.xmlFile:getValue("vehicle.motorized#clutchCrackingGroupWarning", "action_clutchCrackingGroup", self.customEnvironment)
456
457 spec.turnOnText = self.xmlFile:getValue("vehicle.motorized#turnOnText", "action_startMotor", self.customEnvironment)
458 spec.turnOffText = self.xmlFile:getValue("vehicle.motorized#turnOffText", "action_stopMotor", self.customEnvironment)
459
460 spec.speedDisplayScale = 1
461 spec.motorStartTime = 0
462 spec.actualLoadPercentage = 0
463 spec.smoothedLoadPercentage = 0
464 spec.maxDecelerationDuringBrake = 0
465
466 spec.lastControlParameters = {
467 acceleratorPedal = nil,
468 maxSpeed = nil,
469 maxAcceleration = nil,
470 minMotorRotSpeed = nil,
471 maxMotorRotSpeed = nil,
472 maxMotorRotAcceleration = nil,
473 minGearRatio = nil,
474 maxGearRatio = nil,
475 maxClutchTorque = nil,
476 neededPtoTorque = nil,
477 }
478
479 spec.clutchCrackingTimeOut = math.huge
480 spec.clutchState = 0
481 spec.clutchStateSent = 0
482
483 spec.isMotorStarted = false
484 spec.motorStopTimerDuration = g_gameSettings:getValue("motorStopTimerDuration")
485 spec.motorStopTimer = spec.motorStopTimerDuration
486 spec.ignitionState = 0
487
488 spec.motorTemperature = {}
489 spec.motorTemperature.value = 20
490 spec.motorTemperature.valueSend = 20
491 spec.motorTemperature.valueMax = 120
492 spec.motorTemperature.valueMin = 20
493 spec.motorTemperature.heatingPerMS = 1.5 / 1000 -- delta °C per ms, at full load
494 spec.motorTemperature.coolingByWindPerMS = 1.00 / 1000
495
496 spec.motorFan = {}
497 spec.motorFan.enabled = false
498 spec.motorFan.enableTemperature = 95
499 spec.motorFan.disableTemperature = 85
500 spec.motorFan.coolingPerMS = 3.0 / 1000
501
502 spec.lastFuelUsage = 0
503 spec.lastFuelUsageDisplay = 0
504 spec.lastFuelUsageDisplayTime = 0
505 spec.fuelUsageBuffer = ValueBuffer.new(250)
506 spec.lastDefUsage = 0
507 spec.lastAirUsage = 0
508 spec.lastVehicleDamage = 0
509
510 spec.forceSpeedHudDisplay = self.xmlFile:getValue("vehicle.motorized#forceSpeedHudDisplay", false)
511 spec.forceRpmHudDisplay = self.xmlFile:getValue("vehicle.motorized#forceRpmHudDisplay", false)
512
513 spec.statsType = string.lower(self.xmlFile:getValue("vehicle.motorized#statsType", "tractor"))
514 if spec.statsType ~= "tractor" and spec.statsType ~= "car" and spec.statsType ~= "truck" then
515 spec.statsType = "tractor"
516 end
517
518 spec.statsTypeDistance = spec.statsType .. "Distance"
519
520 if self.loadDashboardsFromXML ~= nil then
521 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "rpm",
522 valueObject = spec.motor,
523 valueFunc = "getLastModulatedMotorRpm",
524 minFunc = 0,
525 maxFunc = "getMaxRpm"})
526
527 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "load",
528 valueObject = spec.motor,
529 valueFunc = "getSmoothLoadPercentage",
530 minFunc = 0,
531 maxFunc = 100,
532 valueFactor = 100})
533
534 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "speed",
535 valueObject = self,
536 valueFunc = "getLastSpeed",
537 minFunc = 0,
538 maxFunc = self:getMotor():getMaximumForwardSpeed()*3.6})
539
540 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "speedDir",
541 valueObject = self,
542 valueFunc = Motorized.getDashboardSpeedDir,
543 minFunc = -self:getMotor():getMaximumBackwardSpeed()*3.6,
544 maxFunc = self:getMotor():getMaximumForwardSpeed()*3.6,
545 centerFunc = 0})
546
547 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "fuelUsage",
548 valueObject = spec,
549 valueFunc = "lastFuelUsageDisplay"})
550
551 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "motorTemperature",
552 valueObject = spec.motorTemperature,
553 valueFunc = "value",
554 minFunc = "valueMin",
555 maxFunc = "valueMax"})
556
557 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "motorTemperatureWarning",
558 valueObject = spec.motorTemperature,
559 valueFunc = "value",
560 additionalAttributesFunc = Dashboard.warningAttributes,
561 stateFunc = Dashboard.warningState})
562
563 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "clutchPedal",
564 valueObject = spec.motor,
565 valueFunc = "getSmoothedClutchPedal",
566 minFunc = 0,
567 maxFunc = 1})
568 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "gear",
569 valueObject = spec.motor,
570 valueFunc = "getGearToDisplay",
571 minFunc = 0,
572 maxFunc = math.huge})
573 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "gearGroup",
574 valueObject = spec.motor,
575 valueFunc = "getGearGroupToDisplay",
576 minFunc = 0,
577 maxFunc = math.huge})
578 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "movingDirection",
579 valueObject = spec.motor,
580 valueFunc = "getDrivingDirection",
581 minFunc = -1,
582 maxFunc = 1})
583
584 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "directionForward",
585 valueObject = spec.motor,
586 valueFunc = function(motor)
587 return motor:getDrivingDirection() >= 0
588 end})
589
590 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "directionForwardExclusive",
591 valueObject = spec.motor,
592 valueFunc = function(motor)
593 return motor:getDrivingDirection() > 0
594 end})
595
596 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "directionBackward",
597 valueObject = spec.motor,
598 valueFunc = function(motor)
599 return motor:getDrivingDirection() < 0
600 end})
601
602 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "movingDirectionLetter",
603 valueObject = spec.motor,
604 valueFunc = function(motor)
605 return motor:getDrivingDirection() == 1 and "F" or (motor:getDrivingDirection() == -1 and "R" or "N")
606 end})
607
608 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "ignitionState",
609 valueObject = self,
610 valueFunc = Motorized.getMotorIgnitionState,
611 minFunc = 0,
612 maxFunc = 2})
613
614 self:loadDashboardsFromXML(self.xmlFile, "vehicle.motorized.dashboards", {valueTypeToLoad = "battery",
615 valueObject = self,
616 valueFunc = 12 + (math.random() * 0.5 - 0.15),
617 minFunc = 0,
618 maxFunc = 15})
619 end
620
621 spec.animationNodes = g_animationManager:loadAnimations(self.xmlFile, "vehicle.motorized.animationNodes", self.components, self, self.i3dMappings)
622
623 spec.traveledDistanceBuffer = 0
624
625 spec.dirtyFlag = self:getNextDirtyFlag()
626 spec.inputDirtyFlag = self:getNextDirtyFlag()
627
628 self:registerVehicleSetting(GameSettings.SETTING.DIRECTION_CHANGE_MODE, false)
629 self:registerVehicleSetting(GameSettings.SETTING.GEAR_SHIFT_MODE, false)
630end

onPostLoad

Description
Definition
onPostLoad()
Code
634function Motorized:onPostLoad(savegame)
635 local spec = self.spec_motorized
636 if self.isServer then
637 -- refill the consumers
638 local moneyChange = 0
639 for _, consumer in pairs(spec.consumersByFillTypeName) do
640 local fillLevel = self:getFillUnitFillLevel(consumer.fillUnitIndex)
641 local minFillLevel = self:getFillUnitCapacity(consumer.fillUnitIndex) * 0.1
642 if fillLevel < minFillLevel then
643 local fillLevelToFill = minFillLevel - fillLevel
644 self:addFillUnitFillLevel(self:getOwnerFarmId(), consumer.fillUnitIndex, fillLevelToFill, consumer.fillType, ToolType.UNDEFINED)
645
646 local costs = fillLevelToFill * g_currentMission.economyManager:getCostPerLiter(consumer.fillType) * 2.0
647 g_currentMission:farmStats(self:getOwnerFarmId()):updateStats("expenses", costs)
648 g_currentMission:addMoney(-costs, self:getOwnerFarmId(), MoneyType.PURCHASE_FUEL)
649 moneyChange = moneyChange + costs
650 end
651 end
652
653 if moneyChange > 0 then
654 g_currentMission:addMoneyChange(-moneyChange, self:getOwnerFarmId(), MoneyType.PURCHASE_FUEL, true)
655 end
656
657 end
658
659 -- fill units required to be filled for the engine to run
660 spec.propellantFillUnitIndices = {}
661 for _, fillType in pairs({FillType.DIESEL, FillType.DEF, FillType.ELECTRICCHARGE, FillType.METHANE}) do
662 local fillTypeName = g_fillTypeManager:getFillTypeNameByIndex(fillType)
663 if spec.consumersByFillTypeName[fillTypeName] ~= nil then
664 table.insert(spec.propellantFillUnitIndices, spec.consumersByFillTypeName[fillTypeName].fillUnitIndex)
665 end
666 end
667
668 if spec.motor ~= nil then
669 spec.motor:postLoad(savegame)
670 end
671end

onReadStream

Description
Definition
onReadStream()
Code
698function Motorized:onReadStream(streamId, connection)
699 local isMotorStarted = streamReadBool(streamId)
700 if isMotorStarted then
701 self:startMotor(true)
702 else
703 self:stopMotor(true)
704 end
705end

onReadUpdateStream

Description
Definition
onReadUpdateStream()
Code
715function Motorized:onReadUpdateStream(streamId, timestamp, connection)
716 local spec = self.spec_motorized
717 if connection.isServer then
718 if streamReadBool(streamId) then
719 local rpm = streamReadUIntN(streamId, 11) / 2047
720 local rpmRange = spec.motor:getMaxRpm()- spec.motor:getMinRpm()
721 spec.motor:setEqualizedMotorRpm( (rpm * rpmRange) + spec.motor:getMinRpm() )
722
723 local loadPercentage = streamReadUIntN(streamId, 7)
724 spec.motor.rawLoadPercentage = loadPercentage / 127
725
726 spec.brakeCompressor.doFill = streamReadBool(streamId)
727
728 local clutchState = streamReadUIntN(streamId, 5)
729 spec.motor:onManualClutchChanged(clutchState / 31)
730 end
731
732 if streamReadBool(streamId) then
733 spec.motor:readGearDataFromStream(streamId)
734 end
735 else
736 if streamReadBool(streamId) then
737 if streamReadBool(streamId) then
738 spec.clutchState = streamReadUIntN(streamId, 7) / 127
739
740 spec.motor:onManualClutchChanged(spec.clutchState)
741
742 if spec.clutchState > 0 then
743 self:raiseActive()
744 end
745 end
746 end
747 end
748end

onRegisterActionEvents

Description
Definition
onRegisterActionEvents()
Code
2463function Motorized:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
2464 if self.isClient then
2465 local spec = self.spec_motorized
2466 self:clearActionEventsTable(spec.actionEvents)
2467
2468 if isActiveForInputIgnoreSelection then
2469 local _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.TOGGLE_MOTOR_STATE, self, Motorized.actionEventToggleMotorState, false, true, false, true, nil)
2470 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_VERY_HIGH)
2471 g_inputBinding:setActionEventText(actionEventId, spec.turnOnText)
2472
2473 if spec.motor.minForwardGearRatio == nil or spec.motor.minBackwardGearRatio == nil then
2474 if self:getGearShiftMode() ~= VehicleMotor.SHIFT_MODE_AUTOMATIC or not GS_IS_CONSOLE_VERSION then
2475 if spec.motor.manualShiftGears then
2476 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GEAR_UP, self, Motorized.actionEventShiftGear, false, true, false, true, nil)
2477 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2478 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GEAR_DOWN, self, Motorized.actionEventShiftGear, false, true, false, true, nil)
2479 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2480
2481 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GEAR_SELECT_1, self, Motorized.actionEventSelectGear, true, true, false, true, 1)
2482 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2483 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GEAR_SELECT_2, self, Motorized.actionEventSelectGear, true, true, false, true, 2)
2484 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2485 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GEAR_SELECT_3, self, Motorized.actionEventSelectGear, true, true, false, true, 3)
2486 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2487 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GEAR_SELECT_4, self, Motorized.actionEventSelectGear, true, true, false, true, 4)
2488 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2489 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GEAR_SELECT_5, self, Motorized.actionEventSelectGear, true, true, false, true, 5)
2490 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2491 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GEAR_SELECT_6, self, Motorized.actionEventSelectGear, true, true, false, true, 6)
2492 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2493 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GEAR_SELECT_7, self, Motorized.actionEventSelectGear, true, true, false, true, 7)
2494 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2495 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GEAR_SELECT_8, self, Motorized.actionEventSelectGear, true, true, false, true, 8)
2496 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2497 end
2498
2499 if spec.motor.manualShiftGroups then
2500 if spec.motor.gearGroups ~= nil then
2501 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GROUP_UP, self, Motorized.actionEventShiftGroup, false, true, false, true, nil)
2502 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2503 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GROUP_DOWN, self, Motorized.actionEventShiftGroup, false, true, false, true, nil)
2504 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2505
2506 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GROUP_SELECT_1, self, Motorized.actionEventSelectGroup, true, true, false, true, 1)
2507 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2508 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GROUP_SELECT_2, self, Motorized.actionEventSelectGroup, true, true, false, true, 2)
2509 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2510 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GROUP_SELECT_3, self, Motorized.actionEventSelectGroup, true, true, false, true, 3)
2511 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2512 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.SHIFT_GROUP_SELECT_4, self, Motorized.actionEventSelectGroup, true, true, false, true, 4)
2513 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2514 end
2515 end
2516
2517 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.AXIS_CLUTCH_VEHICLE, self, Motorized.actionEventClutch, false, false, true, true, nil)
2518 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2519 end
2520 end
2521
2522 if self:getDirectionChangeMode() == VehicleMotor.DIRECTION_CHANGE_MODE_MANUAL or self:getGearShiftMode() ~= VehicleMotor.SHIFT_MODE_AUTOMATIC then
2523 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.DIRECTION_CHANGE, self, Motorized.actionEventDirectionChange, false, true, false, true, nil, nil, true)
2524 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2525 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.DIRECTION_CHANGE_POS, self, Motorized.actionEventDirectionChange, false, true, false, true, nil, nil, true)
2526 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2527 _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.DIRECTION_CHANGE_NEG, self, Motorized.actionEventDirectionChange, false, true, false, true, nil, nil, true)
2528 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
2529 end
2530
2531 Motorized.updateActionEvents(self)
2532 end
2533 end
2534end

onReverseDirectionChanged

Description
Definition
onReverseDirectionChanged()
Code
2105function Motorized:onReverseDirectionChanged()
2106 if self:getDirectionChangeMode() == VehicleMotor.DIRECTION_CHANGE_MODE_MANUAL then
2107 MotorGearShiftEvent.sendEvent(self, MotorGearShiftEvent.TYPE_DIRECTION_CHANGE)
2108 end
2109end

onSetBroken

Description
Definition
onSetBroken()
Code
2887function Motorized:onSetBroken()
2888 self:stopMotor(true)
2889end

onStateChange

Description
Definition
onStateChange()
Code
2844function Motorized:onStateChange(state, vehicle, isControlling)
2845 if state == Vehicle.STATE_CHANGE_ENTER_VEHICLE then
2846 if g_currentMission.missionInfo.automaticMotorStartEnabled then
2847 if self:getCanMotorRun() then
2848 self:startMotor(true)
2849 end
2850 end
2851 elseif state == Vehicle.STATE_CHANGE_LEAVE_VEHICLE then
2852 if self:getStopMotorOnLeave() and g_currentMission.missionInfo.automaticMotorStartEnabled then
2853 self:stopMotor(true)
2854 end
2855
2856 self:stopVehicle()
2857 end
2858end

onUpdate

Description
Called on update
Definition
onUpdate(float dt, boolean isActiveForInput, boolean isSelected)
Arguments
floatdttime since last call in ms
booleanisActiveForInputtrue if vehicle is active for input
booleanisSelectedtrue if vehicle is selected
Code
784function Motorized:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
785 local spec = self.spec_motorized
786
787 local accInput = 0
788 if self.getAxisForward ~= nil then
789 accInput = self:getAxisForward()
790 end
791
792 if self:getIsMotorStarted() then
793 spec.motor:update(dt)
794
795 -- client receives this information from server
796 if self.isServer then
797 spec.actualLoadPercentage = spec.motor.rawLoadPercentage
798 end
799
800 spec.smoothedLoadPercentage = spec.motor:getSmoothLoadPercentage()
801
802 if self.getCruiseControlState ~= nil then
803 if self:getCruiseControlState() ~= Drivable.CRUISECONTROL_STATE_OFF then
804 accInput = 1
805 end
806 end
807
808 if self.isServer then
809 self:updateConsumers(dt, accInput)
810
811 -- update motor properties on damage change to update the torque reduction
812 local damage = self:getVehicleDamage()
813 if math.abs(damage - spec.lastVehicleDamage) > 0.05 then
814 self:updateMotorProperties()
815 spec.lastVehicleDamage = self:getVehicleDamage()
816 end
817 end
818
819 if self.isClient then
820 -- update sounds
821 local samples = spec.samples
822 local rpm, minRpm, maxRpm = spec.motor:getLastModulatedMotorRpm(), spec.motor.minRpm, spec.motor.maxRpm
823 local rpmPercentage = math.max(math.min((rpm - minRpm) / (maxRpm - minRpm), 1), 0)
824 local loadPercentage = math.max(math.min(spec.smoothedLoadPercentage, 1), -1)
825 g_soundManager:setSamplesLoopSynthesisParameters(spec.motorSamples, rpmPercentage, loadPercentage)
826
827 if g_soundManager:getIsSamplePlaying(spec.motorSamples[1], 1.5*dt) then
828 -- air compressor fill sound
829 if samples.airCompressorRun ~= nil then
830 if spec.consumersByFillTypeName ~= nil and spec.consumersByFillTypeName["AIR"] ~= nil then
831 local consumer = spec.consumersByFillTypeName["AIR"]
832
833 if not consumer.doRefill then
834 if g_soundManager:getIsSamplePlaying(samples.airCompressorRun) then
835 g_soundManager:stopSample(samples.airCompressorRun)
836 g_soundManager:playSample(samples.airCompressorStop)
837 end
838 else
839 if not g_soundManager:getIsSamplePlaying(samples.airCompressorRun) then
840 if samples.airCompressorStart ~= nil then
841 if not g_soundManager:getIsSamplePlaying(samples.airCompressorStart, 1.5*dt) and spec.brakeCompressor.playSampleRunTime == nil then
842 g_soundManager:playSample(samples.airCompressorStart)
843 spec.brakeCompressor.playSampleRunTime = g_currentMission.time + samples.airCompressorStart.duration
844 end
845 if not g_soundManager:getIsSamplePlaying(samples.airCompressorStart) then
846 spec.brakeCompressor.playSampleRunTime = nil
847 g_soundManager:stopSample(samples.airCompressorStart)
848 g_soundManager:playSample(samples.airCompressorRun)
849 end
850 else
851 g_soundManager:playSample(samples.airCompressorRun)
852 end
853 end
854 end
855 end
856 end
857
858 -- random zsch sound
859 if spec.compressionSoundTime <= g_currentMission.time then
860 g_soundManager:playSample(samples.airRelease)
861 spec.compressionSoundTime = g_currentMission.time + math.random(10000, 40000)
862 end
863
864 local isBraking = self:getDecelerationAxis() > 0 and self:getLastSpeed() > 1
865
866 -- brake zsch sound
867 if samples.compressedAir ~= nil then
868 if isBraking then
869 samples.compressedAir.brakeTime = samples.compressedAir.brakeTime + dt
870 else
871 if samples.compressedAir.brakeTime > 0 then
872 samples.compressedAir.lastBrakeTime = samples.compressedAir.brakeTime
873 samples.compressedAir.brakeTime = 0
874
875 g_soundManager:playSample(samples.compressedAir)
876 end
877 end
878 end
879
880 -- blow off valve sound
881 if spec.motor.blowOffValveState > 0 then
882 if not g_soundManager:getIsSamplePlaying(samples.blowOffValve) then
883 g_soundManager:playSample(samples.blowOffValve)
884 end
885 else
886 if g_soundManager:getIsSamplePlaying(samples.blowOffValve) then
887 g_soundManager:stopSample(samples.blowOffValve)
888 end
889 end
890
891 --brake sound
892 if samples.brake ~= nil then
893 if isBraking then
894 if not spec.isBrakeSamplePlaying then
895 g_soundManager:playSample(samples.brake)
896 spec.isBrakeSamplePlaying = true
897 end
898 else
899 if spec.isBrakeSamplePlaying then
900 g_soundManager:stopSample(samples.brake)
901 spec.isBrakeSamplePlaying = false
902 end
903 end
904 end
905
906 -- reverse driving beep
907 if samples.reverseDrive ~= nil then
908 local reverserDirection = self.getReverserDirection == nil and 1 or self:getReverserDirection()
909 local isReverseDriving = self:getLastSpeed() > spec.reverseDriveThreshold and self.movingDirection ~= reverserDirection
910 if not g_soundManager:getIsSamplePlaying(samples.reverseDrive) and isReverseDriving then
911 g_soundManager:playSample(samples.reverseDrive)
912 elseif not isReverseDriving then
913 g_soundManager:stopSample(samples.reverseDrive)
914 end
915 end
916 end
917
918 for state, gearLeverInterpolator in pairs(spec.activeGearLeverInterpolators) do
919 local currentInterpolation = gearLeverInterpolator.interpolations[gearLeverInterpolator.currentInterpolation]
920 if currentInterpolation ~= nil then
921 if gearLeverInterpolator.handsOnDelay > 0 then
922 gearLeverInterpolator.handsOnDelay = gearLeverInterpolator.handsOnDelay - dt
923
924 if gearLeverInterpolator.handsOnDelay <= 0 then
925 local sample = gearLeverInterpolator.isGear and spec.samples.gearLeverStart or spec.samples.gearGroupLeverStart
926 if not g_soundManager:getIsSamplePlaying(sample) then
927 g_soundManager:playSample(sample)
928 end
929 end
930
931 if self.setCharacterTargetNodeStateDirty ~= nil then
932 self:setCharacterTargetNodeStateDirty(state.node, true)
933 end
934 else
935 state.curRotation[1], state.curRotation[2], state.curRotation[3] = getRotation(state.node)
936 local limit = math.min
937 if currentInterpolation.speed < 0 then
938 limit = math.max
939 end
940
941 state.curRotation[currentInterpolation.axis] = limit(state.curRotation[currentInterpolation.axis] + currentInterpolation.speed * dt, currentInterpolation.tar)
942 setRotation(state.node, state.curRotation[1], state.curRotation[2], state.curRotation[3])
943
944 if state.curRotation[currentInterpolation.axis] == currentInterpolation.tar then
945 gearLeverInterpolator.currentInterpolation = gearLeverInterpolator.currentInterpolation + 1
946 if gearLeverInterpolator.currentInterpolation > #gearLeverInterpolator.interpolations then
947 spec.activeGearLeverInterpolators[state] = nil
948
949 if gearLeverInterpolator.isResetPosition then
950 if self.resetCharacterTargetNodeStateDefaults ~= nil then
951 self:resetCharacterTargetNodeStateDefaults(state.node)
952 end
953 end
954
955 local sample = gearLeverInterpolator.isGear and spec.samples.gearLeverEnd or spec.samples.gearGroupLeverEnd
956 if not g_soundManager:getIsSamplePlaying(sample) then
957 g_soundManager:playSample(sample)
958 end
959 end
960 end
961
962 if self.setCharacterTargetNodeStateDirty ~= nil then
963 self:setCharacterTargetNodeStateDirty(state.node)
964 end
965 end
966 else
967 spec.activeGearLeverInterpolators[state] = nil
968 end
969 end
970 end
971
972 if self.isServer then
973 if not self:getIsAIActive() and self:getTraveledDistanceStatsActive() then
974 if self.lastMovedDistance > 0.001 then
975 spec.traveledDistanceBuffer = spec.traveledDistanceBuffer + self.lastMovedDistance
976 if spec.traveledDistanceBuffer > 10 then
977 local stats = g_currentMission:farmStats(self:getOwnerFarmId())
978 local distance = spec.traveledDistanceBuffer * 0.001
979 stats:updateStats("traveledDistance", distance)
980 stats:updateStats(spec.statsTypeDistance, distance)
981 spec.traveledDistanceBuffer = 0
982 end
983 end
984 end
985 end
986 end
987end

onUpdateTick

Description
Called on update tick
Definition
onUpdateTick(float dt, boolean isActiveForInput, boolean isSelected)
Arguments
floatdttime since last call in ms
booleanisActiveForInputtrue if vehicle is active for input
booleanisSelectedtrue if vehicle is selected
Code
994function Motorized:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
995 local spec = self.spec_motorized
996
997 if self.isServer then
998 -- force stop of motor if player is far away from vehicle for a certain amount of time
999 if not g_currentMission.missionInfo.automaticMotorStartEnabled then
1000 if spec.isMotorStarted and not self:getIsAIActive() then
1001
1002 local isEntered = self.getIsEntered ~= nil and self:getIsEntered()
1003 local isControlled = self.getIsControlled ~= nil and self:getIsControlled()
1004
1005 if not isEntered and not isControlled then
1006
1007 local isPlayerInRange = false
1008
1009 for _, player in pairs(g_currentMission.players) do
1010 if player.isControlled then
1011 local distance = calcDistanceFrom(self.rootNode, player.rootNode)
1012 if distance < 250 then
1013 isPlayerInRange = true
1014 break
1015 end
1016 end
1017 end
1018 if not isPlayerInRange then
1019 for _, enterable in pairs(g_currentMission.enterables) do
1020 if enterable.spec_enterable ~= nil and enterable.spec_enterable.isControlled then
1021 local distance = calcDistanceFrom(self.rootNode, enterable.rootNode)
1022 if distance < 250 then
1023 isPlayerInRange = true
1024 break
1025 end
1026 end
1027 end
1028 end
1029
1030 if isPlayerInRange then
1031 spec.motorStopTimer = spec.motorStopTimerDuration
1032 else
1033 spec.motorStopTimer = spec.motorStopTimer - dt
1034 if spec.motorStopTimer <= 0 then
1035 self:stopMotor()
1036 end
1037 end
1038
1039 end
1040 end
1041 end
1042
1043 if spec.isMotorStarted then
1044 self:updateMotorTemperature(dt)
1045 else
1046 --start motor if fuel was empty and got filled
1047 --also starts the motor again when we toggle the automatic motoro start option
1048 if g_currentMission.missionInfo.automaticMotorStartEnabled then
1049 if self.getIsControlled ~= nil and self:getIsControlled() then
1050 if self:getCanMotorRun() then
1051 self:startMotor(true)
1052 end
1053 end
1054 end
1055 end
1056 end
1057
1058 if self.isClient then
1059 if self:getIsMotorStarted() then
1060 if spec.exhaustParticleSystems ~= nil then
1061 for _, ps in pairs(spec.exhaustParticleSystems) do
1062 local scale = MathUtil.lerp(spec.exhaustParticleSystems.minScale, spec.exhaustParticleSystems.maxScale, spec.motor:getEqualizedMotorRpm() / spec.motor:getMaxRpm())
1063 ParticleUtil.setEmitCountScale(spec.exhaustParticleSystems, scale)
1064 ParticleUtil.setParticleLifespan(ps, ps.originalLifespan * scale)
1065 end
1066 end
1067
1068 if spec.exhaustFlap ~= nil then
1069 local minRandom = -0.1
1070 local maxRandom = 0.1
1071 local angle = MathUtil.lerp(minRandom, maxRandom, math.random()) + spec.exhaustFlap.maxRot * (spec.motor:getEqualizedMotorRpm() / spec.motor:getMaxRpm())
1072 angle = MathUtil.clamp(angle, 0, spec.exhaustFlap.maxRot)
1073
1074 if spec.exhaustFlap.rotationAxis == 1 then
1075 setRotation(spec.exhaustFlap.node, angle, 0, 0)
1076 elseif spec.exhaustFlap.rotationAxis == 2 then
1077 setRotation(spec.exhaustFlap.node, 0, angle, 0)
1078 else
1079 setRotation(spec.exhaustFlap.node, 0, 0, angle)
1080 end
1081 end
1082
1083 if spec.exhaustEffects ~= nil then
1084 for _, effect in pairs(spec.exhaustEffects) do
1085 local posX, posY, posZ = localToWorld(effect.effectNode, 0, 0.5, 0)
1086 if effect.lastPosition == nil then
1087 effect.lastPosition = {posX, posY, posZ}
1088 end
1089
1090 local vx = (posX - effect.lastPosition[1]) * 10
1091 local vy = (posY - effect.lastPosition[2]) * 10
1092 local vz = (posZ - effect.lastPosition[3]) * 10
1093
1094 local ex, ey, ez = localToWorld(effect.effectNode, 0, 1, 0)
1095 vx, vy, vz = ex - vx, ey - vy + effect.upFactor, ez - vz
1096
1097 local lx, ly, lz = worldToLocal(effect.effectNode, vx, vy, vz)
1098
1099 local distance = MathUtil.vector2Length(lx, lz)
1100 lx, lz = MathUtil.vector2Normalize(lx, lz)
1101
1102 ly = math.abs(math.max(ly, 0.01))
1103
1104 local xFactor = math.atan(distance / ly) * (1.2 + 2 * ly)
1105 local yFactor = math.atan(distance / ly) * (1.2 + 2 * ly)
1106
1107 local xRot = math.atan(lz / ly) * xFactor
1108 local zRot = -math.atan(lx / ly) * yFactor
1109
1110 effect.xRot = effect.xRot * 0.95 + xRot * 0.05
1111 effect.zRot = effect.zRot * 0.95 + zRot * 0.05
1112
1113 local rpmScale = spec.motor:getEqualizedMotorRpm() / spec.motor:getMaxRpm()
1114 local scale = MathUtil.lerp(effect.minRpmScale, effect.maxRpmScale, rpmScale)
1115
1116 setShaderParameter(effect.effectNode, "param", effect.xRot, effect.zRot, 0, scale, false)
1117
1118 local r = MathUtil.lerp(effect.minRpmColor[1], effect.maxRpmColor[1], rpmScale)
1119 local g = MathUtil.lerp(effect.minRpmColor[2], effect.maxRpmColor[2], rpmScale)
1120 local b = MathUtil.lerp(effect.minRpmColor[3], effect.maxRpmColor[3], rpmScale)
1121 local a = MathUtil.lerp(effect.minRpmColor[4], effect.maxRpmColor[4], rpmScale)
1122 setShaderParameter(effect.effectNode, "exhaustColor", r, g, b, a, false)
1123
1124 effect.lastPosition[1] = posX
1125 effect.lastPosition[2] = posY
1126 effect.lastPosition[3] = posZ
1127 end
1128 end
1129
1130 spec.lastFuelUsageDisplayTime = spec.lastFuelUsageDisplayTime + dt
1131 if spec.lastFuelUsageDisplayTime > 250 then
1132 spec.lastFuelUsageDisplayTime = 0
1133 spec.lastFuelUsageDisplay = spec.fuelUsageBuffer:getAverage()
1134 end
1135
1136 spec.fuelUsageBuffer:add(spec.lastFuelUsage)
1137 end
1138
1139 if spec.clutchCrackingTimeOut < g_time then
1140 if g_soundManager:getIsSamplePlaying(spec.samples.clutchCracking) then
1141 g_soundManager:stopSample(spec.samples.clutchCracking)
1142 end
1143
1144 if spec.clutchCrackingGearIndex ~= nil then
1145 self:setGearLeversState(0, nil, 500)
1146 end
1147
1148 if spec.clutchCrackingGroupIndex ~= nil then
1149 self:setGearLeversState(nil, 0, 500)
1150 end
1151
1152 spec.clutchCrackingTimeOut = math.huge
1153 end
1154
1155 -- display permanent fuel empty warning if automatic motor start is enabled
1156 if isActiveForInputIgnoreSelection then
1157 if g_currentMission.missionInfo.automaticMotorStartEnabled then
1158 if not self:getCanMotorRun() then
1159 local warning = self:getMotorNotAllowedWarning()
1160 if warning ~= nil then
1161 g_currentMission:showBlinkingWarning(warning, 2000)
1162 end
1163 end
1164 end
1165
1166 Motorized.updateActionEvents(self)
1167 end
1168 end
1169end

onVehicleSettingChanged

Description
Definition
onVehicleSettingChanged()
Code
2113function Motorized:onVehicleSettingChanged(gameSettingId, state)
2114 local spec = self.spec_motorized
2115 local motor = spec.motor
2116
2117 if gameSettingId == GameSettings.SETTING.DIRECTION_CHANGE_MODE then
2118 spec.directionChangeMode = state
2119 if motor ~= nil then
2120 motor:setDirectionChangeMode(state)
2121
2122 self:requestActionEventUpdate()
2123 end
2124 end
2125
2126 if gameSettingId == GameSettings.SETTING.GEAR_SHIFT_MODE then
2127 spec.gearShiftMode = state
2128 if not self:getIsAIActive() then
2129 if motor ~= nil then
2130 motor:setGearShiftMode(state)
2131
2132 self:requestActionEventUpdate()
2133 end
2134 end
2135 end
2136end

onWriteStream

Description
Definition
onWriteStream()
Code
709function Motorized:onWriteStream(streamId, connection)
710 streamWriteBool(streamId, self.spec_motorized.isMotorStarted)
711end

onWriteUpdateStream

Description
Definition
onWriteUpdateStream()
Code
752function Motorized:onWriteUpdateStream(streamId, connection, dirtyMask)
753 local spec = self.spec_motorized
754 if not connection.isServer then
755 if streamWriteBool(streamId, self.spec_motorized.isMotorStarted) then
756 local rpmRange = spec.motor:getMaxRpm() - spec.motor:getMinRpm()
757 local rpm = MathUtil.clamp((spec.motor:getEqualizedMotorRpm() - spec.motor:getMinRpm()) / rpmRange, 0, 1)
758
759 rpm = math.floor(rpm * 2047)
760 streamWriteUIntN(streamId, rpm, 11)
761 streamWriteUIntN(streamId, 127 * spec.actualLoadPercentage, 7)
762 streamWriteBool(streamId, spec.brakeCompressor.doFill)
763 streamWriteUIntN(streamId, 31 * spec.motor:getClutchPedal(), 5)
764 end
765
766 if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlag) ~= 0) then
767 spec.motor:writeGearDataToStream(streamId)
768 end
769 else
770 if streamWriteBool(streamId, bitAND(dirtyMask, spec.inputDirtyFlag) ~= 0) then
771 if streamWriteBool(streamId, spec.clutchState ~= spec.clutchStateSent) then
772 streamWriteUIntN(streamId, 127 * spec.clutchState, 7)
773 spec.clutchStateSent = spec.clutchState
774 end
775 end
776 end
777end

prerequisitesPresent

Description
Definition
prerequisitesPresent()
Code
241function Motorized.prerequisitesPresent(specializations)
242 return SpecializationUtil.hasSpecialization(FillUnit, specializations) and SpecializationUtil.hasSpecialization(VehicleSettings, specializations)
243end

registerConsumerXMLPaths

Description
Definition
registerConsumerXMLPaths()
Code
202function Motorized.registerConsumerXMLPaths(schema, baseKey)
203 schema:register(XMLValueType.L10N_STRING, baseKey .. "#consumersEmptyWarning", "Consumers empty warning", "warning_motorFuelEmpty")
204 schema:register(XMLValueType.INT, baseKey .. ".consumer(?)#fillUnitIndex", "Fill unit index", 1)
205 schema:register(XMLValueType.STRING, baseKey .. ".consumer(?)#fillType", "Fill type name")
206 schema:register(XMLValueType.FLOAT, baseKey .. ".consumer(?)#usage", "Usage in l/h", 1)
207 schema:register(XMLValueType.BOOL, baseKey .. ".consumer(?)#permanentConsumption", "Do permanent consumption", 1)
208 schema:register(XMLValueType.FLOAT, baseKey .. ".consumer(?)#refillLitersPerSecond", "Refill liters per second", 0)
209 schema:register(XMLValueType.FLOAT, baseKey .. ".consumer(?)#refillCapacityPercentage", "Refill capacity percentage", 0)
210 schema:register(XMLValueType.FLOAT, baseKey .. ".consumer(?)#capacity", "If defined the capacity of the fillUnit fill be overwritten with this value")
211end

registerDifferentialXMLPaths

Description
Definition
registerDifferentialXMLPaths()
Code
190function Motorized.registerDifferentialXMLPaths(schema, baseKey)
191 schema:register(XMLValueType.FLOAT, baseKey .. ".differentials.differential(?)#torqueRatio", "Torque ratio", 0.5)
192 schema:register(XMLValueType.FLOAT, baseKey .. ".differentials.differential(?)#maxSpeedRatio", "Max. speed ratio", 1.3)
193
194 schema:register(XMLValueType.INT, baseKey .. ".differentials.differential(?)#wheelIndex1", "Wheel index 1")
195 schema:register(XMLValueType.INT, baseKey .. ".differentials.differential(?)#wheelIndex2", "Wheel index 2")
196 schema:register(XMLValueType.INT, baseKey .. ".differentials.differential(?)#differentialIndex1", "Differential index 1")
197 schema:register(XMLValueType.INT, baseKey .. ".differentials.differential(?)#differentialIndex2", "Differential index 2")
198end

registerEventListeners

Description
Definition
registerEventListeners()
Code
320function Motorized.registerEventListeners(vehicleType)
321 SpecializationUtil.registerEventListener(vehicleType, "onLoad", Motorized)
322 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", Motorized)
323 SpecializationUtil.registerEventListener(vehicleType, "onDelete", Motorized)
324 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Motorized)
325 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Motorized)
326 SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", Motorized)
327 SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", Motorized)
328 SpecializationUtil.registerEventListener(vehicleType, "onUpdate", Motorized)
329 SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", Motorized)
330 SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", Motorized)
331 SpecializationUtil.registerEventListener(vehicleType, "onStateChange", Motorized)
332 SpecializationUtil.registerEventListener(vehicleType, "onFillUnitFillLevelChanged", Motorized)
333 SpecializationUtil.registerEventListener(vehicleType, "onSetBroken", Motorized)
334 SpecializationUtil.registerEventListener(vehicleType, "onGearDirectionChanged", Motorized)
335 SpecializationUtil.registerEventListener(vehicleType, "onGearChanged", Motorized)
336 SpecializationUtil.registerEventListener(vehicleType, "onGearGroupChanged", Motorized)
337 SpecializationUtil.registerEventListener(vehicleType, "onClutchCreaking", Motorized)
338 SpecializationUtil.registerEventListener(vehicleType, "onReverseDirectionChanged", Motorized)
339 SpecializationUtil.registerEventListener(vehicleType, "onVehicleSettingChanged", Motorized)
340 SpecializationUtil.registerEventListener(vehicleType, "onAIJobStarted", Motorized)
341 SpecializationUtil.registerEventListener(vehicleType, "onAIJobFinished", Motorized)
342end

registerEvents

Description
Definition
registerEvents()
Code
247function Motorized.registerEvents(vehicleType)
248 SpecializationUtil.registerEvent(vehicleType, "onStartMotor")
249 SpecializationUtil.registerEvent(vehicleType, "onStopMotor")
250 SpecializationUtil.registerEvent(vehicleType, "onGearDirectionChanged")
251 SpecializationUtil.registerEvent(vehicleType, "onGearChanged")
252 SpecializationUtil.registerEvent(vehicleType, "onGearGroupChanged")
253 SpecializationUtil.registerEvent(vehicleType, "onClutchCreaking")
254end

registerFunctions

Description
Definition
registerFunctions()
Code
258function Motorized.registerFunctions(vehicleType)
259 SpecializationUtil.registerFunction(vehicleType, "loadDifferentials", Motorized.loadDifferentials)
260 SpecializationUtil.registerFunction(vehicleType, "loadMotor", Motorized.loadMotor)
261 SpecializationUtil.registerFunction(vehicleType, "loadGears", Motorized.loadGears)
262 SpecializationUtil.registerFunction(vehicleType, "loadGearGroups", Motorized.loadGearGroups)
263 SpecializationUtil.registerFunction(vehicleType, "loadExhaustEffects", Motorized.loadExhaustEffects)
264 SpecializationUtil.registerFunction(vehicleType, "onExhaustEffectI3DLoaded", Motorized.onExhaustEffectI3DLoaded)
265 SpecializationUtil.registerFunction(vehicleType, "loadSounds", Motorized.loadSounds)
266 SpecializationUtil.registerFunction(vehicleType, "loadConsumerConfiguration", Motorized.loadConsumerConfiguration)
267 SpecializationUtil.registerFunction(vehicleType, "getIsMotorStarted", Motorized.getIsMotorStarted)
268 SpecializationUtil.registerFunction(vehicleType, "getIsMotorInNeutral", Motorized.getIsMotorInNeutral)
269 SpecializationUtil.registerFunction(vehicleType, "getCanMotorRun", Motorized.getCanMotorRun)
270 SpecializationUtil.registerFunction(vehicleType, "getStopMotorOnLeave", Motorized.getStopMotorOnLeave)
271 SpecializationUtil.registerFunction(vehicleType, "getMotorNotAllowedWarning", Motorized.getMotorNotAllowedWarning)
272 SpecializationUtil.registerFunction(vehicleType, "startMotor", Motorized.startMotor)
273 SpecializationUtil.registerFunction(vehicleType, "stopMotor", Motorized.stopMotor)
274 SpecializationUtil.registerFunction(vehicleType, "updateMotorProperties", Motorized.updateMotorProperties)
275 SpecializationUtil.registerFunction(vehicleType, "controlVehicle", Motorized.controlVehicle)
276 SpecializationUtil.registerFunction(vehicleType, "updateConsumers", Motorized.updateConsumers)
277 SpecializationUtil.registerFunction(vehicleType, "updateMotorTemperature", Motorized.updateMotorTemperature)
278 SpecializationUtil.registerFunction(vehicleType, "getMotor", Motorized.getMotor)
279 SpecializationUtil.registerFunction(vehicleType, "getMotorStartTime", Motorized.getMotorStartTime)
280 SpecializationUtil.registerFunction(vehicleType, "getMotorType", Motorized.getMotorType)
281 SpecializationUtil.registerFunction(vehicleType, "getMotorRpmPercentage", Motorized.getMotorRpmPercentage)
282 SpecializationUtil.registerFunction(vehicleType, "getMotorRpmReal", Motorized.getMotorRpmReal)
283 SpecializationUtil.registerFunction(vehicleType, "getMotorLoadPercentage", Motorized.getMotorLoadPercentage)
284 SpecializationUtil.registerFunction(vehicleType, "getMotorBlowOffValveState", Motorized.getMotorBlowOffValveState)
285 SpecializationUtil.registerFunction(vehicleType, "getMotorDifferentialSpeed", Motorized.getMotorDifferentialSpeed)
286 SpecializationUtil.registerFunction(vehicleType, "getConsumerFillUnitIndex", Motorized.getConsumerFillUnitIndex)
287 SpecializationUtil.registerFunction(vehicleType, "getAirConsumerUsage", Motorized.getAirConsumerUsage)
288 SpecializationUtil.registerFunction(vehicleType, "getTraveledDistanceStatsActive", Motorized.getTraveledDistanceStatsActive)
289 SpecializationUtil.registerFunction(vehicleType, "setGearLeversState", Motorized.setGearLeversState)
290 SpecializationUtil.registerFunction(vehicleType, "generateShiftAnimation", Motorized.generateShiftAnimation)
291 SpecializationUtil.registerFunction(vehicleType, "getGearInfoToDisplay", Motorized.getGearInfoToDisplay)
292 SpecializationUtil.registerFunction(vehicleType, "setTransmissionDirection", Motorized.setTransmissionDirection)
293 SpecializationUtil.registerFunction(vehicleType, "getDirectionChangeMode", Motorized.getDirectionChangeMode)
294 SpecializationUtil.registerFunction(vehicleType, "getIsManualDirectionChangeAllowed", Motorized.getIsManualDirectionChangeAllowed)
295 SpecializationUtil.registerFunction(vehicleType, "getGearShiftMode", Motorized.getGearShiftMode)
296 SpecializationUtil.registerFunction(vehicleType, "stopVehicle", Motorized.stopVehicle)
297end

registerMotorXMLPaths

Description
Definition
registerMotorXMLPaths()
Code
117function Motorized.registerMotorXMLPaths(schema, baseKey)
118 schema:register(XMLValueType.STRING, baseKey .. ".motor#type", "Motor type", "vehicle")
119 schema:register(XMLValueType.STRING, baseKey .. ".motor#startAnimationName", "Motor start animation", "vehicle")
120 schema:register(XMLValueType.INT, baseKey .. "#consumerConfigurationIndex", "Consumer configuration index", 1)
121
122 schema:register(XMLValueType.FLOAT, baseKey .. ".motor#minRpm", "Min. RPM", 1000)
123 schema:register(XMLValueType.FLOAT, baseKey .. ".motor#maxRpm", "Max. RPM", 1800)
124 schema:register(XMLValueType.FLOAT, baseKey .. ".motor#minSpeed", "Min. driving speed", 1)
125 schema:register(XMLValueType.FLOAT, baseKey .. ".motor#maxForwardSpeed", "Max. forward speed")
126 schema:register(XMLValueType.FLOAT, baseKey .. ".motor#maxBackwardSpeed", "Max. backward speed")
127
128 schema:register(XMLValueType.FLOAT, baseKey .. ".motor#accelerationLimit", "Acceleration limit", 2.0)
129 schema:register(XMLValueType.FLOAT, baseKey .. ".motor#brakeForce", "Brake force", 10)
130 schema:register(XMLValueType.FLOAT, baseKey .. ".motor#lowBrakeForceScale", "Low brake force scale", 0.5)
131 schema:register(XMLValueType.FLOAT, baseKey .. ".motor#lowBrakeForceSpeedLimit", "Low brake force speed limit (below this speed the lowBrakeForceScale is activated)", 1)
132 schema:register(XMLValueType.FLOAT, baseKey .. ".motor#torqueScale", "Scale factor for torque curve", 1)
133 schema:register(XMLValueType.FLOAT, baseKey .. ".motor#ptoMotorRpmRatio", "PTO to motor rpm ratio", 4)
134
135 schema:register(XMLValueType.FLOAT, baseKey .. ".transmission#minForwardGearRatio", "Min. forward gear ratio")
136 schema:register(XMLValueType.FLOAT, baseKey .. ".transmission#maxForwardGearRatio", "Max. forward gear ratio")
137 schema:register(XMLValueType.FLOAT, baseKey .. ".transmission#minBackwardGearRatio", "Min. backward gear ratio")
138 schema:register(XMLValueType.FLOAT, baseKey .. ".transmission#maxBackwardGearRatio", "Max. backward gear ratio")
139 schema:register(XMLValueType.TIME, baseKey .. ".transmission#gearChangeTime", "Gear change time")
140 schema:register(XMLValueType.TIME, baseKey .. ".transmission#autoGearChangeTime", "Auto gear change time")
141 schema:register(XMLValueType.FLOAT, baseKey .. ".transmission#axleRatio", "Axle ratio", 1)
142 schema:register(XMLValueType.FLOAT, baseKey .. ".transmission#startGearThreshold", "Adjusts which gear is used as start gear", VehicleMotor.GEAR_START_THRESHOLD)
143
144 schema:register(XMLValueType.FLOAT, baseKey .. ".motor.torque(?)#normRpm", "Norm RPM (0-1)")
145 schema:register(XMLValueType.FLOAT, baseKey .. ".motor.torque(?)#rpm", "RPM")
146 schema:register(XMLValueType.FLOAT, baseKey .. ".motor.torque(?)#torque", "Torque")
147
148 schema:register(XMLValueType.FLOAT, baseKey .. ".motor#rotInertia", "Rotation inertia", "Peak. motor torque / 600")
149 schema:register(XMLValueType.FLOAT, baseKey .. ".motor#dampingRateScale", "Scales motor damping rate", 1)
150
151 schema:register(XMLValueType.FLOAT, baseKey .. ".motor#rpmSpeedLimit", "Motor rotation acceleration limit")
152
153 schema:register(XMLValueType.FLOAT, baseKey .. ".transmission.forwardGear(?)#gearRatio", "Gear ratio")
154 schema:register(XMLValueType.FLOAT, baseKey .. ".transmission.forwardGear(?)#maxSpeed", "Gear ratio")
155 schema:register(XMLValueType.BOOL, baseKey .. ".transmission.forwardGear(?)#defaultGear", "Gear ratio")
156 schema:register(XMLValueType.STRING, baseKey .. ".transmission.forwardGear(?)#name", "Gear name to display")
157 schema:register(XMLValueType.STRING, baseKey .. ".transmission.forwardGear(?)#reverseName", "Gear name to display (if reverse direction is active)")
158 schema:register(XMLValueType.STRING, baseKey .. ".transmission.forwardGear(?)#actionName", "Input Action to select this gear", "SHIFT_GEAR_SELECT_X")
159 schema:register(XMLValueType.FLOAT, baseKey .. ".transmission.backwardGear(?)#gearRatio", "Gear ratio")
160 schema:register(XMLValueType.FLOAT, baseKey .. ".transmission.backwardGear(?)#maxSpeed", "Gear ratio")
161 schema:register(XMLValueType.BOOL, baseKey .. ".transmission.backwardGear(?)#defaultGear", "Gear ratio")
162 schema:register(XMLValueType.STRING, baseKey .. ".transmission.backwardGear(?)#name", "Gear name to display")
163 schema:register(XMLValueType.STRING, baseKey .. ".transmission.backwardGear(?)#reverseName", "Gear name to display (if reverse direction is active)")
164 schema:register(XMLValueType.STRING, baseKey .. ".transmission.backwardGear(?)#actionName", "Input Action to select this gear", "SHIFT_GEAR_SELECT_X")
165
166 schema:register(XMLValueType.STRING, baseKey .. ".transmission.groups#type", "Type of groups (powershift/default)", "default")
167 schema:register(XMLValueType.TIME, baseKey .. ".transmission.groups#changeTime", "Change time if default type", 0.5)
168 schema:register(XMLValueType.FLOAT, baseKey .. ".transmission.groups.group(?)#ratio", "Ratio while stage active")
169 schema:register(XMLValueType.BOOL, baseKey .. ".transmission.groups.group(?)#isDefault", "Is default stage", false)
170 schema:register(XMLValueType.STRING, baseKey .. ".transmission.groups.group(?)#name", "Gear name to display")
171 schema:register(XMLValueType.STRING, baseKey .. ".transmission.groups.group(?)#actionName", "Input Action to select this group", "SHIFT_GROUP_SELECT_X")
172
173 schema:register(XMLValueType.BOOL, baseKey .. ".transmission.directionChange#useGroup", "Use group as reverse change", false)
174 schema:register(XMLValueType.INT, baseKey .. ".transmission.directionChange#reverseGroupIndex", "Group will be activated while direction is changed", 1)
175 schema:register(XMLValueType.BOOL, baseKey .. ".transmission.directionChange#useGear", "Use gear as reverse change", false)
176 schema:register(XMLValueType.INT, baseKey .. ".transmission.directionChange#reverseGearIndex", "Gear will be activated while direction is changed", 1)
177 schema:register(XMLValueType.TIME, baseKey .. ".transmission.directionChange#changeTime", "Direction change time", 0.5)
178
179 schema:register(XMLValueType.BOOL, baseKey .. ".transmission.manualShift#gears", "Defines if gears can be shifted manually", true)
180 schema:register(XMLValueType.BOOL, baseKey .. ".transmission.manualShift#groups", "Defines if groups can be shifted manually", true)
181
182 schema:register(XMLValueType.L10N_STRING, baseKey .. ".transmission#name", "Name of transmission to display in the shop")
183 schema:register(XMLValueType.STRING, baseKey .. ".transmission#param", "Parameter to insert in transmission name")
184
185 schema:register(XMLValueType.FLOAT, baseKey .. ".motorStartDuration", "Motor start duration", "Duration motor takes to start. After this time player can start to drive")
186end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
301function Motorized.registerOverwrittenFunctions(vehicleType)
302 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getBrakeForce", Motorized.getBrakeForce)
303 SpecializationUtil.registerOverwrittenFunction(vehicleType, "addToPhysics", Motorized.addToPhysics)
304 SpecializationUtil.registerOverwrittenFunction(vehicleType, "removeFromPhysics", Motorized.removeFromPhysics)
305 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsOperating", Motorized.getIsOperating)
306 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDeactivateOnLeave", Motorized.getDeactivateOnLeave)
307 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDeactivateLightsOnLeave", Motorized.getDeactivateLightsOnLeave)
308 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadDashboardGroupFromXML", Motorized.loadDashboardGroupFromXML)
309 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsDashboardGroupActive", Motorized.getIsDashboardGroupActive)
310 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsActiveForInteriorLights", Motorized.getIsActiveForInteriorLights)
311 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsActiveForWipers", Motorized.getIsActiveForWipers)
312 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getUsageCausesDamage", Motorized.getUsageCausesDamage)
313 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getName", Motorized.getName)
314 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", Motorized.getCanBeSelected)
315 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsPowered", Motorized.getIsPowered)
316end

registerSoundXMLPaths

Description
Definition
registerSoundXMLPaths()
Code
215function Motorized.registerSoundXMLPaths(schema, baseKey)
216 SoundManager.registerSampleXMLPaths(schema, baseKey, "motorStart")
217 SoundManager.registerSampleXMLPaths(schema, baseKey, "motorStop")
218 SoundManager.registerSampleXMLPaths(schema, baseKey, "gearbox(?)")
219 SoundManager.registerSampleXMLPaths(schema, baseKey, "clutchCracking")
220 SoundManager.registerSampleXMLPaths(schema, baseKey, "gearEngaged")
221 SoundManager.registerSampleXMLPaths(schema, baseKey, "gearDisengaged")
222 SoundManager.registerSampleXMLPaths(schema, baseKey, "gearLeverStart")
223 SoundManager.registerSampleXMLPaths(schema, baseKey, "gearLeverEnd")
224 SoundManager.registerSampleXMLPaths(schema, baseKey, "gearGroupLeverStart")
225 SoundManager.registerSampleXMLPaths(schema, baseKey, "gearGroupLeverEnd")
226 SoundManager.registerSampleXMLPaths(schema, baseKey, "gearGroupChange")
227 SoundManager.registerSampleXMLPaths(schema, baseKey, "blowOffValve")
228 SoundManager.registerSampleXMLPaths(schema, baseKey, "retarder")
229 SoundManager.registerSampleXMLPaths(schema, baseKey, "motor(?)")
230 SoundManager.registerSampleXMLPaths(schema, baseKey, "airCompressorStart")
231 SoundManager.registerSampleXMLPaths(schema, baseKey, "airCompressorStop")
232 SoundManager.registerSampleXMLPaths(schema, baseKey, "airCompressorRun")
233 SoundManager.registerSampleXMLPaths(schema, baseKey, "compressedAir")
234 SoundManager.registerSampleXMLPaths(schema, baseKey, "airRelease")
235 SoundManager.registerSampleXMLPaths(schema, baseKey, "reverseDrive")
236 SoundManager.registerSampleXMLPaths(schema, baseKey, "brake")
237end

removeFromPhysics

Description
Definition
removeFromPhysics()
Code
2376function Motorized:removeFromPhysics(superFunc)
2377 if self.isServer then
2378 local spec = self.spec_motorized
2379
2380 if spec.motorizedNode ~= nil then
2381 if next(spec.differentials) ~= nil then
2382 removeAllDifferentials(spec.motorizedNode)
2383 end
2384 end
2385 end
2386
2387 if not superFunc(self) then
2388 return false
2389 end
2390
2391 return true
2392end

setGearLeversState

Description
Definition
setGearLeversState()
Code
2655function Motorized:setGearLeversState(gear, group, time, isResetPosition)
2656 local spec = self.spec_motorized
2657 for i=1, #spec.gearLevers do
2658 local gearLever = spec.gearLevers[i]
2659 for j=1, #gearLever.states do
2660 local state = gearLever.states[j]
2661 if (state.gear ~= nil and state.gear == gear) or (state.group ~= nil and state.group == group) then
2662 self:generateShiftAnimation(gearLever, state, time, isResetPosition)
2663 end
2664 end
2665 end
2666end

setTransmissionDirection

Description
Switches the gear ratios by the given direction
Definition
setTransmissionDirection(integer direction)
Arguments
integerdirectiondirection
Code
2814function Motorized:setTransmissionDirection(direction)
2815 local motor = self.spec_motorized.motor
2816 if motor ~= nil then
2817 motor:setTransmissionDirection(direction)
2818 end
2819end

startMotor

Description
Start motor
Definition
startMotor(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
1768function Motorized:startMotor(noEventSend)
1769 if noEventSend == nil or noEventSend == false then
1770 if g_server ~= nil then
1771 g_server:broadcastEvent(SetMotorTurnedOnEvent.new(self, true), nil, nil, self)
1772 else
1773 g_client:getServerConnection():sendEvent(SetMotorTurnedOnEvent.new(self, true))
1774 end
1775 end
1776 local spec = self.spec_motorized
1777 if not spec.isMotorStarted then
1778 spec.isMotorStarted = true
1779
1780 if self.isClient then
1781 if spec.exhaustParticleSystems ~= nil then
1782 for _, ps in pairs(spec.exhaustParticleSystems) do
1783 ParticleUtil.setEmittingState(ps, true)
1784 end
1785 end
1786 if spec.exhaustEffects ~= nil then
1787 for _, effect in pairs(spec.exhaustEffects) do
1788 setVisibility(effect.effectNode, true)
1789 setShaderParameter(effect.effectNode, "param", effect.xRot, effect.zRot, 0, 0, false)
1790
1791 local color = effect.minRpmColor
1792 setShaderParameter(effect.effectNode, "exhaustColor", color[1], color[2], color[3], color[4], false)
1793 end
1794 end
1795
1796 -- TODO remove debug code
1797 if spec.samples == nil then
1798 Logging.error("Motor samples not found (%s, %d)", self.configFileName, self.loadingState)
1799 printCallstack()
1800 end
1801
1802 g_soundManager:stopSample(spec.samples.motorStop)
1803
1804 g_soundManager:playSample(spec.samples.motorStart)
1805 g_soundManager:playSamples(spec.motorSamples, 0, spec.samples.motorStart)
1806 g_soundManager:playSamples(spec.gearboxSamples, 0, spec.samples.motorStart)
1807 g_soundManager:playSample(spec.samples.retarder, 0, spec.samples.motorStart)
1808
1809 g_animationManager:startAnimations(spec.animationNodes)
1810
1811 if spec.motorStartAnimation ~= nil then
1812 self:playAnimation(spec.motorStartAnimation, 1, nil, true)
1813 end
1814 end
1815
1816 spec.motorStartTime = g_currentMission.time + spec.motorStartDuration
1817 spec.compressionSoundTime = g_currentMission.time + math.random(5000, 20000)
1818 spec.motor.lastMotorRpm = 0
1819
1820 SpecializationUtil.raiseEvent(self, "onStartMotor")
1821 self.rootVehicle:raiseStateChange(Vehicle.STATE_CHANGE_MOTOR_TURN_ON)
1822 end
1823
1824 if self.setDashboardsDirty ~= nil then
1825 self:setDashboardsDirty()
1826 end
1827
1828 -- wake up physics to update the motor attributes at least once
1829 if self.isServer then
1830 self:wakeUp()
1831 end
1832end

stopMotor

Description
Stop motor
Definition
stopMotor(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
1837function Motorized:stopMotor(noEventSend)
1838 if noEventSend == nil or noEventSend == false then
1839 if g_server ~= nil then
1840 g_server:broadcastEvent(SetMotorTurnedOnEvent.new(self, false), nil, nil, self)
1841 else
1842 g_client:getServerConnection():sendEvent(SetMotorTurnedOnEvent.new(self, false))
1843 end
1844 end
1845
1846 local spec = self.spec_motorized
1847 if spec.isMotorStarted then
1848 spec.isMotorStarted = false
1849
1850 if self.isClient then
1851 if spec.exhaustParticleSystems ~= nil then
1852 for _, ps in pairs(spec.exhaustParticleSystems) do
1853 ParticleUtil.setEmittingState(ps, false)
1854 end
1855 end
1856
1857 if spec.exhaustEffects ~= nil then
1858 for _, effect in pairs(spec.exhaustEffects) do
1859 setVisibility(effect.effectNode, false)
1860 end
1861 end
1862 if spec.exhaustFlap ~= nil then
1863 setRotation(spec.exhaustFlap.node, 0, 0, 0)
1864 end
1865
1866 g_soundManager:stopSamples(spec.samples)
1867 g_soundManager:playSample(spec.samples.motorStop)
1868
1869 g_soundManager:stopSamples(spec.motorSamples)
1870 g_soundManager:stopSamples(spec.gearboxSamples)
1871
1872 spec.isBrakeSamplePlaying = false
1873
1874 g_animationManager:stopAnimations(spec.animationNodes)
1875
1876 if spec.motorStartAnimation ~= nil then
1877 self:playAnimation(spec.motorStartAnimation, -1, nil, true)
1878 end
1879 end
1880
1881 SpecializationUtil.raiseEvent(self, "onStopMotor")
1882 self.rootVehicle:raiseStateChange(Vehicle.STATE_CHANGE_MOTOR_TURN_OFF)
1883 end
1884
1885 spec.motor.lastMotorRpm = 0
1886
1887 if self.setDashboardsDirty ~= nil then
1888 self:setDashboardsDirty()
1889 end
1890end

stopVehicle

Description
Definition
stopVehicle()
Code
2862function Motorized:stopVehicle()
2863 if self.isServer then
2864 local spec = self.spec_motorized
2865 if spec.motorizedNode ~= nil then
2866 self:controlVehicle(0.0, 0.0, 0.0, 0.0, math.huge, 0.0, 0.0, 0.0, 0.0, 0.0)
2867 end
2868 end
2869end

updateActionEvents

Description
Definition
updateActionEvents()
Code
2623function Motorized.updateActionEvents(self)
2624 -- hide / show start motor input action if setting is changed on the fly
2625 local spec = self.spec_motorized
2626 local actionEvent = spec.actionEvents[InputAction.TOGGLE_MOTOR_STATE]
2627 if actionEvent ~= nil then
2628 if not g_currentMission.missionInfo.automaticMotorStartEnabled then
2629 local text
2630
2631 g_inputBinding:setActionEventActive(actionEvent.actionEventId, true)
2632 if self:getIsMotorStarted() then
2633 g_inputBinding:setActionEventTextPriority(actionEvent.actionEventId, GS_PRIO_VERY_LOW)
2634 text = spec.turnOffText
2635 else
2636 g_inputBinding:setActionEventTextPriority(actionEvent.actionEventId, GS_PRIO_VERY_HIGH)
2637 text = spec.turnOnText
2638 end
2639
2640 g_inputBinding:setActionEventText(actionEvent.actionEventId, text)
2641 else
2642 g_inputBinding:setActionEventActive(actionEvent.actionEventId, false)
2643 end
2644 end
2645end

updateConsumers

Description
Definition
updateConsumers()
Code
1894function Motorized:updateConsumers(dt, accInput)
1895 local spec = self.spec_motorized
1896
1897 local idleFactor = 0.5
1898 local rpmPercentage = (spec.motor.lastMotorRpm - spec.motor.minRpm) / (spec.motor.maxRpm - spec.motor.minRpm)
1899 local rpmFactor = idleFactor + rpmPercentage * (1-idleFactor)
1900 local loadFactor = math.max(spec.smoothedLoadPercentage * rpmPercentage, 0)
1901 local motorFactor = 0.5 * ( (0.2*rpmFactor) + (1.8*loadFactor) )
1902
1903 local usageFactor = 1.5 -- medium
1904 if g_currentMission.missionInfo.fuelUsage == 1 then
1905 usageFactor = 1.0 -- low
1906 elseif g_currentMission.missionInfo.fuelUsage == 3 then
1907 usageFactor = 2.5 -- high
1908 end
1909
1910 local damage = self:getVehicleDamage()
1911 if damage > 0 then
1912 usageFactor = usageFactor * (1 + damage * Motorized.DAMAGED_USAGE_INCREASE)
1913 end
1914
1915 -- update permanent consumers
1916 for _,consumer in pairs(spec.consumers) do
1917 if consumer.permanentConsumption and consumer.usage > 0 then
1918 local used = usageFactor * motorFactor * consumer.usage * dt
1919 if used ~= 0 then
1920 consumer.fillLevelToChange = consumer.fillLevelToChange + used
1921 if math.abs(consumer.fillLevelToChange) > 1 then
1922 used = consumer.fillLevelToChange
1923 consumer.fillLevelToChange = 0
1924
1925 local fillType = self:getFillUnitLastValidFillType(consumer.fillUnitIndex)
1926
1927 local stats = g_currentMission:farmStats(self:getOwnerFarmId())
1928 stats:updateStats("fuelUsage", used)
1929
1930 if self:getIsAIActive() then
1931 if fillType == FillType.DIESEL or fillType == FillType.DEF then
1932 if g_currentMission.missionInfo.helperBuyFuel then
1933 if fillType == FillType.DIESEL then
1934 local price = used * g_currentMission.economyManager:getCostPerLiter(fillType) * 1.5
1935 stats:updateStats("expenses", price)
1936
1937 g_currentMission:addMoney(-price, self:getOwnerFarmId(), MoneyType.PURCHASE_FUEL, true)
1938 end
1939
1940 used = 0
1941 end
1942 end
1943 end
1944
1945 if fillType == consumer.fillType then
1946 self:addFillUnitFillLevel(self:getOwnerFarmId(), consumer.fillUnitIndex, -used, fillType, ToolType.UNDEFINED)
1947 end
1948 end
1949
1950 if consumer.fillType == FillType.DIESEL or consumer.fillType == FillType.ELECTRICCHARGE or consumer.fillType == FillType.METHANE then
1951 spec.lastFuelUsage = used / dt * 1000 * 60 * 60 -- per hour
1952 elseif consumer.fillType == FillType.DEF then
1953 spec.lastDefUsage = used / dt * 1000 * 60 * 60 -- per hour
1954 end
1955 end
1956 end
1957 end
1958
1959 -- update air consuming
1960 if spec.consumersByFillTypeName["AIR"] ~= nil then
1961 local consumer = spec.consumersByFillTypeName["AIR"]
1962 local fillType = self:getFillUnitLastValidFillType(consumer.fillUnitIndex)
1963 if fillType == consumer.fillType then
1964 local usage = 0
1965
1966 -- consume air on brake
1967 local direction = self.movingDirection * self:getReverserDirection()
1968 local forwardBrake = direction > 0 and accInput < 0
1969 local backwardBrake = direction < 0 and accInput > 0
1970 local brakeIsPressed = self:getLastSpeed() > 1.0 and (forwardBrake or backwardBrake)
1971 if brakeIsPressed then
1972 local delta = math.abs(accInput) * dt * self:getAirConsumerUsage() / 1000
1973 self:addFillUnitFillLevel(self:getOwnerFarmId(), consumer.fillUnitIndex, -delta, consumer.fillType, ToolType.UNDEFINED)
1974
1975 usage = delta / dt * 1000 -- per sec
1976 end
1977
1978 --refill air fill unit if it is below given level
1979 local fillLevelPercentage = self:getFillUnitFillLevelPercentage(consumer.fillUnitIndex)
1980 if fillLevelPercentage < consumer.refillCapacityPercentage then
1981 consumer.doRefill = true
1982 elseif fillLevelPercentage == 1 then
1983 consumer.doRefill = false
1984 end
1985
1986 if consumer.doRefill then
1987 local delta = consumer.refillLitersPerSecond / 1000 * dt
1988 self:addFillUnitFillLevel(self:getOwnerFarmId(), consumer.fillUnitIndex, delta, consumer.fillType, ToolType.UNDEFINED)
1989
1990 usage = -delta / dt * 1000 -- per sec
1991 end
1992
1993 spec.lastAirUsage = usage
1994 end
1995 end
1996end

updateMotorProperties

Description
Update the motor properties based on script motor state
Definition
updateMotorProperties()
Code
2396function Motorized:updateMotorProperties()
2397 local spec = self.spec_motorized
2398 local motor = spec.motor
2399 local torques, rotationSpeeds = motor:getTorqueAndSpeedValues()
2400
2401 setMotorProperties(spec.motorizedNode, motor:getMinRpm()*math.pi/30, motor:getMaxRpm()*math.pi/30, motor:getRotInertia(), motor:getDampingRateFullThrottle(), motor:getDampingRateZeroThrottleClutchEngaged(), motor:getDampingRateZeroThrottleClutchDisengaged(), rotationSpeeds, torques)
2402end

updateMotorTemperature

Description
Definition
updateMotorTemperature()
Code
2000function Motorized:updateMotorTemperature(dt)
2001 local spec = self.spec_motorized
2002
2003 local delta = spec.motorTemperature.heatingPerMS * dt
2004 local factor = (1 + 4*spec.actualLoadPercentage) / 5
2005 delta = delta * (factor + self:getMotorRpmPercentage())
2006 spec.motorTemperature.value = math.min(spec.motorTemperature.valueMax, spec.motorTemperature.value + delta)
2007
2008 -- cooling due to wind
2009 delta = spec.motorTemperature.coolingByWindPerMS * dt
2010 local speedFactor = math.pow( math.min(1.0, self:getLastSpeed() / 30), 2 )
2011 spec.motorTemperature.value = math.max(spec.motorTemperature.valueMin, spec.motorTemperature.value - (speedFactor * delta))
2012
2013 -- cooling per fan
2014 if spec.motorTemperature.value > spec.motorFan.enableTemperature then
2015 spec.motorFan.enabled = true
2016 end
2017 if spec.motorFan.enabled then
2018 if spec.motorTemperature.value < spec.motorFan.disableTemperature then
2019 spec.motorFan.enabled = false
2020 end
2021 end
2022 if spec.motorFan.enabled then
2023 delta = spec.motorFan.coolingPerMS * dt
2024 spec.motorTemperature.value = math.max(spec.motorTemperature.valueMin, spec.motorTemperature.value - delta)
2025 end
2026end