LUADOC - Farming Simulator 17

Printable Version

Script v1.4.4.0

Engine v7.0.0.2

Foundation Reference

MixerWagon

Description
Class for all mixer wagons
Functions

prerequisitesPresent

Description
Checks if all prerequisite specializations are loaded
Definition
prerequisitesPresent(table specializations)
Arguments
tablespecializationsspecializations
Return Values
booleanhasPrerequisitetrue if all prerequisite specializations are loaded
Code
20function MixerWagon.prerequisitesPresent(specializations)
21 return SpecializationUtil.hasSpecialization(Fillable, specializations) and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations);
22end

load

Description
Called on loading
Definition
load(table savegame)
Arguments
tablesavegamesavegame
Code
27function 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;
195end

delete

Description
Called on deleting
Definition
delete()
Code
199function 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()
219end

getSaveAttributesAndNodes

Description
Returns attributes and nodes to save
Definition
getSaveAttributesAndNodes(table nodeIdent)
Arguments
tablenodeIdentnode ident
Return Values
stringattributesattributes
stringnodesnodes
Code
226function 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;
236end

readStream

Description
Called on client side on join
Definition
readStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
242function 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
252end

writeStream

Description
Called on server side on join
Definition
writeStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
258function MixerWagon:writeStream(streamId, connection)
259 for i=1,table.getn(self.mixerWagonFillTypes) do
260 streamWriteFloat32(streamId, self.mixerWagonFillTypes[i].fillLevel);
261 end
262end

readUpdateStream

Description
Called on on update
Definition
readUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdstream ID
integertimestamptimestamp
tableconnectionconnection
Code
269function 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
285end

writeUpdateStream

Description
Called on on update
Definition
writeUpdateStream(integer streamId, table connection, integer dirtyMask)
Arguments
integerstreamIdstream ID
tableconnectionconnection
integerdirtyMaskdirty mask
Code
292function 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
305end

update

Description
Called on update
Definition
update(float dt)
Arguments
floatdttime since last call in ms
Code
316function 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
349end

draw

Description
Called on draw
Definition
draw()
Code
356function 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
364end

onDeactivateSounds

Description
Called on deactivating sounds
Definition
onDeactivateSounds()
Code
374function 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
380end

resetFillLevelIfNeeded

Description
Resets fill level if given fillType is different than the current fill type
Definition
resetFillLevelIfNeeded(integer fillType)
Arguments
integerfillTypefill type
Return Values
booleansuccessreturns false if reset failed
Code
386function 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);
393end

resetUnitFillLevelIfNeeded

Description
Resets fill level of fill unit if given fillType is different than the current fill type
Definition
resetUnitFillLevelIfNeeded(integer fillUnitIndex, integer fillType)
Arguments
integerfillUnitIndexindex of fill unit
integerfillTypefill type
Return Values
booleansuccessreturns false if reset failed
Code
400function 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
416end

allowFillType

Description
Returns if fill type is allowed
Definition
allowFillType(integer fillType, boolean allowEmptying)
Arguments
integerfillTypefill type
booleanallowEmptyingallow emptying
Return Values
booleanallowallow fill type
Code
423function 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);
429end

getCapacity

Description
Returns the capacity of all fill units that support the given fill type
Definition
getCapacity(integer fillType, float capacity)
Arguments
integerfillTypefill type
floatcapacitycapacity
Code
435function 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;
448end

getFillLevel

Description
Returns fill level of given fill type on all fill units
Definition
getFillLevel(integer fillType)
Arguments
integerfillTypefill type
Return Values
floatfillLevelfill level
Code
454function 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;
462end

setFillLevel

Description
Set fill level (filling all fill units that allow given fill type)
Definition
setFillLevel(float filllevel, integer fillType, boolean force, table fillInfo)
Arguments
floatfilllevelnew fill level
integerfillTypefill type
booleanforceforce action
tablefillInfofill info for fill volume
Code
470function 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)
475end

setUnitFillLevel

Description
Set unit fill level
Definition
setUnitFillLevel(integer fillUnitIndex, float fillLevel, integer fillType, boolean force, table fillInfo)
Arguments
integerfillUnitIndexindex of fill unit
floatfillLevelnew fill level
integerfillTypefill type
booleanforceforce action
tablefillInfofill info for fill volume
Code
484function 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
582end

allowUnitFillType

Description
Returns if fill type is allowed by fill unit
Definition
allowUnitFillType(integer fillUnitIndex, integer fillType, boolean allowEmptying)
Arguments
integerfillUnitIndexindex of fill unit
integerfillTypefill type
booleanallowEmptyingallow emptying
Return Values
booleanallowallow fill type
Code
590function 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;
608end

getUnitFillType

Description
Returns current fill type of fill unit
Definition
getUnitFillType(integer fillUnitIndex)
Arguments
integerfillUnitIndexindex of fill unit
Return Values
integerfillTypefill type
Code
614function 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
644end

getCanTipToGround

Description
Returns if can be tipped to ground
Definition
getCanTipToGround()
Return Values
booleancanTipToGroundcan tip to ground
Code
649function 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
674end

mixerWagonBaleTriggerCallback

Description
Trigger callback
Definition
mixerWagonBaleTriggerCallback(integer triggerId, integer otherActorId, boolean onEnter, boolean onLeave, boolean onStay, integer otherShapeId)
Arguments
integertriggerIdid of trigger
integerotherActorIdid of other actor
booleanonEnteron enter
booleanonLeaveon leave
booleanonStayon stay
integerotherShapeIdid of other shape
Code
684function 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
711end

drawMixerWagonHelp

Description
Draw mixer wagon help
Definition
drawMixerWagonHelp(float posY)
Arguments
floatposYy position
Code
716function 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
776end

onTurnedOn

Description
Called on turn on
Definition
onTurnedOn(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
781function 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
790end

onTurnedOff

Description
Called on turn off
Definition
onTurnedOff(boolean noEventSend)
Arguments
booleannoEventSendno event send
Code
795function 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
804end

getCanBeTurnedOn

Description
Returns if can be turned on
Definition
getCanBeTurnedOn()
Return Values
booleancanBeTurnedOnvehicle can be turned on
Code
809function MixerWagon:getCanBeTurnedOn(superFunc)
810 if superFunc ~= nil then
811 return superFunc(self);
812 end
813 return true;
814end

getIsTurnedOnAllowed

Description
Returns if turn on is allowed
Definition
getIsTurnedOnAllowed(boolean isTurnedOn)
Arguments
booleanisTurnedOnis turned on
Return Values
booleanallowallow turn on
Code
820function MixerWagon:getIsTurnedOnAllowed(superFunc, isTurnedOn)
821 if superFunc ~= nil then
822 return superFunc(self, isTurnedOn);
823 end
824 return true;
825end

getAllowFillShovel

Description
Returns fill shovel is allowed
Definition
getAllowFillShovel(integer fillType)
Arguments
integerfillTypefill type
Return Values
booleanallowedfill shovel is allowed
Code
831function 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;
838end

fillShovelFromGroundValue

Description
Fill shovel from ground
Definition
fillShovelFromGroundValue(table areas, integer fillType)
Arguments
tableareasareas
integerfillTypefill type
Return Values
floatvaluepicked up value
Code
845function 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;
854end

fillShovelFromTrigger

Description
Fill shovel from trigger
Definition
fillShovelFromTrigger(table shovelTrigger, float deltaFillLevel, integer fillType, float dt)
Arguments
tableshovelTriggershovelTrigger
floatdeltaFillLevelfill level to fill
integerfillTypefill type to fill
floatdttime since last call in ms
Return Values
floatrealFillDeltareal fill delta
Code
863function 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;
872end