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