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
PlaceableGreenhouse
DescriptionSpecialization for placeablesFunctions
- addPlantPlace
- getRandomGrowthInterval
- getRandomWateringInterval
- initSpecialization
- loadPlantFromXml
- onDelete
- onFinalizePlacement
- onLoad
- onOutputFillTypesChanged
- onProductionStatusChanged
- onUpdate
- plantI3DLoadedCallback
- prerequisitesPresent
- registerEventListeners
- registerFunctions
- registerXMLPaths
- setPlantAtPlace
- updatePlantDistribution
- updatePlantsStage
addPlantPlace
DescriptionDefinitionaddPlantPlace()Code
173 | function PlaceableGreenhouse:addPlantPlace(node, useRandomYRot) |
174 | local spec = self.spec_greenhouse |
175 | |
176 | useRandomYRot = Utils.getNoNil(useRandomYRot, true) |
177 | if useRandomYRot then |
178 | setRotation(node, 0, math.random() * math.pi * 2, 0) |
179 | end |
180 | table.insert(spec.plantPlaces, {node = node, fillType = nil, stage = nil}) |
181 | end |
getRandomGrowthInterval
DescriptionDefinitiongetRandomGrowthInterval()Code
22 | function PlaceableGreenhouse.getRandomGrowthInterval() |
23 | return math.random(PlaceableGreenhouse.GROWTH_INTERVAL_SECONDS_MIN, PlaceableGreenhouse.GROWTH_INTERVAL_SECONDS_MAX) * (1000 + math.random(50)) |
24 | end |
getRandomWateringInterval
DescriptionDefinitiongetRandomWateringInterval()Code
28 | function PlaceableGreenhouse.getRandomWateringInterval() |
29 | return math.random(PlaceableGreenhouse.WATERING_INTERVAL_SECONDS_MIN, PlaceableGreenhouse.WATERING_INTERVAL_SECONDS_MAX) * (1000 + math.random(50)) |
30 | end |
initSpecialization
DescriptionDefinitioninitSpecialization()Code
44 | function PlaceableGreenhouse.initSpecialization() |
45 | local plantXmlSchema = XMLSchema.new("greenhousePlant") |
46 | plantXmlSchema:register(XMLValueType.STRING, "greenhousePlant.i3dFilename", "i3d file of plant") |
47 | plantXmlSchema:register(XMLValueType.NODE_INDEX, "greenhousePlant.stages.growing(?)#node", "Growing mesh") |
48 | plantXmlSchema:register(XMLValueType.NODE_INDEX, "greenhousePlant.stages.withered#node", "Withered mesh") |
49 | |
50 | PlaceableGreenhouse.plantXmlSchema = plantXmlSchema |
51 | end |
loadPlantFromXml
DescriptionDefinitionloadPlantFromXml()Code
185 | function PlaceableGreenhouse:loadPlantFromXml(xmlFilename) |
186 | local plant = { |
187 | i3dFilename = "", |
188 | i3dNode = nil, |
189 | stages = { -- stagse are stored as child indices of meshes -> allows working on cloned nodes without managing node ids |
190 | growing = {}, -- growing stages from small to big |
191 | first = nil, |
192 | last = nil, |
193 | withered = nil, |
194 | } |
195 | } |
196 | |
197 | local plantXmlFile = XMLFile.load("plantXml", xmlFilename, PlaceableGreenhouse.plantXmlSchema) |
198 | if plantXmlFile ~= nil then |
199 | local i3dFilename = plantXmlFile:getValue("greenhousePlant.i3dFilename") |
200 | if i3dFilename ~= nil then |
201 | plant.i3dFilename = Utils.getFilename(i3dFilename, self.baseDirectory) |
202 | |
203 | local loadingTask = self:createLoadingTask() |
204 | |
205 | local arguments = { |
206 | plant = plant, |
207 | plantXmlFile = plantXmlFile, |
208 | loadingTask = loadingTask |
209 | } |
210 | plant.sharedLoadRequestId = g_i3DManager:loadSharedI3DFileAsync(plant.i3dFilename, false, false, self.plantI3DLoadedCallback, self, arguments) |
211 | end |
212 | end |
213 | |
214 | return plant |
215 | end |
onDelete
DescriptionDefinitiononDelete()Code
256 | function PlaceableGreenhouse:onDelete() |
257 | local spec = self.spec_greenhouse |
258 | |
259 | if spec.growthTimer ~= nil then |
260 | spec.growthTimer:delete() |
261 | end |
262 | if spec.wateringTimer ~= nil then |
263 | spec.wateringTimer:delete() |
264 | end |
265 | |
266 | if spec.filltypeIdToPlant ~= nil then |
267 | for _, plant in pairs(spec.filltypeIdToPlant) do |
268 | if plant.sharedLoadRequestId ~= nil then |
269 | g_i3DManager:releaseSharedI3DFile(plant.sharedLoadRequestId) |
270 | end |
271 | |
272 | if plant.i3dNode ~= nil then |
273 | delete(plant.i3dNode) |
274 | plant.i3dNode = nil |
275 | end |
276 | end |
277 | end |
278 | |
279 | g_effectManager:deleteEffects(spec.effects) |
280 | g_soundManager:deleteSamples(spec.samples) |
281 | end |
onFinalizePlacement
DescriptionDefinitiononFinalizePlacement()Code
285 | function PlaceableGreenhouse:onFinalizePlacement() |
286 | self.plantDistributionDirty = true |
287 | self.spec_greenhouse.wateringTimer:start() |
288 | end |
onLoad
DescriptionDefinitiononLoad()Code
94 | function PlaceableGreenhouse:onLoad(savegame) |
95 | local spec = self.spec_greenhouse |
96 | local xmlFile = self.xmlFile |
97 | local key = "placeable.greenhouse" |
98 | |
99 | spec.filltypeIdToPlant = {} |
100 | spec.plantPlaces = {} |
101 | |
102 | spec.activeFilltypes = {} |
103 | spec.hasWater = true |
104 | |
105 | xmlFile:iterate(key .. ".plants.plant", function(index, plantKey) |
106 | local fillTypeName = xmlFile:getValue(plantKey .. "#fillType") |
107 | local fillType = g_fillTypeManager:getFillTypeIndexByName(fillTypeName) |
108 | if fillType ~= nil then |
109 | local plantXmlFilename = xmlFile:getValue(plantKey .. "#xmlFilename") |
110 | if plantXmlFilename ~= nil then |
111 | plantXmlFilename = Utils.getFilename(plantXmlFilename, self.baseDirectory) |
112 | local plant = self:loadPlantFromXml(plantXmlFilename) |
113 | if plant ~= nil then |
114 | spec.filltypeIdToPlant[fillType] = plant |
115 | end |
116 | end |
117 | else |
118 | Logging.xmlWarning(xmlFile, "Unknown fillType '%s' for plant '%s'", fillTypeName, plantKey) |
119 | end |
120 | end) |
121 | |
122 | xmlFile:iterate(key .. ".plantSpaces.space", function(index, plantSpaceKey) |
123 | local plantPlaceNode = self.xmlFile:getValue(plantSpaceKey .. "#node", nil, self.components, self.i3dMappings) |
124 | local useRandomYRot = self.xmlFile:getValue(plantSpaceKey .. "#useRandomYRot", true) |
125 | if plantPlaceNode ~= nil then |
126 | self:addPlantPlace(plantPlaceNode, useRandomYRot) |
127 | end |
128 | end) |
129 | |
130 | xmlFile:iterate(key .. ".plantSpaces.spacesParent", function(index, plantParentKey) |
131 | local parentNode = self.xmlFile:getValue(plantParentKey .. "#node", nil, self.components, self.i3dMappings) |
132 | local useRandomYRot = self.xmlFile:getValue(plantParentKey .. "#useRandomYRot", true) |
133 | local numChildren = getNumOfChildren(parentNode) |
134 | if numChildren > 0 then |
135 | for i=0, numChildren-1 do |
136 | self:addPlantPlace(getChildAt(parentNode, i), useRandomYRot) |
137 | end |
138 | else |
139 | Logging.xmlWarning(xmlFile, "No i3d child nodes for '%s'", plantParentKey) |
140 | end |
141 | end) |
142 | |
143 | if self.isClient then |
144 | spec.samples = {} |
145 | spec.samples.watering = g_soundManager:loadSampleFromXML(xmlFile, key .. ".sounds", "watering", self.baseDirectory, self.components, 1, AudioGroup.ENVIRONMENT, self.i3dMappings, nil) |
146 | |
147 | spec.effects = g_effectManager:loadEffect(xmlFile, key .. ".effectNodes", self.components, self, self.i3dMappings) |
148 | end |
149 | |
150 | spec.growthTimer = Timer.new(PlaceableGreenhouse.getRandomGrowthInterval()) |
151 | spec.growthTimer:setFinishCallback(function(timerInstance) |
152 | timerInstance:setDuration(PlaceableGreenhouse.getRandomGrowthInterval()) |
153 | self:updatePlantsStage() -- restarts timer if reasonable |
154 | end) |
155 | |
156 | spec.wateringTimer = Timer.new(PlaceableGreenhouse.getRandomWateringInterval()) |
157 | spec.wateringTimer:setFinishCallback(function(timerInstance) |
158 | if spec.hasWater then |
159 | g_effectManager:startEffects(spec.effects) |
160 | g_soundManager:playSample(spec.samples.watering) |
161 | |
162 | Timer.createOneshot(PlaceableGreenhouse.WATERING_DURATION_SECONDS * 1000, function() |
163 | g_effectManager:stopEffects(spec.effects) |
164 | g_soundManager:stopSample(spec.samples.watering) |
165 | end) |
166 | timerInstance:start() -- restart for next watering |
167 | end |
168 | end) |
169 | end |
onOutputFillTypesChanged
DescriptionDefinitiononOutputFillTypesChanged()Code
301 | function PlaceableGreenhouse:onOutputFillTypesChanged(outputs, state) |
302 | local spec = self.spec_greenhouse |
303 | |
304 | for _, output in pairs(outputs) do |
305 | local fillType = output.type |
306 | if state then |
307 | if spec.filltypeIdToPlant[fillType] ~= nil then |
308 | spec.activeFilltypes[fillType] = true |
309 | end |
310 | else |
311 | spec.activeFilltypes[fillType] = nil |
312 | end |
313 | end |
314 | |
315 | -- only directly updated visuals if during gameplay -> plants are updated expliclitly once after load onFinalizePlacement |
316 | if self:getIsSynchronized() then |
317 | self.plantDistributionDirty = true |
318 | end |
319 | |
320 | self:raiseActive() |
321 | end |
onProductionStatusChanged
DescriptionDefinitiononProductionStatusChanged()Code
325 | function PlaceableGreenhouse:onProductionStatusChanged(production, status) |
326 | local spec = self.spec_greenhouse |
327 | |
328 | local hasWater = not (status == ProductionPoint.PROD_STATUS.MISSING_INPUTS) |
329 | |
330 | if spec.hasWater ~= hasWater then |
331 | spec.hasWater = hasWater |
332 | self:updatePlantsStage() |
333 | end |
334 | |
335 | if hasWater and next(spec.activeFilltypes) ~= nil then |
336 | spec.wateringTimer:startIfNotRunning() |
337 | else |
338 | spec.wateringTimer:stop() |
339 | end |
340 | end |
onUpdate
DescriptionDefinitiononUpdate()Code
293 | function PlaceableGreenhouse:onUpdate() |
294 | if self.plantDistributionDirty then |
295 | self:updatePlantDistribution() |
296 | end |
297 | end |
plantI3DLoadedCallback
DescriptionDefinitionplantI3DLoadedCallback()Code
219 | function PlaceableGreenhouse:plantI3DLoadedCallback(i3dNode, failedReason, args) |
220 | local plant = args.plant |
221 | local plantXmlFile = args.plantXmlFile |
222 | local loadingTask = args.loadingTask |
223 | |
224 | if i3dNode ~= 0 then |
225 | local components = {} |
226 | local i3dMappings = {} |
227 | I3DUtil.loadI3DComponents(i3dNode, components) |
228 | I3DUtil.loadI3DMapping(plantXmlFile, i3dNode, components, i3dMappings) |
229 | |
230 | plant.i3dNode = i3dNode |
231 | |
232 | plantXmlFile:iterate("greenhousePlant.stages.growing", function(index, key) |
233 | local growingNode = plantXmlFile:getValue(key .. "#node", nil, i3dNode) |
234 | if growingNode ~= nil then |
235 | local childIndex = getChildIndex(growingNode) |
236 | table.insert(plant.stages.growing, childIndex) |
237 | end |
238 | end) |
239 | |
240 | plant.stages.first = plant.stages.growing[1] |
241 | plant.stages.last = plant.stages.growing[#plant.stages.growing] |
242 | |
243 | local witheredNode = plantXmlFile:getValue("greenhousePlant.stages.withered#node", nil, plant.i3dNode) |
244 | if witheredNode ~= nil then |
245 | plant.stages.withered = getChildIndex(witheredNode) |
246 | end |
247 | end |
248 | |
249 | plantXmlFile:delete() |
250 | |
251 | self:finishLoadingTask(loadingTask) |
252 | 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 |
38 | function PlaceableGreenhouse.prerequisitesPresent(specializations) |
39 | return true |
40 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
66 | function PlaceableGreenhouse.registerEventListeners(placeableType) |
67 | SpecializationUtil.registerEventListener(placeableType, "onLoad", PlaceableGreenhouse) |
68 | SpecializationUtil.registerEventListener(placeableType, "onDelete", PlaceableGreenhouse) |
69 | SpecializationUtil.registerEventListener(placeableType, "onFinalizePlacement", PlaceableGreenhouse) |
70 | SpecializationUtil.registerEventListener(placeableType, "onOutputFillTypesChanged", PlaceableGreenhouse) |
71 | SpecializationUtil.registerEventListener(placeableType, "onProductionStatusChanged", PlaceableGreenhouse) |
72 | SpecializationUtil.registerEventListener(placeableType, "onUpdate", PlaceableGreenhouse) |
73 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
55 | function PlaceableGreenhouse.registerFunctions(placeableType) |
56 | SpecializationUtil.registerFunction(placeableType, "loadPlantFromXml", PlaceableGreenhouse.loadPlantFromXml) |
57 | SpecializationUtil.registerFunction(placeableType, "plantI3DLoadedCallback", PlaceableGreenhouse.plantI3DLoadedCallback) |
58 | SpecializationUtil.registerFunction(placeableType, "addPlantPlace", PlaceableGreenhouse.addPlantPlace) |
59 | SpecializationUtil.registerFunction(placeableType, "updatePlantDistribution", PlaceableGreenhouse.updatePlantDistribution) |
60 | SpecializationUtil.registerFunction(placeableType, "setPlantAtPlace", PlaceableGreenhouse.setPlantAtPlace) |
61 | SpecializationUtil.registerFunction(placeableType, "updatePlantsStage", PlaceableGreenhouse.updatePlantsStage) |
62 | end |
registerXMLPaths
DescriptionDefinitionregisterXMLPaths()Code
77 | function PlaceableGreenhouse.registerXMLPaths(schema, basePath) |
78 | schema:setXMLSpecializationType("Greenhouse") |
79 | schema:register(XMLValueType.STRING, basePath .. ".greenhouse.plants.plant(?)#fillType", "FillType of plant") |
80 | schema:register(XMLValueType.STRING, basePath .. ".greenhouse.plants.plant(?)#xmlFilename", "xml file of greenhouse plant") |
81 | |
82 | schema:register(XMLValueType.NODE_INDEX, basePath .. ".greenhouse.plantSpaces.space(?)#node", "node where plant is placed") |
83 | schema:register(XMLValueType.BOOL, basePath .. ".greenhouse.plantSpaces.space(?)#useRandomYRot", "node is randomly rotated on the y axis", true) |
84 | schema:register(XMLValueType.NODE_INDEX, basePath .. ".greenhouse.plantSpaces.spacesParent(?)#node", "parent node of nodes where plants are placed") |
85 | schema:register(XMLValueType.BOOL, basePath .. ".greenhouse.plantSpaces.spacesParent(?)#useRandomYRot", "node is randomly rotated on the y axis", true) |
86 | |
87 | SoundManager.registerSampleXMLPaths(schema, basePath .. ".greenhouse.sounds", "watering") |
88 | EffectManager.registerEffectXMLPaths(schema, basePath .. ".greenhouse.effectNodes") |
89 | schema:setXMLSpecializationType() |
90 | end |
setPlantAtPlace
DescriptionDefinitionsetPlantAtPlace()Code
366 | function PlaceableGreenhouse:setPlantAtPlace(fillType, plantPlace) |
367 | local spec = self.spec_greenhouse |
368 | |
369 | -- only update if required fillType differs from current one |
370 | if plantPlace.fillType ~= fillType then |
371 | if plantPlace.fillType ~= nil then |
372 | -- remove existing stages from other plant |
373 | for i=getNumOfChildren(plantPlace.node)-1, 0, -1 do |
374 | local plantStage = getChildAt(plantPlace.node, i) |
375 | delete(plantStage) |
376 | end |
377 | plantPlace.fillType = nil |
378 | end |
379 | |
380 | local plant = spec.filltypeIdToPlant[fillType] |
381 | if plant ~= nil then |
382 | local plantClone = clone(getChildAt(plant.i3dNode, 0), false, false, false) |
383 | |
384 | for n=getNumOfChildren(plantClone)-1, 0, -1 do |
385 | local plantStage = getChildAt(plantClone, n) |
386 | link(plantPlace.node, plantStage, 0) |
387 | end |
388 | plantPlace.fillType = fillType |
389 | plantPlace.stage = nil |
390 | |
391 | delete(plantClone) |
392 | end |
393 | end |
394 | end |
updatePlantDistribution
Descriptionpopulates the plant nodes with cloned plants set in activeFilltypesDefinition
updatePlantDistribution()Code
344 | function PlaceableGreenhouse:updatePlantDistribution() |
345 | local spec = self.spec_greenhouse |
346 | |
347 | local numActiveFilltypes = table.size(spec.activeFilltypes) |
348 | local numPlaces = #spec.plantPlaces |
349 | |
350 | local fillTypesList = table.toList(spec.activeFilltypes) |
351 | |
352 | for i=1, numPlaces do |
353 | -- rotate active fillTypes through places |
354 | local fillType = fillTypesList[(i % numActiveFilltypes) + 1] |
355 | local plantPlace = spec.plantPlaces[i] |
356 | |
357 | self:setPlantAtPlace(fillType, plantPlace) |
358 | end |
359 | |
360 | self.plantDistributionDirty = false |
361 | self:updatePlantsStage() |
362 | end |
updatePlantsStage
Descriptioncycles throufh plants growth stages or sets plants to withered if no water is availableDefinition
updatePlantsStage()Code
398 | function PlaceableGreenhouse:updatePlantsStage() |
399 | local spec = self.spec_greenhouse |
400 | |
401 | if table.size(spec.activeFilltypes) == 0 then |
402 | return |
403 | end |
404 | |
405 | if not spec.hasWater then |
406 | spec.growthTimer:stop() |
407 | else |
408 | spec.growthTimer:start() |
409 | end |
410 | |
411 | for i=1, #spec.plantPlaces do |
412 | local plantPlace = spec.plantPlaces[i] |
413 | |
414 | local plant = spec.filltypeIdToPlant[plantPlace.fillType] |
415 | |
416 | local newStage |
417 | if not spec.hasWater then |
418 | newStage = plant.stages.withered |
419 | else |
420 | newStage = (plantPlace.stage and (plantPlace.stage + 1)) or plant.stages.first |
421 | if newStage > plant.stages.last then |
422 | newStage = plant.stages.first |
423 | end |
424 | end |
425 | |
426 | if plantPlace.stage ~= newStage then |
427 | for n=0, getNumOfChildren(plantPlace.node)-1 do |
428 | local plantStage = getChildAt(plantPlace.node, n) |
429 | setVisibility(plantStage, n == newStage) |
430 | end |
431 | plantPlace.stage = newStage |
432 | end |
433 | end |
434 | end |