Script v1.7.1.0
- AI
- Animals
- Contracts
- Debug
- Economy
- Effects
- Events
- Farms
- GUI
- Handtools
- I3d
- Materials
- Misc
- Objects
- Placeables
- Player
- Shop
- Sounds
- Specializations
- AIConveyorBelt
- AIImplement
- AIVehicle
- AnimatedVehicle
- ArticulatedAxis
- Attachable
- AttacherJointControl
- AttacherJoints
- BaleGrab
- BaleLoader
- Baler
- BaleWrapper
- BaseMaterial
- BunkerSiloCompacter
- BunkerSiloInteractor
- BuyableBale
- CCTDrivable
- Combine
- ConnectionHoses
- ConveyorBelt
- Cover
- CrabSteering
- Crawlers
- Cultivator
- Cutter
- Cylindered
- CylinderedFoldable
- Dashboard
- Dischargeable
- Drivable
- DynamicallyLoadedParts
- DynamicMountAttacher
- Enterable
- FertilizingCultivator
- FertilizingSowingMachine
- FillTriggerVehicle
- FillUnit
- FillVolume
- Foldable
- FoliageBending
- ForageWagon
- FrontloaderAttacher
- FruitPreparer
- GroundAdjustedNodes
- GroundReference
- Honk
- HookLiftContainer
- HookLiftTrailer
- IKChains
- JigglingParts
- Leveler
- Lights
- LivestockTrailer
- Locomotive
- LogGrab
- ManureBarrel
- MixerWagon
- Motorized
- Mountable
- Mower
- Pickup
- Pipe
- Plow
- PowerConsumer
- PowerTakeOffs
- RandomlyMovingParts
- ReceivingHopper
- ReverseDriving
- Rideable
- RidgeMarker
- Roller
- Ropes
- SemiTrailerFront
- Shovel
- SlopeCompensation
- SmartAttach
- SowingMachine
- SpeedRotatingParts
- SplineVehicle
- Sprayer
- StrawBlower
- StumpCutter
- Suspensions
- Tedder
- TensionBeltObject
- TensionBelts
- TipOccluder
- Trailer
- TreePlanter
- TreeSaw
- TurnOnVehicle
- Washable
- WaterTrailer
- Wearable
- Weeder
- Wheels
- Windrower
- Wipers
- WoodCrusher
- WoodHarvester
- WorkArea
- WorkMode
- WorkParticles
- Triggers
- Utils
- Vehicles
- Weather
Engine v1.7.1.0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- XML
- general
Foundation Reference
Windrower
DescriptionSpecialization for windrowers providing additional animations, effects and drop area functionalitiesFunctions
- doCheckSpeedLimit
- getDefaultSpeedLimit
- getDirtMultiplier
- getWearMultiplier
- initSpecialization
- loadRakeFromXML
- loadWorkAreaFromXML
- onDeactivate
- onDelete
- onEndWorkAreaProcessing
- onLoad
- onPostLoad
- onReadStream
- onReadUpdateStream
- onStartWorkAreaProcessing
- onTurnedOff
- onTurnedOn
- onUpdateTick
- onWriteStream
- onWriteUpdateStream
- prerequisitesPresent
- processDropArea
- processWindrowerArea
- registerEventListeners
- registerFunctions
- registerOverwrittenFunctions
- updateRake
doCheckSpeedLimit
DescriptionDefinitiondoCheckSpeedLimit()Code
318 | function Windrower:doCheckSpeedLimit(superFunc) |
319 | local turnOn = true |
320 | if self.getIsTurnedOn ~= nil then |
321 | turnOn = self:getIsTurnedOn() |
322 | end |
323 | |
324 | return superFunc(self) or (self:getIsImplementChainLowered() and turnOn) |
325 | end |
getDefaultSpeedLimit
DescriptionDefinitiongetDefaultSpeedLimit()Code
394 | function Windrower.getDefaultSpeedLimit() |
395 | return 15 |
396 | end |
getDirtMultiplier
DescriptionDefinitiongetDirtMultiplier()Code
429 | function Windrower:getDirtMultiplier(superFunc) |
430 | local spec = self.spec_windrower |
431 | |
432 | local multiplier = superFunc(self) |
433 | |
434 | if spec.isWorking then |
435 | multiplier = multiplier + self:getWorkDirtMultiplier() * self:getLastSpeed() / self.speedLimit |
436 | end |
437 | |
438 | return multiplier |
439 | end |
getWearMultiplier
DescriptionDefinitiongetWearMultiplier()Code
443 | function Windrower:getWearMultiplier(superFunc) |
444 | local spec = self.spec_windrower |
445 | |
446 | local multiplier = superFunc(self) |
447 | |
448 | if spec.isWorking then |
449 | multiplier = multiplier + self:getWorkWearMultiplier() * self:getLastSpeed() / self.speedLimit |
450 | end |
451 | |
452 | return multiplier |
453 | end |
initSpecialization
DescriptionDefinitioninitSpecialization()Code
15 | function Windrower.initSpecialization() |
16 | g_workAreaTypeManager:addWorkAreaType("windrower", false) |
17 | end |
loadRakeFromXML
DescriptionDefinitionloadRakeFromXML()Code
329 | function Windrower:loadRakeFromXML(rake, xmlFile, key, index) |
330 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, key.."#index", key.."#node") --FS17 to FS19 |
331 | |
332 | rake.node = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, key.."#node"), self.i3dMappings) |
333 | rake.spikes = {} |
334 | rake.maxRotZ = math.rad(getXMLFloat(xmlFile, key.."#spikeMaxRotZ")) |
335 | rake.dir = Utils.getNoNil(getXMLInt(xmlFile, key.."#dir"), 1) |
336 | |
337 | local moveUpRange = StringUtil.getRadiansFromString(getXMLString(xmlFile, key.."#moveUpRange"), 2) |
338 | local moveDownRange = StringUtil.getRadiansFromString(getXMLString(xmlFile, key.."#moveDownRange"), 2) |
339 | rake.moveUpStart = moveUpRange[1] |
340 | rake.moveUpEnd = moveUpRange[2] |
341 | rake.moveDownStart = moveDownRange[1] |
342 | rake.moveDownEnd = moveDownRange[2] |
343 | |
344 | local j = 0 |
345 | while true do |
346 | local spikeKey = string.format(key..".spike(%d)", j) |
347 | if not hasXMLProperty(xmlFile, spikeKey) then |
348 | break |
349 | end |
350 | |
351 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, spikeKey.."#index", spikeKey.."#node") --FS17 to FS19 |
352 | |
353 | local spike = {} |
354 | spike.node = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, spikeKey.."#node"), self.i3dMappings) |
355 | spike.dir = Utils.getNoNil(getXMLInt(xmlFile, spikeKey.."#dir"), 1) |
356 | local _,y,_ = getRotation(getParent(spike.node)) |
357 | spike.yRotOffset = y |
358 | table.insert(rake.spikes, spike) |
359 | j = j + 1 |
360 | end |
361 | |
362 | rake.yRotOffset = (2*math.pi) / #rake.spikes |
363 | |
364 | return true |
365 | end |
loadWorkAreaFromXML
DescriptionDefinitionloadWorkAreaFromXML()Code
400 | function Windrower:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key) |
401 | local retValue = superFunc(self, workArea, xmlFile, key) |
402 | |
403 | if workArea.type == WorkAreaType.DEFAULT then |
404 | workArea.type = WorkAreaType.WINDROWER |
405 | end |
406 | |
407 | if workArea.type == WorkAreaType.WINDROWER then |
408 | workArea.particleSystemIndex = getXMLInt(xmlFile, key .. ".windrower#particleSystemIndex") |
409 | workArea.dropWindrowWorkAreaIndex = Utils.getNoNil(getXMLInt(xmlFile, key .. ".windrower#dropWindrowWorkAreaIndex"), 1) |
410 | |
411 | workArea.lastValidPickupFruitType = FruitType.UNKNOWN |
412 | workArea.lastPickupLiters = 0 |
413 | workArea.lastDroppedLiters = 0 |
414 | workArea.litersToDrop = 0 |
415 | |
416 | local spec = self.spec_windrower |
417 | if spec.windrowerWorkAreaFillTypes == nil then |
418 | spec.windrowerWorkAreaFillTypes = {} |
419 | end |
420 | table.insert(spec.windrowerWorkAreaFillTypes, FruitType.UNKNOWN) |
421 | workArea.windrowerWorkAreaIndex = #spec.windrowerWorkAreaFillTypes |
422 | end |
423 | |
424 | return retValue |
425 | end |
onDeactivate
DescriptionDefinitiononDeactivate()Code
302 | function Windrower:onDeactivate() |
303 | if self.isClient then |
304 | local spec = self.spec_windrower |
305 | for _, effect in ipairs(spec.effects) do |
306 | g_effectManager:stopEffects(effect.effects) |
307 | end |
308 | |
309 | if self.getIsTurnedOn == nil then |
310 | g_soundManager:stopSample(spec.samples.work) |
311 | spec.isWorking = false |
312 | end |
313 | end |
314 | end |
onDelete
DescriptionDefinitiononDelete()Code
156 | function Windrower:onDelete() |
157 | local spec = self.spec_windrower |
158 | if self.isClient then |
159 | for _,sample in pairs(spec.samples) do |
160 | g_soundManager:deleteSample(sample) |
161 | end |
162 | g_animationManager:deleteAnimations(spec.animationNodes) |
163 | |
164 | for _, effect in ipairs(spec.effects) do |
165 | g_effectManager:deleteEffects(effect.effects) |
166 | end |
167 | end |
168 | end |
onEndWorkAreaProcessing
DescriptionDefinitiononEndWorkAreaProcessing()Code
469 | function Windrower:onEndWorkAreaProcessing(dt, workAreas) |
470 | local spec = self.spec_windrower |
471 | |
472 | if self.isClient then |
473 | if self.getIsTurnedOn == nil then |
474 | if spec.isWorking then |
475 | if not g_soundManager:getIsSamplePlaying(spec.samples.work) then |
476 | g_soundManager:playSample(spec.samples.work) |
477 | end |
478 | else |
479 | if g_soundManager:getIsSamplePlaying(spec.samples.work) then |
480 | g_soundManager:stopSample(spec.samples.work) |
481 | end |
482 | end |
483 | end |
484 | end |
485 | end |
onLoad
DescriptionDefinitiononLoad()Code
62 | function Windrower:onLoad(savegame) |
63 | local spec = self.spec_windrower |
64 | |
65 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.animation", "vehicle.windrowers.windrower") --FS13 to FS15 |
66 | |
67 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.windrowers.windrower", "vehicle.windrower.rakes.rake") --FS17 to FS19 |
68 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.windrowerParticleSystems", "vehicle.windrower.effects") --FS17 to FS19 |
69 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.turnedOnRotationNodes.turnedOnRotationNode#type", "vehicle.windrower.animationNodes.animationNode", "windrower") --FS17 to FS19 |
70 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, self.configFileName, "vehicle.windrowerSound", "vehicle.windrower.sounds.work") --FS17 to FS19 |
71 | |
72 | if self.isClient then |
73 | spec.animationNodes = g_animationManager:loadAnimations(self.xmlFile, "vehicle.windrower.animationNodes", self.components, self, self.i3dMappings) |
74 | |
75 | spec.effects = {} |
76 | spec.workAreaToEffects = {} |
77 | local i = 0 |
78 | while true do |
79 | local key = string.format("vehicle.windrower.effects.effect(%d)", i) |
80 | if not hasXMLProperty(self.xmlFile, key) then |
81 | break |
82 | end |
83 | local effects = g_effectManager:loadEffect(self.xmlFile, key, self.components, self, self.i3dMappings) |
84 | if effects ~= nil then |
85 | local effect = {} |
86 | effect.effects = effects |
87 | effect.workAreaIndex = Utils.getNoNil(getXMLInt(self.xmlFile, key .. "#workAreaIndex"), 1) |
88 | effect.activeTime = -1 |
89 | effect.activeTimeDuration = 250 |
90 | effect.isActive = false |
91 | effect.isActiveSent = false |
92 | table.insert(spec.effects, effect) |
93 | end |
94 | i = i + 1 |
95 | end |
96 | |
97 | spec.rakes = {} |
98 | local i = 0 |
99 | while true do |
100 | local key = string.format("vehicle.windrower.rakes.rake(%d)", i) |
101 | if not hasXMLProperty(self.xmlFile, key) then |
102 | break |
103 | end |
104 | |
105 | local rake = {} |
106 | if self:loadRakeFromXML(rake, self.xmlFile, key, i) then |
107 | table.insert(spec.rakes, rake) |
108 | self:updateRake(rake) |
109 | end |
110 | |
111 | i = i + 1 |
112 | end |
113 | |
114 | spec.samples = {} |
115 | spec.samples.work = g_soundManager:loadSampleFromXML(self.xmlFile, "vehicle.windrower.sounds", "work", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
116 | end |
117 | |
118 | spec.isWorking = false |
119 | spec.limitToLineHeight = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.windrower#limitToLineHeight"), false) |
120 | |
121 | spec.fillTypesDirtyFlag = self:getNextDirtyFlag() |
122 | spec.effectDirtyFlag = self:getNextDirtyFlag() |
123 | |
124 | if self.addAIFruitRequirement ~= nil then |
125 | self:addAIFruitRequirement(FruitType.GRASS, 0, g_currentMission.terrainDetailHeightTypeNumChannels) |
126 | self:addAIFruitRequirement(FruitType.DRYGRASS, 0, g_currentMission.terrainDetailHeightTypeNumChannels) |
127 | self:addAIFruitRequirement(FruitType.WHEAT, 0, g_currentMission.terrainDetailHeightTypeNumChannels) |
128 | self:addAIFruitRequirement(FruitType.BARLEY, 0, g_currentMission.terrainDetailHeightTypeNumChannels) |
129 | self:setAIFruitExtraRequirements(true, true) |
130 | end |
131 | end |
onPostLoad
DescriptionDefinitiononPostLoad()Code
135 | function Windrower:onPostLoad(savegame) |
136 | local spec = self.spec_windrower |
137 | for i=#spec.effects, 1, -1 do |
138 | local effect = spec.effects[i] |
139 | local workArea = self:getWorkAreaByIndex(effect.workAreaIndex) |
140 | if workArea ~= nil then |
141 | effect.windrowerWorkAreaFillTypeIndex = workArea.windrowerWorkAreaIndex |
142 | |
143 | if spec.workAreaToEffects[workArea.index] == nil then |
144 | spec.workAreaToEffects[workArea.index] = {} |
145 | end |
146 | table.insert(spec.workAreaToEffects[workArea.index], effect) |
147 | else |
148 | g_logManager:xmlWarning(self.xmlFileName, "Invalid workAreaIndex '%d' for effect 'vehicle.windrower.effects.effect(%d)'!", effect.workAreaIndex, i) |
149 | table.insert(spec.effects, i) |
150 | end |
151 | end |
152 | end |
onReadStream
DescriptionDefinitiononReadStream()Code
172 | function Windrower:onReadStream(streamId, connection) |
173 | local spec = self.spec_windrower |
174 | for index, _ in ipairs(spec.windrowerWorkAreaFillTypes) do |
175 | local fillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS) |
176 | spec.windrowerWorkAreaFillTypes[index] = fillType |
177 | end |
178 | for _, effect in ipairs(spec.effects) do |
179 | if streamReadBool(streamId) then |
180 | local fillType = spec.windrowerWorkAreaFillTypes[effect.windrowerWorkAreaFillTypeIndex] |
181 | g_effectManager:setFillType(effect.effects, fillType) |
182 | g_effectManager:startEffects(effect.effects) |
183 | else |
184 | g_effectManager:stopEffects(effect.effects) |
185 | end |
186 | end |
187 | end |
onReadUpdateStream
DescriptionDefinitiononReadUpdateStream()Code
203 | function Windrower:onReadUpdateStream(streamId, timestamp, connection) |
204 | if connection:getIsServer() then |
205 | local spec = self.spec_windrower |
206 | |
207 | if streamReadBool(streamId) then |
208 | for index, _ in ipairs(spec.windrowerWorkAreaFillTypes) do |
209 | local fillType = streamReadUIntN(streamId, FillTypeManager.SEND_NUM_BITS) |
210 | spec.windrowerWorkAreaFillTypes[index] = fillType |
211 | end |
212 | end |
213 | |
214 | if streamReadBool(streamId) then |
215 | for _, effect in ipairs(spec.effects) do |
216 | if streamReadBool(streamId) then |
217 | local fillType = spec.windrowerWorkAreaFillTypes[effect.windrowerWorkAreaFillTypeIndex] |
218 | g_effectManager:setFillType(effect.effects, fillType) |
219 | g_effectManager:startEffects(effect.effects) |
220 | else |
221 | g_effectManager:stopEffects(effect.effects) |
222 | end |
223 | end |
224 | end |
225 | end |
226 | end |
onStartWorkAreaProcessing
DescriptionDefinitiononStartWorkAreaProcessing()Code
457 | function Windrower:onStartWorkAreaProcessing(dt, workAreas) |
458 | local spec = self.spec_windrower |
459 | for _, workArea in pairs(workAreas) do |
460 | workArea.lastValidPickupFruitType = FruitType.UNKNOWN |
461 | workArea.lastPickupLiters = 0 |
462 | workArea.lastDroppedLiters = 0 |
463 | end |
464 | spec.isWorking = false |
465 | end |
onTurnedOff
DescriptionDefinitiononTurnedOff()Code
290 | function Windrower:onTurnedOff() |
291 | local spec = self.spec_windrower |
292 | g_soundManager:stopSamples(spec.samples) |
293 | |
294 | for _, effect in ipairs(spec.effects) do |
295 | g_effectManager:stopEffects(effect.effects) |
296 | end |
297 | g_animationManager:stopAnimations(spec.animationNodes) |
298 | end |
onTurnedOn
DescriptionDefinitiononTurnedOn()Code
280 | function Windrower:onTurnedOn() |
281 | local spec = self.spec_windrower |
282 | if self.isClient then |
283 | g_soundManager:playSample(spec.samples.work) |
284 | g_animationManager:startAnimations(spec.animationNodes) |
285 | end |
286 | end |
onUpdateTick
DescriptionDefinitiononUpdateTick()Code
250 | function Windrower:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected) |
251 | local spec = self.spec_windrower |
252 | |
253 | if self.isServer then |
254 | for _, effect in ipairs(spec.effects) do |
255 | if effect.isActive and g_currentMission.time > effect.activeTime then |
256 | effect.isActive = false |
257 | if effect.isActiveSent then |
258 | effect.isActiveSent = false |
259 | self:raiseDirtyFlags(spec.effectDirtyFlag) |
260 | end |
261 | g_effectManager:stopEffects(effect.effects) |
262 | end |
263 | end |
264 | end |
265 | |
266 | if self.isClient then |
267 | if g_animationManager:areAnimationsRunning(spec.animationNodes) then |
268 | for _, rake in pairs(spec.rakes) do |
269 | self:updateRake(rake) |
270 | end |
271 | |
272 | -- raise active until the animations are faded out |
273 | self:raiseActive() |
274 | end |
275 | end |
276 | end |
onWriteStream
DescriptionDefinitiononWriteStream()Code
191 | function Windrower:onWriteStream(streamId, connection) |
192 | local spec = self.spec_windrower |
193 | for _, fillTypeIndex in ipairs(spec.windrowerWorkAreaFillTypes) do |
194 | streamWriteUIntN(streamId, fillTypeIndex, FillTypeManager.SEND_NUM_BITS) |
195 | end |
196 | for _, effect in ipairs(spec.effects) do |
197 | streamWriteBool(streamId, effect.isActiveSent) |
198 | end |
199 | end |
onWriteUpdateStream
DescriptionDefinitiononWriteUpdateStream()Code
230 | function Windrower:onWriteUpdateStream(streamId, connection, dirtyMask) |
231 | if not connection:getIsServer() then |
232 | local spec = self.spec_windrower |
233 | |
234 | if streamWriteBool(streamId, bitAND(dirtyMask, spec.fillTypesDirtyFlag) ~= 0) then |
235 | for _, fillTypeIndex in ipairs(spec.windrowerWorkAreaFillTypes) do |
236 | streamWriteUIntN(streamId, fillTypeIndex, FillTypeManager.SEND_NUM_BITS) |
237 | end |
238 | end |
239 | |
240 | if streamWriteBool(streamId, bitAND(dirtyMask, spec.effectDirtyFlag) ~= 0) then |
241 | for _, effect in ipairs(spec.effects) do |
242 | streamWriteBool(streamId, effect.isActiveSent) |
243 | end |
244 | end |
245 | end |
246 | end |
prerequisitesPresent
DescriptionDefinitionprerequisitesPresent()Code
21 | function Windrower.prerequisitesPresent(specializations) |
22 | return SpecializationUtil.hasSpecialization(WorkArea, specializations) |
23 | end |
processDropArea
DescriptionDefinitionprocessDropArea()Code
592 | function Windrower:processDropArea(dropArea, litersToDrop, fillType) |
593 | local lsx, lsy, lsz, lex, ley, lez, radius = DensityMapHeightUtil.getLineByArea(dropArea.start, dropArea.width, dropArea.height) |
594 | local dropped, lineOffset = DensityMapHeightUtil.tipToGroundAroundLine(self, litersToDrop, fillType, lsx,lsy,lsz, lex,ley,lez, radius, nil, dropArea.lineOffset, false, nil, false) |
595 | dropArea.lineOffset = lineOffset |
596 | |
597 | return dropped |
598 | end |
processWindrowerArea
DescriptionDefinitionprocessWindrowerArea()Code
489 | function Windrower:processWindrowerArea(workArea, dt) |
490 | local spec = self.spec_windrower |
491 | local workAreaSpec = self.spec_workArea |
492 | spec.isWorking = self:getLastSpeed() > 0.5 |
493 | |
494 | -- pick up |
495 | local lsx, lsy, lsz, lex, ley, lez, radius = DensityMapHeightUtil.getLineByArea(workArea.start, workArea.width, workArea.height) |
496 | |
497 | -- loop over all fruitTypes or use only lastValidPickupFruitType |
498 | local pickupLiters = 0 |
499 | local pickupFruitType = FruitType.UNKNOWN |
500 | local lastValidFillType = g_fruitTypeManager:getFillTypeIndexByFruitTypeIndex(workArea.lastValidPickupFruitType) |
501 | |
502 | if workArea.lastPickupLiters == 0 and (workArea.lastValidPickupFruitType == FruitType.UNKNOWN or workArea.litersToDrop < g_densityMapHeightManager:getMinValidLiterValue(lastValidFillType)) then |
503 | for fruitTypeIndex, _ in ipairs(g_fruitTypeManager:getFruitTypes()) do |
504 | local fillTypeIndex = g_fruitTypeManager:getWindrowFillTypeIndexByFruitTypeIndex(fruitTypeIndex) |
505 | if fillTypeIndex ~= nil then |
506 | pickupLiters = -DensityMapHeightUtil.tipToGroundAroundLine(self, -math.huge, fillTypeIndex, lsx,lsy,lsz, lex,ley,lez, radius, nil, nil, spec.limitToLineHeight, nil) |
507 | if pickupLiters > 0 then |
508 | pickupFruitType = fruitTypeIndex |
509 | break |
510 | end |
511 | end |
512 | end |
513 | else |
514 | pickupLiters = -DensityMapHeightUtil.tipToGroundAroundLine(self, -math.huge, g_fruitTypeManager:getWindrowFillTypeIndexByFruitTypeIndex(workArea.lastValidPickupFruitType), lsx,lsy,lsz, lex,ley,lez, radius, nil, nil, false, nil) |
515 | |
516 | if workArea.lastValidPickupFruitType == FruitType.GRASS then |
517 | pickupLiters = pickupLiters - DensityMapHeightUtil.tipToGroundAroundLine(self, -math.huge, g_fruitTypeManager:getWindrowFillTypeIndexByFruitTypeIndex(FruitType.DRYGRASS), lsx,lsy,lsz, lex,ley,lez, radius, nil, nil, false, nil) |
518 | elseif workArea.lastValidPickupFruitType == FruitType.DRYGRASS then |
519 | pickupLiters = pickupLiters - DensityMapHeightUtil.tipToGroundAroundLine(self, -math.huge, g_fruitTypeManager:getWindrowFillTypeIndexByFruitTypeIndex(FruitType.GRASS), lsx,lsy,lsz, lex,ley,lez, radius, nil, nil, false, nil) |
520 | end |
521 | |
522 | if pickupLiters > 0 then |
523 | pickupFruitType = workArea.lastValidPickupFruitType |
524 | end |
525 | end |
526 | |
527 | if pickupFruitType ~= FruitType.UNKNOWN then |
528 | workArea.lastValidPickupFruitType = pickupFruitType |
529 | end |
530 | workArea.lastPickupLiters = pickupLiters |
531 | workArea.litersToDrop = workArea.litersToDrop + pickupLiters |
532 | |
533 | --calculating area by area width multiplied by last moved distance (not 100% accuracy in corners) |
534 | local areaWidth = MathUtil.vector3Length(lsx-lex, lsy-ley, lsz-lez) |
535 | local area = areaWidth * self.lastMovedDistance |
536 | |
537 | -- drop |
538 | if workArea.lastPickupLiters > 0 then |
539 | local dropArea = workAreaSpec.workAreas[workArea.dropWindrowWorkAreaIndex] |
540 | if dropArea ~= nil then |
541 | local dropType = g_fruitTypeManager:getWindrowFillTypeIndexByFruitTypeIndex(workArea.lastValidPickupFruitType) |
542 | local dropped = self:processDropArea(dropArea, workArea.lastPickupLiters, dropType) |
543 | workArea.lastDroppedLiters = dropped |
544 | workArea.litersToDrop = workArea.litersToDrop - dropped |
545 | |
546 | if self.isServer then |
547 | --particles |
548 | if self:getLastSpeed(true) > 0.5 then |
549 | if dropped > 0 then |
550 | local changedFillType = false |
551 | if spec.windrowerWorkAreaFillTypes[workArea.windrowerWorkAreaIndex] ~= dropType then |
552 | spec.windrowerWorkAreaFillTypes[workArea.windrowerWorkAreaIndex] = dropType |
553 | self:raiseDirtyFlags(spec.fillTypesDirtyFlag) |
554 | changedFillType = true |
555 | end |
556 | |
557 | local effects = spec.workAreaToEffects[workArea.index] |
558 | if effects ~= nil then |
559 | for _, effect in ipairs(effects) do |
560 | effect.activeTime = g_currentMission.time + effect.activeTimeDuration |
561 | |
562 | -- sync mp |
563 | if not effect.isActiveSent then |
564 | effect.isActiveSent = true |
565 | self:raiseDirtyFlags(spec.effectDirtyFlag) |
566 | end |
567 | |
568 | if changedFillType then |
569 | g_effectManager:setFillType(effect.effects, dropType) |
570 | end |
571 | |
572 | -- enable effect |
573 | if not effect.isActive then |
574 | g_effectManager:setFillType(effect.effects, dropType) |
575 | g_effectManager:startEffects(effect.effects) |
576 | end |
577 | |
578 | effect.isActive = true |
579 | end |
580 | end |
581 | end |
582 | end |
583 | end |
584 | end |
585 | end |
586 | |
587 | return workArea.lastDroppedLiters, area |
588 | end |
registerEventListeners
DescriptionDefinitionregisterEventListeners()Code
45 | function Windrower.registerEventListeners(vehicleType) |
46 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", Windrower) |
47 | SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", Windrower) |
48 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", Windrower) |
49 | SpecializationUtil.registerEventListener(vehicleType, "onReadStream", Windrower) |
50 | SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", Windrower) |
51 | SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", Windrower) |
52 | SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", Windrower) |
53 | SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", Windrower) |
54 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOn", Windrower) |
55 | SpecializationUtil.registerEventListener(vehicleType, "onTurnedOff", Windrower) |
56 | SpecializationUtil.registerEventListener(vehicleType, "onStartWorkAreaProcessing", Windrower) |
57 | SpecializationUtil.registerEventListener(vehicleType, "onEndWorkAreaProcessing", Windrower) |
58 | end |
registerFunctions
DescriptionDefinitionregisterFunctions()Code
27 | function Windrower.registerFunctions(vehicleType) |
28 | SpecializationUtil.registerFunction(vehicleType, "loadRakeFromXML", Windrower.loadRakeFromXML) |
29 | SpecializationUtil.registerFunction(vehicleType, "updateRake", Windrower.updateRake) |
30 | SpecializationUtil.registerFunction(vehicleType, "processWindrowerArea", Windrower.processWindrowerArea) |
31 | SpecializationUtil.registerFunction(vehicleType, "processDropArea", Windrower.processDropArea) |
32 | end |
registerOverwrittenFunctions
DescriptionDefinitionregisterOverwrittenFunctions()Code
36 | function Windrower.registerOverwrittenFunctions(vehicleType) |
37 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "doCheckSpeedLimit", Windrower.doCheckSpeedLimit) |
38 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadWorkAreaFromXML", Windrower.loadWorkAreaFromXML) |
39 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDirtMultiplier", Windrower.getDirtMultiplier) |
40 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getWearMultiplier", Windrower.getWearMultiplier) |
41 | end |
updateRake
DescriptionDefinitionupdateRake()Code
369 | function Windrower:updateRake(rake) |
370 | local _,y,_ = getRotation(rake.node) |
371 | y = y % (2*math.pi) |
372 | if rake.dir == -1 then |
373 | y = math.abs(2*math.pi-y) |
374 | end |
375 | |
376 | for k, spike in pairs(rake.spikes) do |
377 | local yRot = ((y - (k-1)*rake.yRotOffset) + 2*math.pi) % (2*math.pi) |
378 | local alpha = 0 |
379 | |
380 | if yRot > rake.moveUpStart and yRot <= rake.moveUpEnd then |
381 | alpha = 1 - (rake.moveUpEnd-yRot) / (rake.moveUpEnd-rake.moveUpStart) |
382 | elseif yRot > rake.moveDownStart and yRot <= rake.moveDownEnd then |
383 | alpha = ((rake.moveDownEnd-yRot) / (rake.moveDownEnd-rake.moveDownStart)) |
384 | elseif yRot > rake.moveUpEnd and yRot <= rake.moveDownStart then |
385 | alpha = 1 |
386 | end |
387 | |
388 | setRotation(spike.node, 0, 0, rake.maxRotZ*alpha*spike.dir) |
389 | end |
390 | end |