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
SupportVehicle
DescriptionSpecialization for spawning a support vehicle while detaching and removing it again on attachFunctions
- addSupportVehicle
- getAllowMultipleAttachments
- initSpecialization
- onDelete
- onLoad
- onPostDetach
- onUpdate
- prerequisitesPresent
- registerEventListeners
- registerFunctions
- registerOverwrittenFunctions
- removeSupportVehicle
- resolveMultipleAttachments
- supportVehicleLoaded
addSupportVehicle
DescriptionDefinitionaddSupportVehicle()Code
142 | function SupportVehicle:addSupportVehicle(filename, inputAttacherJointIndex, attacherJointIndex) |
143 | local spec = self.spec_supportVehicle |
144 | if spec.filename ~= nil then |
145 | if spec.supportVehicle == nil then |
146 | -- make sure below the vehicle is enough space to place the support vehicle |
147 | local component = self.components[1].node |
148 | for _, check in ipairs(spec.heightChecks) do |
149 | local x, y, z = localToWorld(component, check.x, 0, check.z) |
150 | local height = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, y, z) |
151 | local difference = y - height |
152 | if difference < spec.minTerrainDistance then |
153 | for _, comp in ipairs(self.components) do |
154 | local cx, cy, cz = getWorldTranslation(comp.node) |
155 | setWorldTranslation(comp.node, cx, cy + spec.minTerrainDistance - difference, cz) |
156 | end |
157 | end |
158 | end |
159 | |
160 | local storeItem = g_storeManager:getItemByXMLFilename(filename) |
161 | if storeItem ~= nil then |
162 | local inputAttacherJoint = self:getInputAttacherJoints()[inputAttacherJointIndex] |
163 | if inputAttacherJoint ~= nil then |
164 | local x, y, z = localToWorld(inputAttacherJoint.node, 0, 0, 0) |
165 | local dirX, _, dirZ = localDirectionToWorld(inputAttacherJoint.node, 1, 0, 0) |
166 | local yRot = MathUtil.getYRotationFromDirection(dirX, dirZ) |
167 | local location = {x=x, y=y, z=z, yRot=yRot} |
168 | self:removeFromPhysics() |
169 | local vehicle = VehicleLoadingUtil.loadVehicle(storeItem.xmlFilename, location, false, 0, Vehicle.PROPERTY_STATE_NONE, self:getActiveFarm(), spec.configurations, nil, SupportVehicle.supportVehicleLoaded, self, {attacherJointIndex, inputAttacherJointIndex, inputAttacherJoint.node}) |
170 | if vehicle ~= nil then |
171 | vehicle:setIsSupportVehicle() |
172 | end |
173 | end |
174 | else |
175 | Logging.xmlWarning(self.xmlFile, "Unable to find support vehicle '%s'.", filename) |
176 | end |
177 | end |
178 | end |
179 | end |
getAllowMultipleAttachments
DescriptionFunction to allow showing the attachment dialog even if the attachable is already attachedDefinition
getAllowMultipleAttachments()Code
242 | function SupportVehicle:getAllowMultipleAttachments(superFunc) |
243 | return true |
244 | end |
initSpecialization
DescriptionDefinitioninitSpecialization()Code
21 | function SupportVehicle.initSpecialization() |
22 | local schema = Vehicle.xmlSchema |
23 | schema:setXMLSpecializationType("SupportVehicle") |
24 | |
25 | schema:register(XMLValueType.STRING, "vehicle.supportVehicle#filename", "Path to support vehicle xml") |
26 | schema:register(XMLValueType.INT, "vehicle.supportVehicle#attacherJointIndex", "Attacher joint index on support vehicle", 1) |
27 | schema:register(XMLValueType.INT, "vehicle.supportVehicle#inputAttacherJointIndex", "Input attacher joint index on own vehicle", 1) |
28 | schema:register(XMLValueType.FLOAT, "vehicle.supportVehicle#minTerrainDistance", "Min. distance from vehicle root to ground (To have enough space for support vehicle)", 0.75) |
29 | schema:register(XMLValueType.FLOAT, "vehicle.supportVehicle#attachedMass", "Mass of vehicle components if attached to support vehicle (kg)", 10) |
30 | |
31 | schema:register(XMLValueType.STRING, "vehicle.supportVehicle.configuration(?)#name", "Configuration name") |
32 | schema:register(XMLValueType.INT, "vehicle.supportVehicle.configuration(?)#id", "Configuration id") |
33 | |
34 | schema:setXMLSpecializationType() |
35 | end |
onDelete
DescriptionCalled on deleteDefinition
onDelete()Code
112 | function SupportVehicle:onDelete() |
113 | self:removeSupportVehicle() |
114 | end |
onLoad
DescriptionDefinitiononLoad()Code
62 | function SupportVehicle:onLoad(savegame) |
63 | local spec = self.spec_supportVehicle |
64 | |
65 | local baseKey = "vehicle.supportVehicle" |
66 | |
67 | local filename = self.xmlFile:getValue(baseKey.."#filename") |
68 | if filename ~= nil then |
69 | spec.filename = Utils.getFilename(filename, self.customEnvironment) |
70 | end |
71 | spec.attacherJointIndex = self.xmlFile:getValue(baseKey.."#attacherJointIndex", 1) |
72 | spec.inputAttacherJointIndex = self.xmlFile:getValue(baseKey.."#inputAttacherJointIndex", 1) |
73 | |
74 | spec.minTerrainDistance = self.xmlFile:getValue(baseKey.."#minTerrainDistance", 0.75) |
75 | |
76 | spec.attachedMass = self.xmlFile:getValue(baseKey.."#attachedMass", 10) / 1000 |
77 | |
78 | spec.heightChecks = {} |
79 | table.insert(spec.heightChecks, {x= self.size.width / 2 + self.size.widthOffset, z= self.size.length / 2 + self.size.lengthOffset}) |
80 | table.insert(spec.heightChecks, {x=-self.size.width / 2 + self.size.widthOffset, z= self.size.length / 2 + self.size.lengthOffset}) |
81 | table.insert(spec.heightChecks, {x= self.size.width / 2 + self.size.widthOffset, z=-self.size.length / 2 + self.size.lengthOffset}) |
82 | table.insert(spec.heightChecks, {x=-self.size.width / 2 + self.size.widthOffset, z=-self.size.length / 2 + self.size.lengthOffset}) |
83 | |
84 | spec.configurations = {} |
85 | local i = 0 |
86 | while true do |
87 | local configurationKey = string.format("%s.configuration(%d)", baseKey, i) |
88 | if not self.xmlFile:hasProperty(configurationKey) then |
89 | break |
90 | end |
91 | |
92 | local name = self.xmlFile:getValue(configurationKey.."#name") |
93 | local id = self.xmlFile:getValue(configurationKey.."#id") |
94 | if name ~= nil and id ~= nil then |
95 | spec.configurations[name] = id |
96 | end |
97 | |
98 | i = i + 1 |
99 | end |
100 | |
101 | spec.firstRun = true |
102 | |
103 | if not self.isServer then |
104 | SpecializationUtil.removeEventListener(self, "onDelete", SupportVehicle) |
105 | SpecializationUtil.removeEventListener(self, "onUpdate", SupportVehicle) |
106 | SpecializationUtil.removeEventListener(self, "onPostDetach", SupportVehicle) |
107 | end |
108 | end |
onPostDetach
DescriptionCalled if vehicle gets detachedDefinition
onPostDetach(table attacherVehicle, table implement)Arguments
table | attacherVehicle | attacher vehicle |
table | implement | implement |
120 | function SupportVehicle:onPostDetach(attacherVehicle, implement) |
121 | if not self.isDeleting then |
122 | local spec = self.spec_supportVehicle |
123 | self:addSupportVehicle(spec.filename, spec.inputAttacherJointIndex, spec.attacherJointIndex) |
124 | end |
125 | end |
onUpdate
DescriptionDefinitiononUpdate()Code
129 | function SupportVehicle:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
130 | local spec = self.spec_supportVehicle |
131 | if spec.firstRun then |
132 | if self:getAttacherVehicle() == nil then |
133 | self:addSupportVehicle(spec.filename, spec.inputAttacherJointIndex, spec.attacherJointIndex) |
134 | end |
135 | |
136 | spec.firstRun = false |
137 | end |
138 | end |
prerequisitesPresent
DescriptionDefinitionprerequisitesPresent()Code
15 | function SupportVehicle.prerequisitesPresent(specializations) |
16 | return SpecializationUtil.hasSpecialization(AttacherJoints, specializations) |
17 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
53 | function SupportVehicle.registerEventListeners(vehicleType) |
54 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", SupportVehicle) |
55 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", SupportVehicle) |
56 | SpecializationUtil.registerEventListener(vehicleType, "onUpdate", SupportVehicle) |
57 | SpecializationUtil.registerEventListener(vehicleType, "onPostDetach", SupportVehicle) |
58 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
39 | function SupportVehicle.registerFunctions(vehicleType) |
40 | SpecializationUtil.registerFunction(vehicleType, "addSupportVehicle", SupportVehicle.addSupportVehicle) |
41 | SpecializationUtil.registerFunction(vehicleType, "removeSupportVehicle", SupportVehicle.removeSupportVehicle) |
42 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
46 | function SupportVehicle.registerOverwrittenFunctions(vehicleType) |
47 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAllowMultipleAttachments", SupportVehicle.getAllowMultipleAttachments) |
48 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "resolveMultipleAttachments", SupportVehicle.resolveMultipleAttachments) |
49 | end |
removeSupportVehicle
DescriptionDefinitionremoveSupportVehicle()Code
225 | function SupportVehicle:removeSupportVehicle() |
226 | local spec = self.spec_supportVehicle |
227 | if spec.supportVehicle ~= nil then |
228 | spec.supportVehicle:delete() |
229 | spec.supportVehicle = nil |
230 | end |
231 | |
232 | if self.isServer and self.components ~= nil then |
233 | for i=1, #self.components do |
234 | local component = self.components[i] |
235 | setMass(component.node, component.defaultMass) |
236 | end |
237 | end |
238 | end |
resolveMultipleAttachments
DescriptionFunction that is called before attaching a attachable to second vehicleDefinition
resolveMultipleAttachments()Code
248 | function SupportVehicle:resolveMultipleAttachments(superFunc) |
249 | if self.isServer then |
250 | if self.spec_supportVehicle.filename ~= nil then |
251 | self:removeSupportVehicle() |
252 | else |
253 | local attacherVehicle = self:getAttacherVehicle() |
254 | if attacherVehicle ~= nil then |
255 | attacherVehicle:detachImplementByObject(self) |
256 | end |
257 | end |
258 | end |
259 | |
260 | superFunc(self) |
261 | end |
supportVehicleLoaded
DescriptionCalled after the additional attachment was loadedDefinition
supportVehicleLoaded()Code
183 | function SupportVehicle:supportVehicleLoaded(vehicle, vehicleLoadState, asyncCallbackArguments) |
184 | if vehicleLoadState == VehicleLoadingUtil.VEHICLE_LOAD_OK and vehicle ~= nil then |
185 | local attacherVehicle = self:getAttacherVehicle() |
186 | -- check again if vehicle is already attached (async loading of support vehicle can have a delay |
187 | self:addToPhysics() |
188 | |
189 | local spec = self.spec_supportVehicle |
190 | for i=1, #self.components do |
191 | setMass(self.components[i].node, spec.attachedMass) |
192 | end |
193 | |
194 | if not self.isDeleted and attacherVehicle == nil then |
195 | local offset = {0, 0, 0} |
196 | local dirOffset = {0, 0, 0} |
197 | if vehicle.getAttacherJoints ~= nil then |
198 | local attacherJoints = vehicle:getAttacherJoints() |
199 | if attacherJoints[asyncCallbackArguments[1]] ~= nil then |
200 | offset = attacherJoints[asyncCallbackArguments[1]].jointOrigOffsetComponent |
201 | dirOffset = attacherJoints[asyncCallbackArguments[1]].jointOrigDirOffsetComponent |
202 | end |
203 | end |
204 | |
205 | local x, y, z = localToWorld(asyncCallbackArguments[3], unpack(offset)) |
206 | local dirX, _, dirZ = localDirectionToWorld(asyncCallbackArguments[3], unpack(dirOffset)) |
207 | local yRot = MathUtil.getYRotationFromDirection(dirX, dirZ) |
208 | |
209 | vehicle:setAbsolutePosition(x, y, z, 0, yRot, 0) |
210 | vehicle:attachImplement(self, asyncCallbackArguments[2], asyncCallbackArguments[1], true, nil, nil, true) |
211 | |
212 | self.rootVehicle:updateSelectableObjects() |
213 | self.rootVehicle:setSelectedVehicle(self) |
214 | |
215 | spec.supportVehicle = vehicle |
216 | else |
217 | -- if the parent vehicle was deleted while loading the support vehicle we remove also the support vehicle |
218 | vehicle:delete() |
219 | end |
220 | end |
221 | end |