245 lines
6.8 KiB
Plaintext
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
|