279 | function PlaceableHusbandryPallets:getAllPalletsCallback(pallets) |
280 | local spec = self.spec_husbandryPallets |
281 | local fillLevel = 0 |
282 | local capacity = 0 |
283 | local maxCapacity = 0 |
284 | spec.isPalletInfoUpdateRunning = false |
285 | |
286 | for _, pallet in pairs(pallets) do |
287 | local palletCapacity = pallet:getFillUnitCapacity(spec.fillUnitIndex) |
288 | capacity = capacity + palletCapacity |
289 | maxCapacity = math.max(maxCapacity, palletCapacity) |
290 | fillLevel = fillLevel + pallet:getFillUnitFillLevel(spec.fillUnitIndex) |
291 | end |
292 | |
293 | if #pallets < spec.maxNumPallets then |
294 | capacity = maxCapacity * spec.maxNumPallets |
295 | end |
296 | |
297 | spec.fillLevel = fillLevel |
298 | spec.capacity = capacity |
299 | |
300 | if math.abs(fillLevel - spec.fillLevelSent) > 1 or math.abs(capacity - spec.capacitySent) > 1 then |
301 | spec.fillLevelSent = fillLevel |
302 | spec.capacitySent = capacity |
303 | self:raiseDirtyFlags(spec.dirtyFlag) |
304 | end |
305 | end |
396 | function PlaceableHusbandryPallets:getConditionInfos(superFunc) |
397 | local infos = superFunc(self) |
398 | |
399 | local spec = self.spec_husbandryPallets |
400 | local info = {} |
401 | local fillType = g_fillTypeManager:getFillTypeByIndex(spec.fillTypeIndex) |
402 | info.title = fillType.title |
403 | info.value = spec.fillLevel |
404 | |
405 | local ratio = 0 |
406 | if spec.capacity > 0 then |
407 | ratio = spec.fillLevel / spec.capacity |
408 | end |
409 | |
410 | info.ratio = MathUtil.clamp(ratio, 0, 1) |
411 | info.invertedBar = true |
412 | info.customUnitText = spec.fillTypeUnit |
413 | |
414 | table.insert(infos, info) |
415 | |
416 | return infos |
417 | end |
321 | function PlaceableHusbandryPallets:getPalletCallback(pallet, result, fillTypeIndex) |
322 | local spec = self.spec_husbandryPallets |
323 | spec.spawnPending = false |
324 | spec.currentPallet = pallet |
325 | |
326 | if pallet ~= nil then |
327 | if spec.palletLimitReached then |
328 | spec.palletLimitReached = false |
329 | self:raiseDirtyFlags(spec.dirtyFlag) |
330 | end |
331 | |
332 | if result == PalletSpawner.RESULT_SUCCESS then |
333 | pallet:emptyAllFillUnits(true) |
334 | end |
335 | |
336 | spec.pallets[pallet] = true |
337 | local delta = pallet:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, spec.pendingLiters, fillTypeIndex, ToolType.UNDEFINED) |
338 | |
339 | spec.pendingLiters = math.max(spec.pendingLiters - delta, 0) |
340 | |
341 | if spec.pendingLiters > 5 then |
342 | self:updatePallets() |
343 | end |
344 | elseif result == PalletSpawner.RESULT_NO_SPACE then |
345 | self:showSpawnerBlockedWarning() |
346 | elseif result == PalletSpawner.PALLET_LIMITED_REACHED then |
347 | if not spec.palletLimitReached then |
348 | spec.palletLimitReached = true |
349 | self:raiseDirtyFlags(spec.dirtyFlag) |
350 | end |
351 | end |
352 | |
353 | self:updatePalletInfo() |
354 | end |
229 | function PlaceableHusbandryPallets:onHusbandryAnimalsUpdate(clusters) |
230 | local spec = self.spec_husbandryPallets |
231 | |
232 | spec.litersPerHour = 0 |
233 | for _, cluster in ipairs(clusters) do |
234 | local subType = g_currentMission.animalSystem:getSubTypeByIndex(cluster.subTypeIndex) |
235 | if subType ~= nil then |
236 | local pallets = subType.output.pallets |
237 | if pallets ~= nil then |
238 | local age = cluster:getAge() |
239 | local litersPerAnimal = pallets:get(age) |
240 | local litersPerDay = litersPerAnimal * cluster:getNumAnimals() |
241 | |
242 | spec.litersPerHour = spec.litersPerHour + (litersPerDay / 24) |
243 | end |
244 | end |
245 | end |
246 | end |
80 | function PlaceableHusbandryPallets:onLoad(savegame) |
81 | local spec = self.spec_husbandryPallets |
82 | |
83 | spec.palletSpawner = PalletSpawner.new(self.baseDirectory) |
84 | spec.palletSpawner:load(self.components, self.xmlFile, "placeable.husbandry.pallets", self.customEnvironment, self.i3dMappings) |
85 | |
86 | local fillTypeName = self.xmlFile:getValue("placeable.husbandry.pallets#fillType") |
87 | local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(fillTypeName) |
88 | if fillTypeIndex == nil then |
89 | Logging.xmlError(self.xmlFile, "Pallet filltype '%s' not defined", fillTypeName) |
90 | self:setLoadingState(Placeable.LOADING_STATE_ERROR) |
91 | return |
92 | end |
93 | spec.fillTypeIndex = fillTypeIndex |
94 | spec.fillUnitIndex = 1 |
95 | spec.fillTypeUnit = g_i18n:convertText(self.xmlFile:getValue("placeable.husbandry.pallets#unitText") or "$l10n_unit_literShort", self.customEnvironment) |
96 | |
97 | spec.maxNumPallets = self.xmlFile:getValue("placeable.husbandry.pallets#maxNumPallets", 1) |
98 | |
99 | if self.isServer then |
100 | spec.palletTriggers = {} |
101 | self.xmlFile:iterate("placeable.husbandry.pallets.palletTrigger", function(_, key) |
102 | local node = self.xmlFile:getValue(key .. "#node", nil, self.components, self.i3dMappings) |
103 | if node ~= nil then |
104 | table.insert(spec.palletTriggers, {node=node, added=false}) |
105 | end |
106 | end) |
107 | end |
108 | |
109 | spec.isPalletInfoUpdateRunning = false |
110 | spec.animalTypeName = nil |
111 | spec.currentPallet = nil |
112 | spec.pendingLiters = 0 |
113 | spec.fillLevel = 0 |
114 | spec.fillLevelSent = 0 |
115 | spec.capacity = 0 |
116 | spec.capacitySent = 0 |
117 | spec.litersPerHour = 0 |
118 | spec.fillType = nil |
119 | spec.pallets = {} |
120 | spec.spawnPending = false |
121 | spec.palletLimitReached = false |
122 | spec.infoHudTooManyPallets = {title=g_i18n:getText("infohud_tooManyPallets"), accentuate=true} |
123 | |
124 | spec.dirtyFlag = self:getNextDirtyFlag() |
125 | end |
186 | function PlaceableHusbandryPallets:onWriteUpdateStream(streamId, connection, dirtyMask) |
187 | if not connection:getIsServer() then |
188 | local spec = self.spec_husbandryPallets |
189 | if streamWriteBool(streamId, bitAND(dirtyMask, spec.dirtyFlag) ~= 0) then |
190 | streamWriteFloat32(streamId, spec.fillLevelSent) |
191 | streamWriteFloat32(streamId, spec.capacitySent) |
192 | streamWriteBool(streamId, spec.palletLimitReached) |
193 | end |
194 | end |
195 | end |
44 | function PlaceableHusbandryPallets.registerEventListeners(placeableType) |
45 | SpecializationUtil.registerEventListener(placeableType, "onLoad", PlaceableHusbandryPallets) |
46 | SpecializationUtil.registerEventListener(placeableType, "onDelete", PlaceableHusbandryPallets) |
47 | SpecializationUtil.registerEventListener(placeableType, "onFinalizePlacement", PlaceableHusbandryPallets) |
48 | SpecializationUtil.registerEventListener(placeableType, "onReadStream", PlaceableHusbandryPallets) |
49 | SpecializationUtil.registerEventListener(placeableType, "onWriteStream", PlaceableHusbandryPallets) |
50 | SpecializationUtil.registerEventListener(placeableType, "onReadUpdateStream", PlaceableHusbandryPallets) |
51 | SpecializationUtil.registerEventListener(placeableType, "onWriteUpdateStream", PlaceableHusbandryPallets) |
52 | SpecializationUtil.registerEventListener(placeableType, "onHusbandryAnimalsUpdate", PlaceableHusbandryPallets) |
53 | SpecializationUtil.registerEventListener(placeableType, "onHusbandryAnimalsCreated", PlaceableHusbandryPallets) |
54 | end |
24 | function PlaceableHusbandryPallets.registerFunctions(placeableType) |
25 | SpecializationUtil.registerFunction(placeableType, "onPalletTriggerCallback", PlaceableHusbandryPallets.onPalletTriggerCallback) |
26 | SpecializationUtil.registerFunction(placeableType, "getAllPalletsCallback", PlaceableHusbandryPallets.getAllPalletsCallback) |
27 | SpecializationUtil.registerFunction(placeableType, "updatePallets", PlaceableHusbandryPallets.updatePallets) |
28 | SpecializationUtil.registerFunction(placeableType, "getPalletCallback", PlaceableHusbandryPallets.getPalletCallback) |
29 | SpecializationUtil.registerFunction(placeableType, "showSpawnerBlockedWarning", PlaceableHusbandryPallets.showSpawnerBlockedWarning) |
30 | SpecializationUtil.registerFunction(placeableType, "showPalletBlockedWarning", PlaceableHusbandryPallets.showPalletBlockedWarning) |
31 | SpecializationUtil.registerFunction(placeableType, "updatePalletInfo", PlaceableHusbandryPallets.updatePalletInfo) |
32 | end |
58 | function PlaceableHusbandryPallets.registerXMLPaths(schema, basePath) |
59 | schema:setXMLSpecializationType("Husbandry") |
60 | basePath = basePath .. ".husbandry.pallets" |
61 | schema:register(XMLValueType.NODE_INDEX, basePath .. ".palletTrigger(?)#node", "A pallet trigger") |
62 | schema:register(XMLValueType.STRING, basePath .. "#fillType", "Pallet fill type") |
63 | schema:register(XMLValueType.STRING, basePath .. "#unitText", "Pallet fill type unit") |
64 | schema:register(XMLValueType.INT, basePath .. "#maxNumPallets", "Maximum number of pallets") |
65 | PalletSpawner.registerXMLPaths(schema, basePath) |
66 | schema:setXMLSpecializationType() |
67 | end |
373 | function PlaceableHusbandryPallets:showPalletBlockedWarning() |
374 | local spec = self.spec_husbandryPallets |
375 | if self.isClient and g_currentMission:getFarmId() == self:getOwnerFarmId() then |
376 | local fillType = g_fillTypeManager:getFillTypeByIndex(spec.fillTypeIndex) |
377 | if fillType ~= nil and spec.animalTypeName ~= nil then |
378 | local text = string.format(g_i18n:getText("ingameNotification_palletSpawnerBlocked"), fillType.title, spec.animalTypeName) |
379 | g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_CRITICAL, text) |
380 | end |
381 | end |
382 | end |
421 | function PlaceableHusbandryPallets:updateOutput(superFunc, foodFactor, productionFactor, globalProductionFactor) |
422 | superFunc(self, foodFactor, productionFactor, globalProductionFactor) |
423 | |
424 | local spec = self.spec_husbandryPallets |
425 | spec.showedWarning = false |
426 | |
427 | if self.isServer and spec.litersPerHour > 0 then |
428 | spec.pendingLiters = spec.pendingLiters + productionFactor * globalProductionFactor * spec.litersPerHour * g_currentMission.environment.timeAdjustment |
429 | self:updatePallets() |
430 | end |
431 | end |