26 | function 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; |
90 | end; |
178 | function 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; |
255 | end; |
309 | function 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 |
321 | end; |
331 | function 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; |
350 | end; |