LUADOC - Farming Simulator 17

Printable Version

Script v1.4.4.0

Engine v7.0.0.2

Foundation Reference

ReceivingHopper

Description
Class for all receiving hoppers
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
19function ReceivingHopper.prerequisitesPresent(specializations)
20 return SpecializationUtil.hasSpecialization(Fillable, specializations);
21end;

load

Description
Called on loading
Definition
load(table savegame)
Arguments
tablesavegamesavegame
Code
26function ReceivingHopper:load(savegame)
27
28 self.setUnitFillLevel = Utils.appendedFunction(self.setUnitFillLevel, ReceivingHopper.setUnitFillLevel);
29 self.createBox = ReceivingHopper.createBox;
30 self.onBoxTriggerCallback = ReceivingHopper.onBoxTriggerCallback;
31 self.findFillableRaycastCallback = ReceivingHopper.findFillableRaycastCallback;
32 self.setCreateBoxes = Utils.overwrittenFunction(self.setCreateBoxes, ReceivingHopper.setCreateBoxes);
33
34 self.receivingHopper = {};
35 self.receivingHopper.unloadingDelay = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.receivingHopper#unloadingDelay"), 0)*1000;
36 self.receivingHopper.unloadingStartTime = -1;
37 self.receivingHopper.fillUnitIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.receivingHopper#fillUnitIndex"), 1);
38 self.receivingHopper.unloadInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.receivingHopper#unloadInfoIndex"), 1);
39 self.receivingHopper.dischargeInfoIndex = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.receivingHopper#dischargeInfoIndex"), 1);
40
41 local triggerId = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.receivingHopper.tipTrigger#index"));
42 if triggerId ~= nil and triggerId ~= 0 then
43 self.receivingHopper.tipTrigger = ReceivingTipTrigger:new(self.isServer, self.isClient);
44 self.receivingHopper.tipTrigger:load(triggerId, self);
45 self.receivingHopper.tipTrigger:register(true)
46 self.receivingHopper.tipTrigger:addUpdateEventListener(self)
47 end;
48
49 self.receivingHopper.boxSpawnPlace = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.receivingHopper.boxTrigger#boxSpawnPlaceIndex"));
50
51 self.receivingHopper.boxTriggerNode = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.receivingHopper.boxTrigger#index"));
52 if self.receivingHopper.boxTriggerNode ~= nil and self.isServer then
53 addTrigger(self.receivingHopper.boxTriggerNode, "onBoxTriggerCallback", self);
54 end;
55
56 self.receivingHopper.isOverloading = false;
57 self.receivingHopper.boxes = {};
58 local i=0;
59 while true do
60 local baseName = string.format("vehicle.receivingHopper.boxTrigger.box(%d)", i);
61 if not hasXMLProperty(self.xmlFile, baseName) then
62 break;
63 end;
64
65 local fillType = getXMLString(self.xmlFile, baseName.."#fillType");
66 local filename = getXMLString(self.xmlFile, baseName.."#filename");
67 local fillType = FillUtil.fillTypeNameToInt[fillType];
68 if fillType ~= nil then
69 self.receivingHopper.boxes[fillType] = filename;
70 else
71 print("Warning: invalid fillType '"..fillType.."'");
72 end;
73 i = i + 1;
74 end;
75
76 if self.isClient then
77 self.receivingHopper.fillScrollerNodes = Utils.loadScrollers(self.components, self.xmlFile, "vehicle.receivingHopper.fillScrollerNodes.fillScrollerNode", {}, false);
78 self.receivingHopper.fillBoxEffects = EffectManager:loadEffect(self.xmlFile, "vehicle.receivingHopper.fillEffect", self.components, self);
79 self.receivingHopper.currentBoxFillType = nil
80 end;
81
82 self.receivingHopper.litersPerMs = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.receivingHopper.boxTrigger#litersPerMinute"), 2000) / 60 / 1000;
83 self.receivingHopper.raycastNode = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.receivingHopper.raycastNode#index"));
84 self.receivingHopper.raycastMaxDistance = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.receivingHopper.raycastNode#raycastLength"), 10);
85 self.receivingHopper.objectsInBoxPlace = 0;
86 self.receivingHopper.timeUntilNextBox = 3000;
87 self.receivingHopper.nextBoxWaitTime = 3000;
88 self.receivingHopper.currentBox = nil;
89 self.receivingHopper.createBoxes = false;
90end;

delete

Description
Called on deleting
Definition
delete()
Code
94function ReceivingHopper:delete()
95 if self.receivingHopper.tipTrigger ~= nil then
96 self.receivingHopper.tipTrigger:delete();
97 end
98
99 if self.isServer then
100 if self.receivingHopper.boxTriggerNode ~= nil then
101 removeTrigger(self.receivingHopper.boxTriggerNode);
102 end;
103 end;
104
105 if self.isClient then
106 EffectManager:deleteEffects(self.receivingHopper.fillBoxEffects)
107 end;
108end;

readStream

Description
Called on client side on join
Definition
readStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
114function ReceivingHopper:readStream(streamId, connection)
115 if connection:getIsServer() then
116 self.receivingHopper.isOverloading = streamReadBool(streamId);
117 local tipTriggerId = streamReadInt32(streamId);
118 self.receivingHopper.tipTrigger:readStream(streamId, connection);
119 g_client:finishRegisterObject(self.receivingHopper.tipTrigger, tipTriggerId);
120 end;
121end;

writeStream

Description
Called on server side on join
Definition
writeStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
127function ReceivingHopper:writeStream(streamId, connection)
128 if not connection:getIsServer() then
129 streamWriteBool(streamId, self.receivingHopper.isOverloading);
130 streamWriteInt32(streamId, self.receivingHopper.tipTrigger.id);
131 self.receivingHopper.tipTrigger:writeStream(streamId, connection);
132 g_server:registerObjectInStream(connection, self.receivingHopper.tipTrigger);
133 end;
134end;

readUpdateStream

Description
Called on on update
Definition
readUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdstream ID
integertimestamptimestamp
tableconnectionconnection
Code
141function ReceivingHopper:readUpdateStream(streamId, timestamp, connection)
142 if connection:getIsServer() then
143 self.receivingHopper.isOverloading = streamReadBool(streamId);
144 end;
145end;

writeUpdateStream

Description
Called on on update
Definition
writeUpdateStream(integer streamId, table connection, integer dirtyMask)
Arguments
integerstreamIdstream ID
tableconnectionconnection
integerdirtyMaskdirty mask
Code
152function ReceivingHopper:writeUpdateStream(streamId, connection, dirtyMask)
153 if not connection:getIsServer() then
154 streamWriteBool(streamId, self.receivingHopper.isOverloading)
155 end;
156end;

update

Description
Called on update
Definition
update(float dt)
Arguments
floatdttime since last call in ms
Code
167function ReceivingHopper:update(dt)
168 if self.isClient and self:getIsActiveForInput() then
169 if InputBinding.hasEvent(InputBinding.TOGGLE_TIPSTATE) then
170 self:setCreateBoxes(not self.createBoxes);
171 end
172 end
173end;

updateTick

Description
Called on update tick
Definition
updateTick(float dt)
Arguments
floatdttime since last call in ms
Code
178function ReceivingHopper:updateTick(dt)
179 if self.isServer then
180 self.receivingHopper.isOverloading = false;
181 local fillLevel = self:getUnitFillLevel(self.receivingHopper.fillUnitIndex);
182 if fillLevel > 0 then
183 local fillType = self:getUnitFillType(self.receivingHopper.fillUnitIndex);
184 if self.receivingHopper.currentBox ~= nil then
185 if self.receivingHopper.currentBox:getFillLevel() < self.receivingHopper.currentBox:getCapacity() then
186 local delta = math.min(math.min(self.receivingHopper.litersPerMs * dt, fillLevel), self.receivingHopper.currentBox:getCapacity() - self.receivingHopper.currentBox:getFillLevel());
187 self.receivingHopper.currentBox:setFillLevel(self.receivingHopper.currentBox:getFillLevel() + delta);
188 self:setUnitFillLevel(self.receivingHopper.fillUnitIndex, fillLevel - delta, fillType, false, self.fillVolumeUnloadInfos[self.receivingHopper.unloadInfoIndex]);
189 self.receivingHopper.isOverloading = true;
190 end;
191 else
192 if self.receivingHopper.objectsInBoxPlace == 0 then
193 self.fillableObject = nil;
194 if self.receivingHopper.raycastNode ~= nil then
195 local x,y,z = getWorldTranslation(self.receivingHopper.raycastNode);
196 local dx,dy,dz = localDirectionToWorld(self.receivingHopper.raycastNode, 0,-1,0);
197 raycastAll(x,y,z, dx,dy,dz, "findFillableRaycastCallback", self.receivingHopper.raycastMaxDistance, self);
198 end
199
200 if self.fillableObject == nil then
201 self.receivingHopper.timeUntilNextBox = self.receivingHopper.timeUntilNextBox - dt;
202 if self.receivingHopper.timeUntilNextBox < 0 then
203 if g_currentMission:getCanAddLimitedObject(FSBaseMission.LIMITED_OBJECT_TYPE_PALLET) then
204 self:createBox();
205 else
206 if self.createBoxes then
207 g_currentMission:showBlinkingWarning(g_i18n:getText("warning_tooManyPallets"), 2000)
208 end
209 end
210 self.receivingHopper.timeUntilNextBox = self.receivingHopper.nextBoxWaitTime;
211 end
212 else
213 local object = self.fillableObject;
214 if object:allowFillType(fillType) then
215 if self.receivingHopper.unloadingStartTime < 0 then
216 self.receivingHopper.unloadingStartTime = g_currentMission.time;
217 end;
218
219 local freeCapacity = object:getCapacity(fillType) - object:getFillLevel(fillType);
220 if freeCapacity > 0 then
221 self.receivingHopper.isOverloading = true;
222 end;
223
224 if self.receivingHopper.unloadingStartTime + self.receivingHopper.unloadingDelay < g_currentMission.time then
225 local delta = math.min(fillLevel, freeCapacity, self.receivingHopper.litersPerMs * dt);
226 if math.abs(delta) > 0 then
227 self:setUnitFillLevel(self.receivingHopper.fillUnitIndex, fillLevel - delta, fillType, false, self.fillVolumeUnloadInfos[self.receivingHopper.unloadInfoIndex]);
228 object:setFillLevel(object:getFillLevel(fillType) + delta, fillType, false, self.fillVolumeDischargeInfos[self.receivingHopper.dischargeInfoIndex]);
229 else
230 self.receivingHopper.unloadingStartTime = -1;
231 end
232 end;
233 end
234 end
235 else
236 self.receivingHopper.timeUntilNextBox = self.receivingHopper.nextBoxWaitTime;
237 end;
238 end;
239 end;
240 end;
241
242 if self.isClient then
243 Utils.updateScrollers(self.receivingHopper.fillScrollerNodes, dt, self.receivingHopper.isOverloading, self.receivingHopper.isOverloading);
244
245 if self.receivingHopper.fillBoxEffects ~= nil then
246 if self.receivingHopper.isOverloading then
247 local lastValidFillType = self:getUnitLastValidFillType(self.receivingHopper.fillUnitIndex);
248 EffectManager:setFillType(self.receivingHopper.fillBoxEffects, lastValidFillType)
249 EffectManager:startEffects(self.receivingHopper.fillBoxEffects)
250 else
251 EffectManager:stopEffects(self.receivingHopper.fillBoxEffects)
252 end
253 end
254 end;
255end;

draw

Description
Called on draw
Definition
draw()
Code
259function ReceivingHopper:draw()
260 if self.isClient then
261 if self:getIsActiveForInput() then
262 if self.createBoxes then
263 g_currentMission:addHelpButtonText(g_i18n:getText("action_disablePalletSpawning"), InputBinding.TOGGLE_TIPSTATE, nil, GS_PRIO_NORMAL);
264 else
265 g_currentMission:addHelpButtonText(g_i18n:getText("action_enablePalletSpawning"), InputBinding.TOGGLE_TIPSTATE, nil, GS_PRIO_NORMAL);
266 end
267 end
268 end
269end;

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
281function ReceivingHopper:setUnitFillLevel(fillUnitIndex, fillLevel, fillType, force, fillInfo)
282 if fillLevel > 0 then
283 if self.isClient then
284 if self.receivingHopper.fillBoxEffects ~= nil then
285 if fillType ~= self.receivingHopper.currentBoxFillType then
286 EffectManager:stopEffects(self.receivingHopper.fillBoxEffects)
287 end
288 end
289 self.receivingHopper.currentBoxFillType = fillType
290 end;
291 end;
292end;

setCreateBoxes

Description
Toggle box creating
Definition
setCreateBoxes(boolean state, boolean noEventSend)
Arguments
booleanstatenew state
booleannoEventSendno event send
Code
298function ReceivingHopper:setCreateBoxes(superFunc, state, noEventSend)
299 if superFunc ~= nil then
300 superFunc(self, state, noEventSend)
301 end
302
303 ReceivingHopperSetCreateBoxesEvent.sendEvent(self, state, noEventSend);
304 self.createBoxes = state;
305end

createBox

Description
Create box
Definition
createBox()
Code
309function ReceivingHopper:createBox()
310 if self.isServer then
311 if self.createBoxes then
312 local fillType = self:getUnitFillType(self.receivingHopper.fillUnitIndex);
313 local i3dFilename = Utils.getFilename(self.receivingHopper.boxes[fillType], self.baseDirectory);
314 local x,y,z = getWorldTranslation(self.receivingHopper.boxSpawnPlace);
315 local rx,ry,rz = getWorldRotation(self.receivingHopper.boxSpawnPlace);
316 self.receivingHopper.currentBox = FillablePallet:new(self.isServer, self.isClient);
317 self.receivingHopper.currentBox:load(i3dFilename, x,y,z, rx,ry,rz);
318 self.receivingHopper.currentBox:register();
319 end;
320 end
321end;

onBoxTriggerCallback

Description
Trigger callback
Definition
onBoxTriggerCallback(integer triggerId, integer otherId, boolean onEnter, boolean onLeave, boolean onStay, integer otherShapeId)
Arguments
integertriggerIdid of trigger
integerotherIdid of other actor
booleanonEnteron enter
booleanonLeaveon leave
booleanonStayon stay
integerotherShapeIdid of other shape
Code
331function ReceivingHopper:onBoxTriggerCallback(triggerId, otherId, onEnter, onLeave, onStay, otherShapeId)
332 if onEnter then
333 local object = g_currentMission:getNodeObject(otherShapeId);
334 if object ~= nil then
335 self.receivingHopper.objectsInBoxPlace = self.receivingHopper.objectsInBoxPlace + 1;
336 local fillType = self:getUnitFillType(self.receivingHopper.fillUnitIndex);
337 if self.receivingHopper.currentBox == nil and object:isa(FillablePallet) and object:getFillType() == fillType and object:getFillLevel() < object:getCapacity() then
338 self.receivingHopper.currentBox = object;
339 end;
340 end;
341 elseif onLeave then
342 local object = g_currentMission:getNodeObject(otherShapeId);
343 if object ~= nil then
344 self.receivingHopper.objectsInBoxPlace = math.max(0, self.receivingHopper.objectsInBoxPlace - 1);
345 end;
346 if object == self.receivingHopper.currentBox then
347 self.receivingHopper.currentBox = nil;
348 end;
349 end;
350end;

findFillableRaycastCallback

Description
Raycast callback
Definition
findFillableRaycastCallback(integer transformId, float x, float y, float z, float distance)
Arguments
integertransformIdid raycasted object
floatxx raycast position
floatyy raycast position
floatzz raycast position
floatdistancedistance to raycast position
Return Values
booleancontinuecontinue raycasting
Code
360function ReceivingHopper:findFillableRaycastCallback(transformId, x, y, z, distance)
361 local vehicle = g_currentMission.nodeToVehicle[transformId];
362 if vehicle ~= nil then
363 if vehicle.exactFillRootNode == transformId then
364 self.fillableObject = vehicle;
365 return false;
366 elseif vehicle.shovel ~= nil then
367 self.fillableObject = vehicle;
368 return false;
369 end
370 end
371 return true;
372end