Divergent/mods/Long Repair Fix/Optional/Disappearing items fix/scripts/trade_manager.script

245 lines
6.8 KiB
Plaintext

local tm = {}
local config_by_name = {}
function on_game_start()
RegisterScriptCallback("save_state",trade_save)
RegisterScriptCallback("load_state",trade_load)
end
local function t2c(t)
if not t then return nil end
local ct = game.CTime()
ct:set(t.Y,t.M,t.D,t.h,t.m,t.s,t.ms)
return ct
end
local function c2t(ct)
if not ct then return nil end
-- printf('%s, %s',ct,type(ct))
local Y, M, D, h, m, s, ms = 0, 0, 0, 0, 0, 0, 0
Y, M, D, h, m, s, ms = ct:get(Y, M, D, h, m, s, ms)
return { Y=Y, M=M, D=D, h=h, m=m, s=s, ms=ms }
end
function trade_init(npc, cfg)
if not (db.actor) then
return
end
--[[
No use having trade for enemies or zombied (no dialogs)
Note: it matters if you desguise, because this is called once on NPC switching online. So this can block trading with traders in this case.
if (npc:relation(db.actor) == game_object.enemy or npc:character_community() == "zombied") then
return
end
--]]
local id = npc:id()
if (tm[id] and tm[id].cfg_ltx == cfg) then
config_by_name[cfg] = config_by_name[cfg] or ini_file(cfg)
return
end
tm[id] = empty_table(tm[id])
tm[id].cfg_ltx = cfg
config_by_name[cfg] = config_by_name[cfg] or ini_file(cfg)
if not (config_by_name[cfg]) then
tm[id] = nil
end
end
function setup_buy_sell_conditions(npc,id,config)
local condlist = xr_logic.parse_condlist(npc, "trader", "buy_condition", config:r_string_ex("trader", "buy_condition") or "")
local str = condlist and xr_logic.pick_section_from_condlist(db.actor, npc, condlist)
if (str == nil or str == "" or str == "nil") then
printf("Wrong section in buy_condition condlist for npc [%s]!", npc:name())
return
end
npc:buy_condition(config, str)
tm[id].current_buy_condition = str
condlist = xr_logic.parse_condlist(npc, "trader", "sell_condition", config:r_string_ex("trader", "sell_condition") or "")
str = condlist and xr_logic.pick_section_from_condlist(db.actor, npc, condlist)
if(str == nil or str == "" or str == "nil") then
printf("Wrong section in sell_condition condlist for npc [%s]!", npc:name())
return
end
npc:sell_condition(config, str)
tm[id].current_sell_condition = str
condlist = xr_logic.parse_condlist(npc, "trader", "buy_item_condition_factor", config:r_string_ex("trader", "buy_item_condition_factor") or "0.7")
str = condlist and xr_logic.pick_section_from_condlist(db.actor, npc, condlist)
if (str == nil or str == "") then
printf("Wrong section in buy_item_condition_factor condlist for npc [%s]!", npc:name())
return
end
str = tonumber(str) or 0.7
if alife_storage_manager.get_state().trader_buy_condition_override and alife_storage_manager.get_state().trader_buy_condition_override > 0 then
-- printf('@@@overridden %s', alife_storage_manager.get_state().trader_buy_condition_override/100)
str = alife_storage_manager.get_state().trader_buy_condition_override/100
end
npc:buy_item_condition_factor(str)
tm[id].current_buy_item_condition_factor = str
condlist = xr_logic.parse_condlist(npc, "trader", "buy_item_exponent", config:r_string_ex("trader", "buy_item_exponent") or "0.75")
str = condlist and xr_logic.pick_section_from_condlist(db.actor, npc, condlist)
if (str == nil or str == "") then
printf("Wrong section in buy_item_exponent condlist for npc [%s]!", npc:name())
return
end
str = tonumber(str) or 0.75
npc:buy_item_exponent(str)
tm[id].current_buy_item_exponent = str
condlist = xr_logic.parse_condlist(npc, "trader", "sell_item_exponent", config:r_string_ex("trader", "sell_item_exponent") or "0.75")
str = condlist and xr_logic.pick_section_from_condlist(db.actor, npc, condlist)
if (str == nil or str == "") then
printf("Wrong section in sell_item_exponent condlist for npc [%s]!", npc:name())
return
end
str = tonumber(str) or 0.75
npc:sell_item_exponent(str)
tm[id].current_sell_item_exponent = str
end
function update(npc, force_refresh)
local id = npc and npc:id()
if not (id) then
return
end
if not (tm[id] and tm[id].cfg_ltx) then
return
end
local config = config_by_name[tm[id].cfg_ltx]
if not (config) then
return
end
setup_buy_sell_conditions(npc,id,config)
if has_alife_info(npc:section().."_is_repairing") then
return
end
local restock_time
if force_refresh then
restock_time = 0
else
restock_time = game_difficulties.get_eco_factor("restock") or 24
end
if (tm[id].resupply_time and game.get_game_time():diffSec(t2c(tm[id].resupply_time)) < (restock_time * 3600)) then
return
end
tm[id].resupply_time = c2t(game.get_game_time())
local str = config:r_string_ex("trader", "buy_supplies")
if not (str) then
return -- no buy_supplies this is normal
end
local condlist = xr_logic.parse_condlist(npc, "trader", "buy_supplies", str)
str = condlist and xr_logic.pick_section_from_condlist(db.actor, npc, condlist)
if(str=="" or str==nil) then
printf("Wrong section in buy_supplies condlist for npc [%s]!", npc:name())
return
end
npc:buy_supplies(config, str)
tm[id].current_buy_supplies = str
if (not tm[id].checked) then
tm[id].checked = true
--utils_data.print_table(tm[id])
end
end
function on_npc_death(npc)
if (npc) then
tm[npc:id()] = nil
end
end
function trade_save(m_data)
-- local t = {}
-- copy_table(t,tm)
-- for k,v in pairs(tm) do
-- v.resupply_time = c2t(v.resupply_time)
-- end
m_data.trade_manager = tm
-- trade_load(m_data)
end
function trade_load(m_data)
tm = m_data.trade_manager or {}
-- for k,v in pairs(tm) do
-- tm.resupply_time = t2c(tm.resupply_time)
-- end
end
function get_trade_profile(id, key)
if key then
return tm[id] and tm[id][key]
end
return tm[id]
end
function get_trade_cfg(cfg)
return config_by_name[cfg]
end
----------- NOT TO DELETE!!!!!!!!! called from engine
function get_buy_discount(npc_id)
--utils_data.debug_write("get_buy_discount")
if not (tm[npc_id] and tm[npc_id].cfg_ltx) then
return 1
end
local config = config_by_name[tm[npc_id].cfg_ltx]
local condlist = config and config:r_string_to_condlist("trader","discounts")
local sect = condlist and xr_logic.pick_section_from_condlist(db.actor, nil, condlist)
if (sect == nil or sect == "") then
return 1
end
local factor = config:r_float_ex(sect,"buy") or 1
local eco_factor = game_difficulties.get_eco_factor("buy") or 1
factor = factor * eco_factor
return factor
end
----------- NOT TO DELETE!!!!!!!!! called from engine
function get_sell_discount(npc_id)
--utils_data.debug_write("get_sell_discount")
if not (tm[npc_id] and tm[npc_id].cfg_ltx) then
return 1
end
local config = config_by_name[tm[npc_id].cfg_ltx]
local condlist = config and config:r_string_to_condlist("trader","discounts")
local sect = condlist and xr_logic.pick_section_from_condlist(db.actor, nil, condlist)
if (sect == nil or sect == "") then
return 1
end
local factor = config:r_float_ex(sect,"sell") or 1
local eco_factor = game_difficulties.get_eco_factor("sell") or 1
factor = factor * eco_factor
return factor
end