e4s-sdk/gamedata/scripts/travel_manager.script
2026-06-17 23:06:51 +03:00

482 lines
15 KiB
Text

local travel_class = nil
class "Ctraveler"
function Ctraveler:__init()
local ini_file = ini_file("misc\\travel_manager.ltx")
local id, value, category = "", "", ""
self.smart_to_stringtables = {}
for i=0, ini_file:line_count("locations")-1 do
temp1, id, value = ini_file:r_line("locations", i, "", "")
self.smart_to_stringtables[id] = value
end
self.smart_travels = {}
self.smart_by_phrase = {}
for i=0, ini_file:line_count("traveler")-1 do
temp1, id, value = ini_file:r_line("traveler", i, "", "")
self.smart_travels[id] = {}
self.smart_travels[id].name = ini_file:r_string(id, "name")
self.smart_travels[id].level = ini_file:r_string(id, "level")
self.smart_travels[id].condlist = xr_logic.parse_condlist(db.actor, id, "close_distance", ini_file:r_string(id, "condlist"))
self.smart_travels[id].phrase_id = tostring(1000+i)
self.smart_by_phrase[self.smart_travels[id].phrase_id] = id
end
end
function get_travel_class()
if travel_class == nil then
travel_class = Ctraveler()
end
return travel_class
end
-- Initialize new actor dialog
function init_traveler_dialog(dialog)
local npc = db.actor
local npc_community = "stalker" --npc:character_community()
local actor_phrase = dialog:AddPhrase("dm_traveler_what_are_you_doing", "0", "", -10000)
local actor_script = actor_phrase:GetPhraseScript()
local npc_phrase = dialog:AddPhrase("if you see this - this is bad", "1", "0", -10000)
local npc_phrase_script = npc_phrase:GetPhraseScript()
npc_phrase_script:SetScriptText("travel_manager.squad_action_description")
-- Ìîæåò ëè èãðîê ïîéòè ñ íèìè
actor_phrase = dialog:AddPhrase("dm_traveler_can_i_go_with_you", "11", "1", -10000)
actor_script = actor_phrase:GetPhraseScript()
actor_script:AddPrecondition("travel_manager.squad_on_move")
npc_phrase = dialog:AddPhrase("dm_traveler_"..npc_community.."_actor_companion_yes", "111", "11", -10000)
npc_phrase_script = npc_phrase:GetPhraseScript()
npc_phrase_script:AddPrecondition("travel_manager.squad_can_take_actor")
actor_phrase = dialog:AddPhrase("dm_traveler_actor_go_with_squad", "1111", "111", -10000)
actor_script = actor_phrase:GetPhraseScript()
actor_script:AddAction("travel_manager.actor_go_with_squad")
actor_phrase = dialog:AddPhrase("dm_traveler_actor_dont_go_with_squad", "1112", "111", -10000)
npc_phrase = dialog:AddPhrase("dm_traveler_"..npc_community.."_actor_companion_no", "112", "11", -10000)
npc_phrase_script = npc_phrase:GetPhraseScript()
npc_phrase_script:AddPrecondition("travel_manager.squad_cannot_take_actor")
-- Èãðîê ïðîñèò ðàçðåøåíèÿ ïðîâåñòè åãî
actor_phrase = dialog:AddPhrase("dm_traveler_take_me_to", "12", "1", -10000)
npc_phrase = dialog:AddPhrase("dm_traveler_"..npc_community.."_where_do_you_want", "121", "12", -10000)
npc_phrase_script = npc_phrase:GetPhraseScript()
npc_phrase_script:AddPrecondition("travel_manager.squad_can_travel")
-- Ôîðìèðîâàíèå òàðãåòîâ äëÿ ïðîâîäíèêîâ
local travel_class = get_travel_class()
for k,v in pairs(travel_class.smart_travels) do
actor_phrase = dialog:AddPhrase(game.translate_string(v.name)..".", v.phrase_id, "121", -10000)
actor_script = actor_phrase:GetPhraseScript()
actor_script:AddPrecondition("travel_manager.travel_condlist")
npc_phrase = dialog:AddPhrase("if you see this - this is bad", v.phrase_id.."_1", v.phrase_id, -10000)
npc_phrase_script = npc_phrase:GetPhraseScript()
npc_phrase_script:SetScriptText("travel_manager.get_travel_cost")
actor_phrase = dialog:AddPhrase("dm_traveler_actor_agree", v.phrase_id.."_11", v.phrase_id.."_1", -10000)
actor_script = actor_phrase:GetPhraseScript()
actor_script:AddAction("travel_manager.actor_travel_with_squad")
actor_script:AddPrecondition("travel_manager.actor_have_money")
actor_phrase = dialog:AddPhrase("dm_traveler_actor_has_no_money", v.phrase_id.."_13", v.phrase_id.."_1", -10000)
actor_script = actor_phrase:GetPhraseScript()
actor_script:AddPrecondition("travel_manager.actor_have_not_money")
actor_phrase = dialog:AddPhrase("dm_traveler_actor_refuse", v.phrase_id.."_14", v.phrase_id.."_1", -10000)
end
actor_phrase = dialog:AddPhrase("dm_traveler_actor_refuse", "1211", "121", -10000)
npc_phrase = dialog:AddPhrase("dm_traveler_"..npc_community.."_i_cant_travel", "122", "12", -10000)
npc_phrase_script = npc_phrase:GetPhraseScript()
npc_phrase_script:AddPrecondition("travel_manager.squad_cannot_travel")
-- Èãðîê âûõîäèò èç äèàëîãà
actor_phrase = dialog:AddPhrase("dm_traveler_bye", "13", "1", -10000)
end
function uni_traveler_precond(actor, npc)
local squad = get_object_squad(npc)
if squad ~= nil and squad:commander_id() ~= npc:id() then
return false
end
if npc:character_community() == "bandit" then
return false
end
if npc:character_community() == "army" then
return false
end
local smart = xr_gulag.get_npc_smart(npc)
if (smart) then
if smart:name() == "jup_b41" then
return false
end
end
return true
end
-- Ïåðåíîñ èãðîêà è îòðÿäà
local init_time = nil
local traveler_actor_path = nil
local traveler_squad_path = nil
local traveler_squad = nil
local traveler_distance = nil
local teleport_flag = nil
local traveler_smart_id = nil
function check_squad_for_enemies(squad_obj)
for k in squad_obj:squad_members() do
if relation_registry.get_general_goodwill_between(k.id, alife():actor().id) <= game_relations.ENEMIES then
return true
end
end
return false
end
function traveling()
if time_global() - init_time < 3000 then
return
end
if teleport_flag == false then
printf("trvelling_squad_path [%s] travelling_actor_path [%s]!!!", tostring(traveler_squad_path), tostring(traveler_actor_path))
local point = patrol(traveler_actor_path)
--local dir = vector():sub( point:point(0), point:point(1) ):getH()
--local dir = vector():sub( point:point(1), point:point(0) ):normalize():getH()
local dir = -point:point(1):sub(point:point(0)):getH()
local board = sim_board.get_sim_board()
for k,v in pairs(board.smarts[traveler_smart_id].squads) do
if get_object_story_id(v.id) == nil and check_squad_for_enemies(v) then
board:exit_smart(v, traveler_smart_id)
board:remove_squad(v)
end
end
local curr_smart_id = traveler_squad.smart_id
if curr_smart_id ~= nil then
board:assign_squad_to_smart(traveler_squad, nil)
board:assign_squad_to_smart(traveler_squad, curr_smart_id)
end
local position = patrol(traveler_squad_path):point(0)
traveler_squad:set_squad_position(position)
teleport_flag = true
db.actor:set_actor_direction(dir)
db.actor:set_actor_position(point:point(0))
local minutes = traveler_distance/10 -- Ñêîëüêî ìèíóò íóæíî, ÷òîáû ïðîéòè ðàññòîÿíèå ñî ñêîðîñòüþ 6 êì/÷ (100 ìåòðîâ â ìèíóòó) + Òàê êàê ó íàñ âðåìÿ èäåò â 10 ðàç áûñòðåå
local hours = math.floor(minutes/60)
minutes = minutes - hours*60
level.change_game_time(0,hours,minutes)
surge_manager.get_surge_manager().time_forwarded = true
printf("traveling: time forwarded on [%d][%d]", hours, minutes)
end
if time_global() - init_time < 6000 then
return
end
init_time = nil
traveler_actor_path = nil
traveler_squad_path = nil
traveler_squad = nil
traveler_distance = nil
traveler_smart_id = nil
bind_stalker.travel_func = nil
level.show_weapon(true)
--get_console():execute("hud_weapon 1")
level.enable_input()
level.show_indicators()
end
function squad_action_description(actor, npc, dialog_id, phrase_id)
local npc_squad = get_object_squad(npc)
if npc_squad.current_action == nil or npc_squad.current_action.name == "stay_point" then
return "dm_" .. "stalker" .."_doing_nothing_"..tostring(math.random(1,3)) --npc:character_community()
end
local target_id = npc_squad.assigned_target_id
-- if target_id == nil then
-- return "dm_" .. npc:character_community() .."_doing_nothing"
-- end
local target_obj = alife():object(target_id)
if target_obj == nil then
abort("SIM TARGET NOT EXIST %s, action_name %s", tostring(target_id), tostring(npc_squad.current_action.name))
end
local target_clsid = target_obj:clsid()
if target_clsid == clsid.script_actor then
abort("Actor talking with squad, which chasing actor")
elseif target_clsid == clsid.online_offline_group_s then
return "dm_" .. "stalker" .."_chasing_squad_"..alife_character_community(target_obj) --npc:character_community()
elseif target_clsid == clsid.smart_terrain then
local smart_name = target_obj:name()
local travel_class = get_travel_class()
local desc = travel_class.smart_to_stringtables[smart_name]
if desc == nil then
abort("wrong smart name [%s] in travel_manager.ltx", tostring(smart_name))
end
return desc
end
abort("wrong target clsid [%s]", tostring(target_clsid))
end
function squad_on_move(actor, npc, dialog_id, phrase_id)
local npc_squad = get_object_squad(npc)
if npc_squad.current_action == nil or npc_squad.current_action.name == "stay_point" then
return false
end
return true
end
function squad_can_take_actor(npc, actor, dialog_id, phrase_id)
local npc_squad = get_object_squad(npc)
local target_id = npc_squad.assigned_target_id
local target_obj = alife():object(target_id)
local target_clsid = target_obj:clsid()
if target_clsid == clsid.smart_terrain then
return true
end
return false
end
function squad_cannot_take_actor(npc, actor, dialog_id, phrase_id)
return not squad_can_take_actor(npc, actor, dialog_id, phrase_id)
end
function actor_go_with_squad(actor, npc, dialog_id, phrase_id)
xr_effects.scenario_autosave(actor, npc, {"st_save_uni_travel_generic"})
local npc_squad = get_object_squad(npc)
local target_id = npc_squad.assigned_target_id
local smart = alife():object(target_id)
npc:stop_talk()
--get_console():execute("hud_crosshair 0")
--get_console():execute("hud_weapon 0")
level.disable_input()
level.hide_indicators_safe()
level.add_pp_effector("fade_in_out.ppe", 613, false)
local distance = simulation_objects.sim_dist_to(npc_squad , smart)
traveler_distance = distance
traveler_actor_path = smart.traveler_actor_path
traveler_squad_path = smart.traveler_squad_path
traveler_smart_id = smart.id
traveler_squad = npc_squad
bind_stalker.travel_func = traveling
init_time = time_global()
teleport_flag = false
end
function check_smart_availability(smart_name, smart_table, squad)
local board = sim_board.get_sim_board()
local smart = board:get_smart_by_name(smart_name)
if smart == nil then
abort("Error in travel manager. Smart [%s] doesnt exist.", tostring(smart_name))
end
if xr_logic.pick_section_from_condlist(db.actor, smart, smart_table.condlist) ~= "true" then
return false
end
-- Ïðîâåðêà íà òåêóùèé ëåâåë
if smart_table.level ~= level.name() then
return false
end
-- Ìû íå âîäèì â òåêóùèé ñìàðò
if simulation_objects.sim_dist_to(squad , smart) < 50 then
return false
end
-- local squad_count = smart_terrain.smart_terrain_squad_count(board.smarts[smart.id].squads)
-- if squad_count ~= nil and (smart.max_population <= squad_count) then
-- return false
-- end
return true
end
function squad_can_travel(npc, actor, dialog_id, phrase_id)
local travel_class = get_travel_class()
local npc_squad = get_object_squad(npc)
for id, smart_table in pairs(travel_class.smart_travels) do
if check_smart_availability(id, smart_table, npc_squad) then
return true
end
end
return false
end
function squad_cannot_travel(npc, actor, dialog_id, phrase_id)
return not squad_can_travel(npc, actor, dialog_id, phrase_id)
end
function travel_condlist(actor, npc, dialog_id, prev_phrase_id, phrase_id)
local travel_class = get_travel_class()
-- Áåðåì ïî id ôðàçû ñìàðò
local smart_name = travel_class.smart_by_phrase[phrase_id]
if smart_name == nil then
abort("Error in travel manager %s", tostring(phrase_id))
end
return check_smart_availability(smart_name, travel_class.smart_travels[smart_name], get_object_squad(npc))
end
function get_price_by_distance(distance)
return math.ceil(distance/50)*50
end
function get_travel_cost(actor, npc, dialog_id, phrase_id, p1)
local travel_phrase_id = string.sub(phrase_id, 1, string.len(phrase_id) - 2)
local travel_class = get_travel_class()
-- Áåðåì ïî id ôðàçû ñìàðò
local smart_name = travel_class.smart_by_phrase[travel_phrase_id]
local board = sim_board.get_sim_board()
local smart = board:get_smart_by_name(smart_name)
local npc_squad = get_object_squad(npc)
--local distance = simulation_objects.sim_dist_to(npc_squad , smart)
local squad_position = npc:position()
local smart_position = smart.position
local distance = squad_position:distance_to(smart_position)
local price = get_price_by_distance(distance)
--printf("TRAVEL DISTANCE %s", distance)
return game.translate_string("dm_traveler_travel_cost") .. " " .. tostring(price) .."."
end
function actor_have_money(actor, npc, dialog_id, phrase_id)
local travel_phrase_id = string.sub(phrase_id, 1, string.len(phrase_id) - 2)
local travel_class = get_travel_class()
-- Áåðåì ïî id ôðàçû ñìàðò
local smart_name = travel_class.smart_by_phrase[travel_phrase_id]
local board = sim_board.get_sim_board()
local smart = board:get_smart_by_name(smart_name)
local npc_squad = get_object_squad(npc)
--local distance = simulation_objects.sim_dist_to(npc_squad , smart)
local squad_position = npc:position()
local smart_position = smart.position
local distance = squad_position:distance_to(smart_position)
local price = get_price_by_distance(distance)
return price <= db.actor:money()
end
function actor_have_not_money(actor, npc, dialog_id, phrase_id)
return not actor_have_money(actor, npc, dialog_id, phrase_id)
end
function actor_travel_with_squad(actor, npc, dialog_id, phrase_id)
xr_effects.scenario_autosave(actor, npc, {"st_save_uni_travel_generic"})
local travel_phrase_id = string.sub(phrase_id, 1, string.len(phrase_id) - 3)
local travel_class = get_travel_class()
npc:stop_talk()
--get_console():execute("hud_crosshair 0")
--get_console():execute("hud_weapon 0")
level.disable_input()
level.hide_indicators_safe()
level.add_pp_effector("fade_in_out.ppe", 613, false)
-- Áåðåì ïî id ôðàçû ñìàðò
local smart_name = travel_class.smart_by_phrase[travel_phrase_id]
local board = sim_board.get_sim_board()
local smart = board:get_smart_by_name(smart_name)
local npc_squad = get_object_squad(npc)
local distance = simulation_objects.sim_dist_to(npc_squad , smart)
local price = get_price_by_distance(distance)
db.actor:give_money(-price)
news_manager.relocate_money(db.actor, "out", price)
traveler_actor_path = smart.traveler_actor_path
traveler_squad_path = smart.traveler_squad_path
traveler_smart_id = smart.id
traveler_squad = npc_squad
traveler_distance = distance
bind_stalker.travel_func = traveling
init_time = time_global()
teleport_flag = false
end