Added, Updated and Removed Mods; Updated Readme

This commit is contained in:
2024-04-01 22:56:36 -04:00
parent 255081e1ee
commit 5caee9fba5
1056 changed files with 49175 additions and 1278 deletions
@@ -0,0 +1,624 @@
local HI = has_alife_info
local GI = give_info
local DI = disable_info
local GT = game.translate_string
function NI(str)
return not (has_alife_info(str))
end
local saved_dialog
function add_dialog(p_id,id,phrase_id,cond,act)
if not ( saved_dialog ) then
return
end
local phrase = saved_dialog:AddPhrase(phrase_id,tostring(id),tostring(p_id),-10000)
if not ( phrase ) then
return
end
local phrase_script = phrase:GetPhraseScript()
if ( cond ) then
if ( type(cond) == "table" ) then
for key, value in pairs(cond) do
if (utils_data.findfunction(value,_G)) then
phrase_script:AddPrecondition(value)
else
printe("!ERROR dialog_manager | No such function exists '%s'",value)
end
end
else
if (utils_data.findfunction(cond,_G)) then
phrase_script:AddPrecondition(cond)
else
printe("!ERROR dialog_manager | No such function exists '%s'",cond)
end
end
end
if ( act ) then
if ( type(act) == "table" ) then
for key, value in pairs(act) do
if (utils_data.findfunction(value,_G)) then
phrase_script:AddAction(value)
else
printe("!ERROR dialog_manager | No such function exists '%s'",value)
end
end
else
if (utils_data.findfunction(act,_G)) then
phrase_script:AddAction(act)
else
printe("!ERROR dialog_manager | No such function exists '%s'",act)
end
end
end
return phrase_script
end
--[[----------------------------------------------------------------------------------------------------
General
------------------------------------------------------------------------------------------------------]]
function duty_girl_companion_join_dialog_con(a,b,dialog_name,pre_pid,cur_pid)
if (NI("duty_girl_capture_the_brirge_done")) then
return false
end
if (dialogs_axr_companion.is_actor_companion(a,b)) then
return false
end
return true
end
function duty_girl_companion_join_dialog(dialog)
saved_dialog = dialog
add_dialog("",0,"duty_girl_companion_join_0")
add_dialog(0,1,"duty_girl_companion_join_1","dialogs_duty_girl.duty_girl_companion_join_1_con","dialogs_axr_companion.become_actor_companion")
add_dialog(0,2,"duty_girl_companion_join_2","dialogs_duty_girl.duty_girl_companion_join_2_con")
end
function duty_girl_companion_join_1_con(a,b)
return not duty_girl_companion_join_2_con(a,b)
end
function duty_girl_companion_join_2_con(a,b)
local npc = get_story_object("devushka")
if (npc and npc:alive() and dialogs_axr_companion.is_actor_companion(db.actor,npc)) then
return true
end
return false
end
function duty_girl_companion_leave_dialog_con(a,b,dialog_name,pre_pid,cur_pid)
if (dialogs_axr_companion.is_actor_companion(a,b)) then
return true
end
return false
end
function duty_girl_companion_leave_dialog(dialog)
saved_dialog = dialog
add_dialog("",0,"duty_girl_companion_leave_0")
add_dialog(0,1,"duty_girl_companion_leave_1")
add_dialog(1,2,"duty_girl_companion_leave_2")
add_dialog(1,3,"duty_girl_companion_leave_3")
add_dialog(2,4,"duty_girl_companion_leave_4",nil,"dialogs_axr_companion.remove_companions_from_squad")
end
function duty_girl_actor_ask_companion_dialog_con(a,b,dialog_name,pre_pid,cur_pid)
local str = db.actor and character_community(db.actor) or ""
if (str and string.find(str,"dolg")) then
return false
end
return true
end
function duty_girl_actor_ask_companion_dialog(dialog)
end
function duty_girl_first_meet(dialog)
saved_dialog = dialog
add_dialog("",0,"duty_girl_first_meet_0")
add_dialog(0,1,"duty_girl_first_meet_1")
add_dialog(1,2,"duty_girl_first_meet_2")
add_dialog(2,3,"duty_girl_first_meet_3")
add_dialog(3,4,"duty_girl_first_meet_4")
add_dialog(4,5,"duty_girl_first_meet_5",nil,"dialogs_duty_girl.GI_duty_girl_first_meet")
end
--[[----------------------------------------------------------------------------------------------------
Quests
------------------------------------------------------------------------------------------------------]]
--[[----------------------------------------------------------------------------------------------------
duty_girl_hunting_chimera
------------------------------------------------------------------------------------------------------]]
function duty_girl_hunting_chimera_init_con(a,b,dialog_name,pre_pid,cur_pid)
if (HI("duty_girl_hunting_chimera_done") or HI("duty_girl_hunting_chimera_fail")) then
return false
end
return HI("duty_girl_first_meet") and NI("duty_girl_hunting_chimera_init")
end
function duty_girl_hunting_chimera_init(dialog)
saved_dialog = dialog
add_dialog("",0,"duty_girl_hunting_chimera_init_0")
add_dialog(0,1,"duty_girl_hunting_chimera_init_1",nil,"dialogs_duty_girl.duty_girl_hunting_chimera")
end
function duty_girl_hunting_chimera_move_con(a,b,dialog_name,pre_pid,cur_pid)
if (HI("duty_girl_hunting_chimera_done") or HI("duty_girl_hunting_chimera_fail")) then
return false
end
local npc = dialogs.who_is_npc(a,b)
return HI("duty_girl_hunting_chimera_init") and NI("duty_girl_hunting_chimera_move") and xr_conditions.npc_on_level(db.actor,npc,{"l02_garbage"})
end
function duty_girl_hunting_chimera_move(dialog)
saved_dialog = dialog
add_dialog("",0,"duty_girl_hunting_chimera_move_0")
add_dialog(0,1,"duty_girl_hunting_chimera_move_1",nil,"dialogs_duty_girl.GI_duty_girl_hunting_chimera_move")
end
function duty_girl_hunting_chimera_done_con(a,b,dialog_name,pre_pid,cur_pid)
if (HI("duty_girl_hunting_chimera_done") or HI("duty_girl_hunting_chimera_fail")) then
return false
end
return HI("duty_girl_hunting_chimera_dead") and NI("duty_girl_hunting_chimera_reward")
end
function duty_girl_hunting_chimera_done(dialog)
saved_dialog = dialog
add_dialog("",0,"duty_girl_hunting_chimera_done_0")
local action = {
"dialogs_duty_girl.give_money_8000",
"dialogs_duty_girl.GI_duty_girl_hunting_chimera_reward",
}
add_dialog(0,1,"duty_girl_hunting_chimera_done_1",nil,action)
end
--[[----------------------------------------------------------------------------------------------------
duty_girl_monolith_elite
------------------------------------------------------------------------------------------------------]]
function duty_girl_monolith_elite_init_con(a,b,dialog_name,pre_pid,cur_pid)
if (HI("duty_girl_monolith_elite_done") or HI("duty_girl_monolith_elite_fail")) then
return false
end
local npc = dialogs.who_is_npc(a,b)
return HI("duty_girl_hunting_chimera_done") and NI("duty_girl_monolith_elite_init") and xr_conditions.npc_on_level(db.actor,npc,{"l05_bar"})
end
function duty_girl_monolith_elite_init(dialog)
saved_dialog = dialog
add_dialog("",0,"duty_girl_monolith_elite_init_0")
add_dialog(0,1,"duty_girl_monolith_elite_init_1",nil,"dialogs_duty_girl.duty_girl_monolith_elite")
end
function duty_girl_monolith_elite_join_con(a,b,dialog_name,pre_pid,cur_pid)
if (HI("duty_girl_monolith_elite_done") or HI("duty_girl_monolith_elite_fail")) then
return false
end
local npc = dialogs.who_is_npc(a,b)
return HI("duty_girl_monolith_elite_init") and NI("duty_girl_monolith_elite_join") and xr_conditions.npc_on_level(db.actor,npc,{"l07_military"})
end
function duty_girl_monolith_elite_done_con(a,b,dialog_name,pre_pid,cur_pid)
if (HI("duty_girl_monolith_elite_done") or HI("duty_girl_monolith_elite_fail")) then
return false
end
return HI("duty_girl_monolith_elite_dead") and NI("duty_girl_monolith_elite_reward")
end
function duty_girl_monolith_elite_done(dialog)
saved_dialog = dialog
add_dialog("",0,"duty_girl_monolith_elite_done_0")
local action = {
"dialogs_duty_girl.give_money_12000",
"dialogs_duty_girl.GI_duty_girl_monolith_elite_reward",
}
add_dialog(0,1,"duty_girl_monolith_elite_done_1",nil,action)
end
--[[----------------------------------------------------------------------------------------------------
duty_girl_loot_stash
------------------------------------------------------------------------------------------------------]]
function duty_girl_loot_stash_init_con(a,b,dialog_name,pre_pid,cur_pid)
if (HI("duty_girl_loot_stash_done")) then
return false
end
local npc = dialogs.who_is_npc(a,b)
return HI("duty_girl_monolith_elite_done") and NI("duty_girl_loot_stash_init") and xr_conditions.npc_on_level(db.actor,npc,{"l05_bar"})
end
function duty_girl_loot_stash_init(dialog)
saved_dialog = dialog
add_dialog("",0,"duty_girl_loot_stash_init_0")
add_dialog(0,1,"duty_girl_loot_stash_init_1",nil,"dialogs_duty_girl.duty_girl_loot_stash")
add_dialog(1,2,"duty_girl_loot_stash_init_2")
end
--[[----------------------------------------------------------------------------------------------------
duty_girl_capture_the_brirge
------------------------------------------------------------------------------------------------------]]
function duty_girl_capture_the_brirge_init_con(a,b,dialog_name,pre_pid,cur_pid)
if (HI("duty_girl_capture_the_brirge_done")) then
return false
end
local npc = dialogs.who_is_npc(a,b)
return HI("duty_girl_loot_stash_done") and NI("duty_girl_capture_the_brirge_init") and xr_conditions.npc_on_level(db.actor,npc,{"l05_bar"})
end
function duty_girl_capture_the_brirge_init(dialog)
saved_dialog = dialog
add_dialog("",0,"duty_girl_capture_the_brirge_init_0")
add_dialog(0,1,"duty_girl_capture_the_brirge_init_1",nil,"dialogs_duty_girl.duty_girl_capture_the_brirge")
end
function duty_girl_capture_the_brirge_join_con(a,b,dialog_name,pre_pid,cur_pid)
if (HI("duty_girl_capture_the_brirge_done") or HI("duty_girl_capture_the_brirge_fail")) then
return false
end
local npc = dialogs.who_is_npc(a,b)
return HI("duty_girl_capture_the_brirge_init") and NI("duty_girl_capture_the_brirge_join") and xr_conditions.npc_on_level(db.actor,npc,{"l10_red_forest"})
end
function duty_girl_capture_the_brirge_done_con(a,b,dialog_name,pre_pid,cur_pid)
if (HI("duty_girl_capture_the_brirge_done") or HI("duty_girl_capture_the_brirge_fail")) then
return false
end
return HI("duty_girl_capture_the_brirge_dead") and NI("duty_girl_capture_the_brirge_reward")
end
function duty_girl_capture_the_brirge_done(dialog)
saved_dialog = dialog
add_dialog("",0,"duty_girl_capture_the_brirge_done_0")
local action = {
"dialogs_duty_girl.give_money_20000",
"dialogs_duty_girl.GI_duty_girl_capture_the_brirge_reward",
}
add_dialog(0,1,"duty_girl_capture_the_brirge_done_1",nil,action)
end
--[[----------------------------------------------------------------------------------------------------
Others
------------------------------------------------------------------------------------------------------]]
function red_duty_outpost_trader_concern_hostile(dialog)
saved_dialog = dialog
add_dialog("",0,"red_duty_outpost_trader_concern_hostile_0")
add_dialog(0,1,"red_duty_outpost_trader_concern_hostile_1")
end
function meet_guid_duty_outpost(dialog)
saved_dialog = dialog
add_dialog("",0,"meet_guid_duty_outpost_list_0")
add_dialog(0,1,"meet_guid_duty_outpost_list_1")
end
function travel_guid_duty_outpost(dialog)
saved_dialog = dialog
local action = {}
add_dialog("",0,"travel_guid_duty_outpost_0")
add_dialog(0,1,"travel_guid_duty_outpost_1")
action = { "dialogs_duty_girl.lost_money_1000","dialogs_mlr.l05_bar_guid" }
add_dialog(1,2,"travel_guid_duty_outpost_2","dialogs_duty_girl.have_money_1000",action)
action = { "dialogs_duty_girl.lost_money_2000","dialogs_mlr.zaton_guid" }
add_dialog(1,3,"travel_guid_duty_outpost_3","dialogs_duty_girl.have_money_2000",action)
action = { "dialogs_duty_girl.lost_money_3000","dialogs_mlr.garbage_guid" }
add_dialog(1,4,"travel_guid_duty_outpost_4","dialogs_duty_girl.have_money_3000",action)
action = { "dialogs_duty_girl.lost_money_4000","dialogs_mlr.yantar_guid" }
add_dialog(1,5,"travel_guid_duty_outpost_5","dialogs_duty_girl.have_money_4000",action)
action = { "dialogs_duty_girl.lost_money_5000","dialogs_mlr.agroprom_guid_military" }
add_dialog(1,6,"travel_guid_duty_outpost_6","dialogs_duty_girl.have_money_5000",action)
action = { "dialogs_duty_girl.lost_money_6000","dialogs_mlr.escape_village_guid" }
add_dialog(1,7,"travel_guid_duty_outpost_7","dialogs_duty_girl.have_money_6000",action)
action = { "dialogs_duty_girl.lost_money_6000","dialogs_mlr.marsh_guid" }
add_dialog(1,8,"travel_guid_duty_outpost_8","dialogs_duty_girl.have_money_6000",action)
add_dialog(1,9,"travel_guid_duty_outpost_9")
end
function travel_guid_duty_outpost_from_others_1(str)
return strformat(game.translate_string("travel_guid_duty_outpost_from_others_1"),str)
end
function travel_guid_duty_outpost_from_others_2(str)
return strformat(game.translate_string("travel_guid_duty_outpost_from_others_2"),str)
end
function travel_guid_duty_outpost_from_others_1000(dialog)
saved_dialog = dialog
local txt, action = "", {}
add_dialog("",0,"travel_guid_duty_outpost_from_others_0")
txt = travel_guid_duty_outpost_from_others_1(1000)
add_dialog(0,1,txt)
txt = travel_guid_duty_outpost_from_others_2(1000)
action = {"dialogs_duty_girl.lost_money_1000","dialogs_duty_girl.change_lvl_to_duty_outpost"}
add_dialog(1,2,txt,"dialogs_duty_girl.have_money_1000",action)
add_dialog(1,3,"travel_guid_duty_outpost_from_others_3")
end
function travel_guid_duty_outpost_from_others_2000(dialog)
saved_dialog = dialog
local txt, action = "", {}
add_dialog("",0,"travel_guid_duty_outpost_from_others_0")
txt = travel_guid_duty_outpost_from_others_1(2000)
add_dialog(0,1,txt)
txt = travel_guid_duty_outpost_from_others_2(2000)
action = {"dialogs_duty_girl.lost_money_2000","dialogs_duty_girl.change_lvl_to_duty_outpost"}
add_dialog(1,2,txt,"dialogs_duty_girl.have_money_2000",action)
add_dialog(1,3,"travel_guid_duty_outpost_from_others_3")
end
function travel_guid_duty_outpost_from_others_3000(dialog)
saved_dialog = dialog
local txt, action = "", {}
add_dialog("",0,"travel_guid_duty_outpost_from_others_0")
txt = travel_guid_duty_outpost_from_others_1(3000)
add_dialog(0,1,txt)
txt = travel_guid_duty_outpost_from_others_2(3000)
action = {"dialogs_duty_girl.lost_money_3000","dialogs_duty_girl.change_lvl_to_duty_outpost"}
add_dialog(1,2,txt,"dialogs_duty_girl.have_money_3000",action)
add_dialog(1,3,"travel_guid_duty_outpost_from_others_3")
end
function travel_guid_duty_outpost_from_others_4000(dialog)
saved_dialog = dialog
local txt, action = "", {}
add_dialog("",0,"travel_guid_duty_outpost_from_others_0")
txt = travel_guid_duty_outpost_from_others_1(4000)
add_dialog(0,1,txt)
txt = travel_guid_duty_outpost_from_others_2(4000)
action = {"dialogs_duty_girl.lost_money_4000","dialogs_duty_girl.change_lvl_to_duty_outpost"}
add_dialog(1,2,txt,"dialogs_duty_girl.have_money_4000",action)
add_dialog(1,3,"travel_guid_duty_outpost_from_others_3")
end
function travel_guid_duty_outpost_from_others_5000(dialog)
saved_dialog = dialog
local txt, action = "", {}
add_dialog("",0,"travel_guid_duty_outpost_from_others_0")
txt = travel_guid_duty_outpost_from_others_1(5000)
add_dialog(0,1,txt)
txt = travel_guid_duty_outpost_from_others_2(5000)
action = {"dialogs_duty_girl.lost_money_5000","dialogs_duty_girl.change_lvl_to_duty_outpost"}
add_dialog(1,2,txt,"dialogs_duty_girl.have_money_5000",action)
add_dialog(1,3,"travel_guid_duty_outpost_from_others_3")
end
function travel_guid_duty_outpost_from_others_6000(dialog)
saved_dialog = dialog
local txt, action = "", {}
add_dialog("",0,"travel_guid_duty_outpost_from_others_0")
txt = travel_guid_duty_outpost_from_others_1(6000)
add_dialog(0,1,txt)
txt = travel_guid_duty_outpost_from_others_2(6000)
action = {"dialogs_duty_girl.lost_money_6000","dialogs_duty_girl.change_lvl_to_duty_outpost"}
add_dialog(1,2,txt,"dialogs_duty_girl.have_money_6000",action)
add_dialog(1,3,"travel_guid_duty_outpost_from_others_3")
end
--[[----------------------------------------------------------------------------------------------------
Task
------------------------------------------------------------------------------------------------------]]
function duty_girl_hunting_chimera()
task_manager.get_task_manager():give_task("duty_girl_hunting_chimera")
end
function duty_girl_monolith_elite()
task_manager.get_task_manager():give_task("duty_girl_monolith_elite")
end
function duty_girl_loot_stash()
task_manager.get_task_manager():give_task("duty_girl_loot_stash")
end
function duty_girl_capture_the_brirge()
task_manager.get_task_manager():give_task("duty_girl_capture_the_brirge")
end
--[[----------------------------------------------------------------------------------------------------
Info
------------------------------------------------------------------------------------------------------]]
function GI_duty_girl_first_meet(a,b)
return GI("duty_girl_first_meet")
end
function GI_duty_girl_hunting_chimera_move(a,b)
return GI("duty_girl_hunting_chimera_move")
end
function GI_duty_girl_hunting_chimera_reward(a,b)
return GI("duty_girl_hunting_chimera_reward")
end
function GI_duty_girl_monolith_elite_join(a,b)
return GI("duty_girl_monolith_elite_join")
end
function GI_duty_girl_monolith_elite_reward(a,b)
return GI("duty_girl_monolith_elite_reward")
end
function GI_duty_girl_capture_the_brirge_reward(a,b)
return GI("duty_girl_capture_the_brirge_reward")
end
--[[----------------------------------------------------------------------------------------------------
Phrases
------------------------------------------------------------------------------------------------------]]
function get_phrase_monolith_elite_join_0(a,b)
return NI("duty_girl_monolith_elite_supply") and
GT("duty_girl_monolith_elite_join_0") or
GT("duty_girl_monolith_elite_join_2")
end
function get_phrase_monolith_elite_join_1(a,b)
return NI("duty_girl_monolith_elite_supply") and
GT("duty_girl_monolith_elite_join_1") or " "
end
function action_monolith_elite_join(a,b)
if NI("duty_girl_monolith_elite_supply") then
give_item_monolith_elite_supply(a,b)
else
GI("duty_girl_monolith_elite_join")
dialogs.break_dialog(a,b)
end
end
function get_phrase_capture_the_brirge_join_0(a,b)
return NI("duty_girl_capture_the_brirge_supply") and
GT("duty_girl_capture_the_brirge_join_0") or
GT("duty_girl_capture_the_brirge_join_2")
end
function get_phrase_capture_the_brirge_join_1(a,b)
return NI("duty_girl_capture_the_brirge_supply") and
GT("duty_girl_capture_the_brirge_join_1") or " "
end
function action_capture_the_brirge_join(a,b)
if NI("duty_girl_capture_the_brirge_supply") then
give_item_capture_the_brirge_join(a,b)
else
GI("duty_girl_capture_the_brirge_join")
dialogs.break_dialog(a,b)
end
end
--[[----------------------------------------------------------------------------------------------------
Utilites
------------------------------------------------------------------------------------------------------]]
function give_money_8000(a,b)
return dialogs.relocate_money_to_actor(a,b,8000)
end
function give_money_12000(a,b)
return dialogs.relocate_money_to_actor(a,b,12000)
end
function give_money_20000(a,b)
return dialogs.relocate_money_to_actor(a,b,20000)
end
function have_money_1000(a,b)
return mlr_utils.have_money(1000)
end
function have_money_2000(a,b)
return mlr_utils.have_money(2000)
end
function have_money_3000(a,b)
return mlr_utils.have_money(3000)
end
function have_money_4000(a,b)
return mlr_utils.have_money(4000)
end
function have_money_5000(a,b)
return mlr_utils.have_money(5000)
end
function have_money_6000(a,b)
return mlr_utils.have_money(6000)
end
function lost_money_1000(a,b)
return dialogs.relocate_money_from_actor(a,b,1000)
end
function lost_money_2000(a,b)
return dialogs.relocate_money_from_actor(a,b,2000)
end
function lost_money_3000(a,b)
return dialogs.relocate_money_from_actor(a,b,3000)
end
function lost_money_4000(a,b)
return dialogs.relocate_money_from_actor(a,b,4000)
end
function lost_money_5000(a,b)
return dialogs.relocate_money_from_actor(a,b,5000)
end
function lost_money_6000(a,b)
return dialogs.relocate_money_from_actor(a,b,6000)
end
local function give_items(p)
if not(p and is_not_empty(p)) then return end
for sec,num in pairs(p) do
if (sec and num) then
if (IsItem("ammo",sec)) then
alife_create_item(sec,db.actor,{ammo = num})
else
for k=1,num do
alife_create_item(sec,db.actor)
end
end
news_manager.relocate_item(db.actor,"in",sec,num)
end
end
end
function give_item_monolith_elite_supply(a,b)
give_items({bandage = 5, medkit_army = 3})
GI("duty_girl_monolith_elite_supply")
end
function give_item_capture_the_brirge_join(a,b)
give_items({bandage = 5, medkit_army = 3})
GI("duty_girl_capture_the_brirge_supply")
end
function change_lvl_to_duty_outpost(a,b)
if (db.actor:is_talking()) then
db.actor:stop_talk()
end
local smart = SIMBOARD.smarts_by_names["red_smart_terrain_bridge"]
if (smart) then
ChangeLevel(vector():set(-118,5,-256),smart.m_level_vertex_id,smart.m_game_vertex_id,vector():set(0,0,-1),true)
end
end
@@ -0,0 +1,136 @@
local HI = has_alife_info
local GI = give_info
local DI = disable_info
function NI(str)
return not (has_alife_info(str))
end
--[[----------------------------------------------------------------------------------------------------
Main
------------------------------------------------------------------------------------------------------]]
function duty_girl_init()
if (NI("duty_girl_init")) then
if not (get_story_se_object("squad_duty_girl")) then
local smart = SIMBOARD.smarts_by_names["bar_dolg_general"]
local squad = SIMBOARD:create_squad(smart,"squad_duty_girl")
--[[
if (squad) then
for k in squad:squad_members() do
local se = k.id and alife():object(k.id)
if (se) then
local sim = alife()
for i=1,65534 do
local wpn = sim:object(i)
if (wpn and wpn.parent_id and (wpn.parent_id == se.id) and string.find(wpn:name(),"wpn_"))then
safe_release_manager.release(wpn)
end
end
alife():create("wpn_groza",se.position,se.m_level_vertex_id,se.m_game_vertex_id,se.id)
end
end
end
--]]
end
if (get_story_se_object("squad_duty_girl")) then
GI("duty_girl_init")
end
end
end
function anna_no_hip_allowed()
local ann = get_story_se_object("stalker_duty_girl")
if (ann and alife():has_info(ann.id,"npcx_is_companion")) then
local hip = get_story_se_object("devushka")
if (hip and alife():has_info(hip.id,"npcx_is_companion")) then
local npc = db.storage[ann.id] and db.storage[ann.id].object or level.object_by_id(ann.id)
if (npc) then
dialogs_axr_companion.remove_companions_from_squad(db.actor,npc)
end
end
else
return true
end
end
function actor_on_first_update()
duty_girl_init()
CreateTimeEvent(AC_ID,"anna_no_hip_allowed",1000,anna_no_hip_allowed)
end
function npcs_friendly_to_community(npc_1,npc_2,com)
local com_1 = npc_1 and character_community(npc_1)
local com_2 = npc_2 and character_community(npc_2)
if (com_1 and com_2 and (not game_relations.is_factions_enemies(com_1,com)) and (not game_relations.is_factions_enemies(com_2,com))) then
return true
end
return false
end
function npc_on_before_hit(npc,shit,bone_id,flags)
if (npc and string.find(npc:name(),"stalker_duty_girl")) then
flags.ret_value = false
end
end
function on_enemy_eval(npc,ene,flags)
if (npc:has_info("npcx_is_companion") or ene:has_info("npcx_is_companion")) then
local com = character_community(db.actor)
if (com and npcs_friendly_to_community(npc,ene,com)) then
flags.override = true
flags.result = false
end
end
end
--[[
function npc_on_choose_weapon(npc,cur_wpn,flags)
if not (npc and unique_character_storage[npc:section()] and unique_character_storage[npc:section()].weapon) then
return
end
local wpn_section = unique_character_storage[npc:section()].weapon
if not (wpn_section and (wpn_section ~= "") and (wpn_section ~= "nil")) then
return
end
if (cur_wpn and (cur_wpn:section() == wpn_section)) then
return
end
local function itr(npc,itm)
if (itm and (itm:section() ~= wpn_section) and IsWeapon(itm)) then
local se = alife():object(itm:id())
if (se) then
safe_release_manager.release(se)
end
end
end
npc:iterate_inventory(itr,npc)
if (npc:object(wpn_section)) then
return
end
alife():create(wpn_section,npc:position(),npc:level_vertex_id(),npc:game_vertex_id(),npc:id())
end
--]]
--[[----------------------------------------------------------------------------------------------------
Registers
------------------------------------------------------------------------------------------------------]]
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
RegisterScriptCallback("npc_on_before_hit",npc_on_before_hit)
RegisterScriptCallback("on_enemy_eval",on_enemy_eval)
--RegisterScriptCallback("npc_on_choose_weapon",npc_on_choose_weapon)
end
--[[----------------------------------------------------------------------------------------------------
Debug
------------------------------------------------------------------------------------------------------]]
--[[
cmd = debug_cmd_list.command_get_list()
function cmd.chan()
duty_girl_init()
end
--]]
@@ -0,0 +1,149 @@
local HI = has_alife_info
local GI = give_info
local DI = disable_info
function NI(str)
return not (has_alife_info(str))
end
local storage_data = {}
function reinforce_squad(actor,obj,p)
local squad = p and p[1] and get_story_se_object(p[1])
local smart = squad and squad.smart_id and db.smart_terrain_by_id[squad.smart_id]
if not (squad and smart) then
return
end
local lst = ini_sys:r_string_ex(squad:section_name(),"npc_random")
lst = lst and parse_names(lst)
local str = ini_sys:r_string_ex(squad:section_name(),"npc_in_squad")
str = str and str_explode(str,",")
local num = str and (tonumber(str[2]) or tonumber(str[1]))
--printf("GhenTuong: refill_squad %s",squad:section_name())
if (lst and num) then
local n = tonumber(p[2]) or 1
for k=1,n do
if (squad:npc_count() < num) then
local sec = lst[math.random(#lst)]
local commander = alife_object(squad:commander_id())
if (sec and ini_sys:section_exist(sec) and commander) then
local pos = commander.position
local vid = commander.m_level_vertex_id
local gid = commander.m_game_vertex_id
local id = squad:add_squad_member(sec,pos,vid,gid)
local se = id and alife_object(id)
if (se) then
smart:register_npc(se)
SIMBOARD:setup_squad_and_group(se)
end
squad:update()
end
end
end
end
end
function clean_mess(actor,smart,p)
if (HI("duty_outpost_clean_mess")) then
return
end
local zone = db.zone_by_name["red_smart_terrain_bridge_surge_hide_a1"]
if (smart and zone) then
local section_list = {
["physic_destroyable_object"] = true,
["explosive_barrel_low"] = true,
["explosive_hide"] = true,
}
for id=1,65534 do
local se = alife():object(id)
if (se and section_list[se:section_name()] and simulation_objects.is_on_the_same_level(se,smart) and zone:inside(se.position)) then
safe_release_manager.release(se)
printf("Release [%s]",se:name())
end
end
GI("duty_outpost_clean_mess")
end
end
function play_sound(actor,obj,p)
if (p and p[1]) then
local snd = xr_sound.set_sound_play(obj:id(),p[1])
if (snd and tonumber(p[2]) and (snd.volume ~= tonumber(p[2]))) then
snd.volume = tonumber(p[2])
end
end
end
function level_is_red_forest()
return (level.name() == "l05_bar")
end
function npcs_friendly_to_community(npc_1,npc_2,com)
local com_1 = npc_1 and character_community(npc_1)
local com_2 = npc_2 and character_community(npc_2)
--printf("GhenTuong: %s %s %s %s %s",com_1,com_2,com,game_relations.is_factions_enemies(com_1,com),game_relations.is_factions_enemies(com_2,com))
if (com_1 and com_2 and (not game_relations.is_factions_enemies(com_1,com)) and (not game_relations.is_factions_enemies(com_2,com))) then
return true
end
return false
end
function npc_on_before_hit(npc,shit,bone_id,flags)
if not (HI("red_bridge_outpost") and level_is_red_forest()) then
return
end
if (storage_data.actor_crime) then
return
end
if (shit and shit.draftsman) then
if (shit.draftsman:id() == AC_ID) then
if (npcs_friendly_to_community(npc,shit.draftsman,"dolg")) then
storage_data.actor_crime = true
end
end
end
end
function on_enemy_eval(npc,ene,flags)
if not (HI("red_bridge_outpost") and level_is_red_forest()) then
return
end
if not (IsStalker(npc) and IsStalker(ene)) then
return
end
if (npcs_friendly_to_community(npc,ene,"dolg")) then
if (storage_data.actor_crime and (ene:id() == AC_ID)) then
return
end
flags.override = true
flags.result = false
end
end
function save_state(m_data)
m_data.gameplay_duty_outpost_storage_data = storage_data
end
function load_state(m_data)
storage_data = m_data.gameplay_duty_outpost_storage_data or {}
end
function on_level_changing()
storage_data.actor_crime = nil
end
--[[----------------------------------------------------------------------------------------------------
Registers
------------------------------------------------------------------------------------------------------]]
function on_game_start()
RegisterScriptCallback("save_state",save_state)
RegisterScriptCallback("load_state",load_state)
RegisterScriptCallback("on_level_changing",on_level_changing)
RegisterScriptCallback("npc_on_before_hit",npc_on_before_hit)
RegisterScriptCallback("on_enemy_eval",on_enemy_eval)
end
@@ -0,0 +1,230 @@
local HI = has_alife_info
local GI = give_info
local DI = disable_info
function NI(str)
return not (has_alife_info(str))
end
function create_squad(smart_name,section)
local smart = SIMBOARD.smarts_by_names[smart_name]
if (smart and not get_story_se_object(section)) then
SIMBOARD:create_squad(smart,section)
end
return get_story_se_object(section)
end
function kill_common_enemy(enemy,npc,p)
if (xr_conditions.is_enemy_actor_or_companion(enemy,npc,p)) then
return
end
if (get_object_story_id(enemy:id())) then
return
end
local squad = get_object_squad(enemy)
if (squad and squad.common and (not get_object_story_id(squad.id))) then
local function itr(npc_id,ene_id)
local obj = npc_id and level.object_by_id(npc_id)
local ene = ene_id and level.object_by_id(ene_id)
if (obj and obj:alive() and ene and ene:alive()) then
local h = hit()
h.power = 1
h.direction = vector():set(0,-1,0)
h.bone = "bip01_spine"
h.draftsman = obj
h.impulse = 0
h.type = hit.wound
ene:hit(h)
end
return true
end
CreateTimeEvent(npc:id(),"kill_common_enemy" .. enemy:id(),0,itr,npc:id(),enemy:id())
end
end
function actor_sprint(actor,npc,p)
if (IsMoveState("mcSprint")) then
return true
end
return false
end
function ray_cast_to_actor_le(actor,npc,p)
local act_pos = db.actor and db.actor:position()
local npc_pos = npc and npc:position()
if (act_pos and npc_pos and tonumber(p[1])) then
local dir = vector():set((act_pos):sub(npc_pos)):normalize()
local pick = ray_pick()
pick:set_position(vector():set(npc_pos.x,npc_pos.y+0.5,npc_pos.z))
pick:set_direction(dir)
pick:set_ignore_object(db.actor)
pick:set_flags(2)
pick:set_range(tonumber(p[1])+5)
pick:query()
local distance = pick:get_distance()
if (distance and (distance < tonumber(p[1]))) then
return true
end
end
return false
end
--[[----------------------------------------------------------------------------------------------------
Quests
------------------------------------------------------------------------------------------------------]]
function lure_prey_init()
if (NI("me_lure_prey_init")) then
local smart = SIMBOARD.smarts_by_names["rad2_prip_teleport"]
if (smart) then
SIMBOARD:create_squad(smart,"squad_lure_prey_controller_1")
SIMBOARD:create_squad(smart,"squad_lure_prey_phantom")
local p = vector():set(663.0,-43.60,169.5)
alife():create("merc_outfit",vec_add(p,vector():set(-0.2,0.0,0.0)),smart.m_level_vertex_id,smart.m_game_vertex_id)
alife():create("helm_m40",vec_add(p,vector():set(-0.2,0.0,0.4)),smart.m_level_vertex_id,smart.m_game_vertex_id)
alife():create("wpn_lr300",vec_add(p,vector():set(0.2,0.0,0.0)),smart.m_level_vertex_id,smart.m_game_vertex_id)
alife():create("ammo_5.56x45_fmj",vec_add(p,vector():set(0.6,0.0,0.3)),smart.m_level_vertex_id,smart.m_game_vertex_id)
alife():create("ammo_5.56x45_fmj",vec_add(p,vector():set(0.6,0.0,0.1)),smart.m_level_vertex_id,smart.m_game_vertex_id)
alife():create("ammo_5.56x45_fmj",vec_add(p,vector():set(0.6,0.0,-0.1)),smart.m_level_vertex_id,smart.m_game_vertex_id)
alife():create("ammo_5.56x45_fmj",vec_add(p,vector():set(0.4,0.0,0.3)),smart.m_level_vertex_id,smart.m_game_vertex_id)
alife():create("ammo_5.56x45_fmj",vec_add(p,vector():set(0.4,0.0,0.1)),smart.m_level_vertex_id,smart.m_game_vertex_id)
alife():create("ammo_5.56x45_fmj",vec_add(p,vector():set(0.4,0.0,-0.1)),smart.m_level_vertex_id,smart.m_game_vertex_id)
alife():create("grenade_f1",vec_add(p,vector():set(0.6,0.0,-0.3)),smart.m_level_vertex_id,smart.m_game_vertex_id)
alife():create("grenade_f1",vec_add(p,vector():set(0.6,0.0,-0.3)),smart.m_level_vertex_id,smart.m_game_vertex_id)
end
GI("me_lure_prey_init")
end
end
function lure_prey_before_hit(npc,shit,bone_id,flags)
if (shit.draftsman and (shit.draftsman:id() == AC_ID)) then
if (NI("me_lure_prey_argo")) then
GI("me_lure_prey_argo")
end
return
end
flags.ret_value = false
end
function lure_prey_set_stalker(actor,npc,p)
if (db.actor and npc) then
local com_1 = db.actor:character_community()
local com_2 = npc:character_community()
if (com_1 and com_2 and not string.find(com_1,com_2)) then
local str = string.gsub(com_1,"actor_","")
npc:set_character_community(str)
end
end
end
--[[----------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------]]
function bloodsucker_val_init()
if (NI("me_bloodsucker_val_init")) then
local smart = SIMBOARD.smarts_by_names["val_smart_terrain_1_2"]
if (smart) then
SIMBOARD:create_squad(smart,"squad_bloodsucker_val_1")
SIMBOARD:create_squad(smart,"squad_bloodsucker_val_2")
SIMBOARD:create_squad(smart,"squad_bloodsucker_val_3")
end
GI("me_bloodsucker_val_init")
end
end
function bloodsucker_val_actor_sprint(actor,npc,p)
if not (IsMoveState("mcSprint")) then
return false
end
local pos = db.actor and db.actor:position()
if not (pos) then
return false
end
if not (170 < pos.x and pos.x < 177) then
return false
end
if not (-280 < pos.z and pos.z < -263) then
return false
end
return true
end
function bloodsucker_val_dead(actor,obj,p)
if (obj) then
local sec = {"squad_bloodsucker_val_1","squad_bloodsucker_val_2","squad_bloodsucker_val_3"}
for i,v in pairs (sec) do
if (string.find(obj:section_name(),v)) then
for ii,vv in pairs(sec) do
if (not string.find(obj:section_name(),vv) and get_story_se_object(vv)) then
return
end
end
if (NI("me_bloodsucker_val_dead")) then
GI("me_bloodsucker_val_dead")
end
return
end
end
end
end
--[[----------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------]]
function sleeping_snork_init()
if (NI("me_sleeping_snork_init")) then
create_squad("jup_b47","squad_sleeping_bloodsucker_jup_1")
create_squad("jup_b47","squad_sleeping_bloodsucker_jup_2")
--create_squad("jup_b47","squad_sleeping_bloodsucker_jup_3")
GI("me_sleeping_snork_init")
end
end
--[[----------------------------------------------------------------------------------------------------
Registers
------------------------------------------------------------------------------------------------------]]
function actor_on_first_update()
lure_prey_init()
bloodsucker_val_init()
end
function on_game_start()
RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
end
--[[----------------------------------------------------------------------------------------------------
Debug
------------------------------------------------------------------------------------------------------]]
--[[
cmd = debug_cmd_list.command_get_list()
function cmd.misc1()
lure_prey_init()
story_mercenary_leader()
end
function cmd.misc2()
bloodsucker_val_init()
end
function cmd.misc2kill1()
xr_effects.kill_squad(nil,nil,{"squad_bloodsucker_val_1"})
end
function cmd.misc2kill2()
xr_effects.kill_squad(nil,nil,{"squad_bloodsucker_val_2"})
end
function cmd.misc2kill3()
xr_effects.kill_squad(nil,nil,{"squad_bloodsucker_val_3"})
end
function cmd.misc3()
sleeping_snork_init()
end
function cmd.misc3kill()
xr_effects.kill_squad(nil,nil,{"squad_sleeping_snork_1"})
xr_effects.kill_squad(nil,nil,{"squad_sleeping_snork_2"})
xr_effects.kill_squad(nil,nil,{"squad_sleeping_snork_3"})
end
--]]
@@ -0,0 +1,303 @@
local STEP_SIZE = 5
local STEP_SIZE_OFFLINE = 1
local _mej = {
['logic@bar_zastava_guard_1_walk'] = "logic@duty_guard1",
['logic@bar_zastava_guard_2_walk'] = "logic@duty_guard2",
['logic@bar_zastava_guard_3_walk'] = "logic@duty_guard3",
['logic@bar_zastava_guard_4_walk'] = "logic@duty_guard4",
['logic@bar_zastava_guard_5_walk'] = "logic@duty_guard5",
['logic@bar_zastava_guard_6_walk'] = "logic@duty_guard6",
['logic@bar_zastava_guard_7_walk'] = "logic@duty_guard7",
['logic@bar_zastava_guard_8_walk'] = "logic@duty_guard8",
['logic@bar_zastava_guard_9_walk'] = "logic@duty_guard9",
['logic@follower_bar_zastava_guard_1_walk'] = "logic@duty_guard1",
['logic@follower_bar_zastava_guard_2_walk'] = "logic@duty_guard2",
['logic@follower_bar_zastava_guard_4_walk'] = "logic@duty_guard4",
['logic@follower_bar_zastava_guard_5_walk'] = "logic@duty_guard5",
['logic@follower_bar_zastava_guard_6_walk'] = "logic@duty_guard6",
['logic@follower_bar_zastava_guard_7_walk'] = "logic@duty_guard7",
['logic@follower_bar_zastava_guard_8_walk'] = "logic@duty_guard8",
}
local function allowed(a)
-- printf('allowed: %s',a.section)
if not _mej[a.section] then
return true
end
for k in pairs(db.storage) do
if tonumber(k) and db.storage[k] and db.storage[k].section_logic == _mej[a.section] then
-- printf('[%s] disallowed because [%s] (%s) taken', a.section, db.storage[k].section_logic, _mej[a.section])
return false
end
end
return true
end
local function job_avail_to_npc(npc_info, job, smart)
--[[
if (smart.dead_time[job.section]) then
return false
end
--]]
local precond = gulag_general.get_job_precondition(job)
if (precond) then
return allowed({ section = job.section}) and precond(npc_info.se_obj, smart, job, npc_info)
end
return true
end
function smart_terrain.se_smart_terrain:unregister_npc(obj)
--utils_data.debug_write(strformat("%s:%s:unregister_npc %s",self:name(),self.id,obj and obj:name()))
self.arriving_npc[obj.id] = nil
if (obj.clear_smart_terrain) then
obj:clear_smart_terrain()
end
self:clear_job(obj.id,true)
---[[GhenTuong: ----------------------------------------
if (xr_logic_ex and xr_logic_ex.ignore_smart_job and xr_logic_ex.ignore_smart_job(obj)) then
return
end
------------------------------------------------------]]
local st = db.storage[obj.id]
if (st and st.object) then
local cls = obj.clsid and obj:clsid()
if not (cls) then
return
end
local stype = IsStalker(nil,cls) and 0 or IsMonster(nil,cls) and 1 or IsHelicopter(nil,cls) and 3 or nil
if not (stype) then
return
end
xr_logic.initialize_obj(st.object, st, false, db.actor, stype)
end
--printf("self.npc_info[obj.id] = nil !!! obj.id=%s [%s]", obj.id,obj:name())
end
function smart_terrain.se_smart_terrain:select_npc_job(npc_info,now,surge_started)
if (self.disabled or not self.is_on_actor_level) then
return
end
---[[GhenTuong: ----------------------------------------
if (xr_logic_ex and xr_logic_ex.ignore_smart_job and xr_logic_ex.ignore_smart_job(npc_info and npc_info.se_obj)) then
return
end
------------------------------------------------------]]
--utils_data.debug_write(strformat("%s:select_npc_job %s",self:name()))
if not (npc_info and npc_info.se_obj and npc_info.stype) then
return printf("%s no npc_info!",self:name())
end
-- reference job table according to race
local jobs = npc_info.stype == 0 and self.stalker_jobs or npc_info.stype == 1 and self.monster_jobs or npc_info.stype == 3 and self.heli_jobs
if not (jobs) then
return printf("%s no job table for %s [stype = %s]",self:name(),npc_info.se_obj:name(),npc_info.stype)
end
local new_job
local npc_by_job_section = self.npc_by_job_section
-- If the NPC has an existing job link, validate it and iterate job table
-- for a higher priority job according to defined STEP_SIZE
if (npc_info.job) then
-- Make sure current job is still available
if (npc_by_job_section[npc_info.job.section] == npc_info.se_obj.id) then
-- Make sure current job is still available
if (job_avail_to_npc(npc_info,npc_info.job,self)) then
if (npc_info.current_index == nil or now) then
npc_info.current_index = 1
end
local get_job_prior = gulag_general.get_job_prior
local itr_job
local npc_id
local step = 1
while (new_job == nil and step <= (now and #jobs or st and STEP_SIZE or STEP_SIZE_OFFLINE)) do
step = step + 1
if (npc_info.current_index > #jobs) then
npc_info.current_index = 1
break
end
-- Step through job table one step at a time looking for a higher prior job
itr_job = jobs[npc_info.current_index]
npc_info.current_index = npc_info.current_index + 1
npc_id = npc_by_job_section[itr_job.section]
-- Check empty job
--if (npc_id == nil or npc_id == npc_info.se_obj.id) then
if (npc_id == nil) then
-- Find only higher priority jobs if already linked to a job
if (get_job_prior(itr_job) > get_job_prior(npc_info.job)) then
if (job_avail_to_npc(npc_info, itr_job, self)) then
-- Only take this higher priority job if when there is either no surge or if job is not in surge cover during surge; takes exclusive no matter what
if (itr_job.exclusive or not xr_conditions.surge_started() or not surge_manager.job_in_surge_cover(npc_info.se_obj,npc_info.job)) then
new_job = itr_job
npc_info.current_index = 1
end
end
end
end
end
else
-- Job is no longer available, unlink job info
for sec,npcid in pairs(npc_by_job_section) do
if (npcid == npc_info.se_obj.id) then
npc_by_job_section[sec] = nil
end
end
npc_info.job = nil
npc_info.current_index = 1
end
else
-- Job is not linked properly, npc_id doesn't match owner se_obj
for sec,npcid in pairs(npc_by_job_section) do
if (npcid == npc_info.se_obj.id) then
npc_by_job_section[sec] = nil
end
end
npc_info.job = nil
npc_info.current_index = 1
end
end
if not (npc_info.job) then
if (npc_info.current_index == nil or now) then
npc_info.current_index = 1
end
local itr_job,npc_id
local step = 1
local st = db.storage[npc_info.se_obj.id]
local STEP_SIZE_NO_JOB = #jobs
while (new_job == nil and step <= (now and STEP_SIZE_NO_JOB or st and STEP_SIZE_NO_JOB or STEP_SIZE_OFFLINE)) do
step = step + 1
if (npc_info.current_index > STEP_SIZE_NO_JOB) then
npc_info.current_index = 1
break
end
-- Step through job table one step at a time looking for a high prior job
itr_job = jobs[npc_info.current_index]
npc_info.current_index = npc_info.current_index + 1
npc_id = npc_by_job_section[itr_job.section]
-- validate existing job link
if (npc_id and not self.npc_info[npc_id]) then
npc_by_job_section[itr_job.section] = nil
end
-- Check empty job or re-take current job
if (npc_id == nil or npc_id == npc_info.se_obj.id) and (job_avail_to_npc(npc_info, itr_job, self)) then
new_job = itr_job
npc_info.current_index = 1
end
end
if not (new_job) then
return
end
end
local id = npc_info.se_obj.id
-- newly selected job
if (new_job and new_job ~= npc_info.job) then
-- Unassign npc_id from old job and unreference job section
for sec,npcid in pairs(npc_by_job_section) do
if (npcid == id) then
npc_by_job_section[sec] = nil
end
end
-- setup table that references NPCs by their job section
npc_by_job_section[new_job.section] = id
-- link up NPC info and references
npc_info.job = new_job
npc_info.begin_job = false
-- grab storage and ensure object is online.
local st = self.online and db.storage[id]
-- If NPC has storage, it is online, so switch logic
if (st and st.object) then
--xr_logic.switch_to_section(st.object, self.ltx, "nil")
npc_info.begin_job = true
empty_table(db.offline_objects[id])
self:setup_logic(st.object)
return true
end
end
if (npc_info.begin_job ~= true and npc_info.job) then
-- grab storage and ensure object is online.
local st = self.online and db.storage[id]
-- If NPC has storage it is online, so switch logic
if (st and st.object) then
npc_info.begin_job = true
empty_table(db.offline_objects[id])
self:setup_logic(st.object)
return true
end
end
end
function smart_terrain.setup_gulag_and_logic_on_spawn(obj, st, se_obj, stype, loaded)
--utils_data.debug_write(strformat("smart_terrain.setup_gulag_and_logic_on_spawn %s",obj and obj:name()))
local sim = alife()
---[[GhenTuong: ----------------------------------------
if (xr_logic_ex and xr_logic_ex.ignore_smart_job and xr_logic_ex.ignore_smart_job(se_obj)) then
return
end
------------------------------------------------------]]
-- Expedite arrival and job assignment
local smart = se_obj.m_smart_terrain_id and se_obj.m_smart_terrain_id ~= 65535 and sim:object(se_obj.m_smart_terrain_id)
if (smart and smart:clsid() == clsid.smart_terrain) then
local npc_info = smart.npc_info[se_obj.id]
if (npc_info) then
if not (npc_info.job) then
smart:select_npc_job(npc_info,true)
local smart_task = smart.npc_info[se_obj.id].job and smart.npc_info[se_obj.id].job.alife_task
if (smart_task) then
db.spawned_vertex_by_id[se_obj.id] = smart_task:level_vertex_id()
end
elseif (npc_info.job) then
-- if already job begin then don't spawn at job
local smart_task = npc_info.begin_job ~= true and npc_info.job and npc_info.job.alife_task or nil
if (smart_task) then
db.spawned_vertex_by_id[se_obj.id] = smart_task:level_vertex_id()
end
npc_info.begin_job = true
empty_table(db.offline_objects[se_obj.id])
smart:setup_logic(obj)
end
return
end
end
xr_logic.initialize_obj(obj, st, loaded, db.actor, stype)
end
@@ -0,0 +1,553 @@
local HI = has_alife_info
local GI = give_info
local DI = disable_info
function NI(str)
return not (has_alife_info(str))
end
--[[----------------------------------------------------------------------------------------------------
duty_girl_hunting_chimera
------------------------------------------------------------------------------------------------------]]
function duty_girl_hunting_chimera_status(tsk,task_id)
local sec = "squad_duty_girl_hunting_chimera"
if (tsk.stage == 0) then
if (HI("duty_girl_hunting_chimera_move")) then
local smart = SIMBOARD.smarts_by_names["gar_smart_terrain_2_4"]
local squad = SIMBOARD:create_squad(smart,sec)
tsk.stage = 1
end
end
if (tsk.stage == 1) then
local squad = get_story_se_object(sec)
if not (squad) then
local function message()
local npc = get_story_object("stalker_duty_girl")
if (npc and db.actor) then
if (NI("duty_girl_hunting_chimera_hunt_4") and xr_conditions.check_time_speech(db.actor,npc)) then
GI("duty_girl_hunting_chimera_hunt_4")
xr_effects.speech(db.actor,npc,{"duty_girl_hunting_chimera_hunt_4",5})
end
end
if (HI("duty_girl_hunting_chimera_hunt_4")) then
return true
end
end
local npc = get_story_object("stalker_duty_girl")
if (npc) then
CreateTimeEvent(npc:id(),"speech",0,message)
end
tsk.stage = 2
end
end
if (tsk.stage == 2) then
if (NI("duty_girl_hunting_chimera_dead")) then
GI("duty_girl_hunting_chimera_dead")
end
if (HI("duty_girl_hunting_chimera_reward")) then
return "complete"
end
end
end
function duty_girl_hunting_chimera_target(task_id,field,p,tsk)
if (field == "title") then
return task_id.."_"..field
end
if (field == "descr") then
if (tsk.stage == 0) then
return task_id.."_"..field.."_1"
end
if (tsk.stage == 1) then
return task_id.."_"..field.."_2"
end
if (tsk.stage == 2) then
return task_id.."_"..field.."_3"
end
end
if (field == "target") then
if (tsk.stage == 0) then
local obj = SIMBOARD.smarts_by_names["gar_smart_terrain_6_3"]
return obj and obj.id
end
if (tsk.stage == 1) or (tsk.stage == 2) then
local obj = get_story_se_object("squad_duty_girl")
return obj and obj.id
end
end
end
function hunting_chimera_hit(npc,shit,bone_id,flags)
if (shit and shit.draftsman and IsStalker(shit.draftsman)) then
if (shit.draftsman:id() == AC_ID) then
if (NI("duty_girl_hunting_chimera_fight")) then
GI("duty_girl_hunting_chimera_fight")
end
return
end
if (shit.draftsman:has_info("npcx_is_companion") or string.find(shit.draftsman:name(),"stalker_duty_girl")) then
if (NI("duty_girl_hunting_chimera_fight")) then
GI("duty_girl_hunting_chimera_fight")
end
shit.power = shit.power / 2
return
end
end
flags.ret_value = false
end
--[[----------------------------------------------------------------------------------------------------
duty_girl_monolith_elite
------------------------------------------------------------------------------------------------------]]
function duty_girl_monolith_elite_status(tsk,task_id)
if (tsk.stage == 0) then
SIMBOARD:create_squad(SIMBOARD.smarts_by_names["mil_smart_terrain_2_6"],"squad_duty_girl_monolith_elite_mono")
SIMBOARD:create_squad(SIMBOARD.smarts_by_names["mil_smart_terrain_4_5"],"squad_duty_girl_monolith_elite_duty")
tsk.stage = 1
end
if (tsk.stage == 1) or (tsk.stage == 2) then
local squad = get_story_se_object("squad_duty_girl_monolith_elite_mono")
local mem_num = squad and squad:npc_count() or 0
if (mem_num ~= 0) then
-- Player attack without order
if (mem_num < 8) then
if (NI("duty_girl_monolith_elite_move")) then
GI("duty_girl_monolith_elite_move")
if (NI("duty_girl_monolith_elite_join")) then
GI("duty_girl_monolith_elite_join")
end
local function message()
local npc = get_story_object("stalker_duty_girl")
if (npc and db.actor) then
if (NI("duty_girl_monolith_elite_move_5") and xr_conditions.check_time_speech(db.actor,npc)) then
GI("duty_girl_monolith_elite_move_5")
xr_effects.speech(db.actor,npc,{"duty_girl_monolith_elite_move_5",5})
end
if (NI("duty_girl_monolith_elite_move_6") and xr_conditions.check_time_speech(db.actor,npc)) then
GI("duty_girl_monolith_elite_move_6")
xr_effects.speech(db.actor,npc,{"duty_girl_monolith_elite_move_6",5})
end
end
if (HI("duty_girl_monolith_elite_move_6")) then
return true
end
end
local npc = get_story_object("stalker_duty_girl")
if (npc) then
CreateTimeEvent(npc:id(),"speech",0,message)
end
end
end
else
-- Squad is killed
local function message()
local npc = get_story_object("stalker_duty_girl")
if (npc and db.actor) then
if (NI("duty_girl_monolith_elite_move_4") and xr_conditions.check_time_speech(db.actor,npc)) then
GI("duty_girl_monolith_elite_move_4")
xr_effects.speech(db.actor,npc,{"duty_girl_monolith_elite_move_4",5})
end
end
if (HI("duty_girl_monolith_elite_move_4")) then
return true
end
end
local npc = get_story_object("stalker_duty_girl")
if (npc) then
CreateTimeEvent(npc:id(),"speech",0,message)
end
tsk.stage = 3
end
if (tsk.stage == 1) then
if (HI("duty_girl_monolith_elite_move")) then
tsk.stage = 2
end
end
end
if (tsk.stage == 3) then
if (NI("duty_girl_monolith_elite_dead")) then
GI("duty_girl_monolith_elite_dead")
end
if (HI("duty_girl_monolith_elite_reward")) then
return "complete"
end
end
end
function duty_girl_monolith_elite_target(task_id,field,p,tsk)
if (field == "title") then
return task_id.."_"..field
end
if (field == "descr") then
if (tsk.stage == 0) or (tsk.stage == 1) then
return task_id.."_"..field.."_1"
end
if (tsk.stage == 2) then
return task_id.."_"..field.."_2"
end
if (tsk.stage == 3) then
return task_id.."_"..field.."_3"
end
end
if (field == "target") then
if (tsk.stage == 0) or (tsk.stage == 1) then
local obj = get_story_se_object("squad_duty_girl")
local sqd = get_story_se_object("squad_duty_girl_monolith_elite_duty")
if (obj and sqd and simulation_objects.is_on_the_same_level(obj,sqd)) then
return obj.id
end
return sqd and sqd.id
end
if (tsk.stage == 2) then
local obj = SIMBOARD.smarts_by_names["mil_smart_terrain_2_6"]
return obj and obj.id
end
if (tsk.stage == 3) then
local obj = get_story_se_object("squad_duty_girl")
return obj and obj.id
end
end
end
function monolith_elite_hit(npc,shit,bone_id,flags)
if (shit and shit.draftsman and IsStalker(shit.draftsman)) then
if (shit.draftsman:id() == AC_ID) then
return
end
if (IsStalker(shit.draftsman) and shit.draftsman:has_info("npcx_is_companion") or string.find(shit.draftsman:name(),"stalker_duty_girl")) then
shit.power = shit.power / 4
return
end
local squad = get_object_squad(shit.draftsman)
if (squad and string.find(squad:section_name(),"squad_duty_girl_monolith_elite")) then
if (string.find(npc:name(),"monolith")) then
shit.power = shit.power / 4
else
shit.power = shit.power / 2
end
return
end
end
flags.ret_value = false
end
--[[----------------------------------------------------------------------------------------------------
duty_girl_loot_stash
------------------------------------------------------------------------------------------------------]]
function duty_girl_loot_stash_status(tsk,task_id)
if (tsk.stage == 0) then
local tbl = {
"detector_advanced",
"vodka","vodka",
"bandage","bandage","bandage","bandage","bandage",
"medkit","medkit","medkit","medkit","medkit",
"ammo_5.56x45_fmj","ammo_5.56x45_fmj","ammo_5.56x45_fmj","ammo_5.56x45_fmj","ammo_5.56x45_fmj","ammo_5.56x45_fmj"
}
local sm = SIMBOARD.smarts_by_names["val_smart_terrain_1_2"]
local pos = vector():set(175.7,1,-278.6)
if (sm) then
for i,v in pairs(tbl) do
alife():create(v,pos,sm.m_level_vertex_id,sm.m_game_vertex_id)
end
local se = alife():create("wpn_lr300",pos,sm.m_level_vertex_id,sm.m_game_vertex_id)
if (se) then
save_var(db.actor,task_id,se.id)
end
end
tsk.stage = 1
end
if (tsk.stage == 1) then
local id = load_var(db.actor,task_id)
local se = id and alife():object(id)
if not (se and IsWeapon(se) and string.find(se:name(),"wpn_lr300") and (se.parent_id == 65535)) then
return "complete"
end
end
end
function duty_girl_loot_stash_target(task_id,field,p,tsk)
if (field == "title") then
return task_id.."_"..field
end
if (field == "descr") then
return task_id.."_"..field.."_1"
end
if (field == "target") then
local id = load_var(db.actor,task_id)
local se = id and alife():object(id)
return se and se.id
end
end
--[[----------------------------------------------------------------------------------------------------
duty_girl_capture_the_brirge
------------------------------------------------------------------------------------------------------]]
function duty_girl_capture_the_brirge_status(tsk,task_id)
if (tsk.stage == 0) then
SIMBOARD:create_squad(SIMBOARD.smarts_by_names["red_smart_terrain_bridge"],"squad_duty_girl_capture_the_brirge_mono_1")
SIMBOARD:create_squad(SIMBOARD.smarts_by_names["red_smart_terrain_bridge"],"squad_duty_girl_capture_the_brirge_mono_2")
SIMBOARD:create_squad(SIMBOARD.smarts_by_names["red_smart_terrain_5_5"],"squad_duty_girl_capture_the_brirge_duty")
SIMBOARD:create_squad(SIMBOARD.smarts_by_names["red_smart_terrain_5_5"],"squad_duty_girl_capture_the_brirge_lone")
tsk.stage = 1
end
if (tsk.stage == 1) or (tsk.stage == 2) then
local squad_1 = get_story_se_object("squad_duty_girl_capture_the_brirge_mono_1")
local squad_2 = get_story_se_object("squad_duty_girl_capture_the_brirge_mono_2")
local mem_num = (squad_1 and squad_1:npc_count() or 0) + (squad_2 and squad_2:npc_count() or 0)
if (mem_num ~= 0) then
-- Player attack without order
if (mem_num < 20) then
if (NI("duty_girl_capture_the_brirge_move")) then
GI("duty_girl_capture_the_brirge_move")
if (NI("duty_girl_capture_the_brirge_join")) then
GI("duty_girl_capture_the_brirge_join")
end
local function message()
local npc = get_story_object("stalker_duty_girl")
if (npc and db.actor) then
if (NI("duty_girl_capture_the_brirge_move_5") and xr_conditions.check_time_speech(db.actor,npc)) then
GI("duty_girl_capture_the_brirge_move_5")
xr_effects.speech(db.actor,npc,{"duty_girl_capture_the_brirge_move_5",5})
end
if (NI("duty_girl_capture_the_brirge_move_6") and xr_conditions.check_time_speech(db.actor,npc)) then
GI("duty_girl_capture_the_brirge_move_6")
xr_effects.speech(db.actor,npc,{"duty_girl_capture_the_brirge_move_6",5})
end
end
if (HI("duty_girl_capture_the_brirge_move_6")) then
return true
end
end
local npc = get_story_object("stalker_duty_girl")
if (npc) then
CreateTimeEvent(npc:id(),"speech",0,message)
end
end
end
else
-- Squad is killed
local function message()
local npc = get_story_object("stalker_duty_girl")
if (npc and db.actor) then
if (NI("duty_girl_capture_the_brirge_move_4") and xr_conditions.check_time_speech(db.actor,npc)) then
GI("duty_girl_capture_the_brirge_move_4")
xr_effects.speech(db.actor,npc,{"duty_girl_capture_the_brirge_move_4",5})
end
end
if (HI("duty_girl_capture_the_brirge_move_4")) then
return true
end
end
local npc = get_story_object("stalker_duty_girl")
if (npc) then
CreateTimeEvent(npc:id(),"speech",0,message)
end
tsk.stage = 3
end
if (tsk.stage == 1) then
if (HI("duty_girl_capture_the_brirge_move")) then
tsk.stage = 2
end
end
end
if (tsk.stage == 3) then
if (NI("red_bridge_outpost")) then
GI("red_bridge_outpost")
end
if (NI("duty_girl_capture_the_brirge_dead")) then
GI("duty_girl_capture_the_brirge_dead")
end
if (HI("duty_girl_capture_the_brirge_reward")) then
return "complete"
end
end
end
function duty_girl_capture_the_brirge_target(task_id,field,p,tsk)
if (field == "title") then
return task_id.."_"..field
end
if (field == "descr") then
if (tsk.stage == 0) or (tsk.stage == 1) then
return task_id.."_"..field.."_1"
end
if (tsk.stage == 2) then
return task_id.."_"..field.."_2"
end
if (tsk.stage == 3) then
return task_id.."_"..field.."_3"
end
end
if (field == "target") then
if (tsk.stage == 0) or (tsk.stage == 1) then
local obj = get_story_se_object("squad_duty_girl")
local sqd = get_story_se_object("squad_duty_girl_capture_the_brirge_duty")
if (obj and sqd and simulation_objects.is_on_the_same_level(obj,sqd)) then
return obj.id
end
return sqd and sqd.id
end
if (tsk.stage == 2) then
local obj = SIMBOARD.smarts_by_names["red_smart_terrain_bridge"]
return obj and obj.id
end
if (tsk.stage == 3) then
local obj = get_story_se_object("squad_duty_girl")
return obj and obj.id
end
end
end
function capture_the_brirge_hit(npc,shit,bone_id,flags)
if (shit and shit.draftsman and IsStalker(shit.draftsman)) then
local npc_squad = get_object_squad(npc)
local hit_squad = (shit.draftsman:id() ~= AC_ID) and get_object_squad(shit.draftsman)
if (npc_squad and string.find(npc_squad:section_name(),"squad_duty_girl_capture_the_brirge_mono")) then
if (shit.draftsman:id() == AC_ID) then
return
end
if (shit.draftsman:has_info("npcx_is_companion") or string.find(shit.draftsman:name(),"stalker_duty_girl")) then
shit.power = shit.power / 3
return
end
if (hit_squad and string.find(hit_squad:section_name(),"squad_duty_girl_capture_the_brirge")) then
shit.power = shit.power / 3
return
end
else
if (hit_squad and string.find(hit_squad:section_name(),"squad_duty_girl_capture_the_brirge")) then
shit.power = shit.power / 3
return
end
end
end
flags.ret_value = false
end
function capture_the_brirge_spawn_outpost(actor,squad,p)
local lst = {
"squad_red_duty_outpost_trader",
"squad_red_duty_outpost_medic",
"squad_red_duty_outpost_guide",
"squad_red_duty_outpost_guard_1",
"squad_red_duty_outpost_guard_2",
"squad_red_duty_outpost_visitor_1",
"squad_red_duty_outpost_visitor_2",
"squad_red_duty_outpost_visitor_3",
"squad_red_duty_outpost_visitor_4"
}
for k,sec in pairs(lst) do
if not (get_story_se_object(sec)) then
SIMBOARD:create_squad(SIMBOARD.smarts_by_names["red_smart_terrain_bridge"],sec)
end
end
end
--[[----------------------------------------------------------------------------------------------------
Main
------------------------------------------------------------------------------------------------------]]
task_status_functor.duty_girl_task_status = function(tsk,task_id)
if not (task_id and tsk) then
return
end
return _G["task_duty_girl"][task_id .. "_status"](tsk,task_id)
end
task_functor.duty_girl_task_target = function(task_id,field,p,tsk)
if not (task_id and tsk) then
return
end
return _G["task_duty_girl"][task_id .. "_target"](task_id,field,p,tsk)
end
--[[----------------------------------------------------------------------------------------------------
Debug
------------------------------------------------------------------------------------------------------]]
---[[
cmd = debug_cmd_list.command_get_list()
function cmd.redbase()
if (NI("red_bridge_outpost")) then
GI("red_bridge_outpost")
end
xr_dynamic_object.dynamic_object(db.actor,db.actor,{"misc\\duty_outpost_object.ltx"})
capture_the_brirge_spawn_outpost()
end
function cmd.d1()
gameplay_duty_girl.duty_girl_init()
task_manager.get_task_manager():give_task("duty_girl_hunting_chimera")
end
function cmd.d1kill()
local squad_1 = get_story_se_object("squad_duty_girl_hunting_chimera")
if (squad_1) then
alife_release(squad_1)
end
end
function cmd.d1skip()
gameplay_duty_girl.duty_girl_init()
GI("duty_girl_hunting_chimera_done")
end
function cmd.d2()
gameplay_duty_girl.duty_girl_init()
task_manager.get_task_manager():give_task("duty_girl_monolith_elite")
end
function cmd.d2kill()
local squad_1 = get_story_se_object("squad_duty_girl_monolith_elite_mono")
if (squad_1) then
alife_release(squad_1)
end
end
function cmd.d3()
task_manager.get_task_manager():give_task("duty_girl_loot_stash")
end
function cmd.d3skip()
gameplay_duty_girl.duty_girl_init()
GI("duty_girl_loot_stash_done")
end
function cmd.d4()
gameplay_duty_girl.duty_girl_init()
task_manager.get_task_manager():give_task("duty_girl_capture_the_brirge")
end
function cmd.d4kill()
local squad_1 = get_story_se_object("squad_duty_girl_capture_the_brirge_mono_1")
local squad_2 = get_story_se_object("squad_duty_girl_capture_the_brirge_mono_2")
if (squad_1) then
alife_release(squad_1)
end
if (squad_2) then
alife_release(squad_2)
end
end
--]]
@@ -0,0 +1,197 @@
local dynamic_object_storage = {}
function dynamic_object(actor,obj,p)
local ini = p and p[1] and ini_file(p[1])
local smart_name = ini and ini:r_string_ex("dynamic_object_configs","smart")
local smart = smart_name and SIMBOARD.smarts_by_names[smart_name]
if not (smart) then
return
end
if not (dynamic_object_storage[smart_name]) then
dynamic_object_storage[smart_name] = {}
end
local lst = dynamic_object_storage[smart_name]
local n = ini:line_count("exclusive")
for k=0,n-1 do
local r,i,v = ini:r_line("exclusive",k)
local s = get_object_config(v)
if (i and s) then
local idx = lst[i]
local sec = s.sec
local pos = s.pos
local ang = s.ang
local con = s.con and ini:r_string_to_condlist("dynamic_object_configs",s.con,"true")
if (xr_logic.pick_section_from_condlist(db.actor,obj,con) == "true") then
local se = idx and tonumber(idx.id) and alife():object(tonumber(idx.id))
if (se and string.find(se:name(),sec)) then
-- Correct. Update object.
se.position = vector():set(pos)
se.angle = vector():set(ang)
else
-- Wrong object or doesn't exit. Try to delete the old object and create a new one.
if (se and idx.sec and string.find(se:name(),idx.sec)) then
alife_release(se)
end
local new_se = alife():create(sec,pos,smart.m_level_vertex_id,smart.m_game_vertex_id)
if (new_se) then
new_se.angle = vector():set(ang)
lst[i] = {id = tonumber(new_se.id),sec = tostring(sec)}
--printf("GhenTuong: dynamic_object create %s [%s]",new_se.id,new_se:name())
end
end
else
if (idx) then
local se = tonumber(idx.id) and alife():object(tonumber(idx.id))
if (se and idx.sec and string.find(se:name(),idx.sec)) then
--printf("GhenTuong: dynamic_object delete %s [%s]",se.id,se:name())
alife_release(se)
end
lst[i] = nil
end
end
end
end
for i,idx in pairs(lst) do
if (i and idx) then
if not (ini:line_exist("exclusive",i)) then
local se = idx and tonumber(idx.id) and alife():object(tonumber(idx.id))
if (se and idx.sec and string.find(se:name(),idx.sec)) then
--printf("GhenTuong: dynamic_object delete %s [%s]",se.id,se:name())
alife_release(se)
end
lst[i] = nil
end
else
lst[i] = nil
end
end
end
--[[
if not (ini:section_exist("exclusive") and ini:line_exist("exclusive",i)) then
return
end
local v = ini:r_string_ex("exclusive",i)
--]]
function get_object_config(v)
local str = v and str_explode(v,"|")
local sec = str[1] and (str[1] ~= "") and (str[1] ~= "nil") and tostring(str[1])
local tp = str[2] and str_explode(str[2],",") or nil
local td = str[3] and str_explode(str[3],",") or nil
local pox = tp and tonumber(tp[1])
local poy = tp and tonumber(tp[2])
local poz = tp and tonumber(tp[3])
local rox = td and tonumber(td[1]) and math.rad(tonumber(td[1]))
local roy = td and tonumber(td[2]) and math.rad(tonumber(td[2]))
local roz = td and tonumber(td[3]) and math.rad(tonumber(td[3]))
local con = str[4] or "nil"
if not (pox and poy and poz and rox and roy and roz and con) then
return
end
return {sec = sec, pos = vector():set(pox,poy,poz), ang = vector():set(rox,roy,roz), con = con}
end
function get_object(smart_name,index)
local idx = dynamic_object_storage_loaded and dynamic_object_storage[smart_name] and dynamic_object_storage[smart_name][index]
return idx and {id = tonumber(idx.id),sec = tostring(idx.sec)}
end
--[[----------------------------------------------------------------------------------------------------
Lighting
p[1] action
p[2] sec
p[3] bone
------------------------------------------------------------------------------------------------------]]
function light(actor,obj,p)
local sec = p[1]
local pos = p[2] and obj:bone_position(p[2]) or obj:position()
local st = db.storage[obj:id()]
if not (st and sec and pos) then
return
end
if (st.dynamic_light) then
--Switch
if (st.dynamic_light.light) then
local new_state = (tonumber(p[3]) == 1) and true or false
if (st.dynamic_light.light.enabled ~= new_state) then
st.dynamic_light.light.enabled = new_state
st.dynamic_light.light:update()
end
--Position
st.dynamic_light.light:set_position(pos)
end
else
st.dynamic_light = {}
st.dynamic_light.light = script_light()
st.dynamic_light.sec = tostring(sec)
if (st.dynamic_light.light) then
local ini = st.ini
local n = ini:line_count(sec)
for k=0,n-1 do
local result,i,v = ini:r_line(sec,k)
--Basic
if (i == "range") then
st.dynamic_light.light.range = tonumber(v)
end
if (i == "color") then
st.dynamic_light.light.color = (tonumber(v) and fcolor():set(tonumber(v)))
end
if (i == "shadow") then
st.dynamic_light.light.shadow = (v == "true")
end
--Volumetric
if (i == "volumetric") then
st.dynamic_light.light.volumetric = (v == "true")
end
if (i == "volumetric_quality") then
st.dynamic_light.light.volumetric_quality = tonumber(v)
end
if (i == "volumetric_distance") then
st.dynamic_light.light.volumetric_distance = tonumber(v)
end
if (i == "volumetric_intensity") then
st.dynamic_light.light.volumetric_intensity = tonumber(v)
end
--Texture/Light animation
if (i == "texture") then
st.dynamic_light.light.texture = tostring(v)
end
if (i == "lanim") then
st.dynamic_light.light.lanim = tostring(v)
end
if (i == "lanim_brightness") then
st.dynamic_light.light.lanim_brightness = tonumber(v)
end
end
st.dynamic_light.light:set_position(pos)
st.dynamic_light.light:update()
end
end
end
function save_state(m_data)
m_data.xr_dynamic_object_storage = dynamic_object_storage
end
function load_state(m_data)
dynamic_object_storage = m_data.xr_dynamic_object_storage or {}
end
function on_game_start()
RegisterScriptCallback("save_state",save_state)
RegisterScriptCallback("load_state",load_state)
end
File diff suppressed because it is too large Load Diff