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
SowingMachine
DescriptionClass for all sowing machinesFunctions
- initSpecialization
- prerequisitesPresent
- preLoad
- load
- delete
- readStream
- writeStream
- readUpdateStream
- writeUpdateStream
- getSaveAttributesAndNodes
- update
- updateTick
- draw
- getDrawFirstFillText
- onAttach
- onEnter
- onDeactivate
- getIsTurnedOnAllowed
- onTurnedOff
- onDeactivateSounds
- setSeedIndex
- setSeedFruitType
- onAiTurnOn
- onAiTurnOff
- onAiLower
- onAiRaise
- findAttachedSeedTank
- getAllowFillFromAir
- getDirectionSnapAngle
- resetFillLevelIfNeeded
- resetUnitFillLevelIfNeeded
- allowFillType
- allowUnitFillType
- setUnitFillLevel
- doCheckSpeedLimit
- getDirtMultiplier
- loadWorkAreaFromXML
- getDefaultSpeedLimit
- processSowingMachineAreas
- getFillLevelInformation
- getIsSeedChangeAllowed
- loadSpecValueSeedFillTypes
- getSpecValueSeedFillTypes
initSpecialization
DescriptionCalled on specialization initializingDefinition
initSpecialization()Code
19 | function SowingMachine.initSpecialization() |
20 | WorkArea.registerAreaType("sowingMachine") |
21 | 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 |
27 | function SowingMachine.prerequisitesPresent(specializations) |
28 | return SpecializationUtil.hasSpecialization(Fillable, specializations) and SpecializationUtil.hasSpecialization(WorkArea, specializations) and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations) and SpecializationUtil.hasSpecialization(FillVolume, specializations) |
29 | end |
preLoad
DescriptionCalled before loadingDefinition
preLoad(table savegame)Arguments
table | savegame | savegame |
34 | function SowingMachine:preLoad(savegame) |
35 | self.supportsFillTriggers = true |
36 | self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, SowingMachine.loadWorkAreaFromXML) |
37 | self.getDrawFirstFillText = Utils.overwrittenFunction(self.getDrawFirstFillText, SowingMachine.getDrawFirstFillText) |
38 | end |
load
DescriptionCalled on loadingDefinition
load(table savegame)Arguments
table | savegame | savegame |
43 | function SowingMachine:load(savegame) |
44 | |
45 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.turnOnAnimation#name", "vehicle.turnOnVehicle.turnedAnimation#name") |
46 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.turnOnAnimation#speed", "vehicle.turnOnVehicle.turnedAnimation#turnOnSpeedScale") |
47 | Utils.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.drum#index", "vehicle.speedRotatingParts.speedRotatingPart") |
48 | |
49 | |
50 | self.setSeedFruitType = SpecializationUtil.callSpecializationsFunction("setSeedFruitType") |
51 | self.setSeedIndex = SpecializationUtil.callSpecializationsFunction("setSeedIndex") |
52 | self.getIsTurnedOnAllowed = Utils.overwrittenFunction(self.getIsTurnedOnAllowed, SowingMachine.getIsTurnedOnAllowed) |
53 | self.getAllowFillFromAir = Utils.overwrittenFunction(self.getAllowFillFromAir, SowingMachine.getAllowFillFromAir) |
54 | self.getDirectionSnapAngle = Utils.overwrittenFunction(self.getDirectionSnapAngle, SowingMachine.getDirectionSnapAngle) |
55 | self.resetUnitFillLevelIfNeeded = Utils.overwrittenFunction(self.resetUnitFillLevelIfNeeded, SowingMachine.resetUnitFillLevelIfNeeded) |
56 | self.resetFillLevelIfNeeded = Utils.overwrittenFunction(self.resetFillLevelIfNeeded, SowingMachine.resetFillLevelIfNeeded) |
57 | self.allowFillType = Utils.overwrittenFunction(self.allowFillType, SowingMachine.allowFillType) |
58 | self.allowUnitFillType = Utils.overwrittenFunction(self.allowUnitFillType, SowingMachine.allowUnitFillType) |
59 | self.setUnitFillLevel = Utils.overwrittenFunction(self.setUnitFillLevel, SowingMachine.setUnitFillLevel) |
60 | self.getDirtMultiplier = Utils.overwrittenFunction(self.getDirtMultiplier, SowingMachine.getDirtMultiplier) |
61 | self.doCheckSpeedLimit = Utils.overwrittenFunction(self.doCheckSpeedLimit, SowingMachine.doCheckSpeedLimit) |
62 | self.getFillLevelInformation = Utils.overwrittenFunction(self.getFillLevelInformation, SowingMachine.getFillLevelInformation) |
63 | self.processSowingMachineAreas = SowingMachine.processSowingMachineAreas |
64 | self.getIsSeedChangeAllowed = SowingMachine.getIsSeedChangeAllowed |
65 | |
66 | self.isSeedTank = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.sowingMachine#isTank"), false); |
67 | self.requiresTank = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.sowingMachine#requiresTank"), false); |
68 | |
69 | if next(self.groundReferenceNodes) == nil and not self.isSeedTank then |
70 | print("Warning: No ground reference nodes in "..self.configFileName) |
71 | end |
72 | |
73 | self.allowFillFromAirWhileTurnedOn = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.allowFillFromAirWhileTurnedOn#value"), true) |
74 | self.sowingDirectionNode = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.sowingDirectionNode#index")), self.components[1].node) |
75 | self.useDirectPlanting = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.useDirectPlanting"), false) |
76 | self.sowingMachineHasGroundContact = false |
77 | |
78 | self.seeds = {} |
79 | local fruitTypes = {} |
80 | local fruitTypeCategories = getXMLString(self.xmlFile, "vehicle.seedFruitTypeCategories") |
81 | local fruitTypeNames = getXMLString(self.xmlFile, "vehicle.seedFruitTypes") |
82 | if fruitTypeCategories ~= nil and fruitTypeNames == nil then |
83 | fruitTypes = FruitUtil.getFruitTypeByCategoryName(fruitTypeCategories, "Warning: '"..self.configFileName.. "' has invalid fruitTypeCategory '%s'.") |
84 | elseif fruitTypeCategories == nil and fruitTypeNames ~= nil then |
85 | fruitTypes = FruitUtil.getFruitTypesByNames(fruitTypeNames, "Warning: '"..self.configFileName.. "' has invalid fruitType '%s'.") |
86 | else |
87 | print("Warning: '"..self.configFileName.. "' a sowingMachine needs either the 'seedFruitTypeCategories' or 'seedFruitTypes' element.") |
88 | end |
89 | |
90 | if fruitTypes ~= nil then |
91 | for _,fruitType in pairs(fruitTypes) do |
92 | table.insert(self.seeds, fruitType) |
93 | end |
94 | end |
95 | |
96 | self.needsActivation = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.needsActivation#value"), false) |
97 | |
98 | if self.isClient then |
99 | self.sampleSowing = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.sowingSound", nil, self.baseDirectory) |
100 | self.sampleAirBlower = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.airBlowerSound", nil, self.baseDirectory) |
101 | |
102 | if self.sampleFill == nil then |
103 | local linkNode = Utils.indexToObject(self.components, Utils.getNoNil(getXMLString(self.xmlFile, "vehicle.fillSound#linkNode"), "0>")) |
104 | self.sampleFill = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.fillSound", nil, self.baseDirectory, linkNode) |
105 | end |
106 | self.sampleFillEnabled = false |
107 | self.sampleFillStopTime = -1 |
108 | self.lastFillLevel = -1 |
109 | |
110 | self.sowingMachineTurnedOnRotationNodes = Utils.loadRotationNodes(self.xmlFile, {}, "vehicle.turnedOnRotationNodes.turnedOnRotationNode", "sowingMachine", self.components) |
111 | self.turnedOnScrollers = Utils.loadScrollers(self.components, self.xmlFile, "vehicle.turnedOnScrollers.turnedOnScroller", {}, false) |
112 | |
113 | local changeSeedInputButtonStr = getXMLString(self.xmlFile, "vehicle.changeSeedInputButton") |
114 | if changeSeedInputButtonStr ~= nil then |
115 | self.changeSeedInputButton = InputBinding[changeSeedInputButtonStr] |
116 | end |
117 | self.changeSeedInputButton = Utils.getNoNil(self.changeSeedInputButton, InputBinding.IMPLEMENT_EXTRA3) |
118 | end |
119 | |
120 | self.lastSowingArea = 0 |
121 | self.currentSeed = 1 |
122 | self.allowsSeedChanging = not self.isSeedTank; |
123 | self.showFieldNotOwnedWarning = false |
124 | |
125 | self.isSowingSpeedLimitActive = false |
126 | |
127 | self.sowingMachine = {} |
128 | self.sowingMachine.fillUnitIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.sowingMachine#fillUnitIndex"), 1) |
129 | self.sowingMachine.unloadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.sowingMachine#unloadInfoIndex"), 1) |
130 | self.sowingMachine.loadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.sowingMachine#loadInfoIndex"), 1) |
131 | self.sowingMachine.dischargeInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.sowingMachine#dischargeInfoIndex"), 1) |
132 | |
133 | if self.fillUnits ~= nil and self.fillUnits[self.sowingMachine.fillUnitIndex] ~= nil then |
134 | self.fillUnits[self.sowingMachine.fillUnitIndex].forcedFillPlaneType = self.seeds[self.currentSeed] |
135 | end |
136 | |
137 | if self.fillUnits[self.sowingMachine.fillUnitIndex] ~= nil then |
138 | self.fillUnits[self.sowingMachine.fillUnitIndex].fillTypes[FillUtil.FILLTYPE_SEEDS] = true |
139 | end |
140 | |
141 | self.sowingMachine.supportsAiWithoutSowingMachine = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.sowingMachine#supportsAiWithoutSowingMachine"), false); |
142 | self.sowingMachine.ignoreSowingMachineAiRequirements = false; -- This is set to true in case the ai should not use the sowing machine |
143 | |
144 | self.sowingMachineGroundContactFlag = self:getNextDirtyFlag() |
145 | |
146 | if savegame ~= nil then |
147 | local selectedSeedFruitType = getXMLString(savegame.xmlFile, savegame.key.."#selectedSeedFruitType") |
148 | if selectedSeedFruitType ~= nil then |
149 | local fruitTypeDesc = FruitUtil.fruitTypes[selectedSeedFruitType] |
150 | if fruitTypeDesc ~= nil then |
151 | self:setSeedFruitType(fruitTypeDesc.index, true) |
152 | end |
153 | end |
154 | else |
155 | self:setSeedIndex(1, true) |
156 | end |
157 | end |
delete
DescriptionCalled on deletingDefinition
delete()Code
166 | function SowingMachine:delete() |
167 | if self.isClient then |
168 | SoundUtil.deleteSample(self.sampleSowing) |
169 | SoundUtil.deleteSample(self.sampleAirBlower) |
170 | SoundUtil.deleteSample(self.sampleFill) |
171 | end |
172 | end |
readStream
DescriptionCalled on client side on joinDefinition
readStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
178 | function SowingMachine:readStream(streamId, connection) |
179 | local seedIndex = streamReadUInt8(streamId) |
180 | self:setSeedIndex(seedIndex, true) |
181 | end |
writeStream
DescriptionCalled on server side on joinDefinition
writeStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
187 | function SowingMachine:writeStream(streamId, connection) |
188 | streamWriteUInt8(streamId, self.currentSeed) |
189 | end |
readUpdateStream
DescriptionCalled on on updateDefinition
readUpdateStream(integer streamId, integer timestamp, table connection)Arguments
integer | streamId | stream ID |
integer | timestamp | timestamp |
table | connection | connection |
197 | function SowingMachine:readUpdateStream(streamId, timestamp, connection) |
198 | if connection:getIsServer() then |
199 | self.sowingMachineHasGroundContact = streamReadBool(streamId) |
200 | self.showFieldNotOwnedWarning = streamReadBool(streamId) |
201 | end |
202 | 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 |
209 | function SowingMachine:writeUpdateStream(streamId, connection, dirtyMask) |
210 | if not connection:getIsServer() then |
211 | streamWriteBool(streamId, self.sowingMachineHasGroundContact) |
212 | streamWriteBool(streamId, self.showFieldNotOwnedWarning) |
213 | end |
214 | end |
getSaveAttributesAndNodes
DescriptionReturns attributes and nodes to saveDefinition
getSaveAttributesAndNodes(table nodeIdent)Arguments
table | nodeIdent | node ident |
string | attributes | attributes |
string | nodes | nodes |
221 | function SowingMachine:getSaveAttributesAndNodes(nodeIdent) |
222 | local selectedSeedFruitTypeName = "unknown" |
223 | local selectedSeedFruitType = self.seeds[self.currentSeed] |
224 | if selectedSeedFruitType ~= nil and selectedSeedFruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then |
225 | selectedSeedFruitTypeName = FruitUtil.fruitIndexToDesc[selectedSeedFruitType].name |
226 | end |
227 | local attributes = 'selectedSeedFruitType="'..selectedSeedFruitTypeName..'"' |
228 | return attributes, nil |
229 | end |
update
DescriptionCalled on updateDefinition
update(float dt)Arguments
float | dt | time since last call in ms |
240 | function SowingMachine:update(dt) |
241 | |
242 | if self:getIsActive() then |
243 | if self:getIsActiveForInput() then |
244 | if InputBinding.hasEvent(self.changeSeedInputButton) then |
245 | |
246 | if self:getIsSeedChangeAllowed() then |
247 | local seed = self.currentSeed + 1 |
248 | if seed > table.getn(self.seeds) then |
249 | seed = 1 |
250 | end |
251 | self:setSeedIndex(seed) |
252 | end |
253 | end |
254 | end |
255 | end |
256 | if self.isClient then |
257 | Utils.updateRotationNodes(self, self.sowingMachineTurnedOnRotationNodes, dt, self:getIsActive() and self:getIsTurnedOn()) |
258 | Utils.updateScrollers(self.turnedOnScrollers, dt, self:getIsActive() and self:getIsTurnedOn()) |
259 | end |
260 | end |
updateTick
DescriptionCalled on update tickDefinition
updateTick(float dt)Arguments
float | dt | time since last call in ms |
265 | function SowingMachine:updateTick(dt) |
266 | self.isSowingSpeedLimitActive = false |
267 | if self:getIsActive() then |
268 | |
269 | self.lastSowingArea = 0 |
270 | local showFieldNotOwnedWarning = false |
271 | if self.isServer then |
272 | local hasGroundContact = self:getIsTypedWorkAreaActive(WorkArea.AREATYPE_SOWINGMACHINE) |
273 | |
274 | if self.sowingMachineHasGroundContact ~= hasGroundContact then |
275 | self:raiseDirtyFlags(self.sowingMachineGroundContactFlag) |
276 | |
277 | self.sowingMachineHasGroundContact = hasGroundContact |
278 | end |
279 | end |
280 | local hasGroundContact = self.sowingMachineHasGroundContact |
281 | |
282 | local doGroundManipulation = (self.movingDirection > 0 and hasGroundContact and (not self.needsActivation or self:getIsTurnedOn())) and (not self.sowingMachine.ignoreSowingMachineAiRequirements); |
283 | |
284 | if doGroundManipulation then |
285 | local workAreas, showWarning, _ = self:getTypedNetworkAreas(WorkArea.AREATYPE_SOWINGMACHINE, true) |
286 | |
287 | self.isSowingSpeedLimitActive = true |
288 | if self.isServer then |
289 | |
290 | local hasSeeds = false |
291 | local seedVehicle = self |
292 | local seedTank = nil; |
293 | |
294 | if self:getUnitFillLevel(self.sowingMachine.fillUnitIndex) > 0 then |
295 | hasSeeds = true |
296 | else |
297 | -- try to find another attached sowingMachine |
298 | seedTank = SowingMachine.findAttachedSeedTank(self:getRootAttacherVehicle(), FillUtil.FILLTYPE_SEEDS, self.needsTankActivation) |
299 | if seedTank ~= nil then |
300 | if seedTank:getFillLevel(FillUtil.FILLTYPE_SEEDS) > 0 then |
301 | hasSeeds = true |
302 | seedVehicle = seedTank |
303 | end |
304 | end |
305 | end |
306 | |
307 | if self.requiresTank and seedTank == nil then |
308 | hasSeeds = false; |
309 | end; |
310 | |
311 | if not hasSeeds and (self:getIsHired() and g_currentMission.missionInfo.helperBuySeeds) then |
312 | hasSeeds = true |
313 | end |
314 | |
315 | if hasSeeds then |
316 | showFieldNotOwnedWarning = showWarning |
317 | |
318 | if (table.getn(workAreas) > 0) then |
319 | local seedsFruitType = self.seeds[self.currentSeed] |
320 | local dx,_,dz = localDirectionToWorld(self.sowingDirectionNode, 0, 0, 1) |
321 | |
322 | local angleRad = Utils.getYRotationFromDirection(dx, dz) |
323 | local desc = FruitUtil.fruitIndexToDesc[seedsFruitType] |
324 | if desc ~= nil and desc.directionSnapAngle ~= 0 then |
325 | angleRad = math.floor(angleRad / desc.directionSnapAngle + 0.5) * desc.directionSnapAngle |
326 | end |
327 | |
328 | local angle = Utils.convertToDensityMapAngle(angleRad, g_currentMission.terrainDetailAngleMaxValue) |
329 | |
330 | local area, detailArea = self:processSowingMachineAreas(workAreas, seedsFruitType, angle, self.useDirectPlanting) |
331 | if area > 0 or detailArea > 0 then |
332 | if area > 0 then |
333 | local fruitDesc = FruitUtil.fruitIndexToDesc[seedsFruitType] |
334 | self.lastSowingArea = Utils.areaToHa(area, g_currentMission:getFruitPixelsToSqm()) |
335 | local usage = fruitDesc.seedUsagePerSqm * self.lastSowingArea * 10000 |
336 | |
337 | g_currentMission.missionStats:updateStats("seedUsage", usage) |
338 | g_currentMission.missionStats:updateStats("sownHectares", self.lastSowingArea) |
339 | g_currentMission.missionStats:updateStats("workedHectares", self.lastSowingArea) |
340 | |
341 | if not self:getIsHired() or not g_currentMission.missionInfo.helperBuySeeds then |
342 | local oldFillLevel = seedVehicle:getFillLevel(FillUtil.FILLTYPE_SEEDS) |
343 | local fillInfos = seedVehicle.fillVolumeUnloadInfos[seedVehicle.sowingMachine.unloadInfoIndex] |
344 | seedVehicle:setFillLevel(oldFillLevel - usage, FillUtil.FILLTYPE_SEEDS, fillInfos) |
345 | else |
346 | local price = usage * g_currentMission.economyManager:getCostPerLiter(FillUtil.FILLTYPE_SEEDS) * 1.5 -- increase price if AI is active to reward the player's manual work |
347 | g_currentMission.missionStats:updateStats("expenses", price) |
348 | g_currentMission:addSharedMoney(-price, "purchaseSeeds") |
349 | end |
350 | end |
351 | end |
352 | end |
353 | else |
354 | if self:getIsHired() then |
355 | local rootVehicle = self:getRootAttacherVehicle() |
356 | rootVehicle:stopAIVehicle(AIVehicle.STOP_REASON_OUT_OF_FILL) |
357 | end |
358 | end |
359 | end |
360 | |
361 | -- remove tireTracks |
362 | for _, workArea in pairs(workAreas) do |
363 | Utils.eraseTireTrack(workArea[1], workArea[2], workArea[3], workArea[4], workArea[5], workArea[6]) |
364 | end |
365 | |
366 | g_currentMission.missionStats:updateStats("sownTime", dt/(1000*60)) |
367 | g_currentMission.missionStats:updateStats("workedTime", dt/(1000*60)) |
368 | end |
369 | |
370 | if self.isClient then |
371 | if doGroundManipulation and self:getLastSpeed() > 3 then |
372 | if self:getIsActiveForSound() then |
373 | SoundUtil.playSample(self.sampleSowing, 0, 0, nil) |
374 | end |
375 | else |
376 | SoundUtil.stopSample(self.sampleSowing) |
377 | end |
378 | |
379 | if self:getIsTurnedOn() and self:getIsActiveForSound() then |
380 | SoundUtil.playSample(self.sampleAirBlower, 0, 0, nil) |
381 | end |
382 | end |
383 | |
384 | if self.isServer then |
385 | if showFieldNotOwnedWarning ~= self.showFieldNotOwnedWarning then |
386 | self.showFieldNotOwnedWarning = showFieldNotOwnedWarning |
387 | self:raiseDirtyFlags(self.sowingMachineGroundContactFlag) |
388 | end |
389 | end |
390 | end |
391 | |
392 | if self.isClient then |
393 | if self.isFilling then |
394 | if self:getIsActiveForSound(true) then |
395 | SoundUtil.playSample(self.sampleFill, 0, 0, nil) |
396 | SoundUtil.stop3DSample(self.sampleFill) |
397 | else |
398 | SoundUtil.stopSample(self.sampleFill) |
399 | SoundUtil.play3DSample(self.sampleFill) |
400 | end |
401 | else |
402 | SoundUtil.stopSample(self.sampleFill) |
403 | SoundUtil.stop3DSample(self.sampleFill) |
404 | end |
405 | end |
406 | end |
draw
DescriptionCalled on drawDefinition
draw()Code
410 | function SowingMachine:draw() |
411 | |
412 | if self.isClient then |
413 | if self:getIsActiveForInput(true) then |
414 | if self:getIsSeedChangeAllowed() and table.getn(self.seeds) > 1 then |
415 | g_currentMission:addHelpButtonText(g_i18n:getText("action_chooseSeed"), self.changeSeedInputButton, nil, GS_PRIO_HIGH) |
416 | end |
417 | end |
418 | |
419 | --g_currentMission:setFruitOverlayFruitType(self.seeds[self.currentSeed]) |
420 | |
421 | if self.showFieldNotOwnedWarning then |
422 | g_currentMission:showBlinkingWarning(g_i18n:getText("warning_youDontOwnThisField")) |
423 | end |
424 | end |
425 | end |
getDrawFirstFillText
DescriptionReturns if 'first fill tool' text should be drawedDefinition
getDrawFirstFillText()Return Values
boolean | draw | draw text |
430 | function SowingMachine:getDrawFirstFillText(superFunc) |
431 | if self.isClient then |
432 | if self:getIsActiveForInput(true) then |
433 | if self:getUnitFillLevel(self.sowingMachine.fillUnitIndex) <= 0 and self:getUnitCapacity(self.sowingMachine.fillUnitIndex) ~= 0 then |
434 | return true |
435 | end |
436 | end |
437 | end |
438 | if superFunc ~= nil then |
439 | return superFunc(self) |
440 | end |
441 | |
442 | return false |
443 | end |
onAttach
DescriptionCalled if vehicle gets attachedDefinition
onAttach(table attacherVehicle)Arguments
table | attacherVehicle | attacher vehicle |
448 | function SowingMachine:onAttach(attacherVehicle) |
449 | SowingMachine.onActivate(self) |
450 | end |
onEnter
DescriptionCalled on enter vehicleDefinition
onEnter(boolean isControlling)Arguments
boolean | isControlling | is player controlling the vehicle |
455 | function SowingMachine:onEnter(isControlling) |
456 | if isControlling then |
457 | SowingMachine.onActivate(self) |
458 | end |
459 | end |
onDeactivate
DescriptionCalled on deactivateDefinition
onDeactivate()Code
466 | function SowingMachine:onDeactivate() |
467 | self.showFieldNotOwnedWarning = false |
468 | end |
getIsTurnedOnAllowed
DescriptionReturns if turn on is allowedDefinition
getIsTurnedOnAllowed(boolean isTurnedOn)Arguments
boolean | isTurnedOn | is turned on |
boolean | allow | allow turn on |
474 | function SowingMachine:getIsTurnedOnAllowed(superFunc, isTurnedOn) |
475 | if not self.needsActivation then |
476 | return false |
477 | end |
478 | |
479 | if isTurnedOn and self:getUnitFillLevel(self.sowingMachine.fillUnitIndex) <= 0 then |
480 | if self:getUnitCapacity(self.sowingMachine.fillUnitIndex) > 0 and not self:getIsHired() then |
481 | local seedTank = SowingMachine.findAttachedSeedTank(self:getRootAttacherVehicle(), FillUtil.FILLTYPE_SEEDS, self.needsTankActivation) |
482 | if seedTank ~= nil then |
483 | if seedTank:getFillLevel(FillUtil.FILLTYPE_SEEDS) <= 0 then |
484 | seedTank = nil; |
485 | end; |
486 | end; |
487 | |
488 | if seedTank == nil then |
489 | return false |
490 | end; |
491 | end |
492 | end |
493 | |
494 | if superFunc ~= nil then |
495 | return superFunc(self, isTurnedOn) |
496 | end |
497 | |
498 | return true |
499 | end |
onTurnedOff
DescriptionCalled on turn offDefinition
onTurnedOff(boolean noEventSend)Arguments
boolean | noEventSend | no event send |
504 | function SowingMachine:onTurnedOff(noEventSend) |
505 | if self.isClient then |
506 | SoundUtil.stopSample(self.sampleAirBlower) |
507 | end |
508 | end |
onDeactivateSounds
DescriptionCalled on deactivating soundsDefinition
onDeactivateSounds()Code
512 | function SowingMachine:onDeactivateSounds() |
513 | if self.isClient then |
514 | SoundUtil.stopSample(self.sampleSowing, true) |
515 | SoundUtil.stopSample(self.sampleAirBlower, true) |
516 | end |
517 | end |
setSeedIndex
DescriptionChange selected seedDefinition
setSeedIndex(integer seedIndex, boolean noEventSend)Arguments
integer | seedIndex | new seed index |
boolean | noEventSend | no event send |
523 | function SowingMachine:setSeedIndex(seedIndex, noEventSend) |
524 | SowingMachineSetSeedIndex.sendEvent(self, seedIndex, noEventSend) |
525 | self.currentSeed = math.min(math.max(seedIndex, 1), table.getn(self.seeds)) |
526 | SowingMachine.updateAiParameters(self) |
527 | end |
setSeedFruitType
DescriptionSet selected seed by fruit type indexDefinition
setSeedFruitType(integer fruitType, boolean noEventSend)Arguments
integer | fruitType | index of fruit type |
boolean | noEventSend | no event send |
584 | function SowingMachine:setSeedFruitType(fruitType, noEventSend) |
585 | for i,v in ipairs(self.seeds) do |
586 | if v == fruitType then |
587 | self:setSeedIndex(i, noEventSend) |
588 | break |
589 | end |
590 | end |
591 | end |
onAiTurnOn
DescriptionCalled on ai turn onDefinition
onAiTurnOn()Code
595 | function SowingMachine:onAiTurnOn() |
596 | if self.sowingMachine.supportsAiWithoutSowingMachine then |
597 | if SpecializationUtil.hasSpecialization(Cultivator, self.specializations) or |
598 | SpecializationUtil.hasSpecialization(Weeder, self.specializations) |
599 | then |
600 | -- Don't use the sowing machine, when turning on the helper while the sowing machine is not turned on |
601 | self.sowingMachine.ignoreSowingMachineAiRequirements = self.sowingMachine.ignoreSowingMachineAiRequirements or not self:getIsTurnedOn(); |
602 | SowingMachine.updateAiParameters(self); |
603 | end |
604 | end |
605 | self:setIsTurnedOn(true, true) |
606 | end |
onAiTurnOff
DescriptionCalled on ai turn offDefinition
onAiTurnOff()Code
610 | function SowingMachine:onAiTurnOff() |
611 | self:setIsTurnedOn(false, true) |
612 | if self.sowingMachine.supportsAiWithoutSowingMachine then |
613 | self.sowingMachine.ignoreSowingMachineAiRequirements = false; |
614 | SowingMachine.updateAiParameters(self); |
615 | end |
616 | end |
onAiLower
DescriptionCalled on ai lowerDefinition
onAiLower()Code
620 | function SowingMachine:onAiLower() |
621 | self:setIsTurnedOn(true, true) |
622 | end |
onAiRaise
DescriptionCalled on ai raiseDefinition
onAiRaise()Code
626 | function SowingMachine:onAiRaise() |
627 | end |
findAttachedSeedTank
DescriptionSearches for attached tanksDefinition
findAttachedSeedTank(table currentVehicle, integer fillType, boolean needsActivation)Arguments
table | currentVehicle | current vehicle to check |
integer | fillType | fill type |
boolean | needsActivation | tank has to be turned on |
table | attachedSeedTank | attached seed tank |
635 | function SowingMachine.findAttachedSeedTank(currentVehicle, fillType, needsTankActivation, ignoreFillLevel) |
636 | if currentVehicle.isSeedTank and currentVehicle.getFillLevel ~= nil and currentVehicle.setFillLevel ~= nil and (currentVehicle:getFillLevel(fillType) > 0 or ignoreFillLevel) and (not needsTankActivation or (currentVehicle.getIsTurnedOn ~= nil and currentVehicle:getIsTurnedOn())) then |
637 | return currentVehicle |
638 | end |
639 | for _,implement in pairs(currentVehicle.attachedImplements) do |
640 | if implement.object ~= nil then |
641 | local ret = SowingMachine.findAttachedSeedTank(implement.object, fillType, needsTankActivation, ignoreFillLevel) |
642 | if ret ~= nil then |
643 | return ret |
644 | end |
645 | end |
646 | end |
647 | return nil |
648 | end |
getAllowFillFromAir
DescriptionReturns if fill from air is allowedDefinition
getAllowFillFromAir()Return Values
boolean | isAllowed | fill from air is allowed |
653 | function SowingMachine:getAllowFillFromAir(superFunc) |
654 | if self:getIsTurnedOn() and not self.allowFillFromAirWhileTurnedOn then |
655 | return false |
656 | end |
657 | return superFunc(self) |
658 | end |
getDirectionSnapAngle
DescriptionReturns direction snap angleDefinition
getDirectionSnapAngle()Return Values
float | directionSnapAngle | direction snap angle |
663 | function SowingMachine:getDirectionSnapAngle(superFunc) |
664 | local seedsFruitType = self.seeds[self.currentSeed] |
665 | local desc = FruitUtil.fruitIndexToDesc[seedsFruitType] |
666 | local snapAngle = 0 |
667 | if desc ~= nil then |
668 | snapAngle = desc.directionSnapAngle |
669 | end |
670 | return math.max(snapAngle, superFunc(self)) |
671 | 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 |
677 | function SowingMachine:resetFillLevelIfNeeded(superFunc, fillType) |
678 | return false; |
679 | 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 |
686 | function SowingMachine:resetUnitFillLevelIfNeeded(superFunc, fillUnitIndex, fillType) |
687 | return false; |
688 | 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 |
695 | function SowingMachine:allowFillType(superFunc, fillType, allowEmptying) |
696 | if fillType == FillUtil.FILLTYPE_UNKNOWN then |
697 | return true; |
698 | end |
699 | for i,fillUnit in pairs(self.fillUnits) do |
700 | if fillUnit.fillTypes[fillType] then |
701 | return true; |
702 | end |
703 | end |
704 | return false; |
705 | 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 |
713 | function SowingMachine:allowUnitFillType(superFunc, fillUnitIndex, fillType, allowEmptying) |
714 | if self.fillUnits == nil or self.fillUnits[fillUnitIndex] == nil then |
715 | return false; |
716 | end |
717 | local fillUnit = self.fillUnits[fillUnitIndex]; |
718 | if fillUnit.fillTypes[fillType] then |
719 | return true; |
720 | end |
721 | return false; |
722 | 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 |
731 | function SowingMachine:setUnitFillLevel(superFunc, fillUnitIndex, fillLevel, fillType, force, fillInfo) |
732 | if fillUnitIndex == self.sowingMachine.fillUnitIndex then |
733 | -- convert everything to seeds if it is accepted |
734 | if self:allowUnitFillType(fillUnitIndex, fillType, false) then |
735 | fillType = FillUtil.FILLTYPE_SEEDS |
736 | self.fillUnits[fillUnitIndex].forcedFillPlaneType = FillUtil.FILLTYPE_SEEDS |
737 | end |
738 | |
739 | -- switch from seeds to 'fill type', if possible |
740 | local fruitType = self.seeds[self.currentSeed] |
741 | if fruitType ~= nil then |
742 | local seedsFillType = FruitUtil.fruitTypeToFillType[fruitType] |
743 | if seedsFillType ~= nil then |
744 | if self:allowUnitFillType(fillUnitIndex, seedsFillType, false) then |
745 | self.fillUnits[fillUnitIndex].forcedFillPlaneType = seedsFillType |
746 | end |
747 | end |
748 | end |
749 | |
750 | end |
751 | |
752 | superFunc(self, fillUnitIndex, fillLevel, fillType, force, fillInfo) |
753 | end |
doCheckSpeedLimit
DescriptionReturns if speed limit should be checkedDefinition
doCheckSpeedLimit()Return Values
boolean | checkSpeedlimit | check speed limit |
758 | function SowingMachine:doCheckSpeedLimit(superFunc) |
759 | local parent = false |
760 | if superFunc ~= nil then |
761 | parent = superFunc(self) |
762 | end |
763 | |
764 | return parent or self.isSowingSpeedLimitActive |
765 | end |
getDirtMultiplier
DescriptionReturns current dirt multiplierDefinition
getDirtMultiplier()Return Values
float | dirtMultiplier | current dirt multiplier |
770 | function SowingMachine:getDirtMultiplier(superFunc) |
771 | local multiplier = 0 |
772 | if superFunc ~= nil then |
773 | multiplier = multiplier + superFunc(self) |
774 | end |
775 | |
776 | if self.movingDirection > 0 and self.sowingMachineHasGroundContact and (not self.needsActivation or self:getIsTurnedOn()) then |
777 | multiplier = multiplier + self.workMultiplier * self:getLastSpeed() / self.speedLimit |
778 | end |
779 | |
780 | return multiplier |
781 | end |
loadWorkAreaFromXML
DescriptionLoads work areas from xmlDefinition
loadWorkAreaFromXML(table workArea, integer xmlFile, string key)Arguments
table | workArea | workArea |
integer | xmlFile | id of xml object |
string | key | key |
boolean | success | success |
789 | function SowingMachine:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key) |
790 | local retValue = true |
791 | if superFunc ~= nil then |
792 | retValue = superFunc(self, workArea, xmlFile, key) |
793 | end |
794 | |
795 | if workArea.type == WorkArea.AREATYPE_DEFAULT then |
796 | workArea.type = WorkArea.AREATYPE_SOWINGMACHINE |
797 | end |
798 | |
799 | return retValue |
800 | end |
getDefaultSpeedLimit
DescriptionReturns default speed limitDefinition
getDefaultSpeedLimit()Return Values
float | speedLimit | speed limit |
805 | function SowingMachine.getDefaultSpeedLimit() |
806 | return 15 |
807 | end |
processSowingMachineAreas
DescriptionProcess sowing machine areasDefinition
processSowingMachineAreas(table workAreas, integer seed, float angle, boolean useDirectPlanting)Arguments
table | workAreas | work areas |
integer | seed | seed type |
float | angle | current angle |
boolean | useDirectPlanting | use direction planting |
float | area | area changed |
float | densityArea | density area changed |
817 | function SowingMachine:processSowingMachineAreas(workAreas, seed, angle, useDirectPlanting) |
818 | local area = 0 |
819 | local densityArea = 0 |
820 | local numAreas = table.getn(workAreas) |
821 | for i=1, numAreas do |
822 | local x = workAreas[i][1] |
823 | local z = workAreas[i][2] |
824 | local x1 = workAreas[i][3] |
825 | local z1 = workAreas[i][4] |
826 | local x2 = workAreas[i][5] |
827 | local z2 = workAreas[i][6] |
828 | |
829 | local areaI, densityAreaI |
830 | |
831 | if not useDirectPlanting then |
832 | areaI, densityAreaI = Utils.updateSowingArea(seed, x, z, x1, z1, x2, z2, angle, useDirectPlanting) |
833 | else |
834 | areaI, densityAreaI = Utils.updateDirectSowingArea(seed, x, z, x1, z1, x2, z2, angle, 1); |
835 | end |
836 | area = area + areaI |
837 | densityArea = densityArea + densityAreaI |
838 | end |
839 | return area, densityArea |
840 | end |
getFillLevelInformation
DescriptionAdded fill level information to display it on the hudDefinition
getFillLevelInformation(table fillLevelInformations)Arguments
table | fillLevelInformations | table to add the informations |
845 | function SowingMachine:getFillLevelInformation(superFunc, fillLevelInformations) |
846 | if self.fillUnits ~= nil then |
847 | for fillUnitIndex,fillUnit in pairs(self.fillUnits) do |
848 | if fillUnit.showOnHud then |
849 | -- info for seed type |
850 | local fillType = fillUnit.currentFillType |
851 | local fillLevel = fillUnit.fillLevel; |
852 | local capacity = fillUnit.capacity; |
853 | |
854 | if fillUnitIndex == self.sowingMachine.fillUnitIndex then |
855 | local fruitType = self.seeds[self.currentSeed] |
856 | fillType = FruitUtil.fruitTypeToFillType[fruitType] |
857 | |
858 | -- add fill level from attached seed tank |
859 | if not self.isSeedTank then |
860 | local seedTank = SowingMachine.findAttachedSeedTank(self:getRootAttacherVehicle(), FillUtil.FILLTYPE_SEEDS, self.needsTankActivation, true) |
861 | if seedTank ~= nil then |
862 | fillLevel = fillLevel + seedTank:getUnitFillLevel(seedTank.sowingMachine.fillUnitIndex); |
863 | capacity = capacity + seedTank:getUnitCapacity(seedTank.sowingMachine.fillUnitIndex); |
864 | end; |
865 | end; |
866 | end |
867 | |
868 | -- default info for sprayer, if empty |
869 | if fillUnit.fillLevel == 0 and self.sprayer ~= nil and fillUnitIndex == self.sprayer.fillUnitIndex and self.sprayer.fillUnitIndex ~= self.sowingMachine.fillUnitIndex then |
870 | for fType,state in pairs(fillUnit.fillTypes) do |
871 | if state then |
872 | fillType = fType |
873 | break |
874 | end |
875 | end |
876 | end |
877 | |
878 | local added = false |
879 | for _,fillLevelInformation in pairs(fillLevelInformations) do |
880 | if fillLevelInformation.fillType == fillType then |
881 | fillLevelInformation.fillLevel = fillLevelInformation.fillLevel + fillLevel |
882 | fillLevelInformation.capacity = fillLevelInformation.capacity + capacity |
883 | added = true |
884 | break |
885 | end |
886 | end |
887 | if not added then |
888 | table.insert(fillLevelInformations, {fillType=fillType, fillLevel=fillLevel, capacity=capacity}) |
889 | end |
890 | end; |
891 | end |
892 | end |
893 | |
894 | for _, implement in pairs(self.attachedImplements) do |
895 | if implement.object ~= nil then |
896 | implement.object:getFillLevelInformation(fillLevelInformations) |
897 | end |
898 | end |
899 | end |
getIsSeedChangeAllowed
DescriptionReturns if seed change is allowedDefinition
getIsSeedChangeAllowed()Return Values
boolean | isAllowed | seed change is allowed |
904 | function SowingMachine:getIsSeedChangeAllowed() |
905 | if self.getCanBeTurnedOn ~= nil and self:getCanBeTurnedOn() then |
906 | return (not self:getIsTurnedOn()) and self.allowsSeedChanging |
907 | end |
908 | return self.allowsSeedChanging |
909 | end |
loadSpecValueSeedFillTypes
DescriptionLoads seed fruit type categories and seed fruit types spec valueDefinition
loadSpecValueSeedFillTypes(integer xmlFile, string customEnvironment)Arguments
integer | xmlFile | id of xml object |
string | customEnvironment | custom environment |
table | specValue | [categories, names] |
916 | function SowingMachine.loadSpecValueSeedFillTypes(xmlFile, customEnvironment) |
917 | local categories = Utils.getNoNil(getXMLString(xmlFile, "vehicle.storeData.specs.seedFruitTypeCategories"), getXMLString(xmlFile, "vehicle.seedFruitTypeCategories")) |
918 | local names = Utils.getNoNil(getXMLString(xmlFile, "vehicle.storeData.specs.seedFruitTypes"), getXMLString(xmlFile, "vehicle.seedFruitTypes")) |
919 | |
920 | return {categories=categories, names=names} |
921 | end |
getSpecValueSeedFillTypes
DescriptionReturns seed fill types spec valueDefinition
getSpecValueSeedFillTypes(table storeItem, table realItem)Arguments
table | storeItem | store item |
table | realItem | real item |
table | fruitTypes | fruit types |
928 | function SowingMachine.getSpecValueSeedFillTypes(storeItem, realItem) |
929 | local fruitTypes = nil |
930 | |
931 | if storeItem.specs.seedFillTypes ~= nil then |
932 | local fruits = storeItem.specs.seedFillTypes |
933 | if fruits.categories ~= nil and fruits.names == nil then |
934 | fruitTypes = FillUtil.getFillTypesByFruitTypeCategoryName(fruits.categories, nil) |
935 | elseif fruits.categories == nil and fruits.names ~= nil then |
936 | fruitTypes = FillUtil.getFillTypesByFruitTypeNames(fruits.names, nil) |
937 | end |
938 | if fruitTypes ~= nil then |
939 | return fruitTypes |
940 | end |
941 | end |
942 | |
943 | return nil |
944 | end |