From 8c4551958df868d7e8b55efb46c170e01de2969d Mon Sep 17 00:00:00 2001 From: masterdraco Date: Thu, 24 Sep 2026 02:00:37 +0200 Subject: [PATCH] =?UTF-8?q?feat(lagre):=20staldenes=20produktion=20for=20a?= =?UTF-8?q?lle=20dyretyper=20(m=C3=A6lk,=20g=C3=B8dning,=20gylle,=20=C3=A6?= =?UTF-8?q?g,=20uld,=20gedem=C3=A6lk)=20fra=20output-kurver=20=C3=97=20ant?= =?UTF-8?q?al=20dyr=20(v1.15.1.0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FS25_ADSmartPickup/adSources.lua | 41 ++++++++++++++++++++++++++++++++ FS25_ADSmartPickup/modDesc.xml | 2 +- tests/test_adSources.lua | 38 +++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/FS25_ADSmartPickup/adSources.lua b/FS25_ADSmartPickup/adSources.lua index e61ac47..7cbdbee 100644 --- a/FS25_ADSmartPickup/adSources.lua +++ b/FS25_ADSmartPickup/adSources.lua @@ -678,6 +678,46 @@ local function addHusbandryRates(rates, placeable) end end +-- Staldens produktion: dyrenes output-kurver (liter pr. dyr pr. døgn efter alder) × antal dyr pr. +-- klynge. Output-navne uden fillType: milk -> MILK, manure -> MANURE, liquidManure -> LIQUIDMANURE. +local OUTPUT_DEFAULTS = {milk = "MILK", manure = "MANURE", liquidManure = "LIQUIDMANURE"} + +local function resolveFillType(value, outputName) + if type(value) == "number" then return value end + local name = type(value) == "string" and value or OUTPUT_DEFAULTS[outputName] + if name == nil or g_fillTypeManager == nil or g_fillTypeManager.getFillTypeIndexByName == nil then return nil end + return g_fillTypeManager:getFillTypeIndexByName(name) +end + +local function curveValue(def, age) + local curve = type(def) == "table" and def.curve or def + if curve == nil or curve.get == nil then return nil end + local ok, value = pcall(curve.get, curve, age) + return ok and type(value) == "number" and value or nil +end + +local function addAnimalProduction(rates, placeable) + local animalSystem = g_currentMission ~= nil and g_currentMission.animalSystem or nil + if placeable.getClusters == nil or animalSystem == nil or animalSystem.getSubTypeByIndex == nil then return end + local ok, clusters = pcall(placeable.getClusters, placeable) + if not ok or type(clusters) ~= "table" then return end + for _, cluster in ipairs(clusters) do + local subTypeIndex = cluster.getSubTypeIndex ~= nil and cluster:getSubTypeIndex() or cluster.subTypeIndex + local subType = subTypeIndex ~= nil and animalSystem:getSubTypeByIndex(subTypeIndex) or nil + local age = cluster.getAge ~= nil and cluster:getAge() or cluster.age + local count = cluster.getNumAnimals ~= nil and cluster:getNumAnimals() or cluster.numAnimals or 0 + if subType ~= nil and type(subType.output) == "table" and age ~= nil and count > 0 then + for outputName, def in pairs(subType.output) do + local perAnimal = curveValue(def, age) + local fillType = resolveFillType(type(def) == "table" and (def.fillType or def.fillTypeIndex) or nil, outputName) + if perAnimal ~= nil and perAnimal > 0 then + addRate(rates, fillType, "production", perAnimal * count) + end + end + end + end +end + -- {[fillType] = {consumption, production}} i liter pr. døgn for gårdens fabrikker og stalde. function ADSources.getFarmRates(adEnv, farmId) local placeables = g_currentMission ~= nil and g_currentMission.placeableSystem ~= nil and g_currentMission.placeableSystem.placeables or {} @@ -688,6 +728,7 @@ function ADSources.getFarmRates(adEnv, farmId) addFactoryRates(rates, placeable) elseif placeable.getHusbandryFillLevel ~= nil then addHusbandryRates(rates, placeable) + pcall(addAnimalProduction, rates, placeable) end end end diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml index e5efe2b..4fe0f7e 100644 --- a/FS25_ADSmartPickup/modDesc.xml +++ b/FS25_ADSmartPickup/modDesc.xml @@ -1,7 +1,7 @@ masterdraco - 1.15.0.0 + 1.15.1.0 <en>AD Smart Pickup</en> diff --git a/tests/test_adSources.lua b/tests/test_adSources.lua index 23bf8b9..1a72779 100644 --- a/tests/test_adSources.lua +++ b/tests/test_adSources.lua @@ -405,5 +405,43 @@ check("S18 bedste pris", quote.price, 2.0) check("S18 top ved 80 % af kurven", quote.top, 2.5) check("S18 intet salgssted -> nil", ADSources.getMarketQuote(FORAGE), nil) +-- S19: staldenes produktion pr. døgn fra dyrenes output-kurver (liter pr. dyr pr. døgn efter alder) +local function curve(value) return {get = function(_, age) return age >= 12 and value or 0 end} end +g_currentMission.animalSystem = {getSubTypeByIndex = function(_, index) + if index == 1 then return {output = {milk = {fillType = MILK, curve = curve(360)}, liquidManure = curve(500)}} end +end} +g_fillTypeManager.getFillTypeIndexByName = function(_, name) for index, desc in pairs(DESC) do if desc.name == name then return index end end end +local producingBarn = { + rootNode = {x = 5000, z = 5000}, ownerFarmId = 1, getOwnerFarmId = function() return 1 end, getName = function() return "Malkestald" end, + getHusbandryFillLevel = function() return 0 end, + getClusters = function() return { + {getSubTypeIndex = function() return 1 end, getAge = function() return 24 end, getNumAnimals = function() return 10 end}, + {getSubTypeIndex = function() return 1 end, getAge = function() return 6 end, getNumAnimals = function() return 5 end}, -- kalve: 0 + } end, +} +table.insert(g_currentMission.placeableSystem.placeables, producingBarn) +local rates2 = ADSources.getFarmRates(adEnv, 1) +check("S19 mælk 10 køer × 360", rates2[MILK].production, 3600) +check("S19 gylle via navn", rates2[SLURRY].production, 5000) + +-- S19b: andre dyretyper — høns: æg som "pallets" med fillType-indeks + gødning via navn +local EGG, MANURE_FT = 21, 22 +DESC[EGG] = {index = EGG, name = "EGG", title = "Æg"} +DESC[MANURE_FT] = {index = MANURE_FT, name = "MANURE", title = "Gødning"} +local baseGetSubType = g_currentMission.animalSystem.getSubTypeByIndex +g_currentMission.animalSystem.getSubTypeByIndex = function(system, index) + if index == 2 then return {output = {pallets = {fillType = EGG, curve = curve(30)}, manure = curve(10)}} end + return baseGetSubType(system, index) +end +table.insert(g_currentMission.placeableSystem.placeables, { + rootNode = {x = 6000, z = 6000}, ownerFarmId = 1, getOwnerFarmId = function() return 1 end, getName = function() return "Hønsehus" end, + getHusbandryFillLevel = function() return 0 end, + getClusters = function() return {{subTypeIndex = 2, age = 12, numAnimals = 100}} end, -- felter i stedet for metoder +}) +local rates3 = ADSources.getFarmRates(adEnv, 1) +check("S19b æg 100 høns × 30", rates3[EGG] and rates3[EGG].production, 3000) +check("S19b gødning via navn", rates3[MANURE_FT] and rates3[MANURE_FT].production, 1000) +check("S19b mælk uændret", rates3[MILK].production, 3600) + print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) os.exit(failures == 0 and 0 or 1)