feat: v1.12.1.0 — prisregel via sæsonkurven, reserve til gårdens eget forbrug, paller til palleskur, fanen Lagre (idéer fra Distribution Redux)

This commit is contained in:
2026-09-23 10:34:41 +02:00
parent 43483bda76
commit 2d6e6dd7bf
16 changed files with 595 additions and 43 deletions
+37 -22
View File
@@ -1,14 +1,18 @@
-- AD Prices
-- Prisregel for udkørsel: hvor tæt er salgsstedets pris på årets toppris for varen?
-- Toppris = stationens grundpris lige nu × (årets højeste periodefaktor ÷ nuværende periodes
-- faktor) — dvs. det Priser-menuen ville vise som årets bedste måned for netop den station.
-- Effektiv pris (inkl. prisfald efter salg og stor efterspørgsel) ÷ toppris = pris-%;
-- stor efterspørgsel giver > 100 % og opfylder dermed altid reglen.
-- Grundlaget er spillets faste sæsonkurve (fillType.economy.factors[1..12], samme data som
-- prisgrafen i Priser-menuen; metode fra Distribution Redux): kurve-% = faktor nu ÷ årets højeste.
-- Oven på det ganges stationens egen afvigelse (effektiv pris ÷ stationens grundpris nu), så
-- prisfald efter salg og stor efterspørgsel tæller med — stor efterspørgsel giver > 100 %.
-- Sværhedsgraden skalerer begge priser ens og falder ud af regnestykket. Flade kurver
-- (top/bund under FLAT_THRESHOLD) regnes som 100 %, så varer uden sæson aldrig strander.
-- De rene funktioner øverst har ingen spil-API; getQuote er spil-adapteren.
ADPrices = {}
ADPrices.LOG_PREFIX = "ADSmartPickup: "
-- top/bund under dette = ingen reel sæson (Distribution Redux bruger samme grænse)
ADPrices.FLAT_THRESHOLD = 1.02
function ADPrices.maxFactor(factors)
local best = nil
@@ -37,6 +41,29 @@ function ADPrices.percentOfTop(price, top)
return math.floor(100 * price / top + 0.5)
end
function ADPrices.minFactor(factors)
local best = nil
for _, factor in pairs(factors or {}) do
if type(factor) == "number" and (best == nil or factor < best) then
best = factor
end
end
return best or 1
end
-- Kurve-%: nuværende periodes faktor ÷ årets højeste, afrundet. 100 uden kurve, uden periode
-- eller når kurven er flad.
function ADPrices.curvePercent(factors, period)
if factors == nil or period == nil then
return 100
end
local now, max, min = tonumber(factors[period]), ADPrices.maxFactor(factors), ADPrices.minFactor(factors)
if now == nil or now <= 0 or max <= 0 or min <= 0 or (max / min) < ADPrices.FLAT_THRESHOLD then
return 100
end
return math.floor(100 * now / max + 0.5)
end
-- Rigtige salgssteder: SellingStation der sælger (fabrikkers aflæsningsstationer er
-- også SellingStation-objekter, men med isSellingPoint = false) og vises i Priser-menuen.
function ADPrices.isSellingStation(station)
@@ -49,18 +76,8 @@ local function getCurrentPeriod()
return environment ~= nil and environment.currentPeriod or nil
end
local function getDifficultyMultiplier()
local economy = g_currentMission ~= nil and g_currentMission.economyManager or nil
if economy ~= nil and economy.getPriceMultiplier ~= nil then
local ok, value = pcall(economy.getPriceMultiplier, economy)
if ok and type(value) == "number" then
return value
end
end
return 1
end
-- {price, top, percent} for varen ved stationen; nil hvis stationen ikke kan prissætte den.
-- percent = kurve-% × (effektiv ÷ stationens grundpris nu); top = den pris der svarer til 100 %.
function ADPrices.getQuote(station, fillType)
if station == nil or station.getEffectiveFillTypePrice == nil then
return nil
@@ -71,14 +88,12 @@ function ADPrices.getQuote(station, fillType)
end
local fillTypeDesc = g_fillTypeManager ~= nil and g_fillTypeManager.getFillTypeByIndex ~= nil and g_fillTypeManager:getFillTypeByIndex(fillType) or nil
local factors = fillTypeDesc ~= nil and fillTypeDesc.economy ~= nil and fillTypeDesc.economy.factors or nil
local period = getCurrentPeriod()
local factorNow = factors ~= nil and period ~= nil and tonumber(factors[period]) or 1
local curve = ADPrices.curvePercent(factors, getCurrentPeriod())
local baseNow = station.fillTypePrices ~= nil and tonumber(station.fillTypePrices[fillType]) or nil
if baseNow == nil or baseNow <= 0 then
baseNow = (fillTypeDesc ~= nil and tonumber(fillTypeDesc.pricePerLiter) or 0) * factorNow * getDifficultyMultiplier()
end
local top = ADPrices.topPrice(baseNow, factorNow, ADPrices.maxFactor(factors))
return {price = effective, top = top, percent = ADPrices.percentOfTop(effective, top)}
local stationRatio = (baseNow ~= nil and baseNow > 0) and (effective / baseNow) or 1
local percent = math.floor(curve * stationRatio + 0.5)
local top = percent > 0 and (effective * 100 / percent) or effective
return {price = effective, top = top, percent = percent}
end
-- Højeste pris-%, ved lighed højeste pris. nil ved tom liste.