Script v1_7_1_0
- AI
- Animals
- Collections
- Contracts
- Debug
- Economy
- Elements
- EnvironmentalScore
- Errors
- Events
- GUI
- Handtools
- Hud
- I3d
- Input
- Jobs
- Maps
- Materials
- Misc
- Objects
- Parameters
- Placeables
- Placement
- Player
- Shop
- Sounds
- Specialization
- Specializations
- AIConveyorBelt
- AIDrivable
- AIFieldWorker
- AIImplement
- AIJobVehicle
- AIVehicle
- AIVehicleObstacle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- AutoLoader
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BaseMaterial
- BigBag
- BunkerSiloCompacter
- BunkerSiloInteractor
- CCTDrivable
- Combine
- ConnectionHoses
- ConveyorBelt
- Cover
- CrabSteering
- Crawlers
- CropSensor
- Cultivator
- Cutter
- Cylindered
- CylinderedFoldable
- Dashboard
- Dischargeable
- Drivable
- DynamicallyLoadedParts
- DynamicMountAttacher
- Enterable
- ExtendedAIVehicle
- ExtendedCombine
- ExtendedMotorized
- ExtendedMower
- ExtendedSowingMachine
- ExtendedSprayer
- ExtendedWearable
- FertilizingCultivator
- FertilizingSowingMachine
- FillTriggerVehicle
- FillUnit
- FillVolume
- Foldable
- FoliageBending
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- GroundAdjustedNodes
- GroundReference
- HeadlandAnimation
- Honk
- HookLiftContainer
- HookLiftTrailer
- IKChains
- InlineWrapper
- JigglingParts
- Leveler
- LicensePlates
- Lights
- LivestockTrailer
- Locomotive
- LogGrab
- ManureBarrel
- ManureSensor
- MixerWagon
- Motorized
- Mountable
- Mower
- Mulcher
- MultipleItemPurchase
- Pallet
- Pickup
- Pipe
- PlaceableAI
- PlaceableAnimatedObjects
- PlaceableBeehive
- PlaceableBeehivePalletSpa...
- PlaceableBunkerSilo
- PlaceableBuyingStation
- PlaceableCartridgePlayer
- PlaceableChargingStation
- PlaceableClearAreas
- PlaceableColorable
- PlaceableDeletedNodes
- PlaceableDoghouse
- PlaceableDynamicallyLoade...
- PlaceableFarmhouse
- PlaceableFence
- PlaceableFoliageAreas
- PlaceableGreenhouse
- PlaceableHighPressureWash...
- PlaceableHotspots
- PlaceableHusbandry
- PlaceableHusbandryAnimals
- PlaceableHusbandryFeeding...
- PlaceableHusbandryFence
- PlaceableHusbandryFood
- PlaceableHusbandryLiquidM...
- PlaceableHusbandryMilk
- PlaceableHusbandryPallets
- PlaceableHusbandryStraw
- PlaceableHusbandryWater
- PlaceableIncomePerHour
- PlaceableIndoorAreas
- PlaceableInfoTrigger
- PlaceableLeveling
- PlaceableLights
- PlaceableManureHeap
- PlaceablePlacement
- PlaceableProductionPoint
- PlaceableSellingStation
- PlaceableSilo
- PlaceableSiloExtension
- PlaceableSolarPanels
- PlaceableTipOcclusionArea...
- PlaceableTrainSystem
- PlaceableTriggerMarkers
- PlaceableVine
- PlaceableWardrobe
- PlaceableWeatherStation
- PlaceableWeighingStation
- PlaceableWindTurbine
- PlaceableWorkshop
- Plow
- PlowPacker
- PowerConsumer
- PowerTakeOffs
- PrecisionFarmingStatistic
- PushHandTool
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- Rideable
- RidgeMarker
- Roller
- Ropes
- RTKStation
- SaltSpreader
- SemiTrailerFront
- Shovel
- SlopeCompensation
- SmartAttach
- SoilSampler
- SowingMachine
- SpeedRotatingParts
- SplineVehicle
- Sprayer
- StonePicker
- StrawBlower
- StumpCutter
- SupportVehicle
- Suspensions
- Tedder
- TensionBeltObject
- TensionBelts
- TestAreas
- TipOccluder
- Trailer
- TreePlanter
- TreeSaplingPallet
- TreeSaw
- TurnOnVehicle
- VariableWorkWidth
- VehicleSettings
- VineCutter
- VineDetector
- VinePrepruner
- Washable
- WaterTrailer
- Wearable
- Weeder
- WeedSpotSpray
- Wheels
- WindBending
- Windrower
- Wipers
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkMode
- WorkParticles
- StateMachine
- Statistics
- Tasks
- Triggers
- Utils
- Vehicles
Engine v1_7_1_0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- general
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- NoteNode
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- VoiceChat
- XML
Foundation Reference
Trailer
DescriptionSpecialization for trailers providing tipping animation and tip side selection functionlityFunctions
- actionEventManualToggleDoor
- actionEventManualToggleTip
- actionEventToggleTipSide
- endTipping
- getAIHasFinishedDischarge
- getCanBeSelected
- getCanChangePickupState
- getCanDischargeToGround
- getCanDischargeToGround
- getCanDischargeToObject
- getCanTogglePreferdTipSide
- getDischargeNodeEmptyFactor
- getIsNextCoverStateAllowed
- getIsTipSideAvailable
- getIsTurnedOnAnimationActive
- getNextAvailableTipSide
- getTipState
- initSpecialization
- loadPickupFromXML
- loadTipSide
- loadTurnedOnAnimationFromXML
- onDeactivate
- onDelete
- onDischargeStateChanged
- onFillUnitFillLevelChanged
- onLoad
- onLoadFinished
- onPostLoad
- onReadStream
- onRegisterActionEvents
- onRegisterAnimationValueTypes
- onUpdate
- onWriteStream
- prerequisitesPresent
- registerEventListeners
- registerEvents
- registerFunctions
- registerOverwrittenFunctions
- saveToXMLFile
- setPreferedTipSide
- setTipState
- setTrailerDoorState
- startAIDischarge
- startTipping
- stopTipping
actionEventManualToggleDoor
DescriptionDefinitionactionEventManualToggleDoor()Code
1106 | function Trailer.actionEventManualToggleDoor(self, actionName, inputValue, callbackState, isAnalog) |
1107 | self:setTrailerDoorState() |
1108 | end |
actionEventManualToggleTip
DescriptionDefinitionactionEventManualToggleTip()Code
1093 | function Trailer.actionEventManualToggleTip(self, actionName, inputValue, callbackState, isAnalog) |
1094 | local tipState = self:getTipState() |
1095 | if tipState == Trailer.TIPSTATE_CLOSED or tipState == Trailer.TIPSTATE_CLOSING then |
1096 | self:startTipping(nil, false) |
1097 | TrailerToggleManualTipEvent.sendEvent(self, true) |
1098 | else |
1099 | self:stopTipping() |
1100 | TrailerToggleManualTipEvent.sendEvent(self, false) |
1101 | end |
1102 | end |
actionEventToggleTipSide
DescriptionDefinitionactionEventToggleTipSide()Code
1083 | function Trailer.actionEventToggleTipSide(self, actionName, inputValue, callbackState, isAnalog) |
1084 | local spec = self.spec_trailer |
1085 | |
1086 | if self:getCanTogglePreferdTipSide() then |
1087 | self:setPreferedTipSide(self:getNextAvailableTipSide(spec.preferedTipSideIndex)) |
1088 | end |
1089 | end |
endTipping
DescriptionDefinitionendTipping()Code
715 | function Trailer:endTipping(noEventSend) |
716 | local spec = self.spec_trailer |
717 | |
718 | local tipSide = spec.tipSides[spec.currentTipSideIndex] |
719 | if tipSide ~= nil then |
720 | if not tipSide.manualDoorToggle and tipSide.doorAnimation.name ~= nil then |
721 | if tipSide.doorAnimation.delayedClosing then |
722 | self:setTrailerDoorState(false, true) |
723 | end |
724 | end |
725 | end |
726 | |
727 | spec.tipState = Trailer.TIPSTATE_CLOSED |
728 | spec.currentTipSideIndex = nil |
729 | |
730 | SpecializationUtil.raiseEvent(self, "onEndTipping") |
731 | end |
getAIHasFinishedDischarge
DescriptionDefinitiongetAIHasFinishedDischarge()Code
931 | function Trailer:getAIHasFinishedDischarge(superFunc, dischargeNode) |
932 | if self:getTipState() ~= Trailer.TIPSTATE_CLOSED then |
933 | return false |
934 | end |
935 | |
936 | return superFunc(self, dischargeNode) |
937 | end |
getCanBeSelected
DescriptionDefinitiongetCanBeSelected()Code
869 | function Trailer:getCanBeSelected(superFunc) |
870 | return true |
871 | end |
getCanChangePickupState
DescriptionDefinitiongetCanChangePickupState()Code
961 | function Trailer:getCanChangePickupState(superFunc, spec, newState) |
962 | if not superFunc(self, spec, newState) then |
963 | return false |
964 | end |
965 | |
966 | if not spec.allowWhileTipping then |
967 | return self:getTipState() == Trailer.TIPSTATE_CLOSED |
968 | end |
969 | |
970 | return true |
971 | end |
getCanDischargeToGround
DescriptionDefinitiongetCanDischargeToGround()Code
820 | function Trailer:getCanDischargeToGround(superFunc, dischargeNode) |
821 | local canTip = superFunc(self, dischargeNode) |
822 | if dischargeNode ~= nil then |
823 | local spec = self.spec_trailer |
824 | local tipSide = spec.dischargeNodeIndexToTipSide[dischargeNode.index] |
825 | if tipSide ~= nil then |
826 | local fillUnitIndex = dischargeNode.fillUnitIndex |
827 | if not tipSide.canTipIfEmpty and self:getFillUnitFillLevel(fillUnitIndex) == 0 then |
828 | canTip = false |
829 | end |
830 | end |
831 | end |
832 | |
833 | return canTip |
834 | end |
getCanDischargeToGround
DescriptionDefinitiongetCanDischargeToGround()Code
975 | function Trailer:getCanDischargeToGround(superFunc, dischargeNode) |
976 | if not superFunc(self, dischargeNode) then |
977 | return false |
978 | end |
979 | |
980 | if self.spec_pickup ~= nil and not self.spec_pickup.allowWhileTipping then |
981 | return not self.spec_pickup.isLowered |
982 | end |
983 | |
984 | return true |
985 | end |
getCanDischargeToObject
DescriptionDefinitiongetCanDischargeToObject()Code
989 | function Trailer:getCanDischargeToObject(superFunc, dischargeNode) |
990 | if not superFunc(self, dischargeNode) then |
991 | return false |
992 | end |
993 | |
994 | if self.spec_pickup ~= nil and not self.spec_pickup.allowWhileTipping then |
995 | return not self.spec_pickup.isLowered |
996 | end |
997 | |
998 | return true |
999 | end |
getCanTogglePreferdTipSide
DescriptionDefinitiongetCanTogglePreferdTipSide()Code
543 | function Trailer:getCanTogglePreferdTipSide() |
544 | local spec = self.spec_trailer |
545 | return spec.tipState == Trailer.TIPSTATE_CLOSED and spec.tipSideCount > 0 |
546 | end |
getDischargeNodeEmptyFactor
DescriptionDefinitiongetDischargeNodeEmptyFactor()Code
795 | function Trailer:getDischargeNodeEmptyFactor(superFunc, dischargeNode) |
796 | local spec = self.spec_trailer |
797 | local tipSide = spec.dischargeNodeIndexToTipSide[dischargeNode.index] |
798 | |
799 | if tipSide ~= nil then |
800 | if tipSide.animation.name ~= nil and tipSide.animation.startTipTime ~= 0 then |
801 | if self:getAnimationTime(tipSide.animation.name) < tipSide.animation.startTipTime then |
802 | return 0 |
803 | end |
804 | end |
805 | |
806 | if tipSide.doorAnimation.name ~= nil and tipSide.doorAnimation.startTipTime ~= 0 then |
807 | if self:getAnimationTime(tipSide.doorAnimation.name) < tipSide.doorAnimation.startTipTime then |
808 | return 0 |
809 | end |
810 | end |
811 | |
812 | return tipSide.currentEmptyFactor |
813 | end |
814 | |
815 | return superFunc(self, dischargeNode) |
816 | end |
getIsNextCoverStateAllowed
DescriptionDefinitiongetIsNextCoverStateAllowed()Code
838 | function Trailer:getIsNextCoverStateAllowed(superFunc, nextState) |
839 | local spec = self.spec_trailer |
840 | |
841 | local tipSide |
842 | if spec.currentTipSideIndex ~= nil then |
843 | tipSide = spec.tipSides[spec.currentTipSideIndex] |
844 | end |
845 | |
846 | if spec.preferedTipSideIndex ~= nil then |
847 | local preferedTipSide = spec.tipSides[spec.preferedTipSideIndex] |
848 | if preferedTipSide ~= nil and preferedTipSide.manualDoorToggle and preferedTipSide.doorAnimation.state then |
849 | tipSide = preferedTipSide |
850 | end |
851 | end |
852 | |
853 | if tipSide ~= nil then |
854 | local dischargeNode = self:getDischargeNodeByIndex(tipSide.dischargeNodeIndex) |
855 | |
856 | local cover = self:getCoverByFillUnitIndex(dischargeNode.fillUnitIndex) |
857 | if cover ~= nil then |
858 | if nextState ~= cover.index then |
859 | return false |
860 | end |
861 | end |
862 | end |
863 | |
864 | return superFunc(self, nextState) |
865 | end |
getIsTipSideAvailable
DescriptionDefinitiongetIsTipSideAvailable()Code
550 | function Trailer:getIsTipSideAvailable(sideIndex) |
551 | local spec = self.spec_trailer |
552 | local tipSide = spec.tipSides[sideIndex] |
553 | if tipSide ~= nil then |
554 | if tipSide.fillLevel.fillUnitIndex ~= nil then |
555 | local fillLevelPct = self:getFillUnitFillLevelPercentage(tipSide.fillLevel.fillUnitIndex) |
556 | if fillLevelPct < tipSide.fillLevel.minFillLevelPct or fillLevelPct > tipSide.fillLevel.maxFillLevelPct then |
557 | return false |
558 | end |
559 | end |
560 | |
561 | return true |
562 | end |
563 | |
564 | return false |
565 | end |
getIsTurnedOnAnimationActive
DescriptionDefinitiongetIsTurnedOnAnimationActive()Code
1011 | function Trailer:getIsTurnedOnAnimationActive(superFunc, turnedOnAnimation) |
1012 | if turnedOnAnimation.playWhileTipping then |
1013 | return superFunc(self, turnedOnAnimation) or (self:getTipState() ~= Trailer.TIPSTATE_CLOSED and self:getDischargeNodeEmptyFactor(self:getCurrentDischargeNode()) > 0) |
1014 | end |
1015 | |
1016 | return superFunc(self, turnedOnAnimation) |
1017 | end |
getNextAvailableTipSide
DescriptionDefinitiongetNextAvailableTipSide()Code
569 | function Trailer:getNextAvailableTipSide(index) |
570 | local spec = self.spec_trailer |
571 | local newTipSideIndex = index |
572 | local checkCount = spec.tipSideCount |
573 | local tipSideToCheck = index |
574 | while checkCount > 0 do |
575 | tipSideToCheck = tipSideToCheck + 1 |
576 | if tipSideToCheck > spec.tipSideCount then |
577 | tipSideToCheck = 1 |
578 | end |
579 | |
580 | if self:getIsTipSideAvailable(tipSideToCheck) then |
581 | newTipSideIndex = tipSideToCheck |
582 | break |
583 | end |
584 | |
585 | checkCount = checkCount - 1 |
586 | end |
587 | |
588 | return newTipSideIndex |
589 | end |
getTipState
DescriptionDefinitiongetTipState()Code
764 | function Trailer:getTipState() |
765 | return self.spec_trailer.tipState |
766 | end |
initSpecialization
DescriptionDefinitioninitSpecialization()Code
35 | function Trailer.initSpecialization() |
36 | g_configurationManager:addConfigurationType("trailer", g_i18n:getText("configuration_trailer"), "trailer", nil, nil, nil, ConfigurationUtil.SELECTOR_MULTIOPTION) |
37 | |
38 | local schema = Vehicle.xmlSchema |
39 | schema:setXMLSpecializationType("Trailer") |
40 | |
41 | local key = "vehicle.trailer.trailerConfigurations.trailerConfiguration(?).trailer" |
42 | ObjectChangeUtil.registerObjectChangeXMLPaths(schema, "vehicle.trailer.trailerConfigurations.trailerConfiguration(?)") |
43 | |
44 | schema:register(XMLValueType.L10N_STRING, key .. "#infoText", "Info text", "action_toggleTipSide") |
45 | |
46 | schema:register(XMLValueType.STRING, key .. ".tipSide(?)#name", "Tip side name") |
47 | schema:register(XMLValueType.INT, key .. ".tipSide(?)#dischargeNodeIndex", "Discharge node index", 1) |
48 | schema:register(XMLValueType.BOOL, key .. ".tipSide(?)#canTipIfEmpty", "Can tip if empty", true) |
49 | |
50 | schema:register(XMLValueType.BOOL, key .. ".tipSide(?).manualTipToggle#enabled", "Tip animation can be toggled manually without dischargeable", false) |
51 | schema:register(XMLValueType.BOOL, key .. ".tipSide(?).manualTipToggle#stopOnDeactivate", "Stop manual tipping while vehicle is deactivated (detached, exited etc)", true) |
52 | schema:register(XMLValueType.STRING, key .. ".tipSide(?).manualTipToggle#inputAction", "Input action to toggle tipping", "IMPLEMENT_EXTRA4") |
53 | schema:register(XMLValueType.L10N_STRING, key .. ".tipSide(?).manualTipToggle#inputActionTextPos", "Positive input text to display", "action_startTipping") |
54 | schema:register(XMLValueType.L10N_STRING, key .. ".tipSide(?).manualTipToggle#inputActionTextNeg", "Negative input text to display", "action_stopTipping") |
55 | |
56 | schema:register(XMLValueType.BOOL, key .. ".tipSide(?).manualDoorToggle#enabled", "Door animation can be toggled manually without dischargeable", false) |
57 | schema:register(XMLValueType.STRING, key .. ".tipSide(?).manualDoorToggle#inputAction", "Input action to toggle tipping", "IMPLEMENT_EXTRA3") |
58 | schema:register(XMLValueType.L10N_STRING, key .. ".tipSide(?).manualDoorToggle#inputActionTextPos", "Positive input text to display", "action_openBackDoor") |
59 | schema:register(XMLValueType.L10N_STRING, key .. ".tipSide(?).manualDoorToggle#inputActionTextNeg", "Negative input text to display", "action_closeBackDoor") |
60 | |
61 | schema:register(XMLValueType.STRING, key .. ".tipSide(?).animation#name", "Tip animation name") |
62 | schema:register(XMLValueType.FLOAT, key .. ".tipSide(?).animation#speedScale", "Tip animation speed scale", 1) |
63 | schema:register(XMLValueType.FLOAT, key .. ".tipSide(?).animation#closeSpeedScale", "Tip animation speed scale while stopping to tip", "inversed speed scale") |
64 | schema:register(XMLValueType.FLOAT, key .. ".tipSide(?).animation#startTipTime", "Tip animation start tip time", 0) |
65 | schema:register(XMLValueType.BOOL, key .. ".tipSide(?).animation#resetTipSideChange", "Reset tip animation to zero while tip side is activated", false) |
66 | |
67 | schema:register(XMLValueType.STRING, key .. ".tipSide(?).doorAnimation#name", "Door animation name") |
68 | schema:register(XMLValueType.FLOAT, key .. ".tipSide(?).doorAnimation#speedScale", "Door animation speed scale", 1) |
69 | schema:register(XMLValueType.FLOAT, key .. ".tipSide(?).doorAnimation#closeSpeedScale", "Door animation speed scale while stopping to tip", "inversed speed scale") |
70 | schema:register(XMLValueType.FLOAT, key .. ".tipSide(?).doorAnimation#startTipTime", "Door animation start tip time", 0) |
71 | schema:register(XMLValueType.BOOL, key .. ".tipSide(?).doorAnimation#delayedClosing", "Play door animation after tip animation while closing", false) |
72 | |
73 | schema:register(XMLValueType.STRING, key .. ".tipSide(?).tippingAnimation#name", "Tipping animation name (continously played while tipping)") |
74 | schema:register(XMLValueType.FLOAT, key .. ".tipSide(?).tippingAnimation#speedScale", "Tipping animation speed scale", 1) |
75 | |
76 | schema:register(XMLValueType.INT, key .. ".tipSide(?).fillLevel#fillUnitIndex", "Fill unit index to check") |
77 | schema:register(XMLValueType.FLOAT, key .. ".tipSide(?).fillLevel#minFillLevelPct", "Min. trailer fill level pct to select tip side", 1) |
78 | schema:register(XMLValueType.FLOAT, key .. ".tipSide(?).fillLevel#maxFillLevelPct", "Max. trailer fill level pct to select tip side", 1) |
79 | |
80 | AnimationManager.registerAnimationNodesXMLPaths(schema, key .. ".tipSide(?).animationNodes") |
81 | ObjectChangeUtil.registerObjectChangeXMLPaths(schema, key .. ".tipSide(?)") |
82 | SoundManager.registerSampleXMLPaths(schema, key .. ".tipSide(?)", "unloadSound") |
83 | |
84 | schema:addDelayedRegistrationFunc("AnimatedVehicle:part", function(cSchema, cKey) |
85 | cSchema:register(XMLValueType.FLOAT, cKey .. "#startTipSideEmptyFactor", "Start tip side empty factor") |
86 | cSchema:register(XMLValueType.FLOAT, cKey .. "#endTipSideEmptyFactor", "End tip side empty factor") |
87 | end) |
88 | |
89 | schema:register(XMLValueType.BOOL, Pickup.PICKUP_XML_KEY .. "#allowWhileTipping", "Allow pickup movement while tipping", true) |
90 | schema:register(XMLValueType.BOOL, TurnOnVehicle.TURNED_ON_ANIMATION_XML_PATH .. "#playWhileTipping", "Animation is active while tipping", false) |
91 | |
92 | schema:setXMLSpecializationType() |
93 | |
94 | local schemaSavegame = Vehicle.xmlSchemaSavegame |
95 | schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).trailer#tipSideIndex", "Current tip side index") |
96 | schemaSavegame:register(XMLValueType.BOOL, "vehicles.vehicle(?).trailer#doorState", "Current back door state") |
97 | schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).trailer#tipState", "Current tip state") |
98 | schemaSavegame:register(XMLValueType.FLOAT, "vehicles.vehicle(?).trailer#tipAnimationTime", "Current tip animation time") |
99 | end |
loadPickupFromXML
DescriptionDefinitionloadPickupFromXML()Code
953 | function Trailer:loadPickupFromXML(superFunc, xmlFile, key, spec) |
954 | spec.allowWhileTipping = xmlFile:getValue(key.."#allowWhileTipping", true) |
955 | |
956 | return superFunc(self, xmlFile, key, spec) |
957 | end |
loadTipSide
DescriptionDefinitionloadTipSide()Code
442 | function Trailer:loadTipSide(xmlFile, key, entry) |
443 | local name = xmlFile:getValue(key .. "#name") |
444 | entry.name = g_i18n:convertText(name, self.customEnvironment) |
445 | if entry.name == nil then |
446 | Logging.xmlWarning(self.xmlFile, "Given tipSide name '%s' not found for '%s'!", tostring(name), key) |
447 | return false |
448 | end |
449 | |
450 | entry.dischargeNodeIndex = xmlFile:getValue(key .. "#dischargeNodeIndex", 1) |
451 | entry.canTipIfEmpty = xmlFile:getValue(key .. "#canTipIfEmpty", true) |
452 | |
453 | entry.manualTipToggle = xmlFile:getValue(key .. ".manualTipToggle#enabled", false) |
454 | if entry.manualTipToggle then |
455 | local manualTipToggleActionName = xmlFile:getValue(key .. ".manualTipToggle#inputAction") |
456 | entry.manualTipToggleAction = InputAction[manualTipToggleActionName] or InputAction.IMPLEMENT_EXTRA4 |
457 | |
458 | entry.manualTipToggleStopOnDeactivate = xmlFile:getValue(key .. ".manualTipToggle#stopOnDeactivate", true) |
459 | |
460 | entry.manualTipToggleActionTextPos = xmlFile:getValue(key .. ".manualTipToggle#inputActionTextPos", "action_startTipping", self.customEnvironment, false) |
461 | entry.manualTipToggleActionTextNeg = xmlFile:getValue(key .. ".manualTipToggle#inputActionTextNeg", "action_stopTipping", self.customEnvironment, false) |
462 | end |
463 | |
464 | entry.manualDoorToggle = xmlFile:getValue(key .. ".manualDoorToggle#enabled", false) |
465 | if entry.manualDoorToggle then |
466 | local manualDoorToggleActionName = xmlFile:getValue(key .. ".manualDoorToggle#inputAction") |
467 | entry.manualDoorToggleAction = InputAction[manualDoorToggleActionName] or InputAction.IMPLEMENT_EXTRA3 |
468 | |
469 | entry.manualDoorToggleActionTextPos = xmlFile:getValue(key .. ".manualDoorToggle#inputActionTextPos", "action_openBackDoor", self.customEnvironment, false) |
470 | entry.manualDoorToggleActionTextNeg = xmlFile:getValue(key .. ".manualDoorToggle#inputActionTextNeg", "action_closeBackDoor", self.customEnvironment, false) |
471 | end |
472 | |
473 | entry.animation = {} |
474 | entry.animation.name = xmlFile:getValue(key .. ".animation#name") |
475 | if entry.animation.name == nil or not self:getAnimationExists(entry.animation.name) then |
476 | Logging.xmlWarning(self.xmlFile, "Missing animation name for '%s'!", key) |
477 | return false |
478 | end |
479 | entry.animation.speedScale = xmlFile:getValue(key .. ".animation#speedScale", 1.0) |
480 | entry.animation.closeSpeedScale = -xmlFile:getValue(key .. ".animation#closeSpeedScale", entry.animation.speedScale) |
481 | entry.animation.startTipTime = xmlFile:getValue(key .. ".animation#startTipTime", 0) |
482 | entry.animation.resetTipSideChange = xmlFile:getValue(key .. ".animation#resetTipSideChange", false) |
483 | |
484 | entry.doorAnimation = {} |
485 | entry.doorAnimation.name = xmlFile:getValue(key .. ".doorAnimation#name") |
486 | entry.doorAnimation.speedScale = xmlFile:getValue(key .. ".doorAnimation#speedScale", 1.0) |
487 | entry.doorAnimation.closeSpeedScale = -xmlFile:getValue(key .. ".doorAnimation#closeSpeedScale", entry.doorAnimation.speedScale) |
488 | entry.doorAnimation.startTipTime = xmlFile:getValue(key .. ".doorAnimation#startTipTime", 0) |
489 | entry.doorAnimation.delayedClosing = xmlFile:getValue(key .. ".doorAnimation#delayedClosing", false) |
490 | entry.doorAnimation.state = false |
491 | if entry.doorAnimation.name ~= nil and not self:getAnimationExists(entry.doorAnimation.name) then |
492 | Logging.xmlWarning(self.xmlFile, "Unknown door animation name for '%s'!", key) |
493 | return false |
494 | end |
495 | |
496 | entry.tippingAnimation = {} |
497 | entry.tippingAnimation.name = xmlFile:getValue(key .. ".tippingAnimation#name") |
498 | entry.tippingAnimation.speedScale = xmlFile:getValue(key .. ".tippingAnimation#speedScale", 1.0) |
499 | |
500 | entry.fillLevel = {} |
501 | entry.fillLevel.fillUnitIndex = xmlFile:getValue(key .. ".fillLevel#fillUnitIndex") |
502 | entry.fillLevel.minFillLevelPct = xmlFile:getValue(key .. ".fillLevel#minFillLevelPct", 0) |
503 | entry.fillLevel.maxFillLevelPct = xmlFile:getValue(key .. ".fillLevel#maxFillLevelPct", 1) |
504 | |
505 | if entry.fillLevel.fillUnitIndex ~= nil then |
506 | self.spec_trailer.fillLevelDependentTipSides = true |
507 | end |
508 | |
509 | if self.isClient then |
510 | entry.animationNodes = g_animationManager:loadAnimations(self.xmlFile, key..".animationNodes", self.components, self, self.i3dMappings) |
511 | entry.unloadSound = g_soundManager:loadSampleFromXML(self.xmlFile, key, "unloadSound", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
512 | end |
513 | |
514 | entry.objectChanges = {} |
515 | ObjectChangeUtil.loadObjectChangeFromXML(xmlFile, key, entry.objectChanges, self.components, self) |
516 | ObjectChangeUtil.setObjectChanges(entry.objectChanges, false) |
517 | |
518 | entry.currentEmptyFactor = 1 |
519 | |
520 | return true |
521 | end |
loadTurnedOnAnimationFromXML
DescriptionDefinitionloadTurnedOnAnimationFromXML()Code
1003 | function Trailer:loadTurnedOnAnimationFromXML(superFunc, xmlFile, key, turnedOnAnimation) |
1004 | turnedOnAnimation.playWhileTipping = xmlFile:getValue(key.."#playWhileTipping", false) |
1005 | |
1006 | return superFunc(self, xmlFile, key, turnedOnAnimation) |
1007 | end |
onDeactivate
DescriptionDefinitiononDeactivate()Code
916 | function Trailer:onDeactivate() |
917 | local spec = self.spec_trailer |
918 | local tipSide = spec.tipSides[spec.preferedTipSideIndex] |
919 | if tipSide ~= nil then |
920 | if tipSide.manualTipToggle and tipSide.manualTipToggleStopOnDeactivate then |
921 | local tipState = self:getTipState() |
922 | if tipState == Trailer.TIPSTATE_OPEN or tipState == Trailer.TIPSTATE_OPENING then |
923 | self:stopTipping(true) |
924 | end |
925 | end |
926 | end |
927 | end |
onDelete
DescriptionDefinitiononDelete()Code
255 | function Trailer:onDelete() |
256 | local spec = self.spec_trailer |
257 | if spec.tipSides ~= nil then |
258 | for _, tipSide in ipairs(spec.tipSides) do |
259 | g_animationManager:deleteAnimations(tipSide.animationNodes) |
260 | g_soundManager:deleteSample(tipSide.unloadSound) |
261 | end |
262 | end |
263 | end |
onDischargeStateChanged
DescriptionDefinitiononDischargeStateChanged()Code
906 | function Trailer:onDischargeStateChanged(dischargState) |
907 | if dischargState == Dischargeable.DISCHARGE_STATE_OFF then |
908 | self:stopTipping(true) |
909 | elseif dischargState == Dischargeable.DISCHARGE_STATE_GROUND or dischargState == Dischargeable.DISCHARGE_STATE_OBJECT then |
910 | self:startTipping(nil, true) |
911 | end |
912 | end |
onFillUnitFillLevelChanged
DescriptionDefinitiononFillUnitFillLevelChanged()Code
1065 | function Trailer:onFillUnitFillLevelChanged(fillUnitIndex, fillLevelDelta, fillType, toolType, fillPositionData, appliedDelta) |
1066 | local spec = self.spec_trailer |
1067 | if spec.fillLevelDependentTipSides then |
1068 | if fillLevelDelta ~= 0 then |
1069 | if not self:getIsTipSideAvailable(spec.preferedTipSideIndex) then |
1070 | local tipState = self:getTipState() |
1071 | if tipState == Trailer.TIPSTATE_CLOSED then |
1072 | self:setPreferedTipSide(self:getNextAvailableTipSide(spec.preferedTipSideIndex)) |
1073 | else |
1074 | spec.tipSideUpdateDirty = true |
1075 | end |
1076 | end |
1077 | end |
1078 | end |
1079 | end |
onLoad
DescriptionDefinitiononLoad()Code
163 | function Trailer:onLoad(savegame) |
164 | local spec = self.spec_trailer |
165 | |
166 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.tipScrollerNodes.tipScrollerNode", "vehicle.trailer.trailerConfigurations.trailerConfiguration.trailer.tipSide.animationNodes.animationNode") --FS17 to FS19 |
167 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.tipRotationNodes.tipRotationNode", "vehicle.trailer.trailerConfigurations.trailerConfiguration.trailer.tipSide.animationNodes.animationNode") --FS17 to FS19 |
168 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.tipAnimations.tipAnimation", "vehicle.trailer.trailerConfigurations.trailerConfiguration.trailer.tipSide") --FS17 to FS19 |
169 | |
170 | |
171 | local trailerConfigurationId = Utils.getNoNil(self.configurations["trailer"], 1) |
172 | local configKey = string.format("vehicle.trailer.trailerConfigurations.trailerConfiguration(%d).trailer", trailerConfigurationId -1) |
173 | ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.trailer.trailerConfigurations.trailerConfiguration", trailerConfigurationId , self.components, self) |
174 | |
175 | spec.fillLevelDependentTipSides = false |
176 | spec.tipSideUpdateDirty = false |
177 | |
178 | spec.tipSides = {} |
179 | spec.dischargeNodeIndexToTipSide = {} |
180 | local i = 0 |
181 | while true do |
182 | local key = string.format("%s.tipSide(%d)", configKey, i) |
183 | if not self.xmlFile:hasProperty(key) then |
184 | break |
185 | end |
186 | |
187 | local entry = {} |
188 | if self:loadTipSide(self.xmlFile, key, entry) then |
189 | table.insert(spec.tipSides, entry) |
190 | entry.index = #spec.tipSides |
191 | spec.dischargeNodeIndexToTipSide[entry.dischargeNodeIndex] = entry |
192 | end |
193 | i = i + 1 |
194 | end |
195 | |
196 | spec.infoText = self.xmlFile:getValue(configKey .. "#infoText", "action_toggleTipSide", self.customEnvironment, false) |
197 | |
198 | spec.tipSideCount = #spec.tipSides |
199 | spec.preferedTipSideIndex = 1 |
200 | spec.currentTipSideIndex = nil |
201 | |
202 | spec.tipState = Trailer.TIPSTATE_CLOSED |
203 | |
204 | spec.remainingFillDelta = 0 |
205 | |
206 | spec.dirtyFlag = self:getNextDirtyFlag() |
207 | end |
onLoadFinished
DescriptionDefinitiononLoadFinished()Code
244 | function Trailer:onLoadFinished(savegame) |
245 | local spec = self.spec_trailer |
246 | if spec.tipSideCount > 1 then |
247 | if not self:getIsTipSideAvailable(spec.preferedTipSideIndex) then |
248 | spec.tipSideUpdateDirty = true |
249 | end |
250 | end |
251 | end |
onPostLoad
DescriptionDefinitiononPostLoad()Code
211 | function Trailer:onPostLoad(savegame) |
212 | local spec = self.spec_trailer |
213 | if savegame ~= nil then |
214 | if spec.tipSideCount > 0 then |
215 | if spec.tipSideCount > 1 then |
216 | local tipSideIndex = savegame.xmlFile:getValue(savegame.key..".trailer#tipSideIndex") |
217 | if tipSideIndex ~= nil then |
218 | self:setPreferedTipSide(tipSideIndex, true) |
219 | end |
220 | end |
221 | |
222 | local doorState = savegame.xmlFile:getValue(savegame.key..".trailer#doorState") |
223 | if doorState ~= nil then |
224 | self:setTrailerDoorState(doorState, true, true) |
225 | end |
226 | |
227 | spec.tipState = savegame.xmlFile:getValue(savegame.key..".trailer#tipState", spec.tipState) |
228 | if spec.tipState == Trailer.TIPSTATE_OPENING or spec.tipState == Trailer.TIPSTATE_OPEN then |
229 | spec.currentTipSideIndex = spec.preferedTipSideIndex |
230 | self:setTipState(true) |
231 | end |
232 | |
233 | local tipAnimationTime = savegame.xmlFile:getValue(savegame.key..".trailer#tipAnimationTime") |
234 | if tipAnimationTime ~= nil then |
235 | local tipSide = spec.tipSides[spec.preferedTipSideIndex] |
236 | self:setAnimationTime(tipSide.animation.name, tipAnimationTime, true, false) |
237 | end |
238 | end |
239 | end |
240 | end |
onReadStream
DescriptionCalled on client side on joinDefinition
onReadStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
269 | function Trailer:onReadStream(streamId, connection) |
270 | local spec = self.spec_trailer |
271 | |
272 | if spec.tipSideCount > 1 then |
273 | self:setPreferedTipSide(streamReadUIntN(streamId, Trailer.TIP_SIDE_NUM_BITS), true) |
274 | end |
275 | |
276 | spec.tipState = streamReadUIntN(streamId, Trailer.TIP_STATE_NUM_BITS) |
277 | if streamReadBool(streamId) then |
278 | spec.currentTipSideIndex = streamReadUIntN(streamId, Trailer.TIP_SIDE_NUM_BITS) |
279 | end |
280 | |
281 | if streamReadBool(streamId) then |
282 | local doorState = streamReadBool(streamId) |
283 | self:setTrailerDoorState(doorState, true, true) |
284 | end |
285 | |
286 | if streamReadBool(streamId) then |
287 | local tipSide = spec.tipSides[spec.preferedTipSideIndex] |
288 | local tipAnimationTime = streamReadFloat32(streamId) |
289 | if tipAnimationTime ~= nil then |
290 | self:setAnimationTime(tipSide.animation.name, tipAnimationTime, true, false) |
291 | end |
292 | |
293 | if streamReadBool(streamId) then |
294 | if streamReadBool(streamId) then |
295 | self:playAnimation(tipSide.animation.name, tipSide.animation.speedScale, tipAnimationTime, true) |
296 | else |
297 | self:playAnimation(tipSide.animation.name, tipSide.animation.closeSpeedScale, tipAnimationTime, true) |
298 | end |
299 | end |
300 | end |
301 | |
302 | if streamReadBool(streamId) then |
303 | local tipSide = spec.tipSides[spec.preferedTipSideIndex] |
304 | local doorAnimationTime = streamReadFloat32(streamId) |
305 | if doorAnimationTime ~= nil then |
306 | self:setAnimationTime(tipSide.doorAnimation.name, doorAnimationTime, true, false) |
307 | end |
308 | |
309 | if streamReadBool(streamId) then |
310 | if streamReadBool(streamId) then |
311 | self:playAnimation(tipSide.doorAnimation.name, tipSide.doorAnimation.speedScale, doorAnimationTime, true) |
312 | else |
313 | self:playAnimation(tipSide.doorAnimation.name, tipSide.doorAnimation.closeSpeedScale, doorAnimationTime, true) |
314 | end |
315 | end |
316 | end |
317 | end |
onRegisterActionEvents
DescriptionDefinitiononRegisterActionEvents()Code
875 | function Trailer:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection) |
876 | if self.isClient then |
877 | local spec = self.spec_trailer |
878 | if spec.tipSideCount < 2 then |
879 | return |
880 | end |
881 | |
882 | self:clearActionEventsTable(spec.actionEvents) |
883 | |
884 | if isActiveForInputIgnoreSelection then |
885 | local _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.TOGGLE_TIPSIDE, self, Trailer.actionEventToggleTipSide, false, true, false, true, nil) |
886 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL) |
887 | |
888 | local tipSide = spec.tipSides[spec.preferedTipSideIndex] |
889 | if tipSide ~= nil then |
890 | if tipSide.manualTipToggle then |
891 | _, actionEventId = self:addPoweredActionEvent(spec.actionEvents, tipSide.manualTipToggleAction, self, Trailer.actionEventManualToggleTip, false, true, false, true, nil) |
892 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL) |
893 | end |
894 | |
895 | if tipSide.manualDoorToggle then |
896 | _, actionEventId = self:addPoweredActionEvent(spec.actionEvents, tipSide.manualDoorToggleAction, self, Trailer.actionEventManualToggleDoor, false, true, false, true, nil) |
897 | g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL) |
898 | end |
899 | end |
900 | end |
901 | end |
902 | end |
onRegisterAnimationValueTypes
DescriptionCalled on pre load to register animation value typesDefinition
onRegisterAnimationValueTypes()Code
1021 | function Trailer:onRegisterAnimationValueTypes() |
1022 | self:registerAnimationValueType("tipSideEmptyFactor", "startTipSideEmptyFactor", "endTipSideEmptyFactor", false, AnimationValueFloat, |
1023 | function(value, xmlFile, xmlKey) |
1024 | value.node = xmlFile:getValue(xmlKey .. "#node", nil, value.part.components, value.part.i3dMappings) |
1025 | |
1026 | if value.node ~= nil then |
1027 | value:setWarningInformation("node: " .. getName(value.node)) |
1028 | value:addCompareParameters("node") |
1029 | |
1030 | return true |
1031 | end |
1032 | |
1033 | return false |
1034 | end, |
1035 | |
1036 | function(value) |
1037 | if value.tipSide == nil then |
1038 | local dischargeNode = value.vehicle:getDischargeNodeByNode(value.node) |
1039 | local tipSide |
1040 | if dischargeNode ~= nil then |
1041 | tipSide = value.vehicle.spec_trailer.dischargeNodeIndexToTipSide[dischargeNode.index] |
1042 | end |
1043 | if dischargeNode == nil or tipSide == nil then |
1044 | Logging.xmlWarning(value.xmlFile, "Could not update discharge emptyFactor. No tipSide or dischargeNode defined for node '%s'!", getName(value.node)) |
1045 | value.startValue = nil |
1046 | return 0 |
1047 | end |
1048 | |
1049 | value.tipSide = tipSide |
1050 | end |
1051 | |
1052 | return value.tipSide.currentEmptyFactor |
1053 | end, |
1054 | |
1055 | function(value, emptyFactor) |
1056 | if value.tipSide ~= nil then |
1057 | value.tipSide.currentEmptyFactor = emptyFactor |
1058 | end |
1059 | end) |
1060 | end |
onUpdate
DescriptionDefinitiononUpdate()Code
357 | function Trailer:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
358 | local spec = self.spec_trailer |
359 | |
360 | if spec.tipSideCount > 1 then |
361 | local actionEvent = spec.actionEvents[InputAction.TOGGLE_TIPSIDE] |
362 | if actionEvent ~= nil then |
363 | local state = self:getCanTogglePreferdTipSide() |
364 | g_inputBinding:setActionEventActive(actionEvent.actionEventId, state) |
365 | |
366 | if state then |
367 | local text = string.format(spec.infoText, spec.tipSides[spec.preferedTipSideIndex].name) |
368 | g_inputBinding:setActionEventText(actionEvent.actionEventId, text) |
369 | end |
370 | end |
371 | end |
372 | |
373 | if spec.tipSideUpdateDirty then |
374 | local tipState = self:getTipState() |
375 | if tipState == Trailer.TIPSTATE_CLOSED then |
376 | self:setPreferedTipSide(self:getNextAvailableTipSide(spec.preferedTipSideIndex)) |
377 | spec.tipSideUpdateDirty = false |
378 | end |
379 | end |
380 | |
381 | local tipSide = spec.tipSides[spec.preferedTipSideIndex] |
382 | if tipSide ~= nil then |
383 | if tipSide.manualTipToggle then |
384 | local actionEvent = spec.actionEvents[tipSide.manualTipToggleAction] |
385 | if actionEvent ~= nil then |
386 | local text |
387 | local tipState = self:getTipState() |
388 | if tipState == Trailer.TIPSTATE_CLOSED or tipState == Trailer.TIPSTATE_CLOSING then |
389 | text = tipSide.manualTipToggleActionTextPos |
390 | else |
391 | text = tipSide.manualTipToggleActionTextNeg |
392 | end |
393 | |
394 | g_inputBinding:setActionEventText(actionEvent.actionEventId, text) |
395 | end |
396 | end |
397 | |
398 | if tipSide.manualDoorToggle then |
399 | local actionEvent = spec.actionEvents[tipSide.manualDoorToggleAction] |
400 | if actionEvent ~= nil then |
401 | local text |
402 | if self:getIsAnimationPlaying(tipSide.doorAnimation.name) then |
403 | if self:getAnimationSpeed(tipSide.doorAnimation.name) > 0 then |
404 | text = tipSide.manualDoorToggleActionTextNeg |
405 | else |
406 | text = tipSide.manualDoorToggleActionTextPos |
407 | end |
408 | else |
409 | if self:getAnimationTime(tipSide.doorAnimation.name) <= 0 then |
410 | text = tipSide.manualDoorToggleActionTextPos |
411 | else |
412 | text = tipSide.manualDoorToggleActionTextNeg |
413 | end |
414 | end |
415 | |
416 | g_inputBinding:setActionEventText(actionEvent.actionEventId, text) |
417 | end |
418 | end |
419 | end |
420 | |
421 | -- update tipState |
422 | if spec.tipState == Trailer.TIPSTATE_OPENING then |
423 | tipSide = spec.tipSides[spec.currentTipSideIndex] |
424 | if tipSide ~= nil then |
425 | if self:getAnimationTime(tipSide.animation.name) >= 1.0 or self:getAnimationDuration(tipSide.animation.name) == 0 then |
426 | spec.tipState = Trailer.TIPSTATE_OPEN |
427 | end |
428 | end |
429 | elseif spec.tipState == Trailer.TIPSTATE_CLOSING then |
430 | tipSide = spec.tipSides[spec.currentTipSideIndex] |
431 | if tipSide ~= nil then |
432 | if self:getAnimationTime(tipSide.animation.name) <= 0.0 or self:getAnimationDuration(tipSide.animation.name) == 0 or tipSide.animation.closeSpeedScale == 0 then |
433 | spec.tipState = Trailer.TIPSTATE_CLOSED |
434 | self:endTipping() |
435 | end |
436 | end |
437 | end |
438 | end |
onWriteStream
DescriptionCalled on server side on joinDefinition
onWriteStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
323 | function Trailer:onWriteStream(streamId, connection) |
324 | local spec = self.spec_trailer |
325 | |
326 | if spec.tipSideCount > 1 then |
327 | streamWriteUIntN(streamId, spec.preferedTipSideIndex, Trailer.TIP_SIDE_NUM_BITS) |
328 | end |
329 | |
330 | streamWriteUIntN(streamId, spec.tipState, Trailer.TIP_STATE_NUM_BITS) |
331 | if streamWriteBool(streamId, spec.currentTipSideIndex ~= nil) then |
332 | streamWriteUIntN(streamId, spec.currentTipSideIndex, Trailer.TIP_SIDE_NUM_BITS) |
333 | end |
334 | |
335 | local tipSide = spec.tipSides[spec.preferedTipSideIndex] |
336 | if streamWriteBool(streamId, tipSide ~= nil and tipSide.manualDoorToggle) then |
337 | streamWriteBool(streamId, tipSide.doorAnimation.state) |
338 | end |
339 | |
340 | if streamWriteBool(streamId, tipSide ~= nil and tipSide.animation.name ~= nil) then |
341 | streamWriteFloat32(streamId, self:getAnimationTime(tipSide.animation.name)) |
342 | if streamWriteBool(streamId, self:getIsAnimationPlaying(tipSide.animation.name)) then |
343 | streamWriteBool(streamId, self:getAnimationSpeed(tipSide.animation.name) > 0) |
344 | end |
345 | end |
346 | |
347 | if streamWriteBool(streamId, tipSide ~= nil and not tipSide.manualDoorToggle and tipSide.doorAnimation.name ~= nil) then |
348 | streamWriteFloat32(streamId, self:getAnimationTime(tipSide.doorAnimation.name)) |
349 | if streamWriteBool(streamId, self:getIsAnimationPlaying(tipSide.doorAnimation.name)) then |
350 | streamWriteBool(streamId, self:getAnimationSpeed(tipSide.doorAnimation.name) > 0) |
351 | end |
352 | end |
353 | end |
prerequisitesPresent
DescriptionDefinitionprerequisitesPresent()Code
27 | function Trailer.prerequisitesPresent(specializations) |
28 | return SpecializationUtil.hasSpecialization(FillUnit, specializations) and |
29 | SpecializationUtil.hasSpecialization(Dischargeable, specializations) and |
30 | SpecializationUtil.hasSpecialization(AnimatedVehicle, specializations) |
31 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
146 | function Trailer.registerEventListeners(vehicleType) |
147 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", Trailer) |
148 | SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", Trailer) |
149 | SpecializationUtil.registerEventListener(vehicleType, "onLoadFinished", Trailer) |
150 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", Trailer) |
151 | SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Trailer) |
152 | SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Trailer) |
153 | SpecializationUtil.registerEventListener(vehicleType, "onUpdate", Trailer) |
154 | SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", Trailer) |
155 | SpecializationUtil.registerEventListener(vehicleType, "onDischargeStateChanged", Trailer) |
156 | SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", Trailer) |
157 | SpecializationUtil.registerEventListener(vehicleType, "onRegisterAnimationValueTypes", Trailer) |
158 | SpecializationUtil.registerEventListener(vehicleType, "onFillUnitFillLevelChanged", Trailer) |
159 | end |
registerEvents
DescriptionDefinitionregisterEvents()Code
103 | function Trailer.registerEvents(vehicleType) |
104 | SpecializationUtil.registerEvent(vehicleType, "onStartTipping") |
105 | SpecializationUtil.registerEvent(vehicleType, "onOpenBackDoor") |
106 | SpecializationUtil.registerEvent(vehicleType, "onStopTipping") |
107 | SpecializationUtil.registerEvent(vehicleType, "onCloseBackDoor") |
108 | SpecializationUtil.registerEvent(vehicleType, "onEndTipping") |
109 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
113 | function Trailer.registerFunctions(vehicleType) |
114 | SpecializationUtil.registerFunction(vehicleType, "loadTipSide", Trailer.loadTipSide) |
115 | SpecializationUtil.registerFunction(vehicleType, "getCanTogglePreferdTipSide", Trailer.getCanTogglePreferdTipSide) |
116 | SpecializationUtil.registerFunction(vehicleType, "getIsTipSideAvailable", Trailer.getIsTipSideAvailable) |
117 | SpecializationUtil.registerFunction(vehicleType, "getNextAvailableTipSide", Trailer.getNextAvailableTipSide) |
118 | SpecializationUtil.registerFunction(vehicleType, "setPreferedTipSide", Trailer.setPreferedTipSide) |
119 | SpecializationUtil.registerFunction(vehicleType, "startTipping", Trailer.startTipping) |
120 | SpecializationUtil.registerFunction(vehicleType, "stopTipping", Trailer.stopTipping) |
121 | SpecializationUtil.registerFunction(vehicleType, "endTipping", Trailer.endTipping) |
122 | SpecializationUtil.registerFunction(vehicleType, "setTrailerDoorState", Trailer.setTrailerDoorState) |
123 | SpecializationUtil.registerFunction(vehicleType, "getTipState", Trailer.getTipState) |
124 | SpecializationUtil.registerFunction(vehicleType, "setTipState", Trailer.setTipState) |
125 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
129 | function Trailer.registerOverwrittenFunctions(vehicleType) |
130 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDischargeNodeEmptyFactor", Trailer.getDischargeNodeEmptyFactor) |
131 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanDischargeToGround", Trailer.getCanDischargeToGround) |
132 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsNextCoverStateAllowed", Trailer.getIsNextCoverStateAllowed) |
133 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", Trailer.getCanBeSelected) |
134 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAIHasFinishedDischarge", Trailer.getAIHasFinishedDischarge) |
135 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "startAIDischarge", Trailer.startAIDischarge) |
136 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadPickupFromXML", Trailer.loadPickupFromXML) |
137 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanChangePickupState", Trailer.getCanChangePickupState) |
138 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanDischargeToGround", Trailer.getCanDischargeToGround) |
139 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanDischargeToObject", Trailer.getCanDischargeToObject) |
140 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsTurnedOnAnimationActive", Trailer.getIsTurnedOnAnimationActive) |
141 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadTurnedOnAnimationFromXML", Trailer.loadTurnedOnAnimationFromXML) |
142 | end |
saveToXMLFile
DescriptionDefinitionsaveToXMLFile()Code
525 | function Trailer:saveToXMLFile(xmlFile, key, usedModNames) |
526 | local spec = self.spec_trailer |
527 | |
528 | if spec.tipSideCount > 1 then |
529 | xmlFile:setValue(key.."#tipSideIndex", spec.preferedTipSideIndex) |
530 | end |
531 | |
532 | local tipSide = spec.tipSides[spec.preferedTipSideIndex] |
533 | if tipSide ~= nil then |
534 | xmlFile:setValue(key.."#doorState", self:getAnimationTime(tipSide.doorAnimation.name) > 0) |
535 | xmlFile:setValue(key.."#tipAnimationTime", self:getAnimationTime(tipSide.animation.name)) |
536 | end |
537 | |
538 | xmlFile:setValue(key.."#tipState", spec.tipState) |
539 | end |
setPreferedTipSide
DescriptionDefinitionsetPreferedTipSide()Code
593 | function Trailer:setPreferedTipSide(index, noEventSend) |
594 | local spec = self.spec_trailer |
595 | index = math.max(1, math.min(spec.tipSideCount, index)) |
596 | |
597 | local tipState = self:getTipState() |
598 | if tipState ~= Trailer.TIPSTATE_CLOSED and tipState ~= Trailer.TIPSTATE_CLOSING then |
599 | self:stopTipping(true) |
600 | end |
601 | |
602 | if index ~= spec.preferedTipSideIndex then |
603 | if spec.tipSideCount > 1 then |
604 | if noEventSend == nil or noEventSend == false then |
605 | if g_server ~= nil then |
606 | g_server:broadcastEvent(TrailerToggleTipSideEvent.new(self, index), nil, nil, self) |
607 | else |
608 | g_client:getServerConnection():sendEvent(TrailerToggleTipSideEvent.new(self, index)) |
609 | end |
610 | end |
611 | end |
612 | end |
613 | |
614 | for i=1, #spec.tipSides do |
615 | ObjectChangeUtil.setObjectChanges(spec.tipSides[i].objectChanges, i == index) |
616 | end |
617 | |
618 | local oldTipSide = spec.tipSides[spec.preferedTipSideIndex] |
619 | |
620 | spec.preferedTipSideIndex = index |
621 | local newTipSide = spec.tipSides[index] |
622 | |
623 | if oldTipSide ~= nil then |
624 | -- if we use the same back door animation we keep the state as it is, if not we are closing |
625 | if newTipSide.doorAnimation.name ~= oldTipSide.doorAnimation.name then |
626 | if oldTipSide.doorAnimation.name ~= nil and self:getAnimationTime(oldTipSide.doorAnimation.name) > 0 then |
627 | self:setTrailerDoorState(false, true) |
628 | end |
629 | end |
630 | end |
631 | |
632 | if newTipSide.animation.resetTipSideChange then |
633 | self:setAnimationTime(newTipSide.animation.name, 0, true, false) |
634 | end |
635 | |
636 | self:setCurrentDischargeNodeIndex(newTipSide.dischargeNodeIndex) |
637 | |
638 | self:requestActionEventUpdate() |
639 | end |
setTipState
DescriptionSet inital tip state to open or closedDefinition
setTipState()Code
770 | function Trailer:setTipState(isOpen) |
771 | local spec = self.spec_trailer |
772 | local tipSide = spec.tipSides[spec.currentTipSideIndex] |
773 | if tipSide ~= nil then |
774 | if isOpen then |
775 | self:playAnimation(tipSide.animation.name, tipSide.animation.speedScale, self:getAnimationTime(tipSide.animation.name), true) |
776 | |
777 | if not tipSide.manualDoorToggle and tipSide.doorAnimation.name ~= nil then |
778 | self:playAnimation(tipSide.doorAnimation.name, tipSide.doorAnimation.speedScale, self:getAnimationTime(tipSide.doorAnimation.name), true) |
779 | end |
780 | else |
781 | self:playAnimation(tipSide.animation.name, tipSide.animation.closeSpeedScale, self:getAnimationTime(tipSide.animation.name), true) |
782 | |
783 | if not tipSide.manualDoorToggle and tipSide.doorAnimation.name ~= nil then |
784 | self:playAnimation(tipSide.doorAnimation.name, tipSide.doorAnimation.closeSpeedScale, self:getAnimationTime(tipSide.doorAnimation.name), true) |
785 | end |
786 | end |
787 | |
788 | AnimatedVehicle.updateAnimationByName(self, tipSide.animation.name, 999999, true) |
789 | AnimatedVehicle.updateAnimationByName(self, tipSide.doorAnimation.name, 999999, true) |
790 | end |
791 | end |
setTrailerDoorState
DescriptionDefinitionsetTrailerDoorState()Code
735 | function Trailer:setTrailerDoorState(state, noEventSend, instantUpdate) |
736 | local spec = self.spec_trailer |
737 | local tipSide = spec.tipSides[spec.preferedTipSideIndex] |
738 | if tipSide ~= nil then |
739 | if state == nil then |
740 | state = not tipSide.doorAnimation.state |
741 | end |
742 | |
743 | tipSide.doorAnimation.state = state |
744 | self:playAnimation(tipSide.doorAnimation.name, state and tipSide.doorAnimation.speedScale or tipSide.doorAnimation.closeSpeedScale, self:getAnimationTime(tipSide.doorAnimation.name), true) |
745 | |
746 | if instantUpdate then |
747 | AnimatedVehicle.updateAnimationByName(self, tipSide.doorAnimation.name, 999999, true) |
748 | end |
749 | |
750 | if tipSide.manualDoorToggle and tipSide.doorAnimation.name ~= nil then |
751 | if state then |
752 | SpecializationUtil.raiseEvent(self, "onOpenBackDoor", spec.preferedTipSideIndex) |
753 | else |
754 | SpecializationUtil.raiseEvent(self, "onCloseBackDoor", spec.preferedTipSideIndex) |
755 | end |
756 | end |
757 | |
758 | TrailerToggleManualDoorEvent.sendEvent(self, state, noEventSend) |
759 | end |
760 | end |
startAIDischarge
DescriptionDefinitionstartAIDischarge()Code
941 | function Trailer:startAIDischarge(superFunc, dischargeNode, task) |
942 | local spec = self.spec_trailer |
943 | local tipSide = spec.dischargeNodeIndexToTipSide[dischargeNode.index] |
944 | if tipSide ~= nil then |
945 | self:setPreferedTipSide(tipSide.index) |
946 | end |
947 | |
948 | superFunc(self, dischargeNode, task) |
949 | end |
startTipping
DescriptionDefinitionstartTipping()Code
643 | function Trailer:startTipping(tipSideIndex, noEventSend) |
644 | local spec = self.spec_trailer |
645 | tipSideIndex = tipSideIndex or spec.preferedTipSideIndex |
646 | local tipSide = spec.tipSides[tipSideIndex] |
647 | if tipSide ~= nil then |
648 | local animTime = self:getAnimationTime(tipSide.animation.name) |
649 | self:playAnimation(tipSide.animation.name, tipSide.animation.speedScale, animTime, true) |
650 | |
651 | if not tipSide.manualDoorToggle and tipSide.doorAnimation.name ~= nil then |
652 | self:setTrailerDoorState(true, true) |
653 | end |
654 | |
655 | if tipSide.tippingAnimation.name ~= nil then |
656 | self:playAnimation(tipSide.tippingAnimation.name, tipSide.tippingAnimation.speedScale, self:getAnimationTime(tipSide.tippingAnimation.name), true) |
657 | end |
658 | |
659 | if self.isClient then |
660 | g_animationManager:startAnimations(tipSide.animationNodes) |
661 | g_soundManager:playSample(tipSide.unloadSound) |
662 | end |
663 | |
664 | spec.tipState = Trailer.TIPSTATE_OPENING |
665 | spec.currentTipSideIndex = tipSideIndex |
666 | |
667 | self:setCurrentDischargeNodeIndex(tipSide.dischargeNodeIndex) |
668 | |
669 | spec.remainingFillDelta = 0 |
670 | |
671 | SpecializationUtil.raiseEvent(self, "onStartTipping", tipSideIndex) |
672 | end |
673 | end |
stopTipping
DescriptionDefinitionstopTipping()Code
677 | function Trailer:stopTipping(noEventSend) |
678 | local spec = self.spec_trailer |
679 | local tipSide = spec.tipSides[spec.currentTipSideIndex] |
680 | if tipSide ~= nil then |
681 | if tipSide.animation.closeSpeedScale ~= 0 then |
682 | local animTime = self:getAnimationTime(tipSide.animation.name) |
683 | self:playAnimation(tipSide.animation.name, tipSide.animation.closeSpeedScale, animTime, true) |
684 | else |
685 | if self:getIsAnimationPlaying(tipSide.animation.name) then |
686 | self:stopAnimation(tipSide.animation.name, true) |
687 | end |
688 | end |
689 | |
690 | if not tipSide.manualDoorToggle and tipSide.doorAnimation.name ~= nil then |
691 | if not tipSide.doorAnimation.delayedClosing then |
692 | self:setTrailerDoorState(false, true) |
693 | end |
694 | end |
695 | |
696 | if tipSide.tippingAnimation.name ~= nil then |
697 | self:setAnimationStopTime(tipSide.tippingAnimation.name, 1) |
698 | end |
699 | |
700 | if self.isClient then |
701 | g_animationManager:stopAnimations(tipSide.animationNodes) |
702 | g_soundManager:stopSample(tipSide.unloadSound) |
703 | end |
704 | |
705 | spec.tipState = Trailer.TIPSTATE_CLOSING |
706 | |
707 | spec.remainingFillDelta = 0 |
708 | |
709 | SpecializationUtil.raiseEvent(self, "onStopTipping") |
710 | end |
711 | end |