45 | function Bga:load(id, xmlFile, key, customEnvironment) |
46 | |
47 | self.nodeId = id |
48 | |
49 | local siloKey = key..".digestateSilo" |
50 | |
51 | local loadingNode = I3DUtil.indexToObject(self.nodeId, getXMLString(xmlFile, siloKey..".loadingStation#node")) |
52 | if loadingNode ~= nil then |
53 | local loadingStation = LoadingStation:new(self.isServer, self.isClient) |
54 | if loadingStation:load(loadingNode, xmlFile, siloKey..".loadingStation", customEnvironment) then |
55 | self.digestateSilo.loadingStation = loadingStation |
56 | end |
57 | end |
58 | |
59 | if self.digestateSilo.loadingStation == nil then |
60 | g_logManager:warning("Could not load loading station for '%s.loadingStation'!", siloKey) |
61 | return false |
62 | end |
63 | |
64 | local storages = {} |
65 | local i = 0 |
66 | while true do |
67 | local storageKey = string.format("%s.storages.storage(%d)", siloKey, i) |
68 | if not hasXMLProperty(xmlFile, storageKey) then |
69 | break |
70 | end |
71 | |
72 | local storageNode = I3DUtil.indexToObject(self.nodeId, getXMLString(xmlFile, storageKey.."#node")) |
73 | if storageNode ~= nil then |
74 | local storage = Storage:new(self.isServer, self.isClient) |
75 | if storage:load(storageNode, xmlFile, storageKey) then |
76 | table.insert(storages, storage) |
77 | storage:setOwnerFarmId(self:getOwnerFarmId(), true) |
78 | else |
79 | g_logManager:warning("Could not load storage for '%s'!", storageKey) |
80 | end |
81 | else |
82 | g_logManager:warning("Missing 'node' for storage '%s'!", storageKey) |
83 | end |
84 | |
85 | i = i + 1 |
86 | end |
87 | |
88 | if #storages == 0 then |
89 | g_logManager:warning("Missing digestate silo storages for bga!") |
90 | return false |
91 | end |
92 | |
93 | self.digestateSilo.storages = storages |
94 | |
95 | |
96 | local bunkerKey = "placeable.bga.bunker" |
97 | local unloadingNode = I3DUtil.indexToObject(self.nodeId, getXMLString(xmlFile, bunkerKey..".unloadingStation#node")) |
98 | if unloadingNode ~= nil then |
99 | local unloadingStation = BgaSellStation:new(self.isServer, self.isClient, self) |
100 | if unloadingStation:load(unloadingNode, xmlFile, customEnvironment, bunkerKey..".unloadingStation") then |
101 | self.bunker.unloadingStation = unloadingStation |
102 | unloadingStation:addTargetStorage(self) |
103 | end |
104 | end |
105 | |
106 | if self.bunker.unloadingStation == nil then |
107 | g_logManager:warning("Could not load unloading station for '%s.unloadingStation'!", bunkerKey) |
108 | return false |
109 | end |
110 | |
111 | self.bunker.slots = {} |
112 | self.bunker.fillTypeToSlot = {} |
113 | local i = 0 |
114 | while true do |
115 | local slotKey = string.format("%s.slot(%d)", bunkerKey, i) |
116 | if not hasXMLProperty(xmlFile, slotKey) then |
117 | break |
118 | end |
119 | |
120 | local slot = {} |
121 | slot.capacity = getXMLInt(xmlFile, slotKey.."#capacity") or 40000 |
122 | slot.litersPerSecond = getXMLFloat(xmlFile, slotKey.."#litersPerSecond") or 1 |
123 | slot.fillTypes = {} |
124 | slot.fillLevel = 0 |
125 | |
126 | slot.display = DigitalDisplay:new() |
127 | if not slot.display:load(self.nodeId, xmlFile, slotKey..".display") then |
128 | slot.display = nil |
129 | else |
130 | slot.display:setValue(0) |
131 | end |
132 | |
133 | |
134 | local found = false |
135 | local j = 0 |
136 | while true do |
137 | local fillTypeKey = string.format("%s.fillType(%d)", slotKey, j) |
138 | if not hasXMLProperty(xmlFile, fillTypeKey) then |
139 | break |
140 | end |
141 | |
142 | local fillTypeCategories = getXMLString(xmlFile, fillTypeKey .. "#fillTypeCategories") |
143 | local fillTypeNames = getXMLString(xmlFile, fillTypeKey .. "#fillTypes") |
144 | local fillTypes |
145 | |
146 | if fillTypeCategories ~= nil and fillTypeNames == nil then |
147 | fillTypes = g_fillTypeManager:getFillTypesByCategoryNames(fillTypeCategories, "Warning: '"..tostring(key).. "' has invalid fillTypeCategory '%s'.") |
148 | elseif fillTypeCategories == nil and fillTypeNames ~= nil then |
149 | fillTypes = g_fillTypeManager:getFillTypesByNames(fillTypeNames, "Warning: '"..tostring(key).. "' has invalid fillType '%s'.") |
150 | else |
151 | g_logManager:warning("Missing fillTypeCategories or fillTypes attribute for bga slot '%s'!", slotKey) |
152 | end |
153 | |
154 | for _,fillTypeIndex in pairs(fillTypes) do |
155 | if self.bunker.fillTypeToSlot[fillTypeIndex] == nil then |
156 | self.bunker.fillTypeToSlot[fillTypeIndex] = slot |
157 | |
158 | if slot.fillTypes[fillTypeIndex] == nil then |
159 | found = true |
160 | slot.fillTypes[fillTypeIndex] = {} |
161 | slot.fillTypes[fillTypeIndex].fillLevel = 0 |
162 | slot.fillTypes[fillTypeIndex].scale = getXMLFloat(xmlFile, fillTypeKey.."#scale") or 1 |
163 | slot.fillTypes[fillTypeIndex].pricePerLiter = getXMLFloat(xmlFile, fillTypeKey.."#pricePerLiter") or 1 |
164 | else |
165 | g_logManager:warning("'%s' already used for '%s'!", g_fillTypeManager:getFillTypeNameByIndex(fillTypeIndex), fillTypeKey) |
166 | end |
167 | else |
168 | g_logManager:warning("'%s' already used by another slot for '%s'!", g_fillTypeManager:getFillTypeNameByIndex(fillTypeIndex), slotKey) |
169 | end |
170 | end |
171 | |
172 | j = j + 1 |
173 | end |
174 | |
175 | if found then |
176 | table.insert(self.bunker.slots, slot) |
177 | else |
178 | g_logManager:warning("No fillTypes defined for slot '%s'!", slotKey) |
179 | end |
180 | |
181 | i = i + 1 |
182 | end |
183 | |
184 | self.samples = {} |
185 | if self.isClient then |
186 | self.samples.work = g_soundManager:loadSampleFromXML(xmlFile, "placeable.bga.sounds", "work", self.baseDirectory, self.nodeId, 0, AudioGroup.ENVIRONMENT, nil, nil) |
187 | end |
188 | |
189 | g_currentMission.environment:addDayChangeListener(self) |
190 | |
191 | return true |
192 | end |
391 | function Bga:loadFromXMLFile(xmlFile, key) |
392 | self.bunker.money = getXMLFloat(xmlFile, key.."#money") or 0 |
393 | |
394 | if not self.digestateSilo.loadingStation:loadFromXMLFile(xmlFile, key..".digestateSilo.loadingStation") then |
395 | return false |
396 | end |
397 | |
398 | local i = 0 |
399 | while true do |
400 | local storageKey = string.format("%s.digestateSilo.storage(%d)", key, i) |
401 | if not hasXMLProperty(xmlFile, storageKey) then |
402 | break |
403 | end |
404 | |
405 | local index = getXMLInt(xmlFile, storageKey.."#index") |
406 | if index ~= nil then |
407 | if self.digestateSilo.storages[index] ~= nil then |
408 | if not self.digestateSilo.storages[index]:loadFromXMLFile(xmlFile, storageKey) then |
409 | return false |
410 | end |
411 | else |
412 | g_logManager:warning("Could not load digestateSilo storage. Given 'index' '%d' is not defined!", index) |
413 | end |
414 | end |
415 | |
416 | i = i + 1 |
417 | end |
418 | |
419 | local i = 0 |
420 | while true do |
421 | local slotKey = string.format("%s.slot(%d)", key, i) |
422 | if not hasXMLProperty(xmlFile, slotKey) then |
423 | break |
424 | end |
425 | |
426 | local index = getXMLInt(xmlFile, slotKey.."#index") |
427 | if index ~= nil then |
428 | local slot = self.bunker.slots[index] |
429 | if slot ~= nil then |
430 | local j = 0 |
431 | while true do |
432 | local fillTypeKey = string.format("%s.fillType(%d)", slotKey, j) |
433 | if not hasXMLProperty(xmlFile, fillTypeKey) then |
434 | break |
435 | end |
436 | |
437 | local fillTypeName = getXMLString(xmlFile, fillTypeKey.."#fillType") |
438 | local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(fillTypeName) |
439 | if fillTypeIndex ~= nil and slot.fillTypes[fillTypeIndex] ~= nil then |
440 | slot.fillTypes[fillTypeIndex].fillLevel = getXMLFloat(xmlFile, fillTypeKey.."#fillLevel") or 0 |
441 | slot.fillLevel = slot.fillLevel + slot.fillTypes[fillTypeIndex].fillLevel |
442 | end |
443 | |
444 | j = j + 1 |
445 | end |
446 | end |
447 | |
448 | if slot.fillLevel > 0 then |
449 | self.bunker.isFilled = true |
450 | self:raiseActive() |
451 | |
452 | if slot.display ~= nil then |
453 | slot.display:setValue(slot.fillLevel) |
454 | end |
455 | end |
456 | end |
457 | |
458 | i = i + 1 |
459 | end |
460 | |
461 | return true |
462 | end |
291 | function Bga:readStream(streamId, connection) |
292 | if connection:getIsServer() then |
293 | local loadingStationId = NetworkUtil.readNodeObjectId(streamId) |
294 | self.digestateSilo.loadingStation:readStream(streamId, connection) |
295 | g_client:finishRegisterObject(self.digestateSilo.loadingStation, loadingStationId) |
296 | |
297 | for _, storage in ipairs(self.digestateSilo.storages) do |
298 | local storageId = NetworkUtil.readNodeObjectId(streamId) |
299 | storage:readStream(streamId, connection) |
300 | g_client:finishRegisterObject(storage, storageId) |
301 | end |
302 | |
303 | local unloadingStationId = NetworkUtil.readNodeObjectId(streamId) |
304 | self.bunker.unloadingStation:readStream(streamId, connection) |
305 | g_client:finishRegisterObject(self.bunker.unloadingStation, unloadingStationId) |
306 | |
307 | for _, slot in ipairs(self.bunker.slots) do |
308 | slot.fillLevel = streamReadInt32(streamId) |
309 | if slot.display ~= nil then |
310 | slot.display:setValue(slot.fillLevel) |
311 | end |
312 | end |
313 | end |
314 | end |
512 | function Bga:updateTick(dt) |
513 | if self.isServer and self.bunker.isFilled then |
514 | self.bunker.updateTimer = self.bunker.updateTimer + dt |
515 | |
516 | if self.bunker.updateTimer > 1000 then |
517 | self.bunker.isFilled = false |
518 | |
519 | for _, slot in ipairs(self.bunker.slots) do |
520 | slot.fillLevel = 0 |
521 | |
522 | for _, data in pairs(slot.fillTypes) do |
523 | if data.fillLevel > 0 then |
524 | local deltaLiters = math.min(slot.litersPerSecond*g_currentMission.missionInfo.timeScale, data.fillLevel) |
525 | data.fillLevel = data.fillLevel - deltaLiters |
526 | |
527 | local converted = deltaLiters * data.scale |
528 | if converted > 0 then |
529 | self:addDigestate( converted) |
530 | end |
531 | |
532 | if deltaLiters > 0 then |
533 | self:raiseDirtyFlags(self.bgaDirtyFlag) |
534 | end |
535 | end |
536 | |
537 | slot.fillLevel = slot.fillLevel + data.fillLevel |
538 | end |
539 | |
540 | if slot.fillLevel > 0 then |
541 | self.bunker.isFilled = true |
542 | end |
543 | |
544 | if slot.display ~= nil then |
545 | slot.display:setValue(slot.fillLevel) |
546 | end |
547 | end |
548 | |
549 | self.bunker.updateTimer = 0 |
550 | end |
551 | end |
552 | end |
320 | function Bga:writeStream(streamId, connection) |
321 | if not connection:getIsServer() then |
322 | NetworkUtil.writeNodeObjectId(streamId, NetworkUtil.getObjectId(self.digestateSilo.loadingStation)) |
323 | self.digestateSilo.loadingStation:writeStream(streamId, connection) |
324 | g_server:registerObjectInStream(connection, self.digestateSilo.loadingStation) |
325 | |
326 | for _, storage in ipairs(self.digestateSilo.storages) do |
327 | NetworkUtil.writeNodeObjectId(streamId, NetworkUtil.getObjectId(storage)) |
328 | storage:writeStream(streamId, connection) |
329 | g_server:registerObjectInStream(connection, storage) |
330 | end |
331 | |
332 | NetworkUtil.writeNodeObjectId(streamId, NetworkUtil.getObjectId(self.bunker.unloadingStation)) |
333 | self.bunker.unloadingStation:writeStream(streamId, connection) |
334 | g_server:registerObjectInStream(connection, self.bunker.unloadingStation) |
335 | |
336 | for _, slot in ipairs(self.bunker.slots) do |
337 | streamWriteInt32(streamId, slot.fillLevel) |
338 | end |
339 | end |
340 | end |