feat(marksilo): 'Kør overskud til produktion' — foder først: staldenes forbrug × valgt antal døgn bliver på gården, overskud køres til gårdens fabrikker (v1.44.0.0)
This commit is contained in:
@@ -7,11 +7,15 @@ ADFieldSiloConfig.MAX_VEHICLES = 10
|
||||
ADFieldSiloConfig.DEFAULT_MAX_VEHICLES = 2
|
||||
ADFieldSiloConfig.MIN_LITERS_CHOICES = {5000, 10000, 25000, 50000}
|
||||
ADFieldSiloConfig.DEFAULT_MIN_LITERS = 10000
|
||||
-- foderreserve: staldenes forbrug i så mange døgn bliver på gården, før overskud køres til fabrik
|
||||
ADFieldSiloConfig.RESERVE_DAYS_CHOICES = {3, 7, 14, 30}
|
||||
ADFieldSiloConfig.DEFAULT_RESERVE_DAYS = 7
|
||||
|
||||
local function copy(cfg)
|
||||
local ids = {}
|
||||
for index, id in ipairs(cfg.storeIds or {}) do ids[index] = id end
|
||||
return {enabled = cfg.enabled == true, storeIds = ids, maxVehicles = cfg.maxVehicles, minLiters = cfg.minLiters}
|
||||
return {enabled = cfg.enabled == true, storeIds = ids, maxVehicles = cfg.maxVehicles, minLiters = cfg.minLiters,
|
||||
toProduction = cfg.toProduction == true, reserveDays = cfg.reserveDays}
|
||||
end
|
||||
|
||||
local function clampVehicles(value)
|
||||
@@ -19,19 +23,28 @@ local function clampVehicles(value)
|
||||
return math.max(1, math.min(ADFieldSiloConfig.MAX_VEHICLES, math.floor(value)))
|
||||
end
|
||||
|
||||
local function snapLiters(value)
|
||||
local function snap(value, choices, default)
|
||||
value = tonumber(value)
|
||||
if value == nil then return ADFieldSiloConfig.DEFAULT_MIN_LITERS end
|
||||
if value == nil then return default end
|
||||
local best, bestDiff = nil, nil
|
||||
for _, choice in ipairs(ADFieldSiloConfig.MIN_LITERS_CHOICES) do
|
||||
for _, choice in ipairs(choices) do
|
||||
local diff = math.abs(choice - value)
|
||||
if bestDiff == nil or diff < bestDiff then best, bestDiff = choice, diff end
|
||||
end
|
||||
return best
|
||||
end
|
||||
|
||||
local function snapLiters(value)
|
||||
return snap(value, ADFieldSiloConfig.MIN_LITERS_CHOICES, ADFieldSiloConfig.DEFAULT_MIN_LITERS)
|
||||
end
|
||||
|
||||
local function snapDays(value)
|
||||
return snap(value, ADFieldSiloConfig.RESERVE_DAYS_CHOICES, ADFieldSiloConfig.DEFAULT_RESERVE_DAYS)
|
||||
end
|
||||
|
||||
function ADFieldSiloConfig.new()
|
||||
return {enabled = false, storeIds = {}, maxVehicles = ADFieldSiloConfig.DEFAULT_MAX_VEHICLES, minLiters = ADFieldSiloConfig.DEFAULT_MIN_LITERS}
|
||||
return {enabled = false, storeIds = {}, maxVehicles = ADFieldSiloConfig.DEFAULT_MAX_VEHICLES, minLiters = ADFieldSiloConfig.DEFAULT_MIN_LITERS,
|
||||
toProduction = false, reserveDays = ADFieldSiloConfig.DEFAULT_RESERVE_DAYS}
|
||||
end
|
||||
|
||||
function ADFieldSiloConfig.with(cfg, changes)
|
||||
@@ -39,6 +52,8 @@ function ADFieldSiloConfig.with(cfg, changes)
|
||||
if changes.enabled ~= nil then new.enabled = changes.enabled == true end
|
||||
if changes.maxVehicles ~= nil then new.maxVehicles = clampVehicles(changes.maxVehicles) end
|
||||
if changes.minLiters ~= nil then new.minLiters = snapLiters(changes.minLiters) end
|
||||
if changes.toProduction ~= nil then new.toProduction = changes.toProduction == true end
|
||||
if changes.reserveDays ~= nil then new.reserveDays = snapDays(changes.reserveDays) end
|
||||
return new
|
||||
end
|
||||
|
||||
@@ -62,7 +77,8 @@ end
|
||||
|
||||
function ADFieldSiloConfig.toRecord(cfg)
|
||||
return {enabled = cfg.enabled and 1 or 0, stores = table.concat(cfg.storeIds or {}, " "),
|
||||
maxVehicles = cfg.maxVehicles, minLiters = cfg.minLiters}
|
||||
maxVehicles = cfg.maxVehicles, minLiters = cfg.minLiters, toProduction = cfg.toProduction and 1 or 0,
|
||||
reserveDays = cfg.reserveDays}
|
||||
end
|
||||
|
||||
function ADFieldSiloConfig.fromRecord(record)
|
||||
@@ -72,5 +88,7 @@ function ADFieldSiloConfig.fromRecord(record)
|
||||
cfg.enabled = tonumber(record.enabled) == 1
|
||||
cfg.maxVehicles = clampVehicles(record.maxVehicles)
|
||||
cfg.minLiters = snapLiters(record.minLiters)
|
||||
cfg.toProduction = tonumber(record.toProduction) == 1
|
||||
cfg.reserveDays = snapDays(record.reserveDays)
|
||||
return cfg
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- AD Field Silo Planner
|
||||
-- Ren planlægning for marksilo-flowet: hvilke (silo, vare) skal hjem, hvor mange lånte vogne sendes, og til
|
||||
-- hvilket gårdlager. Ingen spil-kald; input muteres ikke.
|
||||
-- hvilket gårdlager eller (med "kør til produktion") hvilken fabrik. Ingen spil-kald; input muteres ikke.
|
||||
|
||||
ADFieldSiloPlanner = {}
|
||||
|
||||
@@ -24,12 +24,16 @@ local function anyStoreTakes(stores, fillType, minLiters, reserved)
|
||||
return false
|
||||
end
|
||||
|
||||
-- Nærmeste lager med plads til hele turen; ellers det med mest plads (over tærsklen).
|
||||
local function chooseStore(stores, silo, fillType, liters, minLiters, reserved)
|
||||
local function isProduction(store)
|
||||
return store ~= nil and store.kind == "production"
|
||||
end
|
||||
|
||||
-- Nærmeste lager af den ønskede slags (fabrik/gård) med plads til hele turen; ellers det med mest plads.
|
||||
local function chooseStore(stores, silo, fillType, liters, minLiters, reserved, production)
|
||||
local best, bestD, most, mostFree = nil, nil, nil, nil
|
||||
for _, store in ipairs(stores or {}) do
|
||||
local free = freeIn(store, fillType, reserved)
|
||||
if store.markerId ~= nil and free >= minLiters then
|
||||
if store.markerId ~= nil and free >= minLiters and isProduction(store) == production then
|
||||
local d = dist2(store, silo)
|
||||
if free >= liters and (bestD == nil or d < bestD) then best, bestD = store, d end
|
||||
if mostFree == nil or free > mostFree then most, mostFree = store, free end
|
||||
@@ -55,19 +59,34 @@ local function nearestVehicle(vehicles, used, silo, fillType)
|
||||
return best
|
||||
end
|
||||
|
||||
-- Foder først: mangler gården stadig foderreserve for varen (reserve − beholdning − læs på vej hjem), køres til
|
||||
-- gårdlager; ellers til fabrik. Findes kun den ene slags, bruges den.
|
||||
local function pickStore(input, farmIncoming, task, liters, minLiters, reserved)
|
||||
local fillType = task.fillType
|
||||
local short = ((input.feedReserve or {})[fillType] or 0) - ((input.farmStock or {})[fillType] or 0) - (farmIncoming[fillType] or 0)
|
||||
local wantProduction = short <= 0
|
||||
return chooseStore(input.stores, task.silo, fillType, liters, minLiters, reserved, wantProduction)
|
||||
or chooseStore(input.stores, task.silo, fillType, liters, minLiters, reserved, not wantProduction)
|
||||
end
|
||||
|
||||
function ADFieldSiloPlanner.plan(input)
|
||||
local minLiters = input.minLiters or 10000
|
||||
local reserved, onWay = {}, {}
|
||||
local storesById = {}
|
||||
for _, store in ipairs(input.stores or {}) do storesById[store.id] = store end
|
||||
local reserved, onWay, farmIncoming = {}, {}, {}
|
||||
for _, loan in ipairs(input.loans or {}) do
|
||||
local k = key(loan.siloId, loan.fillType)
|
||||
onWay[k] = (onWay[k] or 0) + (loan.liters or 0)
|
||||
if loan.storeId ~= nil and not isProduction(storesById[loan.storeId]) then
|
||||
farmIncoming[loan.fillType] = (farmIncoming[loan.fillType] or 0) + (loan.liters or 0)
|
||||
end
|
||||
-- læs på vej til et lager optager pladsen, til de er aflæsset (også i senere runder)
|
||||
if loan.storeId ~= nil then
|
||||
local reserveKey = loan.storeId .. ":" .. tostring(loan.fillType)
|
||||
reserved[reserveKey] = (reserved[reserveKey] or 0) + (loan.liters or 0)
|
||||
end
|
||||
end
|
||||
local status, tasks = {}, {}
|
||||
local status, tasks, statusByKey = {}, {}, {}
|
||||
for _, silo in ipairs(input.silos or {}) do
|
||||
for fillType, liters in pairs(silo.stock or {}) do
|
||||
if (liters or 0) >= minLiters then
|
||||
@@ -85,6 +104,7 @@ function ADFieldSiloPlanner.plan(input)
|
||||
if rest >= minLiters then table.insert(tasks, {silo = silo, fillType = fillType, rest = rest}) end
|
||||
end
|
||||
table.insert(status, entry)
|
||||
statusByKey[k] = entry
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -104,8 +124,13 @@ function ADFieldSiloPlanner.plan(input)
|
||||
local vehicle = nearestVehicle(input.vehicles, used, task.silo, task.fillType)
|
||||
if vehicle == nil then break end
|
||||
local liters = math.min(vehicle.capacity, task.rest)
|
||||
local store = chooseStore(input.stores, task.silo, task.fillType, liters, minLiters, reserved)
|
||||
local store = pickStore(input, farmIncoming, task, liters, minLiters, reserved)
|
||||
if store == nil then break end
|
||||
if isProduction(store) then
|
||||
statusByKey[key(task.silo.id, task.fillType)].toProduction = true
|
||||
else
|
||||
farmIncoming[task.fillType] = (farmIncoming[task.fillType] or 0) + liters
|
||||
end
|
||||
used[vehicle.id] = true
|
||||
local reserveKey = store.id .. ":" .. tostring(task.fillType)
|
||||
reserved[reserveKey] = (reserved[reserveKey] or 0) + liters
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
-- AD Field Silos
|
||||
-- Marksilo-flowet i spillet: samler marksiloer, gårdlagre og ledige vogne, lader ADFieldSiloPlanner vælge,
|
||||
-- med "kør til produktion" går overskud ud over gårdens foderreserve til gårdens fabrikker;
|
||||
-- låner vogne (AutoDrive "Hent og aflever", én tur, parkering bagefter) og frigiver dem igen.
|
||||
-- Lån ligger kun i hukommelsen; opsætningen gemmes i ADSmartPickup_fieldsilos.xml.
|
||||
|
||||
@@ -142,6 +143,53 @@ local function nearStore(stores, x, z)
|
||||
return false
|
||||
end
|
||||
|
||||
-- Fabrikkens input-varer (dem aflæsningen tager imod) med fri plads i dens lager.
|
||||
local function factoryFree(placeable)
|
||||
local spec = placeable ~= nil and placeable.spec_productionPoint or nil
|
||||
local point = spec ~= nil and spec.productionPoint or nil
|
||||
local storage = point ~= nil and point.storage or nil
|
||||
if storage == nil or storage.getFreeCapacity == nil then return {} end
|
||||
local inputs = {}
|
||||
for fillType in pairs(point.inputFillTypeIds or {}) do inputs[fillType] = true end
|
||||
for _, production in ipairs(point.productions or {}) do
|
||||
for _, input in ipairs(production.inputs or {}) do inputs[input.type] = true end
|
||||
end
|
||||
local free = {}
|
||||
for fillType in pairs(inputs) do free[fillType] = storage:getFreeCapacity(fillType) or 0 end
|
||||
return free
|
||||
end
|
||||
|
||||
-- "Kør til produktion": gårdens fabrikker med aflæsningsmarkør bliver mål ved siden af gårdlagrene.
|
||||
local function addFactories(stores, buildings)
|
||||
for _, building in ipairs(buildings) do
|
||||
local markerId = building.kind == "factory" and firstMarker(building, "unload") or nil
|
||||
if markerId ~= nil then
|
||||
local x, z = position(building.placeable ~= nil and building.placeable.rootNode or nil)
|
||||
table.insert(stores, {id = building.id, name = building.name, kind = "production", markerId = markerId,
|
||||
x = x, z = z, free = factoryFree(building.placeable)})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Foderreserve (staldenes døgnforbrug × døgn) og gårdlagrenes beholdning pr. vare.
|
||||
function ADFieldSilos.collectFeed(stores, byId, fid, reserveDays)
|
||||
local reserve, stock = {}, {}
|
||||
local rates = ADSources ~= nil and ADSources.getFarmRates ~= nil and ADSources.getFarmRates(ADFieldSilos.adEnv, fid, true) or {}
|
||||
for fillType, rate in pairs(rates) do reserve[fillType] = (rate.consumption or 0) * reserveDays end
|
||||
local counted = {} -- Farma-siloer i samme klynge deler lager: tæl hvert lager én gang
|
||||
for _, store in ipairs(stores) do
|
||||
local building = byId[store.id]
|
||||
local spec = store.kind ~= "production" and building ~= nil and building.placeable ~= nil and building.placeable.spec_silo or nil
|
||||
for _, storage in pairs(spec ~= nil and spec.storages or {}) do
|
||||
if not counted[storage] then
|
||||
counted[storage] = true
|
||||
for fillType, level in pairs(storage.fillLevels or {}) do stock[fillType] = (stock[fillType] or 0) + (level or 0) end
|
||||
end
|
||||
end
|
||||
end
|
||||
return reserve, stock
|
||||
end
|
||||
|
||||
-- Gårdlagre fra opsætningen + marksiloer (alle markers marksiloer, uden dubletter og uden gårdlagre).
|
||||
function ADFieldSilos.collectBuildings(adEnv)
|
||||
local fid = farmId()
|
||||
@@ -159,6 +207,7 @@ function ADFieldSilos.collectBuildings(adEnv)
|
||||
x = x, z = z, free = siloFree(building.placeable)})
|
||||
end
|
||||
end
|
||||
if ADFieldSilos.config.toProduction then addFactories(stores, ADBuildings.list(adEnv, fid)) end
|
||||
local silos, seen = {}, runBuildingIds()
|
||||
for id in pairs(farmCluster(allSilos, storeIds)) do seen[id] = true end
|
||||
for _, info in ipairs(ADFields.list()) do
|
||||
@@ -175,7 +224,7 @@ function ADFieldSilos.collectBuildings(adEnv)
|
||||
end
|
||||
end
|
||||
end
|
||||
return silos, stores
|
||||
return silos, stores, byId
|
||||
end
|
||||
|
||||
local function trailerInfo(adEnv, vehicle)
|
||||
@@ -335,10 +384,18 @@ end
|
||||
|
||||
function ADFieldSilos.planNow(adEnv)
|
||||
local cfg = ADFieldSilos.config
|
||||
local silos, stores = ADFieldSilos.collectBuildings(adEnv)
|
||||
local silos, stores, byId = ADFieldSilos.collectBuildings(adEnv)
|
||||
local vehicles, vehiclesById = ADFieldSilos.collectVehicles(adEnv)
|
||||
local feedReserve, farmStock = nil, nil
|
||||
if cfg.toProduction then
|
||||
local ok, reserve, stock = pcall(ADFieldSilos.collectFeed, stores, byId, farmId(), cfg.reserveDays)
|
||||
if ok then feedReserve, farmStock = reserve, stock
|
||||
else Logging.warning(ADFieldSilos.LOG_PREFIX .. "foderreserve kunne ikke beregnes: %s", tostring(reserve)) end
|
||||
end
|
||||
local plan = ADFieldSiloPlanner.plan({silos = silos, stores = stores, loans = loanList(), vehicles = vehicles,
|
||||
paused = currentPaused(), maxVehicles = cfg.maxVehicles, minLiters = cfg.minLiters})
|
||||
paused = currentPaused(), maxVehicles = cfg.maxVehicles, minLiters = cfg.minLiters,
|
||||
feedReserve = feedReserve, farmStock = farmStock})
|
||||
ADFieldSilos.lastFeed = {reserve = feedReserve, stock = farmStock}
|
||||
ADFieldSilos.lastPlan = plan
|
||||
local paused = ADFieldJobs ~= nil and ADFieldJobs.state ~= nil and ADFieldJobs.state.paused
|
||||
if not cfg.enabled or paused then return plan end
|
||||
@@ -395,6 +452,8 @@ function ADFieldSilos.save()
|
||||
xmlFile:setString(ADFieldSilos.ROOT .. "#stores", record.stores)
|
||||
xmlFile:setInt(ADFieldSilos.ROOT .. "#maxVehicles", record.maxVehicles)
|
||||
xmlFile:setInt(ADFieldSilos.ROOT .. "#minLiters", record.minLiters)
|
||||
xmlFile:setInt(ADFieldSilos.ROOT .. "#toProduction", record.toProduction)
|
||||
xmlFile:setInt(ADFieldSilos.ROOT .. "#reserveDays", record.reserveDays)
|
||||
xmlFile:save()
|
||||
xmlFile:delete()
|
||||
return true
|
||||
@@ -416,6 +475,8 @@ function ADFieldSilos.load()
|
||||
stores = xmlFile:getString(ADFieldSilos.ROOT .. "#stores"),
|
||||
maxVehicles = xmlFile:getInt(ADFieldSilos.ROOT .. "#maxVehicles"),
|
||||
minLiters = xmlFile:getInt(ADFieldSilos.ROOT .. "#minLiters"),
|
||||
toProduction = xmlFile:getInt(ADFieldSilos.ROOT .. "#toProduction"),
|
||||
reserveDays = xmlFile:getInt(ADFieldSilos.ROOT .. "#reserveDays"),
|
||||
})
|
||||
xmlFile:delete()
|
||||
end
|
||||
|
||||
@@ -942,16 +942,17 @@ local function addAnimalProduction(rates, placeable)
|
||||
end
|
||||
|
||||
-- {[fillType] = {consumption, production}} i liter pr. døgn for gårdens fabrikker og stalde.
|
||||
function ADSources.getFarmRates(adEnv, farmId)
|
||||
-- feedOnly: kun staldenes forbrug (foder, halm, vand) — marksilo-flowets foderreserve.
|
||||
function ADSources.getFarmRates(adEnv, farmId, feedOnly)
|
||||
local placeables = g_currentMission ~= nil and g_currentMission.placeableSystem ~= nil and g_currentMission.placeableSystem.placeables or {}
|
||||
local rates = {}
|
||||
for _, placeable in pairs(placeables) do
|
||||
if isOwnedBy(placeable, farmId) then
|
||||
if getProductionPoint(placeable) ~= nil then
|
||||
addFactoryRates(rates, placeable)
|
||||
if not feedOnly then addFactoryRates(rates, placeable) end
|
||||
elseif placeable.getHusbandryFillLevel ~= nil then
|
||||
addHusbandryRates(rates, placeable)
|
||||
pcall(addAnimalProduction, rates, placeable)
|
||||
if not feedOnly then pcall(addAnimalProduction, rates, placeable) end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
-- Smart Pickup — fanen Marksiloer
|
||||
-- Opsætning (til/fra, maks. vogne, mindste mængde, gårdlagre) og status for marksilo-flowet.
|
||||
-- Opsætning (til/fra, maks. vogne, mindste mængde, kør til produktion + foderreserve, gårdlagre) og status for marksilo-flowet.
|
||||
-- Klik går til onClickFieldSiloRow; reglerne ligger i ADFieldSilos/ADFieldSiloPlanner.
|
||||
|
||||
SmartPickupFrame.FIELDSILO_ROW_KINDS = {fsEnabled = true, fsMaxVehicles = true, fsMinLiters = true, fsStore = true}
|
||||
SmartPickupFrame.FIELDSILO_ROW_KINDS = {fsEnabled = true, fsMaxVehicles = true, fsMinLiters = true, fsStore = true,
|
||||
fsToProduction = true, fsReserveDays = true}
|
||||
|
||||
local function numberTexts(from, to)
|
||||
local texts = {}
|
||||
@@ -16,6 +17,12 @@ local function literTexts()
|
||||
return texts
|
||||
end
|
||||
|
||||
local function dayTexts(i18n)
|
||||
local texts = {}
|
||||
for _, days in ipairs(ADFieldSiloConfig.RESERVE_DAYS_CHOICES) do table.insert(texts, string.format(i18n:getText("spu_fs_days"), days)) end
|
||||
return texts
|
||||
end
|
||||
|
||||
local function indexOf(list, value)
|
||||
for index, entry in ipairs(list) do if entry == value then return index end end
|
||||
return 1
|
||||
@@ -39,6 +46,10 @@ function SmartPickupFrame:fillFieldSiloRows(adEnv)
|
||||
self:addToggleRow("fsEnabled", i18n:getText("spu_fs_enabled"), onOff, cfg.enabled)
|
||||
self:addFieldSiloChoiceRow("fsMaxVehicles", i18n:getText("spu_fs_maxVehicles"), numberTexts(1, ADFieldSiloConfig.MAX_VEHICLES), cfg.maxVehicles)
|
||||
self:addFieldSiloChoiceRow("fsMinLiters", i18n:getText("spu_fs_minLiters"), literTexts(), indexOf(ADFieldSiloConfig.MIN_LITERS_CHOICES, cfg.minLiters))
|
||||
self:addToggleRow("fsToProduction", i18n:getText("spu_fs_toProduction"), onOff, cfg.toProduction)
|
||||
if cfg.toProduction then
|
||||
self:addFieldSiloChoiceRow("fsReserveDays", i18n:getText("spu_fs_reserveDays"), dayTexts(i18n), indexOf(ADFieldSiloConfig.RESERVE_DAYS_CHOICES, cfg.reserveDays))
|
||||
end
|
||||
|
||||
local plan = ADFieldSilos.lastPlan
|
||||
local waiting = 0
|
||||
@@ -61,6 +72,7 @@ function SmartPickupFrame:fillFieldSiloRows(adEnv)
|
||||
local title = desc ~= nil and (desc.title or desc.name) or tostring(entry.fillType)
|
||||
local state = i18n:getText("spu_fs_state_" .. entry.state)
|
||||
if entry.state == "noFarmStore" then state = string.format(state, title) end
|
||||
if entry.toProduction then state = state .. " " .. i18n:getText("spu_fs_toFactory") end
|
||||
self:addCellRow(self.fieldPrefab, {tostring(entry.siloName), title, string.format("%d", math.floor(entry.liters)),
|
||||
string.format("%d", math.floor(entry.onWay)), state, ""})
|
||||
end
|
||||
@@ -85,6 +97,10 @@ function SmartPickupFrame:onClickFieldSiloRow(state, data)
|
||||
cfg = ADFieldSiloConfig.with(cfg, {maxVehicles = state})
|
||||
elseif data.kind == "fsMinLiters" then
|
||||
cfg = ADFieldSiloConfig.with(cfg, {minLiters = ADFieldSiloConfig.MIN_LITERS_CHOICES[state]})
|
||||
elseif data.kind == "fsToProduction" then
|
||||
cfg = ADFieldSiloConfig.with(cfg, {toProduction = state == SmartPickupFrame.STATE_ON})
|
||||
elseif data.kind == "fsReserveDays" then
|
||||
cfg = ADFieldSiloConfig.with(cfg, {reserveDays = ADFieldSiloConfig.RESERVE_DAYS_CHOICES[state]})
|
||||
elseif data.kind == "fsStore" then
|
||||
cfg = ADFieldSiloConfig.toggleStore(cfg, data.buildingId)
|
||||
end
|
||||
|
||||
@@ -497,5 +497,9 @@
|
||||
<text name="spu_fs_state_noFarmStore" text="ingen gård tager %s"/>
|
||||
<text name="spu_fs_state_paused" text="pause (kom ikke i gang)"/>
|
||||
<text name="spu_fs_storesTitle" text="Gårdlagre (hvor varerne køres hjem til)"/>
|
||||
<text name="spu_fs_toProduction" text="Kør overskud til produktion (foder til staldene først)"/>
|
||||
<text name="spu_fs_reserveDays" text="Foderreserve: staldenes forbrug i"/>
|
||||
<text name="spu_fs_days" text="%d døgn"/>
|
||||
<text name="spu_fs_toFactory" text="→ fabrik"/>
|
||||
</texts>
|
||||
</l10n>
|
||||
|
||||
@@ -497,5 +497,9 @@
|
||||
<text name="spu_fs_state_noFarmStore" text="no farm storage takes %s"/>
|
||||
<text name="spu_fs_state_paused" text="paused (did not get going)"/>
|
||||
<text name="spu_fs_storesTitle" text="Farm storages (where products are brought home to)"/>
|
||||
<text name="spu_fs_toProduction" text="Send surplus to production (barn feed first)"/>
|
||||
<text name="spu_fs_reserveDays" text="Feed reserve: barn consumption for"/>
|
||||
<text name="spu_fs_days" text="%d days"/>
|
||||
<text name="spu_fs_toFactory" text="→ factory"/>
|
||||
</texts>
|
||||
</l10n>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<modDesc descVersion="107">
|
||||
<author>masterdraco</author>
|
||||
<version>1.43.1.0</version>
|
||||
<version>1.44.0.0</version>
|
||||
<title>
|
||||
<en>AD Smart Pickup</en>
|
||||
</title>
|
||||
|
||||
Reference in New Issue
Block a user