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
LicensePlates
DescriptionSpecialization for placing license plates to vehiclesFunctions
- getHasLicensePlates
- getLicensePlateDialogSettings
- getLicensePlatesData
- getLicensePlatesDataIsEqual
- getSpecValuePlateText
- initSpecialization
- loadSpecValuePlateText
- onDelete
- onLoad
- onPostLoad
- onReadStream
- onWriteStream
- prerequisitesPresent
- registerEventListeners
- registerFunctions
- saveToXMLFile
- setLicensePlatesData
getHasLicensePlates
DescriptionReturns if vehicle has license platesDefinition
getHasLicensePlates()Return Values
boolean | hasLicensePlates | has license plates |
318 | function LicensePlates:getHasLicensePlates() |
319 | return #self.spec_licensePlates.licensePlates > 0 |
320 | end |
getLicensePlateDialogSettings
DescriptionReturns license plate settings for dialogDefinition
getLicensePlateDialogSettings()Return Values
string | defaultPlacementIndex | default placement |
boolean | hasFrontPlate | has front license plate |
326 | function LicensePlates:getLicensePlateDialogSettings() |
327 | local spec = self.spec_licensePlates |
328 | local hasFrontPlate = false |
329 | for i=1, #spec.licensePlates do |
330 | local licensePlate = spec.licensePlates[i] |
331 | if licensePlate.position == LicensePlateManager.PLATE_POSITION.FRONT then |
332 | hasFrontPlate = true |
333 | break |
334 | end |
335 | end |
336 | |
337 | return spec.defaultPlacementIndex, hasFrontPlate |
338 | end |
getLicensePlatesData
DescriptionDefinitiongetLicensePlatesData()Code
283 | function LicensePlates:getLicensePlatesData() |
284 | return self.spec_licensePlates.licensePlateData |
285 | end |
getLicensePlatesDataIsEqual
DescriptionDefinitiongetLicensePlatesDataIsEqual()Code
289 | function LicensePlates:getLicensePlatesDataIsEqual(data) |
290 | if data == nil or self.spec_licensePlates.licensePlateData == nil then |
291 | return true |
292 | end |
293 | |
294 | local ownData = self.spec_licensePlates.licensePlateData |
295 | |
296 | if data.variation ~= ownData.variation or data.colorIndex ~= ownData.colorIndex or data.placementIndex ~= ownData.placementIndex then |
297 | return false |
298 | end |
299 | |
300 | if data.characters ~= nil and ownData.characters ~= nil then |
301 | if #data.characters ~= #ownData.characters then |
302 | return false |
303 | end |
304 | |
305 | for i=1, #data.characters do |
306 | if data.characters[i] ~= ownData.characters[i] then |
307 | return false |
308 | end |
309 | end |
310 | end |
311 | |
312 | return true |
313 | end |
getSpecValuePlateText
DescriptionDefinitiongetSpecValuePlateText()Code
349 | function LicensePlates.getSpecValuePlateText(storeItem, realItem) |
350 | if realItem == nil then |
351 | return nil |
352 | end |
353 | |
354 | if realItem.getHasLicensePlates == nil or not realItem:getHasLicensePlates() then |
355 | return nil |
356 | end |
357 | |
358 | local spec = realItem.spec_licensePlates |
359 | for i=1, #spec.licensePlates do |
360 | local licensePlate = spec.licensePlates[i] |
361 | if licensePlate.position == LicensePlateManager.PLATE_POSITION.BACK or i == #spec.licensePlates then |
362 | return licensePlate.data:getFormattedString() |
363 | end |
364 | end |
365 | |
366 | return nil |
367 | end |
initSpecialization
DescriptionDefinitioninitSpecialization()Code
23 | function LicensePlates.initSpecialization() |
24 | g_storeManager:addSpecType("licensePlate", "shopListAttributeIconLicensePlate", LicensePlates.loadSpecValuePlateText, LicensePlates.getSpecValuePlateText, "vehicle") |
25 | |
26 | local schema = Vehicle.xmlSchema |
27 | schema:setXMLSpecializationType("LicensePlates") |
28 | |
29 | schema:register(XMLValueType.STRING, "vehicle.licensePlates#defaultPlacement", "Defines the default placement index independent of map setting (NONE|BOTH|BACK_ONLY)", false) |
30 | schema:register(XMLValueType.NODE_INDEX, "vehicle.licensePlates.licensePlate(?)#node", "License plate node") |
31 | schema:register(XMLValueType.STRING, "vehicle.licensePlates.licensePlate(?)#preferedType", "Prefered license plate type to be placed if available") |
32 | schema:register(XMLValueType.VECTOR_4, "vehicle.licensePlates.licensePlate(?)#placementArea", "Defines the available area around the node (top, right, bottom, left) ('-' means unlimited)") |
33 | schema:register(XMLValueType.STRING, "vehicle.licensePlates.licensePlate(?)#position", "Position of license plate ('FRONT' or 'BACK')", "ANY") |
34 | schema:register(XMLValueType.BOOL, "vehicle.licensePlates.licensePlate(?)#frame", "License plate with frame of without frame", true) |
35 | |
36 | ObjectChangeUtil.registerObjectChangeXMLPaths(schema, "vehicle.licensePlates.licensePlate(?)") |
37 | |
38 | schema:setXMLSpecializationType() |
39 | |
40 | local schemaSavegame = Vehicle.xmlSchemaSavegame |
41 | schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).licensePlates#variation", "License plate variation", 1) |
42 | schemaSavegame:register(XMLValueType.STRING, "vehicles.vehicle(?).licensePlates#characters", "Characters string") |
43 | schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).licensePlates#colorIndex", "Selected color index", 1) |
44 | schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).licensePlates#placementIndex", "Selected placement index", 1) |
45 | end |
loadSpecValuePlateText
DescriptionDefinitionloadSpecValuePlateText()Code
342 | function LicensePlates.loadSpecValuePlateText(xmlFile, customEnvironment, baseDir) |
343 | -- No data to load as this spec is only for existing items |
344 | return nil |
345 | end |
onDelete
DescriptionDefinitiononDelete()Code
200 | function LicensePlates:onDelete(savegame) |
201 | local spec = self.spec_licensePlates |
202 | |
203 | spec.licensePlates = {} |
204 | end |
onLoad
DescriptionCalled on loadingDefinition
onLoad(table savegame)Arguments
table | savegame | savegame |
70 | function LicensePlates:onLoad(savegame) |
71 | local spec = self.spec_licensePlates |
72 | |
73 | spec.licensePlates = {} |
74 | local defaultPlacementName = self.xmlFile:getValue("vehicle.licensePlates#defaultPlacement") |
75 | if defaultPlacementName ~= nil then |
76 | spec.defaultPlacementIndex = LicensePlateManager.PLACEMENT_OPTION[defaultPlacementName:upper()] |
77 | end |
78 | |
79 | if g_licensePlateManager:getAreLicensePlatesAvailable() then |
80 | local i = 0 |
81 | while true do |
82 | local plateKey = string.format("vehicle.licensePlates.licensePlate(%d)", i) |
83 | if not self.xmlFile:hasProperty(plateKey) then |
84 | break |
85 | end |
86 | |
87 | local licensePlate = {} |
88 | |
89 | licensePlate.node = self.xmlFile:getValue(plateKey .. "#node", nil, self.components, self.i3dMappings) |
90 | if licensePlate.node ~= nil then |
91 | local preferedTypeStr = self.xmlFile:getValue(plateKey .. "#preferedType", "ELONGATED") |
92 | licensePlate.preferedType = LicensePlateManager.PLATE_TYPE[preferedTypeStr] |
93 | if licensePlate.preferedType ~= nil then |
94 | licensePlate.placementArea = {1, 1, 1, 1} |
95 | local placementAreaString = self.xmlFile:getString(plateKey .. "#placementArea") |
96 | if placementAreaString ~= nil then |
97 | local placementArea = string.split(placementAreaString, " ") |
98 | if #placementArea == 4 then |
99 | for j=1, 4 do |
100 | if placementArea[j] ~= "-" then |
101 | local numberValue = tonumber(placementArea[j]) |
102 | if numberValue == nil then |
103 | Logging.xmlWarning(self.xmlFile, "Invalid 4-vector '%s' for '%s'. '%s' is not a number!", placementAreaString, plateKey .. "#placementArea", placementArea[j]) |
104 | else |
105 | licensePlate.placementArea[j] = numberValue |
106 | end |
107 | end |
108 | end |
109 | else |
110 | Logging.xmlWarning(self.xmlFile, "Invalid 4-vector '%s' for '%s' ", placementAreaString, plateKey .. "#placementArea") |
111 | end |
112 | end |
113 | |
114 | local positionStr = self.xmlFile:getValue(plateKey .. "#position", "ANY") |
115 | licensePlate.position = LicensePlateManager.PLATE_POSITION[positionStr] or LicensePlateManager.PLATE_POSITION.ANY |
116 | |
117 | local includeFrame = self.xmlFile:getValue(plateKey .. "#frame", true) |
118 | |
119 | licensePlate.data = g_licensePlateManager:getLicensePlate(licensePlate.preferedType, includeFrame) |
120 | if licensePlate.data ~= nil then |
121 | link(licensePlate.node, licensePlate.data.node) |
122 | setTranslation(licensePlate.data.node, 0, 0, 0) |
123 | setRotation(licensePlate.data.node, 0, 0, 0) |
124 | setVisibility(licensePlate.data.node, false) |
125 | |
126 | local widthPos = licensePlate.data.rawWidth * 0.5 + licensePlate.data.widthOffsetLeft |
127 | local widthNeg = licensePlate.data.rawWidth * 0.5 + licensePlate.data.widthOffsetRight |
128 | local heightPos = licensePlate.data.rawHeight * 0.5 + licensePlate.data.heightOffsetTop |
129 | local heightNeg = licensePlate.data.rawHeight * 0.5 + licensePlate.data.heightOffsetBot |
130 | |
131 | local scaleFactorWidth = (licensePlate.placementArea[2] + licensePlate.placementArea[4]) / (widthPos + widthNeg) |
132 | local scaleFactorHeight = (licensePlate.placementArea[1] + licensePlate.placementArea[3]) / (heightPos + heightNeg) |
133 | local minFactor = MathUtil.clamp(math.min(scaleFactorWidth, scaleFactorHeight), 0, 1) |
134 | if minFactor < 1 then |
135 | setScale(licensePlate.data.node, minFactor, minFactor, minFactor) |
136 | |
137 | widthPos = widthPos * minFactor |
138 | widthNeg = widthNeg * minFactor |
139 | heightPos = heightPos * minFactor |
140 | heightNeg = heightNeg * minFactor |
141 | end |
142 | |
143 | local moveX, moveY = 0, 0 |
144 | moveX = moveX - math.max(widthPos - licensePlate.placementArea[2], 0) |
145 | moveX = moveX + math.max(widthNeg - licensePlate.placementArea[4], 0) |
146 | moveY = moveY - math.max(heightPos - licensePlate.placementArea[1], 0) |
147 | moveY = moveY + math.max(heightNeg - licensePlate.placementArea[3], 0) |
148 | setTranslation(licensePlate.data.node, moveX, moveY, 0) |
149 | |
150 | licensePlate.changeObjects = {} |
151 | ObjectChangeUtil.loadObjectChangeFromXML(self.xmlFile, plateKey, licensePlate.changeObjects, self.components, self) |
152 | |
153 | table.insert(spec.licensePlates, licensePlate) |
154 | end |
155 | else |
156 | Logging.xmlError(self.xmlFile, "Unknown preferedType '%s' for license plate '%s'", preferedTypeStr, plateKey) |
157 | end |
158 | end |
159 | |
160 | i = i + 1 |
161 | end |
162 | |
163 | if self:getHasLicensePlates() then |
164 | spec.licensePlateData = {variation=1, characters=nil, colorIndex=nil} |
165 | end |
166 | end |
167 | end |
onPostLoad
DescriptionDefinitiononPostLoad()Code
171 | function LicensePlates:onPostLoad(savegame) |
172 | local spec = self.spec_licensePlates |
173 | |
174 | -- disable all object changes by default - will be enabled again if plate data is available |
175 | for i=1, #spec.licensePlates do |
176 | ObjectChangeUtil.setObjectChanges(spec.licensePlates[i].changeObjects, false, self, self.setMovingToolDirty) |
177 | end |
178 | |
179 | if savegame ~= nil and self:getHasLicensePlates() then |
180 | local variation = savegame.xmlFile:getValue(savegame.key .. ".licensePlates#variation", 1) |
181 | local characters = savegame.xmlFile:getValue(savegame.key .. ".licensePlates#characters") |
182 | local colorIndex = savegame.xmlFile:getValue(savegame.key .. ".licensePlates#colorIndex", 1) |
183 | local placementIndex = savegame.xmlFile:getValue(savegame.key .. ".licensePlates#placementIndex", 1) |
184 | |
185 | if variation ~= nil and characters ~= nil and colorIndex ~= nil and placementIndex ~= nil then |
186 | local characterTbl = {} |
187 | local characterLength = characters:len() |
188 | for i=1, characterLength do |
189 | table.insert(characterTbl, characters:sub(i, i)) |
190 | end |
191 | |
192 | spec.licensePlateData = {variation=variation, characters=characterTbl, colorIndex=colorIndex, placementIndex=placementIndex} |
193 | self:setLicensePlatesData(spec.licensePlateData) |
194 | end |
195 | end |
196 | end |
onReadStream
DescriptionCalled on client side on joinDefinition
onReadStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
229 | function LicensePlates:onReadStream(streamId, connection) |
230 | local spec = self.spec_licensePlates |
231 | spec.licensePlateData = LicensePlateManager.readLicensePlateData(streamId, connection) |
232 | self:setLicensePlatesData(spec.licensePlateData) |
233 | end |
onWriteStream
DescriptionCalled on server side on joinDefinition
onWriteStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
239 | function LicensePlates:onWriteStream(streamId, connection) |
240 | local spec = self.spec_licensePlates |
241 | LicensePlateManager.writeLicensePlateData(streamId, connection, spec.licensePlateData) |
242 | end |
prerequisitesPresent
DescriptionChecks if all prerequisite specializations are loadedDefinition
prerequisitesPresent(table specializations)Arguments
table | specializations | specializations |
boolean | hasPrerequisite | true if all prerequisite specializations are loaded |
17 | function LicensePlates.prerequisitesPresent(specializations) |
18 | return true |
19 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
59 | function LicensePlates.registerEventListeners(vehicleType) |
60 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", LicensePlates) |
61 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", LicensePlates) |
62 | SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", LicensePlates) |
63 | SpecializationUtil.registerEventListener(vehicleType, "onReadStream", LicensePlates) |
64 | SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", LicensePlates) |
65 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
49 | function LicensePlates.registerFunctions(vehicleType) |
50 | SpecializationUtil.registerFunction(vehicleType, "setLicensePlatesData", LicensePlates.setLicensePlatesData) |
51 | SpecializationUtil.registerFunction(vehicleType, "getLicensePlatesData", LicensePlates.getLicensePlatesData) |
52 | SpecializationUtil.registerFunction(vehicleType, "getLicensePlatesDataIsEqual", LicensePlates.getLicensePlatesDataIsEqual) |
53 | SpecializationUtil.registerFunction(vehicleType, "getHasLicensePlates", LicensePlates.getHasLicensePlates) |
54 | SpecializationUtil.registerFunction(vehicleType, "getLicensePlateDialogSettings", LicensePlates.getLicensePlateDialogSettings) |
55 | end |
saveToXMLFile
DescriptionDefinitionsaveToXMLFile()Code
208 | function LicensePlates:saveToXMLFile(xmlFile, key, usedModNames) |
209 | local spec = self.spec_licensePlates |
210 | |
211 | if self:getHasLicensePlates() and spec.licensePlateData then |
212 | if spec.licensePlateData.placementIndex ~= LicensePlateManager.PLACEMENT_OPTION.NONE then |
213 | if spec.licensePlateData.variation ~= nil |
214 | and spec.licensePlateData.characters ~= nil |
215 | and spec.licensePlateData.colorIndex ~= nil then |
216 | xmlFile:setValue(key .. "#variation", spec.licensePlateData.variation) |
217 | xmlFile:setValue(key .. "#characters", table.concat(spec.licensePlateData.characters, "")) |
218 | xmlFile:setValue(key .. "#colorIndex", spec.licensePlateData.colorIndex) |
219 | xmlFile:setValue(key .. "#placementIndex", spec.licensePlateData.placementIndex) |
220 | end |
221 | end |
222 | end |
223 | end |
setLicensePlatesData
DescriptionDefinitionsetLicensePlatesData()Code
246 | function LicensePlates:setLicensePlatesData(licensePlateData) |
247 | local spec = self.spec_licensePlates |
248 | if licensePlateData ~= nil and licensePlateData.variation ~= nil and licensePlateData.characters ~= nil and licensePlateData.colorIndex ~= nil and licensePlateData.placementIndex ~= nil then |
249 | for i=1, #spec.licensePlates do |
250 | local licensePlate = spec.licensePlates[i] |
251 | |
252 | local allowLicensePlate = true |
253 | if licensePlateData.placementIndex == LicensePlateManager.PLACEMENT_OPTION.NONE then |
254 | allowLicensePlate = false |
255 | elseif licensePlateData.placementIndex == LicensePlateManager.PLACEMENT_OPTION.BACK_ONLY then |
256 | if licensePlate.position == LicensePlateManager.PLATE_POSITION.FRONT then |
257 | allowLicensePlate = false |
258 | end |
259 | end |
260 | |
261 | if allowLicensePlate then |
262 | licensePlate.data:updateData(licensePlateData.variation, licensePlate.position, table.concat(licensePlateData.characters, ""), true) |
263 | licensePlate.data:setColorIndex(licensePlateData.colorIndex) |
264 | |
265 | setVisibility(licensePlate.data.node, true) |
266 | else |
267 | setVisibility(licensePlate.data.node, false) |
268 | end |
269 | |
270 | ObjectChangeUtil.setObjectChanges(licensePlate.changeObjects, allowLicensePlate, self, self.setMovingToolDirty) |
271 | end |
272 | |
273 | spec.licensePlateData = licensePlateData |
274 | else |
275 | for i=1, #spec.licensePlates do |
276 | setVisibility(spec.licensePlates[i].data.node, false) |
277 | end |
278 | end |
279 | end |