807 lines
30 KiB
Plaintext
807 lines
30 KiB
Plaintext
|
local nta_utils = new_tasks_addon_tasks_utils
|
||
|
local configs = a_the_living_fire_configs
|
||
|
|
||
|
local state = {
|
||
|
prometheus_id = nil,
|
||
|
garbage_mutant_id = nil,
|
||
|
anomaly_ids = {},
|
||
|
mutant_ids = {},
|
||
|
corpse_ids = {},
|
||
|
corpse_moved = {},
|
||
|
x18_military_ids = {},
|
||
|
x18_military_relation_set = {},
|
||
|
greh_ids = {},
|
||
|
endgame_killed_greh = {}
|
||
|
}
|
||
|
function save_state(mdata)
|
||
|
mdata.the_living_fire_task_data = state
|
||
|
end
|
||
|
|
||
|
function load_state(mdata)
|
||
|
if mdata.the_living_fire_task_data then
|
||
|
state = mdata.the_living_fire_task_data
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local prometheus_icon = 'ui_inGame2_no_data'
|
||
|
local prometheus_name = 'the_living_fire_mysterious_stalker_name'
|
||
|
local prometheus_real_name = 'the_living_fire_prometheus_name'
|
||
|
local sakharov_icon = 'ui_inGame2_sakharov'
|
||
|
local sakharov_name = 'yan_st_sakharov_name'
|
||
|
local snitch_icon = 'ui_inGame2_bandit_4'
|
||
|
local snitch_name = 'bar_informator_mlr_name'
|
||
|
local outskirts_anomalies_spawned = false
|
||
|
|
||
|
task_status_functor.the_living_fire_task_status_functor = function(tsk,task_id)
|
||
|
if not (db.actor and tsk) then return end
|
||
|
local stage = tsk.stage
|
||
|
|
||
|
if stage == 0 then
|
||
|
if db.actor:has_info('baraholka_trader_the_living_fire_1_passed') then
|
||
|
tsk.stage = 1
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 1 then
|
||
|
if
|
||
|
nta_utils.actor_on_level(nta_utils.levels.garbage)
|
||
|
and nta_utils.actor_in_range(configs.garbage_prometheus_location.vector, configs.garbage_prometheus_spawn_activation_distance)
|
||
|
and nta_utils.is_dark_night()
|
||
|
then
|
||
|
spawn_garbage_prometheus()
|
||
|
spawn_garbage_anomalies()
|
||
|
spawn_garbage_trash()
|
||
|
db.actor:give_info_portion("the_living_fire_prometheus_garbage_spawned")
|
||
|
delayed_message('the_living_fire_garbage_actor_msg_1', 1.5, nta_utils.actor_icon(), nta_utils.actor_name())
|
||
|
tsk.stage = 2
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 2 then
|
||
|
if
|
||
|
nta_utils.actor_on_level(nta_utils.levels.garbage)
|
||
|
and nta_utils.actor_in_range(configs.garbage_prometheus_location.vector, configs.garbage_mutant_spawn_activation_distance)
|
||
|
then
|
||
|
spawn_garbage_mutant()
|
||
|
delayed_message('the_living_fire_garbage_prometheus_msg_1', 1, prometheus_icon, prometheus_name)
|
||
|
garbage_delayed_kill_mutant()
|
||
|
tsk.stage = 3
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 3 then
|
||
|
if db.actor:has_info('the_living_fire_garbage_mutant_killed') then
|
||
|
delayed_message('the_living_fire_garbage_actor_msg_2', 3.5, nta_utils.actor_icon(), nta_utils.actor_name())
|
||
|
delayed_message('the_living_fire_garbage_prometheus_msg_2', 4.5, prometheus_icon, prometheus_name)
|
||
|
tsk.stage = 4
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 4 then
|
||
|
CreateTimeEvent(0,"the_living_fire_garbage_prometheus_disappear", 8, function ()
|
||
|
safe_release_manager.release({id = state.prometheus_id})
|
||
|
local explosion_spawn_config = nta_utils.shallow_copy(configs.garbage_prometheus_location)
|
||
|
explosion_spawn_config.section = 'immediate_fiery_explosion'
|
||
|
nta_utils.spawn_helper(explosion_spawn_config)
|
||
|
CreateTimeEvent(0,"the_living_fire_garbage_anomalies_disappear", 0.5, function ()
|
||
|
despawn_anomalies()
|
||
|
return true
|
||
|
end)
|
||
|
|
||
|
delayed_message('the_living_fire_garbage_actor_msg_3', 10, nta_utils.actor_icon(), nta_utils.actor_name())
|
||
|
db.actor:give_info_portion('the_living_fire_prometheus_garbage_disappeared')
|
||
|
tsk.stage = 5
|
||
|
return true
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
if stage == 5 then
|
||
|
if db.actor:has_info('baraholka_trader_the_living_fire_2_passed') then
|
||
|
tsk.stage = 6
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 6 then
|
||
|
if db.actor:has_info('bar_informator_mlr_the_living_fire_2_passed') then
|
||
|
tsk.stage = 7
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 7 then
|
||
|
if db.actor:has_info('yan_stalker_sakharov_the_living_fire_1_passed') then
|
||
|
tsk.stage = 8
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 8 then
|
||
|
if nta_utils.actor_on_level(nta_utils.levels.swamp) and nta_utils.actor_in_range(
|
||
|
get_story_object('mar_smart_terrain_11_3_anomaly_spot'):position(),
|
||
|
configs.swamp_spawn_activation_distance
|
||
|
) then
|
||
|
spawn_explosions(configs.swamp_explosion_locations)
|
||
|
delayed_message('the_living_fire_swamp_actor_msg_1', 3, nta_utils.actor_icon(), nta_utils.actor_name(), 6)
|
||
|
delayed_message('the_living_fire_swamp_sakharov_msg_1', 7, sakharov_icon, sakharov_name, 12)
|
||
|
spawn_mutants(configs.swamp_mutant_locations)
|
||
|
tsk.stage = 9
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 9 then
|
||
|
if not first_alive_mutant_id() then
|
||
|
delayed_message('the_living_fire_swamp_sakharov_msg_2', 2, sakharov_icon, sakharov_name, 12)
|
||
|
db.actor:give_info_portion('the_living_fire_swamp_mutants_killed')
|
||
|
state.mutant_ids = {}
|
||
|
tsk.stage = 10
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 10 then
|
||
|
if db.actor:has_info('yan_stalker_sakharov_the_living_fire_2_passed') then
|
||
|
delayed_message('the_living_fire_yantar_snitch_msg_1', 5, snitch_icon, snitch_name, 8)
|
||
|
delayed_message('the_living_fire_yantar_actor_msg_1', 10, nta_utils.actor_icon(), nta_utils.actor_name(), 8)
|
||
|
tsk.stage = 11
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 11 then
|
||
|
if db.actor:has_info('bar_informator_mlr_the_living_fire_3_passed') then
|
||
|
state.prometheus_id = nta_utils.spawn_helper(configs.x18_prometheus_location)
|
||
|
alife_object(state.prometheus_id):set_character_name(game.translate_string(prometheus_name))
|
||
|
spawn_corpses(configs.dark_valley_corpses_locations)
|
||
|
tsk.stage = 12
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 12 then
|
||
|
move_corpses()
|
||
|
send_dark_valley_actor_msg()
|
||
|
send_x18_prometheus_msg()
|
||
|
adjust_prometheus_position(configs.x18_prometheus_location.vector, 0.3)
|
||
|
if db.actor:has_info('the_living_fire_prometheus_the_living_fire_1_passed') then
|
||
|
despawn_prometheus_mild()
|
||
|
tsk.stage = 13
|
||
|
CreateTimeEvent(0,"the_living_fire_x18_spawn_military", 1, function ()
|
||
|
spawn_x18_military()
|
||
|
-- Exception because it's not NPC
|
||
|
CreateTimeEvent(0,"the_living_fire_x18_send_military_message", 4, function ()
|
||
|
dynamic_news_helper.send_tip(game.translate_string('the_living_fire_x18_military_msg_1'), game.translate_string("army"), nil,nil, 'ui_icon_news_trx_army', nil, 'npc')
|
||
|
return true
|
||
|
end)
|
||
|
return true
|
||
|
end)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 13 then
|
||
|
set_x18_military_relation()
|
||
|
if db.actor:has_info('bar_informator_mlr_the_living_fire_4_passed') then
|
||
|
delayed_message('the_living_fire_bar_actor_msg_1', 5, nta_utils.actor_icon(), nta_utils.actor_name(), 10)
|
||
|
despawn_corpses()
|
||
|
tsk.stage = 14
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 14 then
|
||
|
if db.actor:has_info('esc_2_12_stalker_trader_the_living_fire_1_passed') then
|
||
|
delayed_message('the_living_fire_escape_sakharov_msg_1', 5, sakharov_icon, sakharov_name, 10)
|
||
|
tsk.stage = 15
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 15 then
|
||
|
if db.actor:has_info('yan_stalker_sakharov_the_living_fire_3_passed') then
|
||
|
delayed_message('the_living_fire_yantar_barman_msg_1', 5, 'ui_inGame2_barman', 'bar_barmen_name', 10)
|
||
|
state.prometheus_id = nta_utils.spawn_helper(configs.x16_prometheus_location)
|
||
|
spawn_greh(configs.x16_greh_locations, [[scripts\x16_tlf_greh_beh.ltx]])
|
||
|
spawn_corpses(configs.x16_corpse_locations)
|
||
|
tsk.stage = 16
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 16 then
|
||
|
clear_x16_mutants()
|
||
|
move_corpses()
|
||
|
send_x16_prometheus_msg()
|
||
|
if db.actor:has_info('the_living_fire_prometheus_the_living_fire_2_passed') then
|
||
|
state.greh_ids = {}
|
||
|
despawn_prometheus_mild()
|
||
|
tsk.stage = 17
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 17 then
|
||
|
if db.actor:has_info('yan_stalker_sakharov_the_living_fire_4_passed') then
|
||
|
despawn_corpses()
|
||
|
spawn_greh(configs.red_forest_greh_locations, [[scripts\red_forest_tlf_greh_beh.ltx]])
|
||
|
tsk.stage = 18
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 18 then
|
||
|
if
|
||
|
nta_utils.actor_on_level(nta_utils.levels.red_forest)
|
||
|
and nta_utils.actor_in_range(configs.red_forest_mutants_trigger.vector, configs.red_forest_mutants_trigger_range)
|
||
|
then
|
||
|
spawn_explosions(configs.red_forest_explosion_locations)
|
||
|
spawn_mutants(configs.red_forest_mutant_locations)
|
||
|
earthquake_effect()
|
||
|
tsk.stage = 19
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 19 then
|
||
|
if not first_alive_mutant_id() then
|
||
|
state.greh_ids = {}
|
||
|
spawn_isg()
|
||
|
delayed_message('the_living_fire_red_forest_actor_msg_1', 5, nta_utils.actor_icon(), nta_utils.actor_name(), 10)
|
||
|
delayed_message('the_living_fire_red_forest_sakharov_msg_1', 10, sakharov_icon, sakharov_name, 10)
|
||
|
tsk.stage = 20
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 20 then
|
||
|
if
|
||
|
nta_utils.actor_on_level(nta_utils.levels.red_forest)
|
||
|
and nta_utils.actor_in_range(configs.red_forest_actor_msg_trigger.vector, configs.red_forest_actor_msg_trigger_range)
|
||
|
then
|
||
|
delayed_message('the_living_fire_red_forest_actor_msg_2', 2, nta_utils.actor_icon(), nta_utils.actor_name(), 10)
|
||
|
db.actor:give_info_portion('the_living_fire_red_forest_actor_msg_2_sent')
|
||
|
tsk.stage = 21
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 21 then
|
||
|
if db.actor:has_info('bar_informator_mlr_the_living_fire_5_passed') then
|
||
|
state.anomaly_ids = {}
|
||
|
spawn_greh(configs.outskirts_greh_locations, [[scripts\outskirts_tlf_greh_beh.ltx]])
|
||
|
state.prometheus_id = nta_utils.spawn_helper(configs.outskirts_prometheus_location)
|
||
|
delayed_message('the_living_fire_bar_actor_msg_2', 4, nta_utils.actor_icon(), nta_utils.actor_name(), 10)
|
||
|
delayed_message('the_living_fire_bar_sakharov_msg_1', 10, sakharov_icon, sakharov_name, 10)
|
||
|
tsk.stage = 22
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage >= 22 and stage <=25 then
|
||
|
adjust_prometheus_position(configs.outskirts_prometheus_location.vector, 1.5)
|
||
|
end
|
||
|
|
||
|
if stage == 22 then
|
||
|
if
|
||
|
nta_utils.actor_on_level(nta_utils.levels.outskirts)
|
||
|
and nta_utils.actor_in_range(configs.outskirts_prometheus_location.vector, configs.outskirts_prometheus_msg_trigger_distance)
|
||
|
and not db.actor:has_info('the_living_fire_endgame_start')
|
||
|
then
|
||
|
db.actor:give_info_portion('the_living_fire_endgame_start')
|
||
|
delayed_message('the_living_fire_outskirts_actor_msg_1', 0, nta_utils.actor_icon(), nta_utils.actor_name(), 10)
|
||
|
delayed_message('the_living_fire_outskirts_prometheus_msg_1', 4, prometheus_icon, prometheus_real_name, 10)
|
||
|
CreateTimeEvent(0,"the_living_fire_start_endgame", 7, function ()
|
||
|
state.mutant_ids = {}
|
||
|
earthquake_effect()
|
||
|
spawn_outskirts_anomalies()
|
||
|
level.set_weather_fx("fx_blowout_day")
|
||
|
spawn_mutants(configs.outskirts_mutant_locations, true)
|
||
|
CreateTimeEvent(0,"the_living_fire_start_endgame_2", 1, function ()
|
||
|
-- Give time for stuff to spawn
|
||
|
tsk.stage = 23
|
||
|
return true
|
||
|
end)
|
||
|
return true
|
||
|
end)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 23 then
|
||
|
if
|
||
|
not first_alive_mutant_id()
|
||
|
and not db.actor:has_info('the_living_fire_endgame_mid')
|
||
|
then
|
||
|
db.actor:give_info_portion('the_living_fire_endgame_mid')
|
||
|
delayed_message('the_living_fire_outskirts_prometheus_msg_2', 0, prometheus_icon, prometheus_real_name, 10)
|
||
|
CreateTimeEvent(0,"the_living_fire_endgame_greh", 2, function ()
|
||
|
state.greh_ids = {}
|
||
|
spawn_greh(configs.outskirts_endgame_greh_locations, [[scripts\outskirts_tlf_endgame_greh_beh.ltx]])
|
||
|
CreateTimeEvent(0,"the_living_fire_endgame_greh_2", 1, function ()
|
||
|
-- Give time for stuff to spawn
|
||
|
tsk.stage = 24
|
||
|
return true
|
||
|
end)
|
||
|
return true
|
||
|
end)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage == 24 then
|
||
|
if
|
||
|
not first_alive_greh_id()
|
||
|
and not db.actor:has_info('the_living_fire_endgame_finale')
|
||
|
then
|
||
|
db.actor:give_info_portion('the_living_fire_endgame_finale')
|
||
|
delayed_message('the_living_fire_outskirts_sakharov_msg_1', 0, sakharov_icon, sakharov_name, 6)
|
||
|
delayed_message('the_living_fire_outskirts_actor_msg_2', 2, nta_utils.actor_icon(), nta_utils.actor_name(), 6)
|
||
|
delayed_message('the_living_fire_outskirts_prometheus_msg_3', 8, prometheus_icon, prometheus_real_name, 4)
|
||
|
delayed_message('the_living_fire_outskirts_actor_msg_3', 8, nta_utils.actor_icon(), nta_utils.actor_name(), 6)
|
||
|
CreateTimeEvent(0,"the_living_fire_endgame_despawn_anomalies", 6, function ()
|
||
|
despawn_anomalies()
|
||
|
-- level.stop_weather_fx()
|
||
|
state.greh_ids = {}
|
||
|
tsk.stage = 25
|
||
|
return true
|
||
|
end)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if stage >=23 and stage <=24 then
|
||
|
-- Anomalies can be doubled without it
|
||
|
CreateTimeEvent(0,"the_living_fire_anomaly_spawn_wait", 1, function ()
|
||
|
if not outskirts_anomalies_spawned and not db.actor:has_info('the_living_fire_endgame_finale') then
|
||
|
state.anomaly_ids = {}
|
||
|
-- Anomalies despawn on reloading the game
|
||
|
spawn_outskirts_anomalies()
|
||
|
end
|
||
|
return true
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
if stage == 25 then
|
||
|
CreateTimeEvent(0,"the_living_fire_prometheus_kill_actor", 8, function ()
|
||
|
if not db.actor:has_info('the_living_fire_prometheus_killed_gg') then
|
||
|
prometheus_kill_actor()
|
||
|
end
|
||
|
return true
|
||
|
end)
|
||
|
if db.actor:has_info('the_living_fire_prometheus_killed_gg') then
|
||
|
delayed_message('the_living_fire_outskirts_actor_msg_4', 4, nta_utils.actor_icon(), nta_utils.actor_name(), 6)
|
||
|
delayed_message('the_living_fire_outskirts_sakharov_msg_2', 10, sakharov_icon, sakharov_name, 10)
|
||
|
tsk.stage = 26
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function spawn_garbage_prometheus()
|
||
|
state.prometheus_id = nta_utils.spawn_helper(configs.garbage_prometheus_location)
|
||
|
alife_object(state.prometheus_id):set_character_name(game.translate_string(prometheus_name))
|
||
|
end
|
||
|
|
||
|
function spawn_garbage_anomalies()
|
||
|
table.insert(state.anomaly_ids, nta_utils.spawn_helper(configs.garbage_zhar_location))
|
||
|
for _, spawn_config in pairs(configs.garbage_zharka_locations) do
|
||
|
table.insert(state.anomaly_ids, nta_utils.spawn_helper(spawn_config))
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Spawn a small cup in the middle of anomalies to keep them active
|
||
|
function spawn_garbage_trash()
|
||
|
nta_utils.spawn_helper(configs.garbage_trash_location)
|
||
|
end
|
||
|
|
||
|
function spawn_garbage_mutant()
|
||
|
state.garbage_mutant_id = nta_utils.spawn_helper(configs.garbage_mutant_location)
|
||
|
end
|
||
|
|
||
|
function garbage_delayed_kill_mutant()
|
||
|
CreateTimeEvent(0,"the_living_fire_garbage_kill_mutant", 2, function ()
|
||
|
local sin_snd = xr_sound.get_safe_sound_object([[characters_voice\human\greh_1\fight\enemy_hit\enemy_hit_6]])
|
||
|
sin_snd:play(level.object_by_id(state.prometheus_id), 0, sound_object.s2d)
|
||
|
|
||
|
CreateTimeEvent(0,"the_living_fire_garbage_kill_mutant_2", 1.5, function ()
|
||
|
local spawn_config = nta_utils.obj_position_to_spawn_config_partial(level.object_by_id(state.garbage_mutant_id))
|
||
|
spawn_config.section = 'zone_zhar'
|
||
|
spawn_config.is_anomaly = true
|
||
|
-- spawn_config.vector.y = spawn_config.vector.y - 1
|
||
|
table.insert(state.anomaly_ids, nta_utils.spawn_helper(spawn_config))
|
||
|
|
||
|
local mutant_snd = xr_sound.get_safe_sound_object([[monsters\boar\boar_anomaly_0]])
|
||
|
mutant_snd:play(level.object_by_id(state.garbage_mutant_id), 0, sound_object.s2d)
|
||
|
|
||
|
local zhar_sound = xr_sound.get_safe_sound_object([[new_tasks_addon\zhar_blow]])
|
||
|
zhar_sound:play(level.object_by_id(state.garbage_mutant_id), 0, sound_object.s2d)
|
||
|
|
||
|
safe_release_manager.release({id = state.garbage_mutant_id})
|
||
|
db.actor:give_info_portion('the_living_fire_garbage_mutant_killed')
|
||
|
return true
|
||
|
end)
|
||
|
return true
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
function despawn_anomalies()
|
||
|
for _, anomaly_id in pairs(state.anomaly_ids) do
|
||
|
safe_release_manager.release({id = anomaly_id})
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function snitch_reward_1()
|
||
|
if not db.actor:has_info('bar_informator_mlr_the_living_fire_reward_1_given') then
|
||
|
db.actor:give_info_portion('bar_informator_mlr_the_living_fire_reward_1_given')
|
||
|
dialogs.relocate_money( db.actor, 5000, "in" )
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function snitch_reward_2()
|
||
|
if not db.actor:has_info('bar_informator_mlr_the_living_fire_reward_2_given') then
|
||
|
db.actor:give_info_portion('bar_informator_mlr_the_living_fire_reward_2_given')
|
||
|
dialogs.relocate_money( db.actor, 10000, "in" )
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function spawn_explosions(cfg)
|
||
|
for _, spawn_config in pairs(cfg) do
|
||
|
nta_utils.spawn_helper(spawn_config)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function spawn_mutants(cfg, endgame)
|
||
|
for _, spawn_config in pairs(cfg) do
|
||
|
local id = nta_utils.spawn_helper(spawn_config)
|
||
|
if endgame then
|
||
|
logic_enforcer.assign(id, [[scripts\outskirts_tlf_endgame_mutant_beh.ltx]],'logic', 'beh@base')
|
||
|
end
|
||
|
table.insert(state.mutant_ids, id)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function first_alive_mutant_id()
|
||
|
for _, id in pairs(state.mutant_ids) do
|
||
|
local obj = level.object_by_id(id)
|
||
|
if obj and obj:alive() then
|
||
|
return id
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function first_alive_greh_id()
|
||
|
for _, id in pairs(state.greh_ids) do
|
||
|
local obj = level.object_by_id(id)
|
||
|
if obj and obj:alive() then
|
||
|
return id
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function spawn_corpses(cfg)
|
||
|
for _, spawn_config in pairs(cfg) do
|
||
|
table.insert(state.corpse_ids, nta_utils.spawn_helper(spawn_config))
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function move_corpses()
|
||
|
for _, corpse_id in ipairs(state.corpse_ids) do
|
||
|
local obj = level.object_by_id(corpse_id)
|
||
|
if obj and not state.corpse_moved[corpse_id] then
|
||
|
-- Trigger some force on the object so it turns into ragdoll
|
||
|
obj:get_physics_shell():apply_force(0, 0, 1)
|
||
|
state.corpse_moved[corpse_id] = true
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function despawn_corpses()
|
||
|
for _, id in ipairs(state.corpse_ids) do
|
||
|
safe_release_manager.release({id = id})
|
||
|
end
|
||
|
state.corpse_ids = {}
|
||
|
state.corpse_moved = {}
|
||
|
end
|
||
|
|
||
|
function send_dark_valley_actor_msg()
|
||
|
if
|
||
|
not db.actor:has_info('the_living_fire_dark_valley_actor_msg_sent')
|
||
|
and nta_utils.actor_on_level(nta_utils.levels.dark_valley)
|
||
|
and nta_utils.actor_in_range(configs.dark_valley_actor_msg_trigger_location.vector, configs.dark_valley_actor_msg_trigger_distance)
|
||
|
then
|
||
|
db.actor:give_info_portion("the_living_fire_dark_valley_actor_msg_sent")
|
||
|
delayed_message('the_living_fire_dark_valley_actor_msg_1', 2, nta_utils.actor_icon(), nta_utils.actor_name(), 10)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function send_x18_prometheus_msg()
|
||
|
if
|
||
|
not db.actor:has_info('the_living_fire_x18_prometheus_msg_sent')
|
||
|
and nta_utils.actor_on_level(nta_utils.levels.x18)
|
||
|
and nta_utils.actor_in_range(configs.x18_prometheus_location.vector, configs.x18_prometheus_msg_trigger_distance)
|
||
|
then
|
||
|
db.actor:give_info_portion("the_living_fire_x18_prometheus_msg_sent")
|
||
|
delayed_message('the_living_fire_x18_prometheus_msg_1', 0, prometheus_icon, prometheus_name, 10)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function send_x16_prometheus_msg()
|
||
|
if
|
||
|
not db.actor:has_info('the_living_fire_x16_prometheus_msg_sent')
|
||
|
and nta_utils.actor_on_level(nta_utils.levels.x16)
|
||
|
and nta_utils.actor_in_range(configs.x16_prometheus_location.vector, configs.x16_prometheus_msg_trigger_distance)
|
||
|
then
|
||
|
db.actor:give_info_portion("the_living_fire_x16_prometheus_msg_sent")
|
||
|
delayed_message('the_living_fire_x16_prometheus_msg_1', 0, prometheus_icon, prometheus_real_name, 10)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function adjust_prometheus_position(vec, distance)
|
||
|
-- Prometheus is moved to the ground on reloading the game few times - correction needed
|
||
|
local obj = level.object_by_id(state.prometheus_id)
|
||
|
if obj then
|
||
|
if obj:position():distance_to(vec) > distance then
|
||
|
obj:set_movement_type(move.walk)
|
||
|
obj:set_npc_position(vec)
|
||
|
-- X-ray in its prime - sometimes when Prometheus spawns, the gravity is affecting him (problematic with Outskirts part)
|
||
|
-- Switching movement to walk and then back to stand fixes the issue and puts him back into "wait" state
|
||
|
CreateTimeEvent(0,"the_living_fire_prometheus_stop_moving", 0.2, function ()
|
||
|
obj:set_movement_type(move.stand)
|
||
|
return true
|
||
|
end)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function despawn_prometheus_mild()
|
||
|
local zhar_particle = particles_object([[anomaly2\heat_03]])
|
||
|
local pos = nta_utils.obj_position_to_spawn_config_partial(level.object_by_id(state.prometheus_id)).vector
|
||
|
-- pos.y = pos.y - 1.5
|
||
|
zhar_particle:play_at_pos(pos)
|
||
|
local zhar_sound = xr_sound.get_safe_sound_object([[new_tasks_addon\zhar_blow]])
|
||
|
zhar_sound:play(level.object_by_id(state.prometheus_id), 0, sound_object.s2d)
|
||
|
CreateTimeEvent(0,"the_living_fire_prometheus_zhar_sound_stop", 2, function ()
|
||
|
zhar_sound:stop()
|
||
|
return true
|
||
|
end)
|
||
|
safe_release_manager.release({id = state.prometheus_id})
|
||
|
end
|
||
|
|
||
|
function spawn_x18_military()
|
||
|
for i, spawn_config in ipairs(configs.x18_military_locations) do
|
||
|
local id = nta_utils.spawn_helper(spawn_config)
|
||
|
logic_enforcer.assign(id, [[scripts\x18_tlf_military_beh.ltx]],'logic', 'beh@pos_' .. i)
|
||
|
table.insert(state.x18_military_ids, id)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function set_x18_military_relation()
|
||
|
for _, id in ipairs(state.x18_military_ids) do
|
||
|
local obj = level.object_by_id(id)
|
||
|
if obj and not state.x18_military_relation_set[id] then
|
||
|
state.x18_military_relation_set[id] = true
|
||
|
obj:set_relation(-5000, db.actor)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function spawn_greh(cfg, script_file)
|
||
|
for i, spawn_config in ipairs(cfg) do
|
||
|
local id = nta_utils.spawn_helper(spawn_config)
|
||
|
logic_enforcer.assign(id, script_file,'logic', 'beh@pos_' .. i)
|
||
|
table.insert(state.greh_ids, id)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function clear_x16_mutants()
|
||
|
if nta_utils.actor_on_level(nta_utils.levels.x16) then
|
||
|
level.iterate_nearest(configs.x16_middle.vector, configs.x16_mutant_scanning_range, function (obj)
|
||
|
if IsMonster(obj) and obj:alive() then
|
||
|
safe_release_manager.release({id = obj:id()})
|
||
|
end
|
||
|
end)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function earthquake_effect()
|
||
|
local boom = xr_sound.get_safe_sound_object([[new_tasks_addon\blowout_boom_02_old]])
|
||
|
boom:play(db.actor, 0, sound_object.s2d)
|
||
|
local earthquake_snd = xr_sound.get_safe_sound_object("new_tasks_addon\\earthquake_old")
|
||
|
earthquake_snd:play(db.actor, 0, sound_object.s2d)
|
||
|
nta_utils.earthquake_screen_effect_strong(6)
|
||
|
end
|
||
|
|
||
|
function spawn_isg()
|
||
|
for i, spawn_config in ipairs(configs.red_forest_isg_locations) do
|
||
|
local id = nta_utils.spawn_helper(spawn_config)
|
||
|
logic_enforcer.assign(id, [[scripts\red_forest_tlf_isg_beh.ltx]],'logic', 'beh@pos_' .. i)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function spawn_outskirts_anomalies()
|
||
|
outskirts_anomalies_spawned = true
|
||
|
for i, coords in ipairs(configs.outskirts_anomaly_xz_data) do
|
||
|
-- Spawning 100 anomalies kills FPS - try with lowered number
|
||
|
if math.fmod(i,2) == 0 then
|
||
|
local anomaly_location = nta_utils.shallow_copy(configs.outskirts_prometheus_location)
|
||
|
anomaly_location.vector = vector():set(coords[1], 0, coords[2])
|
||
|
anomaly_location.section = 'zone_zhar_tlf'
|
||
|
anomaly_location.is_anomaly = true
|
||
|
table.insert(state.anomaly_ids, nta_utils.spawn_helper(anomaly_location))
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
xr_effects.tlf_on_outskirts_mutant_death = function()
|
||
|
if #state.mutant_ids < 12 then
|
||
|
local id = nta_utils.spawn_helper(configs.outskirts_mutant_locations[math.random(1,4)])
|
||
|
logic_enforcer.assign(id, [[scripts\outskirts_tlf_endgame_mutant_beh.ltx]],'logic', 'beh@base')
|
||
|
table.insert(state.mutant_ids, id)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function prometheus_kill_actor()
|
||
|
local sin_snd = xr_sound.get_safe_sound_object([[characters_voice\human\greh_1\fight\attack\attack_4]])
|
||
|
sin_snd:play(npc, 0, sound_object.s2d)
|
||
|
|
||
|
CreateTimeEvent(0,"the_living_fire_prometheus_revenge", 2, function ()
|
||
|
local spawn_config = nta_utils.obj_position_to_spawn_config_partial(db.actor)
|
||
|
spawn_config.section = 'zone_zhar'
|
||
|
spawn_config.is_anomaly = true
|
||
|
spawn_config.vector.y = spawn_config.vector.y - 1
|
||
|
|
||
|
nta_utils.spawn_helper(spawn_config)
|
||
|
|
||
|
local zhar_sound = xr_sound.get_safe_sound_object([[new_tasks_addon\zhar_blow]])
|
||
|
zhar_sound:play(db.actor, 0, sound_object.s2d)
|
||
|
|
||
|
CreateTimeEvent(0,"the_living_fire_prometheus_revenge_player_death", 0.2, function ()
|
||
|
db.actor:set_health_ex(0)
|
||
|
return true
|
||
|
end)
|
||
|
return true
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
function tlf_complete()
|
||
|
task_manager.get_task_manager( ):set_task_completed('bar_informator_mlr_task_the_living_fire')
|
||
|
-- TODO: Remove when Grok exposes a table in his script
|
||
|
if grok_artefacts_random_condition then
|
||
|
CreateTimeEvent(0,"the_living_fire_gamma_temp_fix", 1, function ()
|
||
|
db.actor:iterate_inventory(function (_, item)
|
||
|
if item:section() == 'af_tlf_prometheus' then
|
||
|
item:set_condition(0.98)
|
||
|
end
|
||
|
end, nil)
|
||
|
return true
|
||
|
end)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local delayed_message_index = 0
|
||
|
function delayed_message(msg, delay, icon, name, keep_time)
|
||
|
local k_time = keep_time or 5
|
||
|
CreateTimeEvent(0,"the_living_fire_delayed_message_" .. delayed_message_index, delay, function ()
|
||
|
dynamic_news_helper.send_tip(msg, name, nil, k_time, icon, nil, 'npc')
|
||
|
return true
|
||
|
end)
|
||
|
delayed_message_index = delayed_message_index + 1
|
||
|
end
|
||
|
|
||
|
task_functor.the_living_fire_task_target_functor = function(task_id,field,p,tsk)
|
||
|
if not (db.actor and tsk) then return nil end
|
||
|
|
||
|
if tsk.stage == 0 then
|
||
|
return get_story_object_id('baraholka_trader')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 5 then
|
||
|
return get_story_object_id('baraholka_trader')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 6 then
|
||
|
return get_story_object_id('bar_informator_mlr')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 7 then
|
||
|
return get_story_object_id('yan_stalker_sakharov')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 8 then
|
||
|
return get_story_object_id('mar_smart_terrain_11_3_anomaly_spot')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 9 then
|
||
|
return first_alive_mutant_id()
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 10 then
|
||
|
return get_story_object_id('yan_stalker_sakharov')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 11 then
|
||
|
return get_story_object_id('bar_informator_mlr')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 12 then
|
||
|
return get_story_object_id('the_living_fire_prometheus')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 13 then
|
||
|
return get_story_object_id('bar_informator_mlr')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 14 then
|
||
|
return get_story_object_id('esc_m_trader')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 15 then
|
||
|
return get_story_object_id('yan_stalker_sakharov')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 16 then
|
||
|
return get_story_object_id('the_living_fire_prometheus')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 17 then
|
||
|
return get_story_object_id('yan_stalker_sakharov')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 18 then
|
||
|
return get_story_object_id('red_smart_terrain_6_3_anomaly_spot')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 19 then
|
||
|
return first_alive_mutant_id()
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 21 then
|
||
|
return get_story_object_id('bar_informator_mlr')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 22 then
|
||
|
return get_story_object_id('the_living_fire_prometheus')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 23 then
|
||
|
return first_alive_mutant_id()
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 24 then
|
||
|
return first_alive_greh_id()
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 25 then
|
||
|
return get_story_object_id('the_living_fire_prometheus')
|
||
|
end
|
||
|
|
||
|
if tsk.stage == 26 then
|
||
|
return get_story_object_id('yan_stalker_sakharov')
|
||
|
end
|
||
|
return
|
||
|
end
|
||
|
|
||
|
local hit_already = false
|
||
|
function npc_on_before_hit(npc,shit,bone_id)
|
||
|
-- TODO: Add Prometheus to invulnerable npcs array in GBO once it's available
|
||
|
if npc:id() == get_story_object_id('the_living_fire_prometheus') then
|
||
|
shit.power = 0
|
||
|
npc:set_health_ex(1)
|
||
|
if shit.draftsman and shit.draftsman:id() == AC_ID and not hit_already then
|
||
|
if not db.actor:has_info('the_living_fire_endgame_finale') then
|
||
|
hit_already = true
|
||
|
prometheus_kill_actor()
|
||
|
else
|
||
|
local wpn = level.object_by_id(shit.weapon_id)
|
||
|
local sec = wpn:section()
|
||
|
if bone_id == 15 and (sec == 'wpn_gauss' or sec == 'wpn_gauss_quest') then
|
||
|
safe_release_manager.release({id = state.prometheus_id})
|
||
|
local explosion_spawn_config = nta_utils.shallow_copy(configs.outskirts_prometheus_location)
|
||
|
explosion_spawn_config.vector.y = explosion_spawn_config.vector.y - 3
|
||
|
explosion_spawn_config.vector.z = explosion_spawn_config.vector.z + 1
|
||
|
explosion_spawn_config.vector.x = explosion_spawn_config.vector.x + 1
|
||
|
|
||
|
explosion_spawn_config.section = 'immediate_fiery_explosion'
|
||
|
for i=1,5 do nta_utils.spawn_helper(explosion_spawn_config) end
|
||
|
db.actor:give_info_portion("the_living_fire_prometheus_killed_gg")
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function npc_on_death_callback(npc)
|
||
|
if npc and nta_utils.has_value(state.greh_ids, npc:id()) then
|
||
|
local explosion_spawn_config = nta_utils.obj_position_to_spawn_config_partial(npc)
|
||
|
explosion_spawn_config.section = 'immediate_fiery_explosion'
|
||
|
nta_utils.spawn_helper(explosion_spawn_config)
|
||
|
nta_utils.hide_through_teleport(npc:id())
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function on_game_start()
|
||
|
RegisterScriptCallback("save_state",save_state)
|
||
|
RegisterScriptCallback("load_state",load_state)
|
||
|
RegisterScriptCallback("npc_on_before_hit",npc_on_before_hit)
|
||
|
RegisterScriptCallback("npc_on_death_callback",npc_on_death_callback)
|
||
|
end
|