Script v1.4.4.0
- Handtools
- Events
- Objects
- Placeables
- Triggers
- Utils
- Vehicles
- Specializations
- AIVehicle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BuiltInCutterTrailer
- BunkerSiloCompacter
- Combine
- ConveyorBelt
- Cover
- CrabSteering
- Crawler
- Cultivator
- Cutter
- Cylindered
- Drivable
- DynamicMountAttacher
- Fillable
- FillActivatable
- FillVolume
- Foldable
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- FuelTrailer
- Honk
- HookLiftContainer
- HookLiftTrailer
- Leveler
- Lights
- LivestockTrailer
- ManureBarrel
- ManureSpreader
- MixerWagon
- Motorized
- Mountable
- Mower
- NonTabbable
- Overloading
- Pickup
- Pipe
- Plough
- PowerConsumer
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- RidgeMarker
- Roller
- Ropes
- RotorSpreader
- SemiTrailerFront
- Shovel
- SowingMachine
- SpeedRotatingParts
- Sprayer
- Steerable
- StrawBlower
- StumpCutter
- Tedder
- TensionBelts
- Trailer
- TreePlanter
- TreePlanterActivatable
- TreeSaw
- TurnOnVehicle
- Washable
- WaterTrailer
- Weeder
- WheelRotations
- Windrower
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkParticles
Engine v7.0.0.2
- General
- Entity
- Node
- Scenegraph
- Lighting
- Camera
- Shape
- Particle System
- Physics
- Spline
- Animation
- Overlays
- Sound
- Input
- XML
- Network
- Callbacks
- Text Rendering
- Terrain Detail
- Tire Track
- Editor
- Rendering
- String
- Math
- I3D
- Fillplanes
Foundation Reference
Fillable
DescriptionThis is the specialization for fillable vehicles, such as trailers or sprayersFunctions
- prerequisitesPresent
- preLoad
- load
- postLoad
- delete
- getSaveAttributesAndNodes
- getXMLStatsAttributes
- addNodeVehicleMapping
- removeNodeVehicleMapping
- readStream
- writeStream
- readUpdateStream
- writeUpdateStream
- update
- updateTick
- draw
- getDrawFirstFillText
- getAdditiveClientMass
- getFillUnitsWithFillType
- resetFillLevelIfNeeded
- allowFillType
- getCurrentFillTypes
- getFillLevel
- setFillLevel
- getCapacity
- getFreeCapacity
- resetUnitFillLevelIfNeeded
- allowUnitFillType
- getUnitFillTypes
- getUnitFillType
- getUnitLastValidFillType
- setUnitLastValidFillType
- getUnitFillLevel
- setUnitFillLevel
- getUnitCapacity
- setUnitCapacity
- getAllowFillFromAir
- getFirstEnabledFillType
- setIsFilling
- addFillTrigger
- removeFillTrigger
- onAttach
- onDetach
- attachPipe
- detachPipe
- findAttacherPipeVehicle
- loadSpecValueCapacity
- getSpecValueCapacity
- loadSpecValueFillTypes
- getSpecValueFillTypes
prerequisitesPresent
DescriptionChecks if all prerequisite specializations are loadedDefinition
prerequisitesPresent(table specializations)Arguments
table | specializations | specializations |
boolean | hasPrerequisite | true if all prerequisite specializations are loaded |
19 | function Fillable.prerequisitesPresent(specializations) |
20 | return true; |
21 | end |
preLoad
DescriptionCalled before loadingDefinition
preLoad(table savegame)Arguments
table | savegame | savegame |
26 | function Fillable:preLoad(savegame) |
27 | self.getAllowFillFromAir = Fillable.getAllowFillFromAir; |
28 | self.getDrawFirstFillText = Utils.overwrittenFunction(self.getDrawFirstFillText, Fillable.getDrawFirstFillText); |
29 | end |
load
DescriptionCalled on loadingDefinition
load(table savegame)Arguments
table | savegame | savegame |
34 | function Fillable:load(savegame) |
35 | |
36 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.capacity", "vehicle.fillUnits.fillUnit#capacity") |
37 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.fillTypes", "vehicle.fillUnits.fillUnit#fillTypes") |
38 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.fruitTypes", "vehicle.fillUnits.fillUnit#fillTypes") |
39 | |
40 | self.allowFillType = Fillable.allowFillType; |
41 | self.getFillUnitsWithFillType = Fillable.getFillUnitsWithFillType; |
42 | self.resetFillLevelIfNeeded = Fillable.resetFillLevelIfNeeded; |
43 | |
44 | self.setFillLevel = Fillable.setFillLevel; |
45 | self.getFillLevel = Fillable.getFillLevel; |
46 | self.getCurrentFillTypes = Fillable.getCurrentFillTypes; |
47 | self.getCapacity = Fillable.getCapacity; |
48 | self.getFreeCapacity = Fillable.getFreeCapacity; |
49 | self.resetUnitFillLevelIfNeeded = Fillable.resetUnitFillLevelIfNeeded; |
50 | |
51 | self.allowUnitFillType = Fillable.allowUnitFillType; |
52 | self.getUnitFillTypes = Fillable.getUnitFillTypes; |
53 | self.getUnitFillType = Fillable.getUnitFillType; |
54 | self.getUnitLastValidFillType = Fillable.getUnitLastValidFillType; |
55 | self.setUnitLastValidFillType = Fillable.setUnitLastValidFillType; |
56 | self.getUnitFillLevel = Fillable.getUnitFillLevel; |
57 | self.setUnitFillLevel = Fillable.setUnitFillLevel; |
58 | self.getUnitCapacity = Fillable.getUnitCapacity; |
59 | self.setUnitCapacity = Fillable.setUnitCapacity; |
60 | |
61 | self.getFirstEnabledFillType = Fillable.getFirstEnabledFillType; |
62 | self.setLastValidFillType = SpecializationUtil.callSpecializationsFunction("setLastValidFillType"); |
63 | self.updateMeasurementNode = Fillable.updateMeasurementNode; |
64 | self.attachPipe = Fillable.attachPipe; |
65 | self.detachPipe = Fillable.detachPipe; |
66 | |
67 | self.supportsFillTriggers = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.supportsFillTriggers#value"), self.supportsFillTriggers); |
68 | |
69 | if self.supportsFillTriggers then |
70 | assert(self.setIsFilling == nil, "Fillable needs to be the first specialization which implements setIsFilling"); |
71 | self.setIsFilling = Fillable.setIsFilling; |
72 | self.addFillTrigger = Fillable.addFillTrigger; |
73 | self.removeFillTrigger = Fillable.removeFillTrigger; |
74 | self.fillLitersPerSecond = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.fillLitersPerSecond"), 500); |
75 | local unitFillTime = getXMLFloat(self.xmlFile, "vehicle.unitFillTime"); |
76 | if unitFillTime ~= nil then |
77 | self.unitFillTime = unitFillTime * 1000; |
78 | end |
79 | self.currentFillTime = 0; |
80 | self.fillTriggers = {}; |
81 | self.fillActivatable = FillActivatable:new(self); |
82 | self.isFilling = false; |
83 | end |
84 | |
85 | self.fillTypeChangeThreshold = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.fillTypeChangeThreshold"), 0.05); -- fill level percentage that still allows overriding with another fill type |
86 | |
87 | self.fillUnits = {}; |
88 | local i=0; |
89 | while true do |
90 | local key = string.format("vehicle.fillUnits.fillUnit(%d)", i); |
91 | if not hasXMLProperty(self.xmlFile, key) then |
92 | break; |
93 | end |
94 | local entry = {}; |
95 | |
96 | entry.fillUnitIndex = i+1; |
97 | entry.fillVolumeIndex = Utils.getNoNil(getXMLInt(self.xmlFile, key .. "#fillVolumeIndex"), entry.fillUnitIndex); |
98 | |
99 | entry.currentFillType = FillUtil.FILLTYPE_UNKNOWN; |
100 | entry.lastValidFillType = FillUtil.FILLTYPE_UNKNOWN; |
101 | entry.fillLevel = 0; |
102 | |
103 | if self.isServer then |
104 | entry.sentFillType = entry.currentFillType; |
105 | entry.sentFillLevel = entry.fillLevel; |
106 | end |
107 | |
108 | entry.capacity = getXMLFloat(self.xmlFile, key .. "#capacity"); |
109 | entry.unit = getXMLString(self.xmlFile, key .. "#unit"); |
110 | entry.showOnHud = Utils.getNoNil(getXMLBool(self.xmlFile, key .. "#showOnHud"), true); |
111 | |
112 | entry.fillTypes = {}; |
113 | local fillTypes = {}; |
114 | local fillTypeCategories = getXMLString(self.xmlFile, key .. "#fillTypeCategories"); |
115 | local fillTypeNames = getXMLString(self.xmlFile, key .. "#fillTypes"); |
116 | if fillTypeCategories ~= nil and fillTypeNames == nil then |
117 | fillTypes = FillUtil.getFillTypeByCategoryName(fillTypeCategories, "Warning: '"..self.configFileName.. "' has invalid fillTypeCategory '%s'.") |
118 | elseif fillTypeCategories == nil and fillTypeNames ~= nil then |
119 | fillTypes = FillUtil.getFillTypesByNames(fillTypeNames, "Warning: '"..self.configFileName.. "' has invalid fillType '%s'.") |
120 | else |
121 | print("Warning: '"..self.configFileName.. "' a fillUnit entry needs either the 'fillTypeCategories' or 'fillTypes' attribute.") |
122 | end |
123 | |
124 | if fillTypes ~= nil then |
125 | for _,fillType in pairs(fillTypes) do |
126 | entry.fillTypes[fillType] = true; |
127 | end |
128 | end |
129 | |
130 | entry.lastFillLevel = 0; |
131 | entry.fillLevelHud = VehicleHudUtils.loadHud(self, self.xmlFile, "fillLevel", nil, i); |
132 | |
133 | table.insert(self.fillUnits, entry); |
134 | i=i+1; |
135 | end |
136 | |
137 | |
138 | -- fallback |
139 | if self.fillUnits == nil or table.getn(self.fillUnits) == 0 then |
140 | local entry = {}; |
141 | |
142 | entry.fillVolumeIndex = 1; |
143 | |
144 | entry.currentFillType = FillUtil.FILLTYPE_UNKNOWN; |
145 | entry.lastValidFillType = FillUtil.FILLTYPE_UNKNOWN; |
146 | entry.fillLevel = 0; |
147 | |
148 | if self.isServer then |
149 | entry.sentFillType = entry.currentFillType; |
150 | entry.sentFillLevel = entry.fillLevel; |
151 | end |
152 | |
153 | entry.capacity = getXMLFloat(self.xmlFile, "vehicle.capacity"); |
154 | entry.unit = getXMLString(self.xmlFile, "vehicle.capacity#unit"); |
155 | |
156 | entry.fillTypes = {}; |
157 | local fillTypes = {}; |
158 | local fillTypeCategories = getXMLString(self.xmlFile, "vehicle.fillTypeCategories"); |
159 | local fillTypeNames = getXMLString(self.xmlFile, "vehicle.fillTypes"); |
160 | if fillTypeCategories ~= nil and fillTypeNames == nil then |
161 | fillTypes = FillUtil.getFillTypeByCategoryName(fillTypeCategories, "Warning: '"..self.configFileName.. "' has invalid fillTypeCategory '%s'.") |
162 | elseif fillTypeCategories == nil and fillTypeNames ~= nil then |
163 | fillTypes = FillUtil.getFillTypesByNames(fillTypeNames, "Warning: '"..self.configFileName.. "' has invalid fillType '%s'.") |
164 | end |
165 | |
166 | if fillTypes ~= nil then |
167 | for _,fillType in pairs(fillTypes) do |
168 | entry.fillTypes[fillType] = true; |
169 | end |
170 | end |
171 | |
172 | entry.lastFillLevel = 0; |
173 | entry.fillLevelHud = VehicleHudUtils.loadHud(self, self.xmlFile, "fillLevel", nil, 0); |
174 | |
175 | table.insert(self.fillUnits, entry); |
176 | end |
177 | |
178 | |
179 | self.synchronizeFillLevels = true; |
180 | self.synchronizeFullFillLevel = false; |
181 | |
182 | self.fillRootNode = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.fillRootNode#index")); |
183 | if self.fillRootNode == nil then |
184 | self.fillRootNode = self.components[1].node; |
185 | end |
186 | |
187 | self.fillMassNode = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.fillMassNode#index")); |
188 | local updateFillLevelMass = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.fillMassNode#updateFillLevelMass"), true); |
189 | if self.fillMassNode == nil and updateFillLevelMass then |
190 | self.fillMassNode = self.components[1].node; |
191 | end |
192 | |
193 | self.exactFillRootNode = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.exactFillRootNode#index")); |
194 | if self.exactFillRootNode == nil then |
195 | self.exactFillRootNode = self.fillRootNode; |
196 | end |
197 | |
198 | self.fillAutoAimTarget = {}; |
199 | self.fillAutoAimTarget.node = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.fillAutoAimTargetNode#index")); |
200 | if self.fillAutoAimTarget.node == nil then |
201 | self.fillAutoAimTarget.node = self.exactFillRootNode; |
202 | end |
203 | self.fillAutoAimTarget.baseTrans = {getTranslation(self.fillAutoAimTarget.node)}; |
204 | self.fillAutoAimTarget.startZ = getXMLFloat(self.xmlFile, "vehicle.fillAutoAimTargetNode#startZ"); |
205 | self.fillAutoAimTarget.endZ = getXMLFloat(self.xmlFile, "vehicle.fillAutoAimTargetNode#endZ"); |
206 | self.fillAutoAimTarget.fillUnitIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.fillAutoAimTargetNode#fillUnitIndex"), 1); |
207 | self.fillAutoAimTarget.startPercentage = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.fillAutoAimTargetNode#startPercentage"), 25)/100; |
208 | self.fillAutoAimTarget.invert = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.fillAutoAimTargetNode#invert"), false); |
209 | if self.fillAutoAimTarget.startZ ~= nil and self.fillAutoAimTarget.endZ ~= nil then |
210 | local startZ = self.fillAutoAimTarget.startZ; |
211 | if self.fillAutoAimTarget.invert then |
212 | startZ = self.fillAutoAimTarget.endZ; |
213 | end; |
214 | |
215 | setTranslation(self.fillAutoAimTarget.node, self.fillAutoAimTarget.baseTrans[1], self.fillAutoAimTarget.baseTrans[2], startZ); |
216 | end; |
217 | |
218 | self.attacherPipeRef = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.attacherPipe#refIndex")); |
219 | self.attacherPipeRefVehicle = nil; |
220 | |
221 | self.attacherPipe = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.attacherPipe#index")); |
222 | self.attacherPipeAnimation = getXMLString(self.xmlFile, "vehicle.attacherPipe#animationName"); |
223 | self.attacherPipeVehicle = nil; |
224 | |
225 | self.allowFillFromAir = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.allowFillFromAir#value"), true); |
226 | |
227 | local unloadTriggerNode = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.unloadTrigger#index")); |
228 | if unloadTriggerNode ~= nil then |
229 | self.unloadTrigger = FillTrigger:new(); |
230 | self.unloadTrigger:load(unloadTriggerNode, nil, self); |
231 | end |
232 | self.unloadTriggerFillUnitIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.unloadTrigger#fillUnitIndex"), 1); |
233 | |
234 | if self.isClient then |
235 | |
236 | local fillPlanesRotDeg = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.fillPlanes#rotationDegrees"), false); |
237 | local i = 0; |
238 | while true do |
239 | local key = string.format("vehicle.fillPlanes.fillPlane(%d)", i); |
240 | if not hasXMLProperty(self.xmlFile, key) then |
241 | break; |
242 | end |
243 | local fillUnitIndex = getXMLInt(self.xmlFile, key.."#fillUnitIndex"); |
244 | if self.fillUnits[fillUnitIndex] == nil then |
245 | print("Warning: fillUnitIndex '"..tostring(fillUnitIndex).."' in fillPlane("..i..") does not point to a valid fillUnit!"); |
246 | end |
247 | if self.fillUnits[fillUnitIndex].fillPlanes == nil then |
248 | self.fillUnits[fillUnitIndex].fillPlanes = {}; |
249 | end |
250 | local fillPlane = {}; |
251 | fillPlane.nodes = {}; |
252 | local fillTypeName = getXMLString(self.xmlFile, key.."#fillType") |
253 | local fillType = Utils.getNoNil(FillUtil.fillTypeNameToInt[fillTypeName], FillUtil.FILLTYPE_UNKNOWN); |
254 | |
255 | if fillType ~= nil then |
256 | local nodeI = 0; |
257 | while true do |
258 | local nodeKey = key..string.format(".node(%d)", nodeI); |
259 | if not hasXMLProperty(self.xmlFile, nodeKey) then |
260 | break; |
261 | end |
262 | local node = Utils.indexToObject(self.components, getXMLString(self.xmlFile, nodeKey.."#index")); |
263 | if node ~= nil then |
264 | local defaultX, defaultY, defaultZ = getTranslation(node); |
265 | local defaultRX, defaultRY, defaultRZ = getRotation(node); |
266 | |
267 | local animCurve = AnimCurve:new(linearInterpolatorTransRotScale); |
268 | local keyI = 0; |
269 | while true do |
270 | local animKey = nodeKey..string.format(".key(%d)", keyI); |
271 | local keyTime = getXMLFloat(self.xmlFile, animKey.."#time"); |
272 | local x,y,z = Utils.getVectorFromString(getXMLString(self.xmlFile, animKey.."#translation")); |
273 | if y == nil then |
274 | y = getXMLFloat(self.xmlFile, animKey.."#y"); |
275 | end |
276 | local rx,ry,rz = Utils.getVectorFromString(getXMLString(self.xmlFile, animKey.."#rotation")); |
277 | local sx,sy,sz = Utils.getVectorFromString(getXMLString(self.xmlFile, animKey.."#scale")); |
278 | if keyTime == nil then |
279 | break; |
280 | end |
281 | local x = Utils.getNoNil(x, defaultX); |
282 | local y = Utils.getNoNil(y, defaultY); |
283 | local z = Utils.getNoNil(z, defaultZ); |
284 | if fillPlanesRotDeg then |
285 | rx = Utils.getNoNilRad(rx, defaultRX); |
286 | ry = Utils.getNoNilRad(ry, defaultRY); |
287 | rz = Utils.getNoNilRad(rz, defaultRZ); |
288 | else |
289 | rx = Utils.getNoNil(rx, defaultRX); |
290 | ry = Utils.getNoNil(ry, defaultRY); |
291 | rz = Utils.getNoNil(rz, defaultRZ); |
292 | end |
293 | local sx = Utils.getNoNil(sx, 1); |
294 | local sy = Utils.getNoNil(sy, 1); |
295 | local sz = Utils.getNoNil(sz, 1); |
296 | animCurve:addKeyframe({x=x, y=y, z=z, rx=rx, ry=ry, rz=rz, sx=sx, sy=sy, sz=sz, time = keyTime}); |
297 | keyI = keyI +1; |
298 | end |
299 | if keyI == 0 then |
300 | local minY, maxY = Utils.getVectorFromString(getXMLString(self.xmlFile, nodeKey.."#minMaxY")); |
301 | local minY = Utils.getNoNil(minY, defaultY); |
302 | local maxY = Utils.getNoNil(maxY, defaultY); |
303 | animCurve:addKeyframe({x=defaultX, y=minY, z=defaultZ, rx=defaultRX, ry=defaultRY, rz=defaultRZ, sx=1, sy=1, sz=1, time = 0}); |
304 | animCurve:addKeyframe({x=defaultX, y=maxY, z=defaultZ, rx=defaultRX, ry=defaultRY, rz=defaultRZ, sx=1, sy=1, sz=1, time = 1}); |
305 | end |
306 | local alwaysVisible = Utils.getNoNil(getXMLBool(self.xmlFile, nodeKey.."#alwaysVisible"), false); |
307 | setVisibility(node, alwaysVisible); |
308 | table.insert(fillPlane.nodes, {node=node, animCurve = animCurve, alwaysVisible=alwaysVisible}); |
309 | end |
310 | nodeI = nodeI +1; |
311 | end |
312 | if table.getn(fillPlane.nodes) > 0 then |
313 | if self.fillUnits[fillUnitIndex].defaultFillPlane == nil then |
314 | self.fillUnits[fillUnitIndex].defaultFillPlane = fillPlane; |
315 | end |
316 | self.fillUnits[fillUnitIndex].fillPlanes[fillType] = fillPlane; |
317 | end |
318 | end |
319 | i = i +1; |
320 | end |
321 | |
322 | self.measurementNodes = {}; |
323 | local i=0; |
324 | while true do |
325 | local key = string.format("vehicle.measurementNodes.measurementNode(%d)", i); |
326 | if not hasXMLProperty(self.xmlFile, key) then |
327 | break; |
328 | end |
329 | local node = Utils.indexToObject(self.components, getXMLString(self.xmlFile, key .. "#index")); |
330 | local fillUnitIndex = getXMLInt(self.xmlFile, key.."#fillUnitIndex"); |
331 | if self.fillUnits[fillUnitIndex] == nil then |
332 | print("Warning: fillUnitIndex '"..tostring(fillUnitIndex).."' in measurementNode("..i..") does not point to a valid fillUnit!"); |
333 | break; |
334 | end |
335 | if self.fillUnits[fillUnitIndex].measurementNodes == nil then |
336 | self.fillUnits[fillUnitIndex].measurementNodes = {}; |
337 | end |
338 | table.insert(self.fillUnits[fillUnitIndex].measurementNodes, node); |
339 | i=i+1; |
340 | end |
341 | self.measurementTime = 0; |
342 | end |
343 | |
344 | self:setFillLevel(0, FillUtil.FILLTYPE_UNKNOWN); |
345 | |
346 | self.fillableDirtyFlag = self:getNextDirtyFlag(); |
347 | self.lastFillLevelChangeTime = 0; |
348 | end |
postLoad
DescriptionCalled after loadingDefinition
postLoad(table savegame)Arguments
table | savegame | savegame |
353 | function Fillable:postLoad(savegame) |
354 | local startFillLevel = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.startFillLevel"), 0); |
355 | if startFillLevel > 0 then |
356 | local firstFillType = self:getFirstEnabledFillType(); |
357 | |
358 | if firstFillType ~= FillUtil.FILLTYPE_UNKNOWN then |
359 | self:setFillLevel(startFillLevel, firstFillType, true); |
360 | end |
361 | end |
362 | |
363 | if savegame ~= nil and not savegame.resetVehicles and self.synchronizeFillLevels then |
364 | if hasXMLProperty(savegame.xmlFile, savegame.key.."#fillLevels") and hasXMLProperty(savegame.xmlFile, savegame.key.."#fillTypes") then |
365 | local fillLevels = { Utils.getVectorFromString(Utils.getNoNil(getXMLString(savegame.xmlFile, savegame.key.."#fillLevels"), "")) }; |
366 | local fillTypes = Utils.splitString(" ", Utils.getNoNil(getXMLString(savegame.xmlFile, savegame.key.."#fillTypes"), "")); |
367 | |
368 | for i,fillType in pairs(fillTypes) do |
369 | if fillLevels[i] ~= nil then |
370 | local fillTypeInt = FillUtil.fillTypeNameToInt[fillType]; |
371 | self:setUnitFillLevel(i, fillLevels[i], fillTypeInt, false); |
372 | end |
373 | end |
374 | end |
375 | end |
376 | end |
delete
DescriptionCalled on deletingDefinition
delete()Code
380 | function Fillable:delete() |
381 | if self.unloadTrigger ~= nil then |
382 | self.unloadTrigger:delete(); |
383 | self.unloadTrigger = nil; |
384 | end |
385 | |
386 | if self.fillActivatable ~= nil then |
387 | g_currentMission:removeActivatableObject(self.fillActivatable); |
388 | end |
389 | end |
getSaveAttributesAndNodes
DescriptionReturns attributes and nodes to saveDefinition
getSaveAttributesAndNodes(table nodeIdent)Arguments
table | nodeIdent | node ident |
string | attributes | attributes |
string | nodes | nodes |
396 | function Fillable:getSaveAttributesAndNodes(nodeIdent) |
397 | if self.synchronizeFillLevels then |
398 | local fillTypes = 'fillTypes="'; |
399 | local fillLevels = 'fillLevels="'; |
400 | local numFillUnits = table.getn(self.fillUnits); |
401 | for i,fillUnit in pairs(self.fillUnits) do |
402 | local fillTypeName = FillUtil.fillTypeIntToName[fillUnit.currentFillType]; |
403 | if fillTypeName == nil then |
404 | fillTypeName = "unknown"; |
405 | end |
406 | fillTypes = fillTypes .. fillTypeName; |
407 | fillLevels = fillLevels .. fillUnit.fillLevel; |
408 | if numFillUnits > 1 and i ~= numFillUnits then |
409 | fillTypes = fillTypes .. ' '; |
410 | fillLevels = fillLevels .. ' '; |
411 | end |
412 | end |
413 | fillTypes = fillTypes .. '"'; |
414 | fillLevels = fillLevels .. '"'; |
415 | return fillTypes .. " " .. fillLevels, nil; |
416 | end |
417 | return nil; |
418 | end |
getXMLStatsAttributes
DescriptionReturns string with fillLevels and fillTypes for game stats xmlDefinition
getXMLStatsAttributes()Return Values
string | statesAttributes | states attributes |
423 | function Fillable:getXMLStatsAttributes() |
424 | local fillTypes = 'fillTypes="'; |
425 | local fillLevels = 'fillLevels="'; |
426 | local numFillUnits = table.getn(self.fillUnits); |
427 | for i,fillUnit in pairs(self.fillUnits) do |
428 | local fillTypeName = FillUtil.fillTypeIntToName[fillUnit.currentFillType]; |
429 | if fillTypeName == nil then |
430 | fillTypeName = "unknown"; |
431 | end |
432 | fillTypes = fillTypes .. Utils.encodeToHTML(tostring(fillTypeName)); |
433 | fillLevels = fillLevels .. string.format("%.3f", fillUnit.fillLevel); |
434 | if numFillUnits > 1 and i ~= numFillUnits then |
435 | fillTypes = fillTypes .. ' '; |
436 | fillLevels = fillLevels .. ' '; |
437 | end |
438 | end |
439 | return fillLevels .. '" '.. fillTypes..'"'; |
440 | end |
addNodeVehicleMapping
DescriptionAdd fillRootNode and exactFillRootNode to 'nodeToVehicle' mappingDefinition
addNodeVehicleMapping(table list)Arguments
table | list | list |
445 | function Fillable:addNodeVehicleMapping(list) |
446 | list[self.fillRootNode] = self; |
447 | list[self.exactFillRootNode] = self; |
448 | end |
removeNodeVehicleMapping
DescriptionRemove fillRootNode and exactFillRootNode from 'nodeToVehicle' mappingDefinition
removeNodeVehicleMapping(table list)Arguments
table | list | list |
453 | function Fillable:removeNodeVehicleMapping(list) |
454 | list[self.fillRootNode] = nil; |
455 | list[self.exactFillRootNode] = nil; |
456 | end |
readStream
DescriptionCalled on client side on joinDefinition
readStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
468 | function Fillable:readStream(streamId, connection) |
469 | if connection:getIsServer() then |
470 | if self.synchronizeFillLevels then |
471 | for i=1,table.getn(self.fillUnits) do |
472 | local fillLevel = streamReadFloat32(streamId); |
473 | local fillType = streamReadUIntN(streamId, FillUtil.sendNumBits); |
474 | self:setUnitFillLevel(i, fillLevel, fillType); |
475 | |
476 | local lastValidFillType = streamReadUIntN(streamId, FillUtil.sendNumBits); |
477 | self:setUnitLastValidFillType(i, lastValidFillType, true); |
478 | end |
479 | end |
480 | end |
481 | if self.supportsFillTriggers then |
482 | local isFilling = streamReadBool(streamId); |
483 | self:setIsFilling(isFilling, true); |
484 | end |
485 | end |
writeStream
DescriptionCalled on server side on joinDefinition
writeStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
491 | function Fillable:writeStream(streamId, connection) |
492 | if not connection:getIsServer() then |
493 | if self.synchronizeFillLevels then |
494 | for i=1,table.getn(self.fillUnits) do |
495 | local fillUnit = self.fillUnits[i]; |
496 | streamWriteFloat32(streamId, fillUnit.fillLevel); |
497 | streamWriteUIntN(streamId, fillUnit.currentFillType, FillUtil.sendNumBits); |
498 | streamWriteUIntN(streamId, fillUnit.lastValidFillType, FillUtil.sendNumBits); |
499 | end |
500 | end |
501 | end |
502 | if self.supportsFillTriggers then |
503 | streamWriteBool(streamId, self.isFilling); |
504 | end |
505 | end |
readUpdateStream
DescriptionCalled on on updateDefinition
readUpdateStream(integer streamId, integer timestamp, table connection)Arguments
integer | streamId | stream ID |
integer | timestamp | timestamp |
table | connection | connection |
512 | function Fillable:readUpdateStream(streamId, timestamp, connection) |
513 | if connection:getIsServer() then |
514 | if self.synchronizeFillLevels then |
515 | if streamReadBool(streamId) then |
516 | for i=1,table.getn(self.fillUnits) do |
517 | local fillUnit = self.fillUnits[i]; |
518 | local fillLevel; |
519 | if self.synchronizeFullFillLevel then |
520 | fillLevel = streamReadFloat32(streamId); |
521 | else |
522 | fillLevel = streamReadUInt16(streamId)/65535*fillUnit.capacity |
523 | end |
524 | local fillType = streamReadUIntN(streamId, FillUtil.sendNumBits); |
525 | |
526 | self:setUnitFillLevel(i, fillLevel, fillType, true); |
527 | |
528 | local lastValidFillType = streamReadUIntN(streamId, FillUtil.sendNumBits); |
529 | self:setUnitLastValidFillType(i, lastValidFillType, lastValidFillType ~= fillUnit.lastValidFillType) |
530 | end |
531 | end |
532 | end |
533 | end |
534 | end |
writeUpdateStream
DescriptionCalled on on updateDefinition
writeUpdateStream(integer streamId, table connection, integer dirtyMask)Arguments
integer | streamId | stream ID |
table | connection | connection |
integer | dirtyMask | dirty mask |
541 | function Fillable:writeUpdateStream(streamId, connection, dirtyMask) |
542 | if not connection:getIsServer() then |
543 | if self.synchronizeFillLevels then |
544 | if streamWriteBool(streamId, bitAND(dirtyMask, self.fillableDirtyFlag) ~= 0) then |
545 | for i=1,table.getn(self.fillUnits) do |
546 | local fillUnit = self.fillUnits[i]; |
547 | if self.synchronizeFullFillLevel then |
548 | streamWriteFloat32(streamId, fillUnit.fillLevel); |
549 | else |
550 | local percent = 0; |
551 | if fillUnit.capacity > 0 then |
552 | percent = Utils.clamp(fillUnit.fillLevel / fillUnit.capacity, 0, 1); |
553 | end |
554 | streamWriteUInt16(streamId, math.floor(percent*65535)); |
555 | end |
556 | streamWriteUIntN(streamId, fillUnit.currentFillType, FillUtil.sendNumBits); |
557 | streamWriteUIntN(streamId, fillUnit.lastValidFillType, FillUtil.sendNumBits); |
558 | end |
559 | end |
560 | end |
561 | end |
562 | end |
update
DescriptionCalled on updateDefinition
update(float dt)Arguments
float | dt | time since last call in ms |
567 | function Fillable:update(dt) |
568 | if self.firstTimeRun then |
569 | if self.isServer then |
570 | if self.fillMassNode ~= nil then |
571 | if self.emptyMass == nil then |
572 | self.emptyMass = getMass(self.fillMassNode); |
573 | self.currentMass = self.emptyMass; |
574 | end |
575 | local newMass = 0; |
576 | for i,fillUnit in pairs(self.fillUnits) do |
577 | if fillUnit.currentFillType ~= nil and fillUnit.currentFillType ~= FillUtil.FILLTYPE_UNKNOWN then |
578 | local desc = FillUtil.fillTypeIndexToDesc[fillUnit.currentFillType]; |
579 | newMass = newMass + (fillUnit.fillLevel * desc.massPerLiter); |
580 | end |
581 | end |
582 | newMass = newMass + self.emptyMass; |
583 | if newMass ~= self.currentMass then |
584 | setMass(self.fillMassNode, newMass); |
585 | self.currentMass = newMass; |
586 | end |
587 | end; |
588 | end |
589 | end |
590 | end |
updateTick
DescriptionCalled on update tickDefinition
updateTick(float dt)Arguments
float | dt | time since last call in ms |
595 | function Fillable:updateTick(dt) |
596 | if self.isServer then |
597 | if self.synchronizeFillLevels then |
598 | local hasChanged = false; |
599 | for i,fillUnit in pairs(self.fillUnits) do |
600 | if fillUnit.sentLastValidFillType ~= fillUnit.lastValidFillType or fillUnit.sentFillLevel ~= fillUnit.fillLevel or fillUnit.sentFillType ~= fillUnit.currentFillType then |
601 | hasChanged = true; |
602 | fillUnit.sentLastValidFillType = fillUnit.lastValidFillType; |
603 | fillUnit.sentFillLevel = fillUnit.fillLevel |
604 | fillUnit.sentFillType = fillUnit.currentFillType; |
605 | end |
606 | end |
607 | if hasChanged then |
608 | self:raiseDirtyFlags(self.fillableDirtyFlag); |
609 | end |
610 | end |
611 | |
612 | if self.isFilling then |
613 | local delta = 0; |
614 | local doFill = false; |
615 | if self.fillTrigger ~= nil then |
616 | if self.unitFillTime ~= nil then |
617 | self.currentFillTime = self.currentFillTime - dt; |
618 | if self.currentFillTime <= 0 then |
619 | doFill = true; |
620 | delta = self.fillTrigger:fill(self, 1); |
621 | self.currentFillTime = self.unitFillTime; |
622 | end |
623 | else |
624 | delta = self.fillLitersPerSecond*dt*0.001; |
625 | delta = self.fillTrigger:fill(self, delta); |
626 | doFill = true; |
627 | end |
628 | end |
629 | |
630 | if delta <= 0 and doFill then |
631 | self:setIsFilling(false); |
632 | end |
633 | end |
634 | end |
635 | |
636 | if self.isClient then |
637 | if self.measurementTime > 0 then |
638 | self.measurementTime = self.measurementTime - dt |
639 | |
640 | for _, fillUnit in pairs(self.fillUnits) do |
641 | if fillUnit.measurementNodes ~= nil then |
642 | for _, measurementNode in pairs(fillUnit.measurementNodes) do |
643 | local isWorking = 1; |
644 | if self.measurementTime <= 0 or fillUnit.fillLevel <= 0 then |
645 | isWorking = 0; |
646 | end; |
647 | |
648 | setShaderParameter(measurementNode, "fillLevel", fillUnit.fillLevel / fillUnit.capacity, isWorking, 0, 0, false); |
649 | end |
650 | end |
651 | end |
652 | end |
653 | end |
654 | end |
draw
DescriptionCalled on drawDefinition
draw()Code
658 | function Fillable:draw() |
659 | if self:getDrawFirstFillText() then |
660 | g_currentMission:addExtraPrintText(g_i18n:getText("info_firstFillTheTool")); |
661 | end; |
662 | end |
getDrawFirstFillText
DescriptionReturns if 'first fill tool' text should be drawedDefinition
getDrawFirstFillText()Return Values
boolean | draw | draw text |
667 | function Fillable:getDrawFirstFillText(superFunc) |
668 | if superFunc ~= nil then |
669 | return superFunc(self); |
670 | end; |
671 | |
672 | return false; |
673 | end; |
getAdditiveClientMass
DescriptionReturns additive mass of filled goodsDefinition
getAdditiveClientMass()Return Values
float | mass | mass in t |
678 | function Fillable:getAdditiveClientMass() |
679 | local mass = 0; |
680 | if self.fillUnits ~= nil then |
681 | for i,fillUnit in pairs(self.fillUnits) do |
682 | if fillUnit.currentFillType ~= nil and fillUnit.currentFillType ~= FillUtil.FILLTYPE_UNKNOWN then |
683 | local desc = FillUtil.fillTypeIndexToDesc[fillUnit.currentFillType]; |
684 | mass = mass + (fillUnit.fillLevel * desc.massPerLiter); |
685 | end |
686 | end |
687 | end |
688 | return mass; |
689 | end |
getFillUnitsWithFillType
DescriptionReturns a table with fill units that allow given fill typeDefinition
getFillUnitsWithFillType(integer fillType)Arguments
integer | fillType | fill type |
table | fillUnits | fill units |
695 | function Fillable:getFillUnitsWithFillType(fillType) |
696 | local tbl = {}; |
697 | for i,fillUnit in pairs(self.fillUnits) do |
698 | if fillUnit.fillTypes[fillType] then |
699 | table.insert(tbl, fillUnit); |
700 | end |
701 | end |
702 | return tbl; |
703 | end |
resetFillLevelIfNeeded
DescriptionResets fill level if given fillType is different than the current fill typeDefinition
resetFillLevelIfNeeded(integer fillType)Arguments
integer | fillType | fill type |
boolean | success | returns false if reset failed |
709 | function Fillable:resetFillLevelIfNeeded(fillType) |
710 | if self.lastFillLevelChangeTime + 500 > g_currentMission.time then |
711 | return false; |
712 | end; |
713 | |
714 | for i,fillUnit in pairs(self.fillUnits) do |
715 | if fillUnit.fillTypes[fillType] then |
716 | if fillUnit.currentFillType ~= fillType then |
717 | self:setUnitFillLevel(i, 0, FillUtil.FILLTYPE_UNKNOWN, true); |
718 | end |
719 | end |
720 | end |
721 | end |
allowFillType
DescriptionReturns if fill type is allowedDefinition
allowFillType(integer fillType, boolean allowEmptying)Arguments
integer | fillType | fill type |
boolean | allowEmptying | allow emptying |
boolean | allow | allow fill type |
728 | function Fillable:allowFillType(fillType, allowEmptying) |
729 | if fillType == FillUtil.FILLTYPE_UNKNOWN then |
730 | return true; |
731 | end |
732 | for i,fillUnit in pairs(self.fillUnits) do |
733 | if fillUnit.fillTypes[fillType] then |
734 | if fillUnit.currentFillType ~= FillUtil.FILLTYPE_UNKNOWN then |
735 | if fillUnit.fillLevel <= fillUnit.capacity*self.fillTypeChangeThreshold then |
736 | if allowEmptying then |
737 | self:setUnitFillLevel(i, 0, FillUtil.FILLTYPE_UNKNOWN, true); |
738 | end |
739 | return true; |
740 | else |
741 | if fillType == fillUnit.currentFillType then |
742 | return true; |
743 | end |
744 | end |
745 | else |
746 | return true; |
747 | end |
748 | end |
749 | end |
750 | return false; |
751 | end |
getCurrentFillTypes
DescriptionReturns table filled with current filltypes of all fill unitsDefinition
getCurrentFillTypes()Return Values
table | fillTypes | fill types |
756 | function Fillable:getCurrentFillTypes() |
757 | local tbl = {}; |
758 | for _,fillUnit in pairs(self.fillUnits) do |
759 | if fillUnit.currentFillType ~= FillUtil.FILLTYPE_UNKNOWN and fillUnit.fillLevel > 0 then |
760 | table.insert(tbl, fillUnit.currentFillType); |
761 | end |
762 | end |
763 | return tbl; |
764 | end |
getFillLevel
DescriptionReturns fill level of given fill type on all fill unitsDefinition
getFillLevel(integer fillType)Arguments
integer | fillType | fill type |
float | fillLevel | fill level |
770 | function Fillable:getFillLevel(fillType) |
771 | local fillLevel = 0; |
772 | for i,fillUnit in pairs(self.fillUnits) do |
773 | if fillType == nil or fillUnit.fillTypes[fillType] then |
774 | fillLevel = fillLevel + fillUnit.fillLevel; |
775 | end |
776 | end |
777 | return fillLevel; |
778 | end |
setFillLevel
DescriptionSet fill level (filling all fill units that allow given fill type)Definition
setFillLevel(float filllevel, integer fillType, boolean force, table fillInfo)Arguments
float | filllevel | new fill level |
integer | fillType | fill type |
boolean | force | force action |
table | fillInfo | fill info for fill volume |
786 | function Fillable:setFillLevel(fillLevel, fillType, force, fillInfo) |
787 | |
788 | if (force == nil or force == false) and not self:allowFillType(fillType, false) then |
789 | return; |
790 | end |
791 | |
792 | local availableFillUnits = self:getFillUnitsWithFillType(fillType); |
793 | local delta = fillLevel - self:getFillLevel(fillType); |
794 | |
795 | if availableFillUnits ~= nil then |
796 | for _,fillUnit in pairs(availableFillUnits) do |
797 | local oldFillLevel = self:getUnitFillLevel(fillUnit.fillUnitIndex); |
798 | self:setUnitFillLevel(fillUnit.fillUnitIndex, oldFillLevel + delta, fillType, force, fillInfo); |
799 | delta = delta - (self:getUnitFillLevel(fillUnit.fillUnitIndex) - oldFillLevel); |
800 | if math.abs(delta) < 0.0001 then |
801 | break; |
802 | end |
803 | end |
804 | end |
805 | |
806 | if self.unloadTrigger ~= nil then |
807 | if self.fillUnits[self.unloadTriggerFillUnitIndex] ~= nil then |
808 | self.unloadTrigger.fillType = self.fillUnits[self.unloadTriggerFillUnitIndex].currentFillType; |
809 | end |
810 | end |
811 | end |
getCapacity
DescriptionReturns the capacity of all fill units that support the given fill typeDefinition
getCapacity(integer fillType)Arguments
integer | fillType | fill type |
float | capacity | capacity |
817 | function Fillable:getCapacity(fillType) |
818 | local capacity = 0; |
819 | for i,fillUnit in pairs(self.fillUnits) do |
820 | if fillType == nil or fillType == FillUtil.FILLTYPE_UNKNOWN or fillUnit.fillTypes[fillType] then |
821 | capacity = capacity + fillUnit.capacity; |
822 | end |
823 | end |
824 | return capacity; |
825 | end |
getFreeCapacity
DescriptionReturns the free capacity of all fill units that support the given fill typeDefinition
getFreeCapacity(integer fillType)Arguments
integer | fillType | fill type |
float | freeCapacity | free capacity |
831 | function Fillable:getFreeCapacity(fillType) |
832 | local freeCapacity = 0; |
833 | for i,fillUnit in pairs(self.fillUnits) do |
834 | if fillType == nil or fillType == FillUtil.FILLTYPE_UNKNOWN or fillUnit.fillTypes[fillType] then |
835 | freeCapacity = freeCapacity + (fillUnit.capacity - fillUnit.fillLevel); |
836 | end |
837 | end |
838 | return freeCapacity; |
839 | end |
resetUnitFillLevelIfNeeded
DescriptionResets fill level of fill unit if given fillType is different than the current fill typeDefinition
resetUnitFillLevelIfNeeded(integer fillUnitIndex, integer fillType)Arguments
integer | fillUnitIndex | index of fill unit |
integer | fillType | fill type |
boolean | success | returns false if reset failed |
846 | function Fillable:resetUnitFillLevelIfNeeded(fillUnitIndex, fillType) |
847 | if self.fillUnits == nil or self.fillUnits[fillUnitIndex] == nil or self.lastFillLevelChangeTime + 500 > g_currentMission.time then |
848 | return; |
849 | end |
850 | local fillUnit = self.fillUnits[fillUnitIndex]; |
851 | if fillUnit.fillTypes[fillType] then |
852 | if fillUnit.currentFillType ~= fillType then |
853 | self:setUnitFillLevel(fillUnitIndex, 0, FillUtil.FILLTYPE_UNKNOWN, true); |
854 | end |
855 | end |
856 | end |
allowUnitFillType
DescriptionReturns if fill type is allowed by fill unitDefinition
allowUnitFillType(integer fillUnitIndex, integer fillType, boolean allowEmptying)Arguments
integer | fillUnitIndex | index of fill unit |
integer | fillType | fill type |
boolean | allowEmptying | allow emptying |
boolean | allow | allow fill type |
864 | function Fillable:allowUnitFillType(fillUnitIndex, fillType, allowEmptying) |
865 | if self.fillUnits == nil or self.fillUnits[fillUnitIndex] == nil then |
866 | return false; |
867 | end |
868 | local fillUnit = self.fillUnits[fillUnitIndex]; |
869 | if fillUnit.fillTypes[fillType] then |
870 | if fillUnit.currentFillType ~= FillUtil.FILLTYPE_UNKNOWN then |
871 | if fillUnit.fillLevel <= fillUnit.capacity*self.fillTypeChangeThreshold then |
872 | if allowEmptying then |
873 | self:setUnitFillLevel(fillUnitIndex, 0, FillUtil.FILLTYPE_UNKNOWN, true); |
874 | end |
875 | return true; |
876 | else |
877 | if fillType == fillUnit.currentFillType then |
878 | return true; |
879 | end |
880 | end |
881 | else |
882 | return true; |
883 | end |
884 | end |
885 | return false; |
886 | end |
getUnitFillTypes
DescriptionReturns a table with supported fill types of the given fill unitDefinition
getUnitFillTypes(integer fillUnitIndex)Arguments
integer | fillUnitIndex | index of fill unit |
table | fillTypes | fill types |
892 | function Fillable:getUnitFillTypes(fillUnitIndex) |
893 | if self.fillUnits == nil or self.fillUnits[fillUnitIndex] == nil then |
894 | return {FillUtil.FILLTYPE_UNKNOWN}; |
895 | else |
896 | return self.fillUnits[fillUnitIndex].fillTypes; |
897 | end |
898 | end |
getUnitFillType
DescriptionReturns current fill type of fill unitDefinition
getUnitFillType(integer fillUnitIndex)Arguments
integer | fillUnitIndex | index of fill unit |
integer | fillType | fill type |
904 | function Fillable:getUnitFillType(fillUnitIndex) |
905 | if self.fillUnits == nil or self.fillUnits[fillUnitIndex] == nil then |
906 | return FillUtil.FILLTYPE_UNKNOWN; |
907 | else |
908 | local fillUnit = self.fillUnits[fillUnitIndex]; |
909 | if fillUnit.fillLevel > 0 then |
910 | return fillUnit.currentFillType; |
911 | else |
912 | return FillUtil.FILLTYPE_UNKNOWN; |
913 | end |
914 | end |
915 | end |
getUnitLastValidFillType
DescriptionReturns last valid fill type of fill unitDefinition
getUnitLastValidFillType(integer fillUnitIndex)Arguments
integer | fillUnitIndex | index of fill unit |
integer | lastValidFillType | last valid fill type |
921 | function Fillable:getUnitLastValidFillType(fillUnitIndex) |
922 | if self.fillUnits == nil or self.fillUnits[fillUnitIndex] == nil then |
923 | return FillUtil.FILLTYPE_UNKNOWN; |
924 | else |
925 | return self.fillUnits[fillUnitIndex].lastValidFillType; |
926 | end |
927 | end |
setUnitLastValidFillType
DescriptionSet unit last valid fill typeDefinition
setUnitLastValidFillType(integer fillUnitIndex, integer lastValidFillType, boolean hasChanged)Arguments
integer | fillUnitIndex | index of fill unit |
integer | lastValidFillType | index new last valid fill type |
boolean | hasChanged | fill type has changed |
934 | function Fillable:setUnitLastValidFillType(fillUnitIndex, lastValidFillType, hasChanged) |
935 | if self.fillUnits == nil or self.fillUnits[fillUnitIndex] == nil then |
936 | return; |
937 | else |
938 | if self.fillUnits[fillUnitIndex].lastValidFillType ~= lastValidFillType then |
939 | self.fillUnits[fillUnitIndex].lastValidFillType = lastValidFillType; |
940 | end |
941 | end |
942 | end |
getUnitFillLevel
DescriptionReturns fill level of fill unitDefinition
getUnitFillLevel(integer fillUnitIndex)Arguments
integer | fillUnitIndex | fill unit index |
float | fillLevel | fill level of fill unit |
948 | function Fillable:getUnitFillLevel(fillUnitIndex) |
949 | if self.fillUnits == nil or self.fillUnits[fillUnitIndex] == nil then |
950 | return 0; |
951 | end |
952 | return self.fillUnits[fillUnitIndex].fillLevel; |
953 | end |
setUnitFillLevel
DescriptionSet unit fill levelDefinition
setUnitFillLevel(integer fillUnitIndex, float fillLevel, integer fillType, boolean force, table fillInfo)Arguments
integer | fillUnitIndex | index of fill unit |
float | fillLevel | new fill level |
integer | fillType | fill type |
boolean | force | force action |
table | fillInfo | fill info for fill volume |
962 | function Fillable:setUnitFillLevel(fillUnitIndex, fillLevel, fillType, force, fillInfo) |
963 | if self.fillUnits == nil or self.fillUnits[fillUnitIndex] == nil then |
964 | return false; |
965 | end |
966 | |
967 | if (force == nil or force == false) and not self:allowUnitFillType(fillUnitIndex, fillType, false) then |
968 | return false; |
969 | end |
970 | |
971 | local fillUnit = self.fillUnits[fillUnitIndex]; |
972 | |
973 | if fillLevel < fillUnit.fillLevel and fillLevel < 0.0000001 then |
974 | fillLevel = 0; |
975 | end |
976 | |
977 | fillUnit.currentFillType = fillType; |
978 | fillUnit.fillLevel = fillLevel; |
979 | |
980 | if fillUnit.capacity == 0 then |
981 | fillUnit.fillLevel = math.max(fillLevel, 0); |
982 | else |
983 | fillUnit.fillLevel = Utils.clamp(fillLevel, 0, fillUnit.capacity); |
984 | end |
985 | |
986 | if fillUnit.fillLevel <= 0 then |
987 | fillUnit.fillLevel = 0; |
988 | fillUnit.currentFillType = FillUtil.FILLTYPE_UNKNOWN; |
989 | end |
990 | |
991 | if fillUnit.currentFillType ~= FillUtil.FILLTYPE_UNKNOWN and fillUnit.fillLevel > 0 then |
992 | self:setUnitLastValidFillType(fillUnitIndex, fillUnit.currentFillType); |
993 | end |
994 | |
995 | if fillUnit.fillLevelHud ~= nil and math.abs(fillUnit.lastFillLevel-fillUnit.fillLevel) > 1 then |
996 | fillUnit.lastFillLevel = fillUnit.fillLevel; |
997 | VehicleHudUtils.setHudValue(self, fillUnit.fillLevelHud, fillUnit.fillLevel, fillUnit.capacity); |
998 | end |
999 | |
1000 | if fillUnit.currentFillPlane ~= nil then |
1001 | for _, node in ipairs(fillUnit.currentFillPlane.nodes) do |
1002 | setVisibility(node.node, false); |
1003 | end |
1004 | fillUnit.currentFillPlane = nil; |
1005 | end |
1006 | if fillUnit.fillPlanes ~= nil and fillUnit.defaultFillPlane ~= nil then |
1007 | local fillPlane; |
1008 | local t = 0; |
1009 | if fillType ~= FillUtil.FILLTYPE_UNKNOWN then |
1010 | fillPlane = fillUnit.fillPlanes[fillType]; |
1011 | t = fillUnit.fillLevel/fillUnit.capacity; |
1012 | end |
1013 | if fillPlane == nil then |
1014 | fillPlane = fillUnit.defaultFillPlane |
1015 | end |
1016 | for _, node in ipairs(fillPlane.nodes) do |
1017 | local x,y,z, rx,ry,rz, sx,sy,sz = node.animCurve:get(t); |
1018 | |
1019 | setTranslation(node.node, x, y, z); |
1020 | setRotation(node.node, rx, ry, rz); |
1021 | setScale(node.node, sx, sy, sz); |
1022 | setVisibility(node.node, fillUnit.fillLevel > 0 or node.alwaysVisible); |
1023 | end |
1024 | fillUnit.currentFillPlane = fillPlane; |
1025 | end |
1026 | |
1027 | if fillUnit.measurementNodes ~= nil then |
1028 | if fillUnit.fillLevel > 0 then |
1029 | self.measurementTime = math.min(self.measurementTime+5000, 5000) |
1030 | end |
1031 | end |
1032 | |
1033 | if self.fillAutoAimTarget.fillUnitIndex == fillUnitIndex then |
1034 | if self.fillAutoAimTarget.startZ ~= nil and self.fillAutoAimTarget.endZ ~= nil then |
1035 | local startFillLevel = fillUnit.capacity * self.fillAutoAimTarget.startPercentage; |
1036 | local percent = Utils.clamp((fillUnit.fillLevel-startFillLevel) / (fillUnit.capacity-startFillLevel), 0, 1); |
1037 | if self.fillAutoAimTarget.invert then |
1038 | percent = 1 - percent; |
1039 | end; |
1040 | local newZ = (self.fillAutoAimTarget.endZ-self.fillAutoAimTarget.startZ) * percent + self.fillAutoAimTarget.startZ; |
1041 | setTranslation(self.fillAutoAimTarget.node, self.fillAutoAimTarget.baseTrans[1], self.fillAutoAimTarget.baseTrans[2], newZ); |
1042 | end; |
1043 | end; |
1044 | |
1045 | self.lastFillLevelChangeTime = g_currentMission.time; |
1046 | end |
getUnitCapacity
DescriptionReturns capacity of fill unitDefinition
getUnitCapacity(integer fillUnitIndex)Arguments
integer | fillUnitIndex | index of fill volume |
float | capacity | capacity of fill unit |
1052 | function Fillable:getUnitCapacity(fillUnitIndex) |
1053 | if self.fillUnits == nil or self.fillUnits[fillUnitIndex] == nil then |
1054 | return 0; |
1055 | end |
1056 | return self.fillUnits[fillUnitIndex].capacity; |
1057 | end |
setUnitCapacity
DescriptionSets unit capacityDefinition
setUnitCapacity(integer fillUnitIndex, float capacity)Arguments
integer | fillUnitIndex | fill unit index |
float | capacity | new capacity |
1063 | function Fillable:setUnitCapacity(fillUnitIndex, capacity) |
1064 | if self.fillUnits == nil or self.fillUnits[fillUnitIndex] == nil then |
1065 | return; |
1066 | end |
1067 | self.fillUnits[fillUnitIndex].capacity = capacity; |
1068 | end |
getAllowFillFromAir
DescriptionReturns if fill from air is allowedDefinition
getAllowFillFromAir()Return Values
boolean | isAllowed | fill from air is allowed |
1073 | function Fillable:getAllowFillFromAir() |
1074 | return self.allowFillFromAir; |
1075 | end |
getFirstEnabledFillType
DescriptionReturns first enabled fill typeDefinition
getFirstEnabledFillType()Return Values
integer | filltype | first enabled fill type |
1080 | function Fillable:getFirstEnabledFillType() |
1081 | for _,fillUnit in pairs(self.fillUnits) do |
1082 | for fillType, enabled in pairs(fillUnit.fillTypes) do |
1083 | if fillType ~= FillUtil.FILLTYPE_UNKNOWN and enabled then |
1084 | return fillType; |
1085 | end |
1086 | end |
1087 | end |
1088 | return FillUtil.FILLTYPE_UNKNOWN; |
1089 | end |
setIsFilling
DescriptionSet is fillingDefinition
setIsFilling(boolean isFilling, boolean noEventSend)Arguments
boolean | isFilling | is filling |
boolean | noEventSend | no event send |
1095 | function Fillable:setIsFilling(isFilling, noEventSend) |
1096 | SetIsFillingEvent.sendEvent(self, isFilling, noEventSend) |
1097 | if self.isFilling ~= isFilling then |
1098 | self.isFilling = isFilling; |
1099 | |
1100 | self.fillTrigger = nil; |
1101 | if isFilling then |
1102 | -- find the first trigger which is activable |
1103 | for _, trigger in ipairs(self.fillTriggers) do |
1104 | if trigger:getIsActivatable(self) then |
1105 | self.fillTrigger = trigger; |
1106 | break; |
1107 | end |
1108 | end |
1109 | end |
1110 | end |
1111 | end |
addFillTrigger
DescriptionCalled if vehicle is in fill triggerDefinition
addFillTrigger(table trigger)Arguments
table | trigger | trigger |
1116 | function Fillable:addFillTrigger(trigger) |
1117 | if table.getn(self.fillTriggers) == 0 then |
1118 | g_currentMission:addActivatableObject(self.fillActivatable); |
1119 | end |
1120 | table.insert(self.fillTriggers, trigger); |
1121 | end |
removeFillTrigger
DescriptionCalled if vehicle leaves fill triggerDefinition
removeFillTrigger(table trigger)Arguments
table | trigger | trigger |
1126 | function Fillable:removeFillTrigger(trigger) |
1127 | for i=1, table.getn(self.fillTriggers) do |
1128 | if self.fillTriggers[i] == trigger then |
1129 | table.remove(self.fillTriggers, i); |
1130 | break; |
1131 | end |
1132 | end |
1133 | if self.fillTrigger == trigger then |
1134 | if self.isServer then |
1135 | self:setIsFilling(false); |
1136 | end |
1137 | end |
1138 | if table.getn(self.fillTriggers) == 0 then |
1139 | self:setIsFilling(false); |
1140 | g_currentMission:removeActivatableObject(self.fillActivatable); |
1141 | end |
1142 | end |
onAttach
DescriptionCalled if vehicle gets attachedDefinition
onAttach(table attacherVehicle)Arguments
table | attacherVehicle | attacher vehicle |
1147 | function Fillable:onAttach(attacherVehicle) |
1148 | if self.attacherPipe ~= nil then |
1149 | local vehicle = Fillable.findAttacherPipeVehicle(attacherVehicle, self, true, nil); |
1150 | if vehicle ~= nil then |
1151 | self:attachPipe(self, vehicle); |
1152 | end |
1153 | elseif self.attacherPipeRef ~= nil then |
1154 | local vehicle = Fillable.findAttacherPipeVehicle(attacherVehicle, self, false, nil); |
1155 | if vehicle ~= nil then |
1156 | self:attachPipe(vehicle, self); |
1157 | end |
1158 | end |
1159 | end |
onDetach
DescriptionCalled if vehicle gets detachedDefinition
onDetach()Code
1163 | function Fillable:onDetach() |
1164 | if self.attacherPipe ~= nil then |
1165 | if self.attacherPipeRefVehicle ~= nil then |
1166 | self:detachPipe(); |
1167 | end; |
1168 | elseif self.attacherPipeRef ~= nil then |
1169 | if self.attacherPipeVehicle ~= nil then |
1170 | self:detachPipe(); |
1171 | end; |
1172 | end |
1173 | end |
attachPipe
DescriptionAttach connection pipe between 2 fillablesDefinition
attachPipe(table pipeVehicle, table refVehicle)Arguments
table | pipeVehicle | vehicle with pipe |
table | refVehicle | vehicle to attach the pipe |
1179 | function Fillable:attachPipe(pipeVehicle, refVehicle) |
1180 | pipeVehicle.attacherPipeRefVehicle = refVehicle; |
1181 | refVehicle.attacherPipeVehicle = pipeVehicle; |
1182 | |
1183 | for _, movingPart in pairs(pipeVehicle.activeDirtyMovingParts) do |
1184 | if movingPart.node == pipeVehicle.attacherPipe then |
1185 | movingPart.referenceFrameBackUp = movingPart.referenceFrame; |
1186 | movingPart.referenceFrame = refVehicle.attacherPipeRef; |
1187 | movingPart.referenceFrameOffset = {0,0,0}; |
1188 | Cylindered.updateMovingPart(self, movingPart, false); |
1189 | break; |
1190 | end |
1191 | end |
1192 | |
1193 | if pipeVehicle.attacherPipeAnimation ~= nil and pipeVehicle.attacherPipeAnimation ~= "" then |
1194 | self:playAnimation(pipeVehicle.attacherPipeAnimation, 1, nil, true); |
1195 | end |
1196 | end |
detachPipe
DescriptionDetach pipeDefinition
detachPipe()Code
1200 | function Fillable:detachPipe() |
1201 | if self.attacherPipeRefVehicle ~= nil then |
1202 | for _, movingPart in pairs(self.activeDirtyMovingParts) do |
1203 | if movingPart.node == self.attacherPipe then |
1204 | movingPart.referenceFrame = movingPart.referenceFrameBackUp; |
1205 | break; |
1206 | end |
1207 | end |
1208 | self.attacherPipeRefVehicle.attacherPipeVehicle = nil; |
1209 | self.attacherPipeRefVehicle = nil; |
1210 | end |
1211 | |
1212 | if self.attacherPipeAnimation ~= nil and self.attacherPipeAnimation ~= "" then |
1213 | self:playAnimation(self.attacherPipeAnimation, -1, nil, true); |
1214 | end |
1215 | |
1216 | if self.attacherPipeVehicle ~= nil then |
1217 | |
1218 | for _, movingPart in pairs(self.attacherPipeVehicle.activeDirtyMovingParts) do |
1219 | if movingPart.node == self.attacherPipeVehicle.attacherPipe then |
1220 | movingPart.referenceFrame = self.attacherPipeVehicle.rootNode; |
1221 | break; |
1222 | end |
1223 | end |
1224 | self.attacherPipeVehicle.attacherPipeRefVehicle = nil; |
1225 | local attacherPipeVehicle = self.attacherPipeVehicle; |
1226 | self.attacherPipeVehicle = nil; |
1227 | -- try to reattach |
1228 | if attacherPipeVehicle.attacherVehicle ~= nil then |
1229 | local vehicle = Fillable.findAttacherPipeVehicle(attacherPipeVehicle.attacherVehicle, attacherPipeVehicle, true, self); |
1230 | if vehicle ~= nil then |
1231 | attacherPipeVehicle:attachPipe(attacherPipeVehicle, vehicle); |
1232 | end |
1233 | end |
1234 | end |
1235 | end |
findAttacherPipeVehicle
DescriptionReturns pipe vehicle if existsDefinition
findAttacherPipeVehicle(table currentVehicle, table lastVehicle, boolean lookForPipeRef, table ignoreVehicle)Arguments
table | currentVehicle | current vehicle to check |
table | lastVehicle | last vehicle checked |
boolean | lookForPipeRef | only search pipe ref vehicles |
table | ignoreVehicle | ignore that vehicle on search |
table | pipeVehicle | pipe vehicle |
1244 | function Fillable.findAttacherPipeVehicle(currentVehicle, lastVehicle, lookForPipeRef, ignoreVehicle) |
1245 | if lookForPipeRef then |
1246 | if currentVehicle.attacherPipeRef ~= nil and currentVehicle.attacherPipeRefVehicle == nil then |
1247 | return currentVehicle; |
1248 | end |
1249 | else |
1250 | if currentVehicle.attacherPipe ~= nil and currentVehicle.attacherPipeVehicle == nil then |
1251 | return currentVehicle; |
1252 | end |
1253 | end |
1254 | |
1255 | for _,implement in pairs(currentVehicle.attachedImplements) do |
1256 | if implement.object ~= nil and implement.object ~= lastVehicle and (ignoreVehicle == nil or ignoreVehicle ~= implement.object) then |
1257 | local ret = Fillable.findAttacherPipeVehicle(implement.object, currentVehicle, lookForPipeRef, nil); |
1258 | if ret ~= nil then |
1259 | return ret; |
1260 | end |
1261 | end |
1262 | end |
1263 | |
1264 | if currentVehicle.attacherVehicle ~= nil and currentVehicle.attacherVehicle ~= lastVehicle then |
1265 | return Fillable.findAttacherPipeVehicle(currentVehicle.attacherVehicle, currentVehicle, lookForPipeRef, nil); |
1266 | end |
1267 | |
1268 | end |
loadSpecValueCapacity
DescriptionLoads capacity spec valueDefinition
loadSpecValueCapacity(integer xmlFile, string customEnvironment)Arguments
integer | xmlFile | id of xml object |
string | customEnvironment | custom environment |
table | capacityAndUnit | capacity and unit |
1275 | function Fillable.loadSpecValueCapacity(xmlFile, customEnvironment) |
1276 | local capacity = 0 |
1277 | local capacityUnit = nil |
1278 | |
1279 | local rootName = getXMLRootName(xmlFile) |
1280 | |
1281 | local i=0; |
1282 | while true do |
1283 | local key = string.format(rootName..".fillUnits.fillUnit(%d)", i); |
1284 | if not hasXMLProperty(xmlFile, key) then |
1285 | break; |
1286 | end |
1287 | |
1288 | local showInShop = getXMLBool(xmlFile, key.."#showInShop") |
1289 | if showInShop == nil or showInShop then |
1290 | capacity = capacity + getXMLFloat(xmlFile, key .. "#capacity") |
1291 | if capacityUnit == nil then |
1292 | capacityUnit = getXMLString(xmlFile, key .. "#unit") |
1293 | end |
1294 | end |
1295 | |
1296 | i = i + 1 |
1297 | end |
1298 | |
1299 | -- fallback |
1300 | capacity = capacity + Utils.getNoNil(getXMLFloat(xmlFile, rootName..".capacity"), 0) |
1301 | if capacityUnit == nil then |
1302 | capacityUnit = getXMLString(xmlFile, rootName..".capacity#unit") |
1303 | end |
1304 | |
1305 | local storeDataCapacity = getXMLString(xmlFile, rootName..".storeData.specs.capacity") |
1306 | local storeDataCapacityUnit = getXMLString(xmlFile, rootName..".storeData.specs.capacity#unit") |
1307 | |
1308 | if storeDataCapacity ~= nil then |
1309 | capacity = storeDataCapacity |
1310 | end |
1311 | if storeDataCapacityUnit ~= nil then |
1312 | capacityUnit = storeDataCapacityUnit |
1313 | end |
1314 | |
1315 | return {value=capacity, unit=capacityUnit} |
1316 | end |
getSpecValueCapacity
DescriptionReturns capacity spec valueDefinition
getSpecValueCapacity(table storeItem, table realItem)Arguments
table | storeItem | store item |
table | realItem | real item |
string | l10n | l10n text |
float | capacity | capacity |
string | unit | unit |
1325 | function Fillable.getSpecValueCapacity(storeItem, realItem) |
1326 | if storeItem.specs.capacity ~= nil then |
1327 | if storeItem.specs.capacity.value == 0 then |
1328 | return nil |
1329 | end |
1330 | local unit = nil |
1331 | if storeItem.specs.capacity.unit ~= nil then |
1332 | if storeItem.specs.capacity.unit:sub(1,6) == "$l10n_" then |
1333 | unit = g_i18n:getText(storeItem.specs.capacity.unit:sub(7)); |
1334 | end; |
1335 | end |
1336 | return string.format(g_i18n:getText("shop_capacityValue"), storeItem.specs.capacity.value, Utils.getNoNil(unit, g_i18n:getText("unit_literShort"))) |
1337 | end |
1338 | return nil |
1339 | end |
loadSpecValueFillTypes
DescriptionLoads capacity spec valueDefinition
loadSpecValueFillTypes(integer xmlFile, string customEnvironment)Arguments
integer | xmlFile | id of xml object |
string | customEnvironment | custom environment |
table | specValue | [categoryNames, fillTypes, fruitTypeCategoryNames, useWindrowed] |
1346 | function Fillable.loadSpecValueFillTypes(xmlFile, customEnvironment) |
1347 | local fillTypeNames = nil |
1348 | local fillTypeCategoryNames = nil |
1349 | local fruitTypeCategoryNames = nil |
1350 | local fillTypes = nil |
1351 | |
1352 | local rootName = getXMLRootName(xmlFile) |
1353 | |
1354 | local i=0; |
1355 | while true do |
1356 | local key = string.format(rootName..".fillUnits.fillUnit(%d)", i); |
1357 | if not hasXMLProperty(xmlFile, key) then |
1358 | break; |
1359 | end |
1360 | local currentFillTypes = getXMLString(xmlFile, key .. "#fillTypes"); |
1361 | if currentFillTypes ~= nil then |
1362 | if fillTypeNames == nil then |
1363 | fillTypeNames = currentFillTypes |
1364 | else |
1365 | fillTypeNames = fillTypeNames .. " " .. currentFillTypes |
1366 | end |
1367 | end |
1368 | local currentFillTypeCategories = getXMLString(xmlFile, key .. "#fillTypeCategories"); |
1369 | if currentFillTypeCategories ~= nil then |
1370 | if fillTypeCategoryNames == nil then |
1371 | fillTypeCategoryNames = currentFillTypeCategories |
1372 | else |
1373 | fillTypeCategoryNames = fillTypeCategoryNames .. " " .. currentFillTypeCategories |
1374 | end |
1375 | end |
1376 | i=i+1; |
1377 | end |
1378 | |
1379 | if fillTypeNames == nil then |
1380 | fillTypeNames = getXMLString(xmlFile, rootName..".fillTypes"); |
1381 | end |
1382 | |
1383 | fillTypeNames = Utils.getNoNil(getXMLString(xmlFile, rootName..".storeData.specs.fillTypes"), fillTypeNames) |
1384 | if fillTypeNames ~= nil then |
1385 | fillTypes = FillUtil.getFillTypesByNames(fillTypeNames, nil) |
1386 | fillTypeCategoryNames = nil |
1387 | end |
1388 | |
1389 | if fillTypeCategoryNames == nil then |
1390 | fillTypeCategoryNames = getXMLString(xmlFile, rootName..".fillTypeCategories") |
1391 | end |
1392 | |
1393 | if fillTypes == nil then |
1394 | local fruitTypeNames = getXMLString(xmlFile, rootName..".fruitTypes") |
1395 | if fruitTypeNames ~= nil then |
1396 | fillTypes = FillUtil.getFillTypesByFruitTypeNames(fruitTypeNames, nil) |
1397 | end |
1398 | end |
1399 | |
1400 | if fillTypes == nil then |
1401 | local fruitTypeNames = getXMLString(xmlFile, rootName..".cutter#fruitTypes") |
1402 | if fruitTypeNames ~= nil then |
1403 | fillTypes = FillUtil.getFillTypesByFruitTypeNames(fruitTypeNames, nil) |
1404 | end |
1405 | end |
1406 | |
1407 | fruitTypeCategoryNames = getXMLString(xmlFile, rootName..".cutter#fruitTypeCategories") |
1408 | local useWindrowed = Utils.getNoNil(getXMLBool(xmlFile, rootName..".cutter#useWindrowed"), false) |
1409 | |
1410 | fillTypeCategoryNames = Utils.getNoNil(getXMLString(xmlFile, rootName..".storeData.specs.fillTypeCategories"), fillTypeCategoryNames) |
1411 | |
1412 | return {categoryNames=fillTypeCategoryNames, fillTypes=fillTypes, fruitTypeCategoryNames=fruitTypeCategoryNames, useWindrowed=useWindrowed} |
1413 | end |
getSpecValueFillTypes
DescriptionReturns capacity spec valueDefinition
getSpecValueFillTypes(table storeItem, table realItem)Arguments
table | storeItem | store item |
table | realItem | real item |
table | fillTypes | fill types |
1420 | function Fillable.getSpecValueFillTypes(storeItem, realItem) |
1421 | if storeItem.specs.fillTypes ~= nil then |
1422 | if storeItem.specs.fillTypes.categoryNames ~= nil then |
1423 | return FillUtil.getFillTypeByCategoryName(storeItem.specs.fillTypes.categoryNames, nil) |
1424 | elseif storeItem.specs.fillTypes.fillTypes ~= nil then |
1425 | return storeItem.specs.fillTypes.fillTypes |
1426 | elseif storeItem.specs.fillTypes.fruitTypeCategoryNames ~= nil then |
1427 | if storeItem.specs.fillTypes.useWindrowed then |
1428 | local fruitTypes = FruitUtil.getFruitTypeByCategoryName(storeItem.specs.fillTypes.fruitTypeCategoryNames, "Warning: Cutter has invalid fruitTypeCategory '%s'.") |
1429 | local windrowFillTypes = {}; |
1430 | |
1431 | for _, fruitType in pairs(fruitTypes) do |
1432 | table.insert(windrowFillTypes, FruitUtil.fruitTypeToWindrowFillType[fruitType]); |
1433 | end; |
1434 | |
1435 | return windrowFillTypes; |
1436 | else |
1437 | return FillUtil.getFillTypesByFruitTypeCategoryName(storeItem.specs.fillTypes.fruitTypeCategoryNames, nil) |
1438 | end |
1439 | end |
1440 | end |
1441 | return nil |
1442 | end |