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
MixerWagon
DescriptionClass for all mixer wagonsFunctions
- prerequisitesPresent
- load
- delete
- getSaveAttributesAndNodes
- readStream
- writeStream
- readUpdateStream
- writeUpdateStream
- update
- draw
- onDeactivateSounds
- resetFillLevelIfNeeded
- resetUnitFillLevelIfNeeded
- allowFillType
- getCapacity
- getFillLevel
- setFillLevel
- setUnitFillLevel
- allowUnitFillType
- getUnitFillType
- getCanTipToGround
- mixerWagonBaleTriggerCallback
- drawMixerWagonHelp
- onTurnedOn
- onTurnedOff
- getCanBeTurnedOn
- getIsTurnedOnAllowed
- getAllowFillShovel
- fillShovelFromGroundValue
- fillShovelFromTrigger
prerequisitesPresent
DescriptionChecks if all prerequisite specializations are loadedDefinition
prerequisitesPresent(table specializations)Arguments
table | specializations | specializations |
boolean | hasPrerequisite | true if all prerequisite specializations are loaded |
20 | function MixerWagon.prerequisitesPresent(specializations) |
21 | return SpecializationUtil.hasSpecialization(Fillable, specializations) and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations); |
22 | end |
load
DescriptionCalled on loadingDefinition
load(table savegame)Arguments
table | savegame | savegame |
27 | function MixerWagon:load(savegame) |
28 | |
29 | self.mixerWagonSuperAllowFillType = self.allowFillType; |
30 | self.allowFillType = Utils.overwrittenFunction(self.allowFillType, MixerWagon.allowFillType); |
31 | |
32 | self.getCapacity = Utils.overwrittenFunction(self.getCapacity, MixerWagon.getCapacity); |
33 | self.getFillLevel = Utils.overwrittenFunction(self.getFillLevel, MixerWagon.getFillLevel); |
34 | self.setFillLevel = Utils.overwrittenFunction(self.setFillLevel, MixerWagon.setFillLevel); |
35 | self.setUnitFillLevel = Utils.overwrittenFunction(self.setUnitFillLevel, MixerWagon.setUnitFillLevel); |
36 | self.allowUnitFillType = Utils.overwrittenFunction(self.allowUnitFillType, MixerWagon.allowUnitFillType); |
37 | self.getUnitFillType = Utils.overwrittenFunction(self.getUnitFillType, MixerWagon.getUnitFillType); |
38 | self.getCanTipToGround = Utils.overwrittenFunction(self.getCanTipToGround, MixerWagon.getCanTipToGround); |
39 | |
40 | self.resetFillLevelIfNeeded = Utils.overwrittenFunction(self.resetFillLevelIfNeeded, MixerWagon.resetFillLevelIfNeeded); |
41 | self.resetUnitFillLevelIfNeeded = Utils.overwrittenFunction(self.resetUnitFillLevelIfNeeded, MixerWagon.resetUnitFillLevelIfNeeded); |
42 | |
43 | self.fillShovelFromGroundValue = Utils.overwrittenFunction(self.fillShovelFromGroundValue, MixerWagon.fillShovelFromGroundValue); |
44 | self.fillShovelFromTrigger = Utils.overwrittenFunction(self.fillShovelFromTrigger, MixerWagon.fillShovelFromTrigger); |
45 | self.mixerWagonBaleTriggerCallback = MixerWagon.mixerWagonBaleTriggerCallback; |
46 | self.getCanBeTurnedOn = Utils.overwrittenFunction(self.getCanBeTurnedOn, MixerWagon.getCanBeTurnedOn); |
47 | self.getIsTurnedOnAllowed = Utils.overwrittenFunction(self.getIsTurnedOnAllowed, MixerWagon.getIsTurnedOnAllowed); |
48 | self.drawMixerWagonHelp = SpecializationUtil.callSpecializationsFunction("drawMixerWagonHelp"); |
49 | |
50 | self.getAllowFillShovel = Utils.overwrittenFunction(self.getAllowFillShovel, MixerWagon.getAllowFillShovel); |
51 | |
52 | self.mixerWagonNeedsTurnOn = false; |
53 | if self.shovelNodes ~= nil then |
54 | self.mixerWagonNeedsTurnOn = true; |
55 | end |
56 | |
57 | self.mixerWagonPickupSoundEnabled = false; |
58 | if self.isClient then |
59 | self.sampleMixerWagonPickup = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.mixerWagonPickupSound", nil, self.baseDirectory, self.components[1].node); |
60 | self.sampleMixerWagonStart = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.mixerWagonPickupStartSound", nil, self.baseDirectory); |
61 | self.sampleMixerWagonStop = SoundUtil.loadSample(self.xmlFile, {}, "vehicle.mixerWagonPickupStopSound", nil, self.baseDirectory); |
62 | self.mixerWagonPickupSoundPitchOffset = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.mixerWagonPickupSound#pitchOffset"), 1); |
63 | self.mixerWagonPickupSoundPickupPitchOffset = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.mixerWagonPickupSound#pickupPitchOffset"), 0.8*self.mixerWagonPickupSoundPitchOffset); |
64 | |
65 | self.mixerWagonMixRotatingParts = Utils.loadRotationNodes(self.xmlFile, {}, "vehicle.mixerWagonRotatingParts.mixerWagonRotatingPart", "mixerWagonMix", self.components); |
66 | self.mixerWagonPickupRotatingParts = Utils.loadRotationNodes(self.xmlFile, {}, "vehicle.mixerWagonRotatingParts.mixerWagonRotatingPart", "mixerWagonPickup", self.components); |
67 | self.mixerWagonPickupScroller = Utils.loadScrollers(self.components, self.xmlFile, "vehicle.mixerWagonRotatingParts.mixerWagonScroller", {}, false); |
68 | end |
69 | |
70 | |
71 | local uiScale = g_gameSettings:getValue("uiScale") |
72 | |
73 | self.mixerWagonFillTypes = {}; |
74 | self.fillTypeToMixerWagonFillType = {}; |
75 | local i=0; |
76 | while true do |
77 | local baseName = string.format("vehicle.mixerWagonFillTypes.mixerWagonFillType(%d)", i); |
78 | if not hasXMLProperty(self.xmlFile, baseName) then |
79 | break; |
80 | end |
81 | local entry = {}; |
82 | entry.fillTypes = {}; |
83 | |
84 | local j=0; |
85 | while true do |
86 | local fillTypeKey = baseName..string.format(".fillType(%d)", j); |
87 | if not hasXMLProperty(self.xmlFile, fillTypeKey) then |
88 | break; |
89 | end |
90 | local fillType = getXMLString(self.xmlFile, fillTypeKey.."#fillType"); |
91 | if fillType ~= nil then |
92 | local fillTypeInt = FillUtil.fillTypeNameToInt[fillType]; |
93 | -- we do not want to support grass in mixer wagons becasue this would make hay "useless" |
94 | if fillTypeInt ~= nil and fillTypeInt ~= FillUtil.FILLTYPE_GRASS_WINDROW then |
95 | if self.fillTypeToMixerWagonFillType[fillTypeInt] == nil then |
96 | entry.fillTypes[fillTypeInt] = true; |
97 | self.fillTypeToMixerWagonFillType[fillTypeInt] = entry; |
98 | else |
99 | print("Warning: Invalid mixerWagonFillType '"..fillType.."' used multiple times in '"..self.configFileName.."'."); |
100 | end |
101 | else |
102 | print("Warning: Invalid mixerWagonFillType '"..fillType.."' in '"..self.configFileName.. "'."); |
103 | end |
104 | end |
105 | |
106 | j = j+1; |
107 | end |
108 | entry.minPercentage = Utils.getNoNil(getXMLFloat(self.xmlFile, baseName.."#minPercentage"), 0)*0.01; |
109 | entry.maxPercentage = Utils.getNoNil(getXMLFloat(self.xmlFile, baseName.."#maxPercentage"), 100)*0.01; |
110 | entry.fillLevel = 0; |
111 | |
112 | local name = Utils.getNoNil(getXMLString(self.xmlFile, baseName.."#name"), "unknown"); |
113 | entry.name = name; |
114 | local i18n = g_i18n; |
115 | if self.customEnvironment ~= nil then |
116 | i18n = _G[self.customEnvironment].g_i18n; |
117 | end |
118 | entry.nameI18N = i18n:getText("fillType_" .. name); |
119 | |
120 | local fillTypeDesc = FillUtil.fillTypeNameToDesc[name]; |
121 | if fillTypeDesc ~= nil then |
122 | local width, height = getNormalizedScreenValues(20*uiScale, 20*uiScale); |
123 | entry.overlay = Overlay:new("MixerWagonFillType", fillTypeDesc.hudOverlayFilenameSmall, 0, 0, width, height) |
124 | entry.overlay:setColor(unpack(g_currentMission.helpBoxTextColor)) |
125 | end |
126 | |
127 | if next(entry.fillTypes) ~= nil then |
128 | entry.statusBarColor = {0.2122, 0.5271, 0.0307, 1}; |
129 | entry.statusBarColor2 = {0.2832, 0.0091, 0.0091, 1} |
130 | local width, height = getNormalizedScreenValues(208*uiScale, 8*uiScale); |
131 | entry.statusBar = StatusBar:new(g_baseUIFilename, g_colorBgUVs, nil, {0.0075, 0.0075, 0.0075, 1}, entry.statusBarColor2, nil, 0, 0, width, height); |
132 | table.insert(self.mixerWagonFillTypes, entry); |
133 | end |
134 | i = i+1; |
135 | end |
136 | |
137 | |
138 | if self.isServer then |
139 | self.mixerWagonBaleTriggerId = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.mixerWagonBaleTrigger#index")); |
140 | if self.mixerWagonBaleTriggerId ~= nil then |
141 | addTrigger(self.mixerWagonBaleTriggerId, "mixerWagonBaleTriggerCallback", self); |
142 | end |
143 | end |
144 | |
145 | self.mixingActiveTimerMax = 5000; |
146 | self.mixingActiveTimer = 0; |
147 | |
148 | self.mixerWagonFillLevelTextOffsetX, self.mixerWagonFillLevelTextOffsetY = getNormalizedScreenValues(28*uiScale, 7*uiScale) |
149 | _, self.mixerWagonHelpHeightPerFruit = getNormalizedScreenValues(0, 22*uiScale) |
150 | _, self.mixerWagonHelpHeightOffset = getNormalizedScreenValues(0, 10*uiScale) |
151 | |
152 | local width, height = getNormalizedScreenValues(7*uiScale, 12*uiScale) |
153 | self.mixerWagonFillRangeMarkerOverlay = Overlay:new("mixerWagonFillRangeMarkerOverlay", g_baseUIFilename, 0, 0, width, height); |
154 | self.mixerWagonFillRangeMarkerOverlay:setAlignment(Overlay.ALIGN_VERTICAL_MIDDLE, Overlay.ALIGN_HORIZONTAL_LEFT) |
155 | self.mixerWagonFillRangeMarkerOverlay:setUVs(getNormalizedUVs({374, 648, 12, 20})) |
156 | self.mixerWagonFillRangeMarkerOverlay:setColor(unpack(g_currentMission.helpBoxTextColor)) |
157 | |
158 | self.mixerWagonLastPickupTime = -10000; |
159 | |
160 | -- disable fill level sync and save of Fillable |
161 | self.synchronizeFillLevel = false; |
162 | |
163 | self.mixerWagon = {}; |
164 | self.mixerWagon.fillUnitIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.mixerWagon#fillUnitIndex"), 1); |
165 | self.mixerWagon.unloadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.mixerWagon#unloadInfoIndex"), 1); |
166 | self.mixerWagon.loadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.mixerWagon#loadInfoIndex"), 1); |
167 | self.mixerWagon.dischargeInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.mixerWagon#dischargeInfoIndex"), 1); |
168 | |
169 | -- remove grass_windrow from fillTypes, we do not want to support grass in mixer wagons becasue this would make hay "useless" |
170 | local fillUnit = self.fillUnits[self.mixerWagon.fillUnitIndex]; |
171 | if fillUnit ~= nil then |
172 | if fillUnit.fillTypes[FillUtil.FILLTYPE_GRASS_WINDROW] then |
173 | fillUnit.fillTypes[FillUtil.FILLTYPE_GRASS_WINDROW] = nil; |
174 | end |
175 | end |
176 | |
177 | self.mixerWagonDirtyFlag = self:getNextDirtyFlag(); |
178 | |
179 | if savegame ~= nil then |
180 | for i=1, table.getn(self.mixerWagonFillTypes) do |
181 | local fillTypeKey = savegame.key..string.format(".mixerWagonFillType%d#fillLevel", i); |
182 | local fillLevel = getXMLFloat(savegame.xmlFile, fillTypeKey); |
183 | if fillLevel == nil then |
184 | fillLevel = 0; |
185 | end |
186 | if fillLevel > 0 then |
187 | fillLevel = fillLevel + self:getFillLevel( next(self.mixerWagonFillTypes[i].fillTypes) ); |
188 | self:setUnitFillLevel(self.mixerWagon.fillUnitIndex, fillLevel, next(self.mixerWagonFillTypes[i].fillTypes)); |
189 | end |
190 | end |
191 | end |
192 | |
193 | -- disable syncing of fillLevels by Fillable.lua |
194 | self.synchronizeFillLevels = false; |
195 | end |
delete
DescriptionCalled on deletingDefinition
delete()Code
199 | function MixerWagon:delete() |
200 | if self.isServer then |
201 | if self.mixerWagonBaleTriggerId ~= nil then |
202 | removeTrigger(self.mixerWagonBaleTriggerId); |
203 | end |
204 | end |
205 | |
206 | for _,entry in pairs(self.mixerWagonFillTypes) do |
207 | if entry.overlay ~= nil then |
208 | entry.overlay:delete() |
209 | end |
210 | entry.statusBar:delete(); |
211 | end |
212 | if self.isClient then |
213 | SoundUtil.deleteSample(self.sampleMixerWagonPickup); |
214 | SoundUtil.deleteSample(self.sampleMixerWagonStart); |
215 | SoundUtil.deleteSample(self.sampleMixerWagonStop); |
216 | end |
217 | |
218 | self.mixerWagonFillRangeMarkerOverlay:delete() |
219 | end |
getSaveAttributesAndNodes
DescriptionReturns attributes and nodes to saveDefinition
getSaveAttributesAndNodes(table nodeIdent)Arguments
table | nodeIdent | node ident |
string | attributes | attributes |
string | nodes | nodes |
226 | function MixerWagon:getSaveAttributesAndNodes(nodeIdent) |
227 | local nodes = ""; |
228 | for i=1, table.getn(self.mixerWagonFillTypes) do |
229 | if i>1 then |
230 | nodes = nodes.."\n"; |
231 | end |
232 | local fillLevel = self.mixerWagonFillTypes[i].fillLevel; |
233 | nodes = nodes.. nodeIdent..string.format('<mixerWagonFillType%d', i)..' fillLevel="'..fillLevel..'" />'; |
234 | end |
235 | return "", nodes; |
236 | end |
readStream
DescriptionCalled on client side on joinDefinition
readStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
242 | function MixerWagon:readStream(streamId, connection) |
243 | self:setUnitFillLevel(self.mixerWagon.fillUnitIndex, 0, FillUtil.FILLTYPE_UNKNOWN); |
244 | for i=1,table.getn(self.mixerWagonFillTypes) do |
245 | local fillLevel = streamReadFloat32(streamId); |
246 | if fillLevel > 0 then |
247 | local basicFillLevel = self:getUnitFillLevel(self.mixerWagon.fillUnitIndex); |
248 | local mixerWagonFillType = self.mixerWagonFillTypes[i]; |
249 | self:setUnitFillLevel(self.mixerWagon.fillUnitIndex, basicFillLevel+fillLevel, next(mixerWagonFillType.fillTypes)); |
250 | end |
251 | end |
252 | end |
writeStream
DescriptionCalled on server side on joinDefinition
writeStream(integer streamId, integer connection)Arguments
integer | streamId | streamId |
integer | connection | connection |
258 | function MixerWagon:writeStream(streamId, connection) |
259 | for i=1,table.getn(self.mixerWagonFillTypes) do |
260 | streamWriteFloat32(streamId, self.mixerWagonFillTypes[i].fillLevel); |
261 | end |
262 | end |
readUpdateStream
DescriptionCalled on on updateDefinition
readUpdateStream(integer streamId, integer timestamp, table connection)Arguments
integer | streamId | stream ID |
integer | timestamp | timestamp |
table | connection | connection |
269 | function MixerWagon:readUpdateStream(streamId, timestamp, connection) |
270 | if connection:getIsServer() then |
271 | if streamReadBool(streamId) then |
272 | self.mixingActiveTimer = streamReadUIntN(streamId, 4)/15 * self.mixingActiveTimerMax; |
273 | |
274 | self:setUnitFillLevel(self.mixerWagon.fillUnitIndex, 0, FillUtil.FILLTYPE_UNKNOWN); |
275 | for i=1,table.getn(self.mixerWagonFillTypes) do |
276 | local fillLevel = streamReadFloat32(streamId); |
277 | if fillLevel > 0 then |
278 | local basicFillLevel = self:getUnitFillLevel(self.mixerWagon.fillUnitIndex); |
279 | local mixerWagonFillType = self.mixerWagonFillTypes[i]; |
280 | self:setUnitFillLevel(self.mixerWagon.fillUnitIndex, basicFillLevel+fillLevel, next(mixerWagonFillType.fillTypes)); |
281 | end |
282 | end |
283 | end |
284 | end |
285 | 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 |
292 | function MixerWagon:writeUpdateStream(streamId, connection, dirtyMask) |
293 | if not connection:getIsServer() then |
294 | if streamWriteBool(streamId, bitAND(dirtyMask, self.mixerWagonDirtyFlag) ~= 0) then |
295 | streamWriteUIntN(streamId, math.floor(self.mixingActiveTimer/self.mixingActiveTimerMax*15), 4); |
296 | for i=1,table.getn(self.mixerWagonFillTypes) do |
297 | local percent = 0; |
298 | if self:getCapacity() ~= 0 then |
299 | percent = Utils.clamp(self.mixerWagonFillTypes[i].fillLevel / self:getUnitCapacity(self.mixerWagon.fillUnitIndex), 0, 1); |
300 | end |
301 | streamWriteFloat32(streamId, self.mixerWagonFillTypes[i].fillLevel); |
302 | end |
303 | end |
304 | end |
305 | end |
update
DescriptionCalled on updateDefinition
update(float dt)Arguments
float | dt | time since last call in ms |
316 | function MixerWagon:update(dt) |
317 | if self.isClient then |
318 | if self.mixingActiveTimer > 0 or self:getIsTurnedOn() or self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN then |
319 | if self:getIsActiveForSound() then |
320 | if not SoundUtil.isSamplePlaying(self.sampleMixerWagonStart, 1.8*dt) then |
321 | SoundUtil.playSample(self.sampleMixerWagonPickup, 0, 0, nil); |
322 | end |
323 | else |
324 | SoundUtil.play3DSample(self.sampleMixerWagonPickup); |
325 | end |
326 | if SoundUtil.isSamplePlaying(self.sampleMixerWagonPickup) then |
327 | if self.mixerWagonLastPickupTime >= g_currentMission.time-200 then |
328 | SoundUtil.setSamplePitch(self.sampleMixerWagonPickup, self.mixerWagonPickupSoundPickupPitchOffset); |
329 | else |
330 | SoundUtil.setSamplePitch(self.sampleMixerWagonPickup, self.mixerWagonPickupSoundPitchOffset); |
331 | end |
332 | end |
333 | else |
334 | SoundUtil.stopSample(self.sampleMixerWagonStart, true); |
335 | SoundUtil.stopSample(self.sampleMixerWagonStop, true); |
336 | SoundUtil.stopSample(self.sampleMixerWagonPickup, true); |
337 | SoundUtil.stop3DSample(self.sampleMixerWagonPickup); |
338 | end |
339 | |
340 | -- update pickup rotating parts |
341 | Utils.updateRotationNodes(self, self.mixerWagonPickupRotatingParts, dt, self:getIsActive() and self:getIsTurnedOn()); |
342 | Utils.updateScrollers(self.mixerWagonPickupScroller, dt, self:getIsActive() and self:getIsTurnedOn()); |
343 | Utils.updateRotationNodes(self, self.mixerWagonMixRotatingParts, dt, self.mixingActiveTimer > 0 or self:getIsTurnedOn() or self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN); |
344 | end |
345 | |
346 | if self.mixingActiveTimer > 0 or self:getIsTurnedOn() or self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN then |
347 | self.mixingActiveTimer = self.mixingActiveTimer - dt; |
348 | end |
349 | end |
draw
DescriptionCalled on drawDefinition
draw()Code
356 | function MixerWagon:draw() |
357 | if self:getIsActiveForInput(true) then |
358 | local numFillTypes = table.getn(self.mixerWagonFillTypes); |
359 | if numFillTypes > 0 then |
360 | local helpHeight = (numFillTypes+1)*self.mixerWagonHelpHeightPerFruit + self.mixerWagonHelpHeightOffset |
361 | g_currentMission:addHelpTextFunction(self.drawMixerWagonHelp, self, helpHeight, nil); |
362 | end |
363 | end |
364 | end |
onDeactivateSounds
DescriptionCalled on deactivating soundsDefinition
onDeactivateSounds()Code
374 | function MixerWagon:onDeactivateSounds() |
375 | if self.isClient then |
376 | SoundUtil.stopSample(self.sampleMixerWagonPickup, true); |
377 | SoundUtil.stopSample(self.sampleMixerWagonStart, true); |
378 | SoundUtil.stop3DSample(self.sampleMixerWagonPickup); |
379 | end |
380 | 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 |
386 | function MixerWagon:resetFillLevelIfNeeded(superFunc, fillType) |
387 | local mixerWagonFillType = self.fillTypeToMixerWagonFillType[fillType]; |
388 | if mixerWagonFillType ~= nil then |
389 | -- nothing to do |
390 | return; |
391 | end |
392 | superFunc(self, fillType); |
393 | 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 |
400 | function MixerWagon:resetUnitFillLevelIfNeeded(superFunc, fillUnitIndex, fillType) |
401 | if self.fillUnits == nil or self.fillUnits[fillUnitIndex] == nil or self.lastFillLevelChangeTime + 500 > g_currentMission.time then |
402 | return; |
403 | end |
404 | |
405 | local mixerWagonFillType = self.fillTypeToMixerWagonFillType[fillType]; |
406 | if mixerWagonFillType ~= nil then |
407 | return; |
408 | end |
409 | |
410 | local fillUnit = self.fillUnits[fillUnitIndex]; |
411 | if fillUnit.fillTypes[fillType] then |
412 | if fillUnit.currentFillType ~= fillType then |
413 | self:setUnitFillLevel(fillUnitIndex, 0, FillUtil.FILLTYPE_UNKNOWN, true); |
414 | end |
415 | end |
416 | 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 |
423 | function MixerWagon:allowFillType(superFunc, fillType, allowEmptying) |
424 | local mixerWagonFillType = self.fillTypeToMixerWagonFillType[fillType]; |
425 | if mixerWagonFillType ~= nil then |
426 | return true; |
427 | end |
428 | return superFunc(self, fillType, allowEmptying); |
429 | end |
getCapacity
DescriptionReturns the capacity of all fill units that support the given fill typeDefinition
getCapacity(integer fillType, float capacity)Arguments
integer | fillType | fill type |
float | capacity | capacity |
435 | function MixerWagon:getCapacity(superFunc, fillType) |
436 | local capacity = 0; |
437 | for _,fillUnit in pairs(self.fillUnits) do |
438 | if fillType == nil or fillType == FillUtil.FILLTYPE_UNKNOWN or fillUnit.fillTypes[fillType] then |
439 | capacity = capacity + fillUnit.capacity; |
440 | end |
441 | end |
442 | |
443 | if self:getFillLevel() == capacity then |
444 | return self:getFillLevel(fillType); |
445 | end; |
446 | |
447 | return capacity; |
448 | 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 |
454 | function MixerWagon:getFillLevel(superFunc, fillType) |
455 | local totalFillLevel = 0; |
456 | -- always return the overall fillLevel |
457 | for _, mixerWagonFillType in pairs(self.mixerWagonFillTypes) do |
458 | totalFillLevel = totalFillLevel + mixerWagonFillType.fillLevel; |
459 | end |
460 | |
461 | return totalFillLevel; |
462 | 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 |
470 | function MixerWagon:setFillLevel(superFunc, fillLevel, fillType, force, fillInfo) |
471 | if not self:allowFillType(fillType) then |
472 | return; |
473 | end |
474 | self:setUnitFillLevel(self.mixerWagon.fillUnitIndex, fillLevel, fillType, force, fillInfo) |
475 | 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 |
484 | function MixerWagon:setUnitFillLevel(superFunc, fillUnitIndex, fillLevel, fillType, force, fillInfo) |
485 | if fillUnitIndex ~= self.mixerWagon.fillUnitIndex then |
486 | superFunc(self, fillUnitIndex, fillLevel, fillType, force, fillInfo); |
487 | return; |
488 | end |
489 | |
490 | if not self:allowFillType(fillType, false) then |
491 | return; |
492 | end |
493 | |
494 | fillLevel = Utils.clamp(fillLevel, 0, self:getUnitCapacity(self.mixerWagon.fillUnitIndex)); |
495 | |
496 | local mixerWagonFillType = self.fillTypeToMixerWagonFillType[fillType]; |
497 | if mixerWagonFillType == nil then |
498 | if fillLevel == 0 and fillType == FillUtil.FILLTYPE_UNKNOWN then |
499 | for _,entry in pairs(self.mixerWagonFillTypes) do |
500 | entry.fillLevel = 0; |
501 | end |
502 | superFunc(self, fillUnitIndex, fillLevel, fillType, true, fillInfo); |
503 | return; |
504 | end |
505 | |
506 | -- used for discharge |
507 | if fillLevel < self:getUnitFillLevel(self.mixerWagon.fillUnitIndex) and self:getUnitFillLevel(self.mixerWagon.fillUnitIndex) > 0 then |
508 | -- remove values from all fill types such that the ratio doesn't change |
509 | fillLevel = Utils.clamp(fillLevel, 0, self:getUnitCapacity(self.mixerWagon.fillUnitIndex)); |
510 | local delta = fillLevel - self:getUnitFillLevel(self.mixerWagon.fillUnitIndex); |
511 | |
512 | local newFillLevel = 0; |
513 | for _, entry in pairs(self.mixerWagonFillTypes) do |
514 | local entryDelta = delta * (entry.fillLevel / self:getUnitFillLevel(self.mixerWagon.fillUnitIndex)); |
515 | entry.fillLevel = math.max(entry.fillLevel + entryDelta, 0); |
516 | newFillLevel = newFillLevel + entry.fillLevel; |
517 | end |
518 | |
519 | self:raiseDirtyFlags(self.mixerWagonDirtyFlag); |
520 | |
521 | superFunc(self, fillUnitIndex, newFillLevel, fillType, force, fillInfo); |
522 | else |
523 | end |
524 | return; |
525 | end |
526 | |
527 | local fillUnitIndex = self.mixerWagon.fillUnitIndex; |
528 | local fillUnit = self.fillUnits[fillUnitIndex]; |
529 | |
530 | local delta = fillLevel - fillUnit.fillLevel; |
531 | local free = fillUnit.capacity - fillUnit.fillLevel; |
532 | |
533 | if delta > 0 then |
534 | mixerWagonFillType.fillLevel = mixerWagonFillType.fillLevel + math.min(free, delta); |
535 | elseif delta < 0 then |
536 | mixerWagonFillType.fillLevel = math.max(0, mixerWagonFillType.fillLevel + delta); |
537 | end |
538 | |
539 | if delta > 0 then |
540 | self.mixingActiveTimer = self.mixingActiveTimerMax; |
541 | self.mixerWagonLastPickupTime = g_currentMission.time; |
542 | end |
543 | |
544 | local newFillLevel = 0; |
545 | for _, mixerWagonFillType in pairs(self.mixerWagonFillTypes) do |
546 | newFillLevel = newFillLevel + mixerWagonFillType.fillLevel; |
547 | end |
548 | newFillLevel = Utils.clamp(newFillLevel, 0, self:getUnitCapacity(fillUnitIndex)); |
549 | |
550 | local newFillType = FillUtil.FILLTYPE_UNKNOWN; |
551 | |
552 | local isSingleFilled = false; |
553 | for _, mixerWagonFillType in pairs(self.mixerWagonFillTypes) do |
554 | if newFillLevel == mixerWagonFillType.fillLevel then |
555 | isSingleFilled = true; |
556 | newFillType = next(mixerWagonFillType.fillTypes); |
557 | break; |
558 | end |
559 | end |
560 | |
561 | local isForageOk = false; |
562 | if not isSingleFilled then |
563 | isForageOk = true; |
564 | for _, mixerWagonFillType in pairs(self.mixerWagonFillTypes) do |
565 | if mixerWagonFillType.fillLevel < mixerWagonFillType.minPercentage * newFillLevel - 0.01 or mixerWagonFillType.fillLevel > mixerWagonFillType.maxPercentage * newFillLevel + 0.01 then |
566 | isForageOk = false; |
567 | break; |
568 | end |
569 | end |
570 | end |
571 | |
572 | if isForageOk then |
573 | newFillType = FillUtil.FILLTYPE_FORAGE; |
574 | elseif not isSingleFilled then |
575 | newFillType = FillUtil.FILLTYPE_FORAGE_MIXING; |
576 | end |
577 | |
578 | superFunc(self, fillUnitIndex, newFillLevel, newFillType, true, fillInfo); |
579 | |
580 | self:raiseDirtyFlags(self.mixerWagonDirtyFlag); |
581 | |
582 | 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 |
590 | function MixerWagon:allowUnitFillType(superFunc, fillUnitIndex, inputFillType, allowEmptying) |
591 | if fillUnitIndex ~= self.mixerWagon.fillUnitIndex then |
592 | return superFunc(self, fillUnitIndex, inputFillType, allowEmptying); |
593 | end |
594 | |
595 | local isAllowed = false; |
596 | for _, entry in pairs(self.mixerWagonFillTypes) do |
597 | if entry.fillTypes[inputFillType] == true then |
598 | isAllowed = true; |
599 | break; |
600 | end |
601 | end |
602 | |
603 | if not isAllowed then |
604 | isAllowed = superFunc(self, fillUnitIndex, inputFillType, allowEmptying); |
605 | end |
606 | |
607 | return isAllowed; |
608 | end |
getUnitFillType
DescriptionReturns current fill type of fill unitDefinition
getUnitFillType(integer fillUnitIndex)Arguments
integer | fillUnitIndex | index of fill unit |
integer | fillType | fill type |
614 | function MixerWagon:getUnitFillType(superFunc, fillUnitIndex) |
615 | |
616 | if fillUnitIndex == self.trailer.fillUnitIndex then |
617 | if self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN then |
618 | |
619 | local currentFillType; |
620 | |
621 | local fillUnit = self.fillUnits[self.trailer.fillUnitIndex]; |
622 | if fillUnit.currentFillType == FillUtil.FILLTYPE_FORAGE_MIXING and fillUnit.fillLevel > 0 then |
623 | local maxFillType = FillUtil.FILLTYPE_UNKNOWN; |
624 | for _, entry in pairs(self.mixerWagonFillTypes) do |
625 | if entry.fillLevel > 0 then |
626 | maxFillType = next(entry.fillTypes); |
627 | break; |
628 | end |
629 | end |
630 | currentFillType = maxFillType; |
631 | else |
632 | currentFillType = fillUnit.currentFillType; |
633 | end |
634 | |
635 | return currentFillType; |
636 | |
637 | else |
638 | return superFunc(self, fillUnitIndex); |
639 | end |
640 | else |
641 | return superFunc(self, fillUnitIndex); |
642 | end |
643 | |
644 | end |
getCanTipToGround
DescriptionReturns if can be tipped to groundDefinition
getCanTipToGround()Return Values
boolean | canTipToGround | can tip to ground |
649 | function MixerWagon:getCanTipToGround(superFunc) |
650 | if TipUtil.isValid() then |
651 | local currentFillType; |
652 | |
653 | local fillUnit = self.fillUnits[self.trailer.fillUnitIndex]; |
654 | if fillUnit.currentFillType == FillUtil.FILLTYPE_FORAGE_MIXING and fillUnit.fillLevel > 0 then |
655 | local maxFillType = FillUtil.FILLTYPE_UNKNOWN; |
656 | for _, entry in pairs(self.mixerWagonFillTypes) do |
657 | if entry.fillLevel > 0 then |
658 | maxFillType = next(entry.fillTypes); |
659 | break; |
660 | end |
661 | end |
662 | currentFillType = maxFillType; |
663 | else |
664 | currentFillType = fillUnit.currentFillType; |
665 | end |
666 | |
667 | if currentFillType == FillUtil.FILLTYPE_UNKNOWN then |
668 | return true; |
669 | end |
670 | return TipUtil.getCanTipToGround(currentFillType); |
671 | else |
672 | return false; |
673 | end |
674 | end |
mixerWagonBaleTriggerCallback
DescriptionTrigger callbackDefinition
mixerWagonBaleTriggerCallback(integer triggerId, integer otherActorId, boolean onEnter, boolean onLeave, boolean onStay, integer otherShapeId)Arguments
integer | triggerId | id of trigger |
integer | otherActorId | id of other actor |
boolean | onEnter | on enter |
boolean | onLeave | on leave |
boolean | onStay | on stay |
integer | otherShapeId | id of other shape |
684 | function MixerWagon:mixerWagonBaleTriggerCallback(triggerId, otherActorId, onEnter, onLeave, onStay, otherShapeId) |
685 | if onEnter then |
686 | -- this happens if a compound child of a deleted compound is entering |
687 | if otherActorId ~= 0 then |
688 | local object = g_currentMission:getNodeObject(otherActorId); |
689 | if object ~= nil then |
690 | if object:isa(Bale) then |
691 | local fillLevel = object:getFillLevel(); |
692 | local fillType = object:getFillType(); |
693 | |
694 | if self:allowFillType(fillType, false) then |
695 | fillLevel = fillLevel + self:getFillLevel(); |
696 | self:setUnitFillLevel(self.mixerWagon.fillUnitIndex, fillLevel, fillType, false, self.fillVolumeLoadInfos[self.mixerWagon.loadInfoIndex]); |
697 | |
698 | object:delete(); |
699 | self.mixingActiveTimer = self.mixingActiveTimerMax; |
700 | self:raiseDirtyFlags(self.mixerWagonDirtyFlag); |
701 | else |
702 | if self.isClient then |
703 | g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_CRITICAL, g_i18n:getText("warning_baleNotSupported")); |
704 | end |
705 | g_server:broadcastEvent(MixerWagonBaleNotAcceptedEvent:new(vehicle), nil, nil, vehicle); |
706 | end |
707 | end |
708 | end |
709 | end |
710 | end |
711 | end |
drawMixerWagonHelp
DescriptionDraw mixer wagon helpDefinition
drawMixerWagonHelp(float posY)Arguments
float | posY | y position |
716 | function MixerWagon:drawMixerWagonHelp(posY, param) |
717 | -- do not draw mixer wagon help when in game message is visible |
718 | if g_currentMission.inGameMessage:getIsVisible() then return; end |
719 | |
720 | local posX = g_currentMission.helpBoxTextPos1X; |
721 | local posX2 = g_currentMission.helpBoxTextPos2X; |
722 | |
723 | setTextColor(g_currentMission.helpBoxTextColor[1], g_currentMission.helpBoxTextColor[2], g_currentMission.helpBoxTextColor[3], g_currentMission.helpBoxTextColor[4]); |
724 | |
725 | posY = posY - self.mixerWagonHelpHeightPerFruit |
726 | setTextBold(true); |
727 | renderText(posX, posY + (self.mixerWagonHelpHeightPerFruit-g_currentMission.helpBoxTextSize)*0.5, g_currentMission.helpBoxTextSize, g_i18n:getText("info_mixingRatio")); |
728 | setTextBold(false); |
729 | |
730 | local totalFillLevel = 0; |
731 | if self:getUnitFillLevel(self.mixerWagon.fillUnitIndex) > 0 then |
732 | for _, mixerWagonFillType in pairs(self.mixerWagonFillTypes) do |
733 | totalFillLevel = totalFillLevel + mixerWagonFillType.fillLevel; |
734 | end |
735 | end |
736 | |
737 | for _, mixerWagonFillType in pairs(self.mixerWagonFillTypes) do |
738 | posY = posY - self.mixerWagonHelpHeightPerFruit; |
739 | |
740 | local percentage = 0; |
741 | if self:getUnitFillLevel(self.mixerWagon.fillUnitIndex) > 0 then |
742 | percentage = mixerWagonFillType.fillLevel / totalFillLevel; |
743 | end |
744 | |
745 | if mixerWagonFillType.fillLevel > 0 then |
746 | if self:getUnitFillType(self.mixerWagon.fillUnitIndex) ~= FillUtil.FILLTYPE_FORAGE_MIXING or (percentage >= mixerWagonFillType.minPercentage and percentage <= mixerWagonFillType.maxPercentage) then |
747 | mixerWagonFillType.statusBar:setColor(unpack(mixerWagonFillType.statusBarColor)); |
748 | else |
749 | mixerWagonFillType.statusBar:setColor(unpack(mixerWagonFillType.statusBarColor2)); |
750 | end |
751 | end |
752 | mixerWagonFillType.statusBar:setPosition(posX2 - mixerWagonFillType.statusBar.width, posY+(self.mixerWagonHelpHeightPerFruit-mixerWagonFillType.statusBar.height)*0.5); |
753 | mixerWagonFillType.statusBar:setValue(percentage); |
754 | mixerWagonFillType.statusBar:render(); |
755 | |
756 | if mixerWagonFillType.overlay ~= nil then |
757 | mixerWagonFillType.overlay:setPosition(posX, posY+(self.mixerWagonHelpHeightPerFruit-mixerWagonFillType.overlay.height)*0.5) |
758 | mixerWagonFillType.overlay:render() |
759 | end |
760 | |
761 | setTextAlignment(RenderText.ALIGN_LEFT); |
762 | renderText(posX + self.mixerWagonFillLevelTextOffsetX, posY+self.mixerWagonFillLevelTextOffsetY, g_currentMission.helpBoxTextSize, string.format("%1.2f%%", percentage * 100)); |
763 | |
764 | |
765 | local y = mixerWagonFillType.statusBar.y + mixerWagonFillType.statusBar.height*0.5 |
766 | local maxLeft = mixerWagonFillType.statusBar.x + mixerWagonFillType.statusBar.width; |
767 | local xLeft = math.min(mixerWagonFillType.statusBar.x + mixerWagonFillType.statusBar.width*mixerWagonFillType.minPercentage, maxLeft); |
768 | local xRight = math.min(mixerWagonFillType.statusBar.x + mixerWagonFillType.statusBar.width*mixerWagonFillType.maxPercentage, maxLeft); |
769 | self.mixerWagonFillRangeMarkerOverlay:setInvertX(false) |
770 | self.mixerWagonFillRangeMarkerOverlay:setPosition(xLeft, y) |
771 | self.mixerWagonFillRangeMarkerOverlay:render() |
772 | self.mixerWagonFillRangeMarkerOverlay:setInvertX(true) |
773 | self.mixerWagonFillRangeMarkerOverlay:setPosition(xRight-self.mixerWagonFillRangeMarkerOverlay.width, y) |
774 | self.mixerWagonFillRangeMarkerOverlay:render() |
775 | end |
776 | end |
onTurnedOn
DescriptionCalled on turn onDefinition
onTurnedOn(boolean noEventSend)Arguments
boolean | noEventSend | no event send |
781 | function MixerWagon:onTurnedOn(noEventSend) |
782 | if self.isClient then |
783 | SoundUtil.stopSample(self.sampleMixerWagonStop, true); |
784 | SoundUtil.stopSample(self.sampleMixerWagonPickup, true); |
785 | SoundUtil.stop3DSample(self.sampleMixerWagonPickup); |
786 | if self:getIsActiveForSound() then |
787 | SoundUtil.playSample(self.sampleMixerWagonStart, 1, 0, nil); |
788 | end |
789 | end |
790 | end |
onTurnedOff
DescriptionCalled on turn offDefinition
onTurnedOff(boolean noEventSend)Arguments
boolean | noEventSend | no event send |
795 | function MixerWagon:onTurnedOff(noEventSend) |
796 | if self.isClient then |
797 | SoundUtil.stopSample(self.sampleMixerWagonStart, true); |
798 | SoundUtil.stopSample(self.sampleMixerWagonPickup, true); |
799 | SoundUtil.stop3DSample(self.sampleMixerWagonPickup); |
800 | if self:getIsActiveForSound() then |
801 | SoundUtil.playSample(self.sampleMixerWagonStop, 1, 0, nil); |
802 | end |
803 | end |
804 | end |
getCanBeTurnedOn
DescriptionReturns if can be turned onDefinition
getCanBeTurnedOn()Return Values
boolean | canBeTurnedOn | vehicle can be turned on |
809 | function MixerWagon:getCanBeTurnedOn(superFunc) |
810 | if superFunc ~= nil then |
811 | return superFunc(self); |
812 | end |
813 | return true; |
814 | end |
getIsTurnedOnAllowed
DescriptionReturns if turn on is allowedDefinition
getIsTurnedOnAllowed(boolean isTurnedOn)Arguments
boolean | isTurnedOn | is turned on |
boolean | allow | allow turn on |
820 | function MixerWagon:getIsTurnedOnAllowed(superFunc, isTurnedOn) |
821 | if superFunc ~= nil then |
822 | return superFunc(self, isTurnedOn); |
823 | end |
824 | return true; |
825 | end |
getAllowFillShovel
DescriptionReturns fill shovel is allowedDefinition
getAllowFillShovel(integer fillType)Arguments
integer | fillType | fill type |
boolean | allowed | fill shovel is allowed |
831 | function MixerWagon:getAllowFillShovel(superFunc, fillType) |
832 | if self:getIsTurnedOn() then |
833 | if superFunc ~= nil then |
834 | return superFunc(self, fillType); |
835 | end |
836 | end |
837 | return false; |
838 | end |
fillShovelFromGroundValue
DescriptionFill shovel from groundDefinition
fillShovelFromGroundValue(table areas, integer fillType)Arguments
table | areas | areas |
integer | fillType | fill type |
float | value | picked up value |
845 | function MixerWagon:fillShovelFromGroundValue(superFunc, areas, fillType) |
846 | local value = false; |
847 | if superFunc ~= nil then |
848 | value = superFunc(self, areas, fillType) |
849 | end |
850 | if value then |
851 | self.mixerWagonLastPickupTime = g_currentMission.time; |
852 | end |
853 | return value; |
854 | end |
fillShovelFromTrigger
DescriptionFill shovel from triggerDefinition
fillShovelFromTrigger(table shovelTrigger, float deltaFillLevel, integer fillType, float dt)Arguments
table | shovelTrigger | shovelTrigger |
float | deltaFillLevel | fill level to fill |
integer | fillType | fill type to fill |
float | dt | time since last call in ms |
float | realFillDelta | real fill delta |
863 | function MixerWagon:fillShovelFromTrigger(superFunc, shovelTrigger, deltaFillLevel, fillType, dt) |
864 | local value = 0; |
865 | if superFunc ~= nil then |
866 | value = superFunc(self, shovelTrigger, deltaFillLevel, fillType, dt) |
867 | end |
868 | if value > 0 then |
869 | self.mixerWagonLastPickupTime = g_currentMission.time; |
870 | end |
871 | return value; |
872 | end |