94 lines
3.8 KiB
Lua
94 lines
3.8 KiB
Lua
-- 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.
|
||
-- De rene funktioner øverst har ingen spil-API; getQuote er spil-adapteren.
|
||
|
||
ADPrices = {}
|
||
|
||
ADPrices.LOG_PREFIX = "ADSmartPickup: "
|
||
|
||
function ADPrices.maxFactor(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
|
||
|
||
function ADPrices.topPrice(baseNow, factorNow, maxFactor)
|
||
if baseNow == nil or baseNow <= 0 then
|
||
return 0
|
||
end
|
||
if factorNow == nil or factorNow <= 0 or maxFactor == nil or maxFactor <= 0 then
|
||
return baseNow
|
||
end
|
||
return baseNow * maxFactor / factorNow
|
||
end
|
||
|
||
function ADPrices.percentOfTop(price, top)
|
||
if top == nil or top <= 0 or price == nil then
|
||
return 0
|
||
end
|
||
return math.floor(100 * price / top + 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)
|
||
return station ~= nil and station.isa ~= nil and SellingStation ~= nil and station:isa(SellingStation) == true
|
||
and station.isSellingPoint == true and not station.hideFromPricesMenu
|
||
end
|
||
|
||
local function getCurrentPeriod()
|
||
local environment = g_currentMission ~= nil and g_currentMission.environment or nil
|
||
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.
|
||
function ADPrices.getQuote(station, fillType)
|
||
if station == nil or station.getEffectiveFillTypePrice == nil then
|
||
return nil
|
||
end
|
||
local ok, effective = pcall(station.getEffectiveFillTypePrice, station, fillType)
|
||
if not ok or type(effective) ~= "number" then
|
||
return nil
|
||
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 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)}
|
||
end
|
||
|
||
-- Højeste pris-%, ved lighed højeste pris. nil ved tom liste.
|
||
function ADPrices.bestQuote(quotes)
|
||
local best = nil
|
||
for _, quote in ipairs(quotes or {}) do
|
||
if best == nil or quote.percent > best.percent or (quote.percent == best.percent and quote.price > best.price) then
|
||
best = quote
|
||
end
|
||
end
|
||
return best
|
||
end
|