aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobTheBob <32057864+BobTheBob9@users.noreply.github.com>2021-08-31 23:14:58 +0100
committerBobTheBob <32057864+BobTheBob9@users.noreply.github.com>2021-08-31 23:14:58 +0100
commit9a96d0bff56f1969c68bb52a2f33296095bdc67d (patch)
tree4175928e488632705692e3cccafa1a38dd854615
parent27bd240871b7c0f2f49fef137718b2e3c208e3b4 (diff)
downloadNorthstarMods-9a96d0bff56f1969c68bb52a2f33296095bdc67d.tar.gz
NorthstarMods-9a96d0bff56f1969c68bb52a2f33296095bdc67d.zip
move to new mod format
-rw-r--r--Northstar.Client/mod.json57
-rw-r--r--Northstar.Client/mod/resource/northstar_client_localisation_english.txtbin0 -> 5866 bytes
-rw-r--r--Northstar.Client/mod/resource/ui/menus/connect_password.menu (renamed from Northstar.Client/resource/ui/menus/modlist.menu)71
-rw-r--r--Northstar.Client/mod/resource/ui/menus/custom_match_settings.menu2203
-rw-r--r--Northstar.Client/mod/resource/ui/menus/custom_match_settings_categories.menu752
-rw-r--r--Northstar.Client/mod/resource/ui/menus/modlist.menu255
-rw-r--r--Northstar.Client/mod/resource/ui/menus/server_browser.menu338
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut (renamed from Northstar.Client/scripts/vscripts/ui/menu_lobby.nut)0
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_map_select.nut (renamed from Northstar.Client/scripts/vscripts/ui/menu_map_select.nut)0
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_match_settings.nut (renamed from Northstar.Client/scripts/vscripts/ui/menu_match_settings.nut)0
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_mode_select.nut (renamed from bobthebob.testing/scripts/vscripts/ui/menu_mode_select.nut)9
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_ns_connect_password.nut30
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_ns_custom_match_settings.nut140
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_ns_custom_match_settings_categories.nut68
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut108
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut198
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_private_match.nut (renamed from Northstar.Client/scripts/vscripts/ui/menu_private_match.nut)29
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/panel_mainmenu.nut (renamed from Northstar.Client/scripts/vscripts/ui/panel_mainmenu.nut)20
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/ui_utility.gnut (renamed from Northstar.Client/scripts/vscripts/ui/ui_utility.gnut)0
-rw-r--r--Northstar.Client/scripts/vscripts/ui/_menus.nut2010
-rw-r--r--Northstar.Client/scripts/vscripts/ui/menu_main.nut608
-rw-r--r--Northstar.Client/scripts/vscripts/ui/menu_mode_select.nut135
-rw-r--r--Northstar.Coop/mod.json24
-rw-r--r--Northstar.Coop/scripts/vscripts/client/cl_respawnselect_sp.gnut110
-rw-r--r--Northstar.Coop/scripts/vscripts/sp/_base_gametype_sp.gnut657
-rw-r--r--Northstar.Coop/scripts/vscripts/sp/_coop_sp_utils.gnut177
-rw-r--r--Northstar.Coop/scripts/vscripts/sp/_gamestate_sp.gnut793
-rw-r--r--Northstar.Coop/scripts/vscripts/sp/_gauntlet.gnut1054
-rw-r--r--Northstar.Coop/scripts/vscripts/sp/_savegame.gnut860
-rw-r--r--Northstar.Coop/scripts/vscripts/sp/hubs/sp_timeshift_spoke02.nut3891
-rw-r--r--Northstar.Coop/scripts/vscripts/sp/hubs/sp_timeshift_utility.nut7253
-rw-r--r--Northstar.Coop/scripts/vscripts/sp/sh_coop_sp_utils.gnut34
-rw-r--r--Northstar.Coop/scripts/vscripts/sp/sh_sp_objective.gnut537
-rw-r--r--Northstar.Coop/scripts/vscripts/sp/sp_training.nut7554
-rw-r--r--Northstar.Custom/keyvalues/playlists_v2.txt572
-rw-r--r--Northstar.Custom/keyvalues/scripts/weapons/mp_titanweapon_particle_accelerator.txt4
-rw-r--r--Northstar.Custom/mod.json211
-rw-r--r--Northstar.Custom/mod/resource/northstar_custom_english.txt69
-rw-r--r--Northstar.Custom/mod/scripts/levels/mp_box.rson (renamed from Northstar.Custom/scripts/levels/mp_box.rson)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/_custom_air_accel.gnut23
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/_droppod_spawn.gnut79
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/_northstar_devcommands.gnut (renamed from Northstar.Custom/scripts/vscripts/_northstar_devcommands.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/_promode.gnut25
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/burnmeter/sh_boost_store.gnut762
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/burnmeter/sh_burnmeter.gnut488
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/client/cl_gamestate.gnut (renamed from Northstar.Custom/scripts/vscripts/client/cl_gamestate.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_arena.gnut185
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_fastball.gnut)2
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball_intro.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_fastball_intro.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_gg.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_gg.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_inf.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_inf.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_kr.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_kr.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_sbox.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_sbox.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_tt.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_tt.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/_riff_instagib.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/_riff_instagib.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_arena.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_arena.gnut)5
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_fastball.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_fastball.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_gg.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_gg.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_inf.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_inf.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_kr.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_kr.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_tt.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_tt.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_arena_loadouts.gnut98
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_arena.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_arena.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_bomb.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_bomb.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_ctf_comp.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_ctf_comp.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_fastball.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_fastball.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_fw_custom.nut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_fw_custom.nut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_gg.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_gg.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_inf.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_inf.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_kr.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_kr.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_sbox.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_sbox.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_tt.gnut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_tt.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_riff_floor_is_lava.nut (renamed from Northstar.Custom/scripts/vscripts/gamemodes/sh_riff_floor_is_lava.nut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/lobby/sh_private_lobby_custom_modes_init.gnut (renamed from Northstar.Custom/scripts/vscripts/lobby/sh_private_lobby_custom_modes_init.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/mp/levels/mp_box.nut (renamed from Northstar.Custom/scripts/vscripts/mp/levels/mp_box.nut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/northstar_custom_autoprecache.gnut (renamed from Northstar.Custom/scripts/vscripts/northstar_custom_autoprecache.gnut)2
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/titan/sh_first_person_embark.gnut (renamed from Northstar.Custom/scripts/vscripts/titan/sh_first_person_embark.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/titan/sh_titan_embark.gnut (renamed from Northstar.Custom/scripts/vscripts/titan/sh_titan_embark.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/weapons/mp_weapon_peacekraber.nut (renamed from Northstar.Custom/scripts/vscripts/weapons/mp_weapon_peacekraber.nut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/weapons/mp_weapon_toolgun.nut (renamed from Northstar.Custom/scripts/vscripts/weapons/mp_weapon_toolgun.nut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/weapons/toolgun/sh_toolgun_tool_explode.nut (renamed from Northstar.Custom/scripts/vscripts/weapons/toolgun/sh_toolgun_tool_explode.nut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/weapons/toolgun/sh_toolgun_tool_throw.nut (renamed from Northstar.Custom/scripts/vscripts/weapons/toolgun/sh_toolgun_tool_throw.nut)0
-rw-r--r--Northstar.Custom/mod/scripts/vscripts/weapons/toolgun/sh_toolgun_tools.gnut (renamed from Northstar.Custom/scripts/vscripts/weapons/toolgun/sh_toolgun_tools.gnut)0
-rw-r--r--Northstar.Custom/mod/scripts/weapons/melee_pilot_emptyhanded.txt (renamed from Northstar.Custom/scripts/weapons/melee_pilot_emptyhanded.txt)0
-rw-r--r--Northstar.Custom/mod/scripts/weapons/melee_pilot_kunai.txt (renamed from Northstar.Custom/scripts/weapons/melee_pilot_kunai.txt)0
-rw-r--r--Northstar.Custom/mod/scripts/weapons/mp_weapon_peacekraber.txt (renamed from Northstar.Custom/scripts/weapons/mp_weapon_peacekraber.txt)0
-rw-r--r--Northstar.Custom/mod/scripts/weapons/mp_weapon_sniper.txt (renamed from Northstar.Custom/scripts/weapons/mp_weapon_sniper.txt)0
-rw-r--r--Northstar.Custom/mod/scripts/weapons/mp_weapon_toolgun.txt (renamed from Northstar.Custom/scripts/weapons/mp_weapon_toolgun.txt)0
-rw-r--r--Northstar.Custom/playlists_v2.txt5859
-rw-r--r--Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_arena.gnut99
-rw-r--r--Northstar.Custom/vpk/client_mp_northstar_common.bsp.pak000_000.vpkbin0 -> 88553677 bytes
-rw-r--r--Northstar.Custom/vpk/englishclient_mp_northstar_common.bsp.pak000_dir.vpkbin0 -> 6272 bytes
-rw-r--r--Northstar.CustomServers/mod.json36
-rw-r--r--Northstar.CustomServers/mod/cfg/autoexec_ns_server.cfg8
-rw-r--r--Northstar.CustomServers/mod/cfg/server/persistent_player_data_version_231.pdef (renamed from Northstar.CustomServers/cfg/server/persistent_player_data_version_231.pdef)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_drone.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_drone.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_dropship.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_dropship.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_flyer.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_flyer.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_frag_drone.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_frag_drone.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_goliath.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_goliath.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_gunship.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_gunship.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_marvin.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_marvin.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_mp_auto_titan.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_mp_auto_titan.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_mp_auto_titan_enhanced.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_mp_auto_titan_enhanced.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_mp_auto_titan_enhanced_guard.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_mp_auto_titan_enhanced_guard.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_mp_auto_titan_guard.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_mp_auto_titan_guard.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_pilot_elite.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_pilot_elite.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_pilot_elite_assassin.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_pilot_elite_assassin.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_pilot_elite_assassin_cqb.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_pilot_elite_assassin_cqb.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_pilot_elite_assassin_sniper.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_pilot_elite_assassin_sniper.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_prowler.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_prowler.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_prowler_cqb.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_prowler_cqb.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_soldier.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_soldier.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_sp_auto_titan.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_sp_auto_titan.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_sp_npc_titan_proto_stasisgun.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_sp_npc_titan_proto_stasisgun.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_sp_soldier.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_sp_soldier.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_spectre.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_spectre.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_stalker.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_stalker.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_stalker_crawling.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_stalker_crawling.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_super_spectre.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_super_spectre.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_titan.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_buddy.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_titan_buddy.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_long_range.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_titan_long_range.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_melee.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_titan_melee.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_melee_core.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_titan_melee_core.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_ogre_meteor.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_titan_ogre_meteor.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_ogre_minigun.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_titan_ogre_minigun.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_ogre_minigun_nuke.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_titan_ogre_minigun_nuke.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_rocketeer.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_titan_rocketeer.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_shotgun.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_titan_shotgun.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_sniper.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behavior_titan_sniper.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/behaviors.txt (renamed from Northstar.CustomServers/scripts/aibehavior/behaviors.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aibehavior/common_schedules.txt (renamed from Northstar.CustomServers/scripts/aibehavior/common_schedules.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/base_vehicle.txt (renamed from Northstar.CustomServers/scripts/aisettings/base_vehicle.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/classes.txt (renamed from Northstar.CustomServers/scripts/aisettings/classes.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_bullseye.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_bullseye.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_drone.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_drone.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_drone_beam.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_drone_beam.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_drone_cloaked.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_drone_cloaked.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_drone_plasma.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_drone_plasma.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_drone_plasma_fast.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_drone_plasma_fast.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_drone_plasma_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_drone_plasma_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_drone_rocket.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_drone_rocket.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_drone_rocket_fast.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_drone_rocket_fast.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_drone_shield.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_drone_shield.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_drone_worker.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_drone_worker.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_drone_worker_fast.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_drone_worker_fast.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_dropship.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_dropship.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_dropship_dogfighter.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_dropship_dogfighter.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_dropship_hero.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_dropship_hero.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_frag_drone.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_frag_drone.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_frag_drone_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_frag_drone_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_frag_drone_throwable.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_frag_drone_throwable.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_gunship.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_gunship.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_gunship_scripted.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_gunship_scripted.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_marvin.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_marvin.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_pilot_elite.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite_assassin.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_pilot_elite_assassin.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite_assassin_cqb.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_pilot_elite_assassin_cqb.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite_assassin_sniper.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_pilot_elite_assassin_sniper.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite_s2s.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_pilot_elite_s2s.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_prowler.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_prowler.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_bish.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier_bish.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_blisk.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier_blisk.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_drone_summoner.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier_drone_summoner.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_hero_bear.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier_hero_bear.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_hero_sarah.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier_hero_sarah.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_pve_eliteguard.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier_pve_eliteguard.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_pve_sandbox.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier_pve_sandbox.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_pve_specialist.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier_pve_specialist.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_shield_captain.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier_shield_captain.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_sidearm.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier_sidearm.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_specialist.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier_specialist.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_specialist_militia.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier_specialist_militia.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_spyglass.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier_spyglass.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_training_sentry.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_soldier_training_sentry.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_spectre.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_spectre.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_spectre_mortar.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_spectre_mortar.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_stalker.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_stalker.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_crawling.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_stalker_crawling.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_crawling_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_stalker_crawling_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_crawling_mossy.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_stalker_crawling_mossy.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_stalker_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_zombie.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_stalker_zombie.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_zombie_mossy.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_stalker_zombie_mossy.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_super_spectre.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre_aitdm.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_super_spectre_aitdm.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre_burnmeter.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_super_spectre_burnmeter.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre_calmer.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_super_spectre_calmer.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_super_spectre_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_arc.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_arc.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_atlas.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_ion_prime_bounty.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_ion_prime_bounty.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_stickybomb.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_stickybomb.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_stickybomb_boss_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_stickybomb_boss_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_stickybomb_bounty.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_stickybomb_bounty.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker_boss_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker_boss_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker_bounty.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker_bounty.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker_fd_sniper.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker_fd_sniper.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker_mortar.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker_mortar.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_vanguard.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_vanguard.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_vanguard_boss_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_vanguard_boss_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_vanguard_bounty.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_vanguard_bounty.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_ion_prime.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_ion_prime.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_rocketeer.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_rocketeer.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_stickybomb.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_stickybomb.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_tone_prime.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_tone_prime.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_tracker.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_tracker.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_vanguard.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_vanguard.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_fighter.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_fighter.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_legion_prime.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_legion_prime.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_meteor.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_meteor.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_minigun.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_minigun.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_scorch_prime.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_scorch_prime.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_arc.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_arc.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_leadwall.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_leadwall.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_northstar_prime.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_northstar_prime.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_ronin_prime.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_ronin_prime.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_sniper.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_sniper.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_buddy.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_buddy.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_buddy_s2s.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_buddy_s2s.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_buddy_skyway.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_buddy_skyway.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_mortar.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_mortar.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_nuke.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_nuke.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_ogre.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_fighter.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_fighter.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_fighter_berserker_core.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_fighter_berserker_core.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_legion_prime_bounty.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_legion_prime_bounty.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_meteor.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_meteor.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_meteor_boss_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_meteor_boss_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_meteor_bounty.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_meteor_bounty.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_meteor_nuke.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_meteor_nuke.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_minigun.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_minigun.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_minigun_boss_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_minigun_boss_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_minigun_bounty.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_minigun_bounty.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_minigun_nuke.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_minigun_nuke.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_scorch_prime_bounty.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_scorch_prime_bounty.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_proto_stasisgun.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_proto_stasisgun.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_sarah.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_sarah.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_sniper.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_sniper.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_stryder.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_arc.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_arc.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall_arc.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall_arc.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall_boss_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall_boss_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall_bounty.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall_bounty.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall_shift_core.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall_shift_core.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_northstar_prime_bounty.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_northstar_prime_bounty.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_rocketeer.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_rocketeer.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_rocketeer_dash_core.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_rocketeer_dash_core.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_sniper.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_sniper.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_sniper_boss_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_sniper_boss_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_sniper_bounty.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_sniper_bounty.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_sniper_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_sniper_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_titan_vanguard.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_titan_vanguard.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_mega.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_attrition.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_mega_attrition.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_fortwar.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_mega_fortwar.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_frontierdefense.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_mega_frontierdefense.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_nowindup.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_mega_nowindup.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_old.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_mega_old.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_windup.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_mega_windup.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_sentry.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_burn_card_ap.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_burn_card_ap.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_burn_card_ap_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_burn_card_ap_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_burn_card_at.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_burn_card_at.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_burn_card_at_fd.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_burn_card_at_fd.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_plasma.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_plasma.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_plasma_skyway.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_plasma_skyway.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_tactical_ability.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_tactical_ability.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_tday.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_tday.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_windup.txt (renamed from Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_windup.txt)0
-rw-r--r--Northstar.CustomServers/mod/scripts/aisettings/synced_melee_data.rson (renamed from Northstar.CustomServers/scripts/aisettings/synced_melee_data.rson)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_anim.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_anim.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_auto_precache.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_auto_precache.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_bubble_shield.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_bubble_shield.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_codecallbacks_common.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_codecallbacks_common.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_codecallbacks_player_input.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_codecallbacks_player_input.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_control_panel.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_control_panel.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_dogfighter.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_dogfighter.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_entitystructs.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_entitystructs.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_global_entities.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_global_entities.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_harvester.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_harvester.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_health_regen.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_health_regen.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_init.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_init.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_loadouts_mp.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_mapspawn.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_mapspawn.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_menu_callbacks.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_menu_callbacks.gnut)5
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_misc.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_misc.gnut)13
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_networkvars.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_networkvars.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_objective.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_objective.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_on_spawned.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_on_spawned.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_pain_death_sounds.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_pain_death_sounds.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_passives.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_passives.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_ping.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_ping.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_powerup.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_powerup.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_remote_functions_mp.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_remote_functions_mp.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_script_movers.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_script_movers.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_script_movers_light.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_script_movers_light.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_script_triggers.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_script_triggers.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_side_notifications.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_side_notifications.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_store.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_store.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_trigger_functions.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_trigger_functions.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_utility.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_utility.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_utility_shared.nut (renamed from Northstar.CustomServers/scripts/vscripts/_utility_shared.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_viewcone.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_viewcone.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_vscript.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_vscript.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/_xp.gnut (renamed from Northstar.CustomServers/scripts/vscripts/_xp.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_boss_titan.gnut794
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_chatter.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_chatter.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_cloak_drone.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_cloak_drone.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_drone.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_drone.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_emp_titans.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_emp_titans.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_gunship.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_gunship.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_lethality.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_lethality.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_marvin_faces.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_marvin_faces.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_marvin_jobs.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_marvin_jobs.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_marvins.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_marvins.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_mortar_spectres.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_mortar_spectres.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_mortar_titans.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_mortar_titans.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_nuke_titans.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_nuke_titans.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_personal_shield.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_personal_shield.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_pilots.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_pilots.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_sniper_titans.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_sniper_titans.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_soldiers.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_soldiers.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_soldiers_mp.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_soldiers_mp.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_soldiers_sp.gnut17
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_spawn.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_spawn.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_spawn_content.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_spawn_content.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_spectre.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_spectre.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_stalker.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_stalker.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_stationary_firing_positions.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_stationary_firing_positions.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_suicide_spectres.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_suicide_spectres.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_turret.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret_sentry.gnut72
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_utility.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_ai_utility.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_droppod.gnut187
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_droppod_fireteam.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_droppod_fireteam.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_grunt_chatter.gnut1786
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_squad_spawn.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_squad_spawn.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/ai/_titan_npc_behavior.gnut (renamed from Northstar.CustomServers/scripts/vscripts/ai/_titan_npc_behavior.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut (renamed from Northstar.CustomServers/scripts/vscripts/burnmeter/_burnmeter.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/class/CHardPointEntity.nut (renamed from Northstar.CustomServers/scripts/vscripts/class/CHardPointEntity.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/class/cai_basenpc.nut (renamed from Northstar.CustomServers/scripts/vscripts/class/cai_basenpc.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/class/cbasecombatcharacter.nut (renamed from Northstar.CustomServers/scripts/vscripts/class/cbasecombatcharacter.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/class/cbaseentity.nut (renamed from Northstar.CustomServers/scripts/vscripts/class/cbaseentity.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/class/cplayer.nut (renamed from Northstar.CustomServers/scripts/vscripts/class/cplayer.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/class/ctitansoul.nut (renamed from Northstar.CustomServers/scripts/vscripts/class/ctitansoul.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/conversation/_battle_chatter.gnut (renamed from Northstar.CustomServers/scripts/vscripts/conversation/_battle_chatter.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/conversation/_conversation_schedule.gnut (renamed from Northstar.CustomServers/scripts/vscripts/conversation/_conversation_schedule.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/conversation/_faction_dialogue.gnut (renamed from Northstar.CustomServers/scripts/vscripts/conversation/_faction_dialogue.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/conversation/_grunt_chatter_mp.gnut (renamed from Northstar.CustomServers/scripts/vscripts/conversation/_grunt_chatter_mp.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/conversation/_spectre_chatter_mp.gnut (renamed from Northstar.CustomServers/scripts/vscripts/conversation/_spectre_chatter_mp.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter.gnut (renamed from Northstar.CustomServers/scripts/vscripts/earn_meter/sv_earn_meter.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut (renamed from Northstar.CustomServers/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/evac/_evac.gnut (renamed from Northstar.CustomServers/scripts/vscripts/evac/_evac.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/faction_xp.gnut (renamed from Northstar.CustomServers/scripts/vscripts/faction_xp.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_ai_frontline.gnut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_ai_frontline.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_ai_gamemodes.gnut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_ai_gamemodes.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_capture_point.gnut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_capture_point.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_featured_mode_settings.gnut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_featured_mode_settings.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_frontline.gnut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_frontline.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_aitdm.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_aitdm.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_at.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_coliseum.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_coliseum.nut)3
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_cp.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_cp.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ctf.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_ctf.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_fd.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ffa.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_ffa.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fra.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_fra.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_lts.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_lts.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_mfd.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_mfd.nut)4
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_ps.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_speedball.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_tdm.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ttdm.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_ttdm.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_hardpoints.gnut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_hardpoints.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_riff_floor_is_lava.nut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_riff_floor_is_lava.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_spawnpoints.gnut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/_spawnpoints.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/sh_gamemodes.gnut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/sh_gamemodes.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/gamemodes/sh_gamemodes_custom.gnut (renamed from Northstar.CustomServers/scripts/vscripts/gamemodes/sh_gamemodes_custom.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut (renamed from Northstar.CustomServers/scripts/vscripts/item_inventory/sv_item_inventory.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/lobby/_lobby.gnut (renamed from Northstar.CustomServers/scripts/vscripts/lobby/_lobby.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/lobby/_private_lobby.gnut (renamed from Northstar.CustomServers/scripts/vscripts/lobby/_private_lobby.gnut)25
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/lobby/sh_lobby.gnut (renamed from Northstar.CustomServers/scripts/vscripts/lobby/sh_lobby.gnut)139
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/lobby/sh_private_lobby_modes_init.gnut55
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/melee/_melee.gnut (renamed from Northstar.CustomServers/scripts/vscripts/melee/_melee.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/melee/_melee_rewards.gnut (renamed from Northstar.CustomServers/scripts/vscripts/melee/_melee_rewards.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/melee/_melee_synced_human.gnut (renamed from Northstar.CustomServers/scripts/vscripts/melee/_melee_synced_human.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/melee/_melee_synced_titan.gnut (renamed from Northstar.CustomServers/scripts/vscripts/melee/_melee_synced_titan.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_mp.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_ai_mp.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_mp.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_ai_mp.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_superspectre.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_ai_superspectre.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_base_gametype.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_base_gametype_mp.gnut)2
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_battery_port.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_battery_port.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_bleedout.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_bleedout.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_challenges.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_challenges.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_changemap.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_changemap.nut)10
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_classic_mp.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_no_intro.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_classic_mp_no_intro.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_codecallbacks.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_codecallbacks.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_dropship_spawn_common.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_dropship_spawn_common.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_gamestate.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_gamestate_mp.nut)1
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_goblin_dropship.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_goblin_dropship.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_lasermesh.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_lasermesh.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_loadout_crate.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_loadout_crate.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_mp_mapspawn.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_mp_mapspawn.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_music.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_music.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_pickups.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_pickups.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_pickups_glow.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_pickups_glow.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_playlist.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_playlist.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_revive.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_revive.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_score.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_serverflags.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_serverflags.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_sniper_spectres.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_sniper_spectres.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_spawn_functions.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_spawn_functions.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_spectre_rack.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_spectre_rack.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_stats.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_titan_npc.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_titan_npc.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_titan_tether.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_titan_tether.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_titan_transfer.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_titan_transfer.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_tonecontroller.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_tonecontroller.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_utility_mp.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_utility_mp.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_vr.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/_vr.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/_lf_maps_shared.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/_lf_maps_shared.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_angel_city.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city_fd.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_angel_city_fd.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_black_water_canal.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_black_water_canal.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_black_water_canal_fd.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_black_water_canal_fd.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_coliseum.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_coliseum.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_coliseum_column.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_coliseum_column.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_colony02.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_colony02.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_colony02_fd.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_colony02_fd.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_complex3.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_complex3.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_crashsite3.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_crashsite3.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_drydock.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_drydock.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_drydock_fd.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_drydock_fd.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_eden.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_eden.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_forwardbase_kodai.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_forwardbase_kodai.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_forwardbase_kodai_fd.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_forwardbase_kodai_fd.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_glitch.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_glitch.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_glitch_fd.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_glitch_fd.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_grave.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_grave.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_grave_fd.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_grave_fd.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_homestead.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_homestead.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_homestead_fd.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_homestead_fd.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_deck.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_deck.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_meadow.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_meadow.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_stacks.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_stacks.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_township.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_township.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_traffic.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_traffic.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_uma.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_uma.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_relic02.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_relic02.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_relic02_fd.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_relic02_fd.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_rise.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_rise.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_rise_fd.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_rise_fd.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_thaw.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_thaw.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_thaw_fd.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_thaw_fd.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_wargames.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames_fd.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/levels/mp_wargames_fd.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/pintelemetry.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/pintelemetry.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/player_cloak.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/player_cloak.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut (renamed from Northstar.CustomServers/scripts/vscripts/mp/spawn.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/spawn_debug.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/spawn_debug.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/spawn_on_friendly.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/spawn_on_friendly.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/spawn_wave.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/spawn_wave.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/spawn_wave_dropship.gnut (renamed from Northstar.CustomServers/scripts/vscripts/mp/spawn_wave_dropship.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/pilot/_leeching.gnut (renamed from Northstar.CustomServers/scripts/vscripts/pilot/_leeching.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/pilot/_pilot_leeching.gnut (renamed from Northstar.CustomServers/scripts/vscripts/pilot/_pilot_leeching.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/pilot/_slamzoom.nut (renamed from Northstar.CustomServers/scripts/vscripts/pilot/_slamzoom.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/pilot/_zipline.gnut (renamed from Northstar.CustomServers/scripts/vscripts/pilot/_zipline.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/pilot/class_wallrun.gnut (renamed from Northstar.CustomServers/scripts/vscripts/pilot/class_wallrun.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/rodeo/_rodeo.gnut (renamed from Northstar.CustomServers/scripts/vscripts/rodeo/_rodeo.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut (renamed from Northstar.CustomServers/scripts/vscripts/rodeo/_rodeo_titan.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/sh_calling_cards.gnut (renamed from Northstar.CustomServers/scripts/vscripts/sh_calling_cards.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/sh_loadouts_mp.nut (renamed from Northstar.CustomServers/scripts/vscripts/sh_loadouts_mp.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/sh_northstar_utils.gnut (renamed from bobthebob.testing/scripts/vscripts/sh_northstar_utils.gnut)9
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/sh_remote_functions_mp_custom.gnut (renamed from Northstar.CustomServers/scripts/vscripts/sh_remote_functions_mp_custom.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/sh_stats.gnut (renamed from Northstar.CustomServers/scripts/vscripts/sh_stats.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/superbar/orbitalstrike.nut (renamed from Northstar.CustomServers/scripts/vscripts/superbar/orbitalstrike.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/superbar/smokescreen.nut (renamed from Northstar.CustomServers/scripts/vscripts/superbar/smokescreen.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/sv_globals.gnut (renamed from Northstar.CustomServers/scripts/vscripts/sv_globals.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/titan/_battery_generator.gnut (renamed from Northstar.CustomServers/scripts/vscripts/titan/_battery_generator.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/titan/_replacement_titans.gnut (renamed from Northstar.CustomServers/scripts/vscripts/titan/_replacement_titans.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/titan/_replacement_titans_drop.gnut (renamed from Northstar.CustomServers/scripts/vscripts/titan/_replacement_titans_drop.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_commands.gnut (renamed from Northstar.CustomServers/scripts/vscripts/titan/_titan_commands.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_health.gnut (renamed from Northstar.CustomServers/scripts/vscripts/titan/_titan_health.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_hints.gnut (renamed from Northstar.CustomServers/scripts/vscripts/titan/_titan_hints.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_hotdrop.gnut (renamed from Northstar.CustomServers/scripts/vscripts/titan/_titan_hotdrop.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_triple_health.gnut (renamed from Northstar.CustomServers/scripts/vscripts/titan/_titan_triple_health.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/titan/class_titan.gnut (renamed from Northstar.CustomServers/scripts/vscripts/titan/class_titan.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/titan_xp.gnut (renamed from Northstar.CustomServers/scripts/vscripts/titan_xp.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/vehicle/_vehicle_behavior.gnut (renamed from Northstar.CustomServers/scripts/vscripts/vehicle/_vehicle_behavior.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/vehicle/_vehicle_dropship_new.nut (renamed from Northstar.CustomServers/scripts/vscripts/vehicle/_vehicle_dropship_new.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/weapon_xp.gnut (renamed from Northstar.CustomServers/scripts/vscripts/weapon_xp.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/weapons/_arc_cannon.nut (renamed from Northstar.CustomServers/scripts/vscripts/weapons/_arc_cannon.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/weapons/_at_turrets.gnut (renamed from Northstar.CustomServers/scripts/vscripts/weapons/_at_turrets.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/weapons/_ball_lightning.gnut (renamed from Northstar.CustomServers/scripts/vscripts/weapons/_ball_lightning.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/weapons/_cloaker.gnut (renamed from Northstar.CustomServers/scripts/vscripts/weapons/_cloaker.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/weapons/_grenade.nut (renamed from Northstar.CustomServers/scripts/vscripts/weapons/_grenade.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/weapons/_particle_wall.gnut (renamed from Northstar.CustomServers/scripts/vscripts/weapons/_particle_wall.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/weapons/_team_emp.gnut (renamed from Northstar.CustomServers/scripts/vscripts/weapons/_team_emp.gnut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/weapons/_vortex.nut (renamed from Northstar.CustomServers/scripts/vscripts/weapons/_vortex.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/weapons/_weapon_dialogue.nut (renamed from Northstar.CustomServers/scripts/vscripts/weapons/_weapon_dialogue.nut)0
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/weapons/_weapon_utility.nut (renamed from Northstar.CustomServers/scripts/vscripts/weapons/_weapon_utility.nut)0
-rw-r--r--Northstar.CustomServers/scripts/vscripts/ai/_droppod.gnut6
-rw-r--r--Northstar.CustomServers/scripts/vscripts/lobby/sh_private_lobby_modes_init.gnut21
-rw-r--r--Northstar.CustomServers/scripts/vscripts/sh_northstar_utils.gnut49
-rw-r--r--bobthebob.testing/mod.json34
-rw-r--r--bobthebob.testing/scripts/vscripts/_bobtestingfunctions_mp.gnut239
-rw-r--r--bobthebob.testing/scripts/vscripts/_bobtestingfunctions_sp.gnut13
-rw-r--r--bobthebob.testing/scripts/vscripts/mp/levels/mp_box.nut24
-rw-r--r--bobthebob.testing/scripts/vscripts/mp/sh_revive.gnut19
-rw-r--r--bobthebob.testing/scripts/vscripts/sh_bleedout_test.gnut34
-rw-r--r--bobthebob.testing/scripts/vscripts/sh_bobtestingfunctions_mp.gnut135
-rw-r--r--bobthebob.testing/scripts/vscripts/ui/menu_dev.nut707
-rw-r--r--bobthebob.testing/scripts/vscripts/ui/menu_map_select.nut162
-rw-r--r--bobthebob.testing/scripts/vscripts/ui/menu_team_titan_select.nut723
528 files changed, 9838 insertions, 33952 deletions
diff --git a/Northstar.Client/mod.json b/Northstar.Client/mod.json
index f9a6fea5..1edf2ba1 100644
--- a/Northstar.Client/mod.json
+++ b/Northstar.Client/mod.json
@@ -1,15 +1,54 @@
{
- "ApiId" : "Northstar.Client",
"Name" : "Northstar.Client",
"Description" : "Various ui and client changes to fix bugs and add better support for mods",
- "Authors" : [
- "BobTheBob"
- ],
- "Contacts" : [
- "BobTheBob#1150"
- ],
- "Version" : "0.1",
- "CustomScripts": [
+ "LoadPriority": 0,
+
+ // ui inits need to happen before so our init callbacks get called
+ "Scripts": [
+ {
+ "Path": "ui/menu_ns_modmenu.nut",
+ "RunOn": "UI",
+ "UICallback": {
+ "Before": "AddNorthstarModMenu",
+ "After": "AddNorthstarModMenu_MainMenuFooter" // need to do this after, so we add footer after mainmenu init
+ }
+ },
+
+ {
+ "Path": "ui/menu_ns_serverbrowser.nut",
+ "RunOn": "UI",
+ "UICallback": {
+ "Before": "AddNorthstarServerBrowserMenu"
+ }
+ },
+
+ {
+ "Path": "ui/menu_ns_connect_password.nut",
+ "RunOn": "UI",
+ "UICallback": {
+ "Before": "AddNorthstarConnectWithPasswordMenu"
+ }
+ },
+
+ {
+ "Path": "ui/menu_ns_custom_match_settings_categories.nut",
+ "RunOn": "UI",
+ "UICallback": {
+ "Before": "AddNorthstarCustomMatchSettingsCategoryMenu"
+ }
+ },
+
+ {
+ "Path": "ui/menu_ns_custom_match_settings.nut",
+ "RunOn": "UI",
+ "UICallback": {
+ "Before": "AddNorthstarCustomMatchSettingsMenu"
+ }
+ }
+ ],
+
+ "Localisation": [
+ "resource/northstar_client_localisation_%language%.txt"
]
} \ No newline at end of file
diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_english.txt b/Northstar.Client/mod/resource/northstar_client_localisation_english.txt
new file mode 100644
index 00000000..1fc54f2b
--- /dev/null
+++ b/Northstar.Client/mod/resource/northstar_client_localisation_english.txt
Binary files differ
diff --git a/Northstar.Client/resource/ui/menus/modlist.menu b/Northstar.Client/mod/resource/ui/menus/connect_password.menu
index 289ff484..b5e12ad2 100644
--- a/Northstar.Client/resource/ui/menus/modlist.menu
+++ b/Northstar.Client/mod/resource/ui/menus/connect_password.menu
@@ -26,7 +26,7 @@ resource/ui/menus/mods_browse.menu
{
ControlName Label
InheritProperties MenuTitle
- labelText "Configure"
+ labelText "#MENU_TITLE_CONNECT_PASSWORD"
}
ImgTopBar
@@ -34,7 +34,16 @@ resource/ui/menus/mods_browse.menu
ControlName ImagePanel
InheritProperties MenuTopBar
}
+
+ ButtonRowAnchor
+ {
+ ControlName Label
+ labelText ""
+ xpos 120
+ ypos 160
+ }
+
MatchmakingStatus
{
ControlName CNestedPanel
@@ -48,36 +57,44 @@ resource/ui/menus/mods_browse.menu
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- LblMenuItemDescription
+ EnterPasswordBox
{
- ControlName Label
- InheritProperties OptionMenuTooltip
- classname MenuItemDescriptionClass
- xpos 975
- ypos 168
- }
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
- SwitchCommunityPanel
- {
- ControlName CNestedPanel
- wide f0
- tall f0
+ ControlName TextEntry
+ wide 700
+ tall 53
visible 1
- controlSettingsFile "resource/ui/menus/panels/switch_configure_mods.res"
+ enabled 1
+ textHidden 1
+ editable 1
+ maxchars 32
+ NumericInputOnly 0
+ textAlignment "east"
+ font DefaultBold_53
+ keyboardTitle "#CONNECT_WITH_PASSWORD"
+ keyboardDescription "#ENTER_PASSWORD"
+ allowRightClickMenu 1
+ allowSpecialCharacters 0
+ unicode 0
+ paintborder 0
+
+ pin_to_sibling ButtonRowAnchor
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
}
-
- BtnModOptions
- {
- xpos 120
- ypos 160
- ControlName RuiButton
- InheritProperties RuiSmallButton
- visible 1
- }
+
+ ConnectButton
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ wide 200
+ classname ModButton
+ scriptID 0
+ visible 1
+ pin_to_sibling EnterPasswordBox
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/Northstar.Client/mod/resource/ui/menus/custom_match_settings.menu b/Northstar.Client/mod/resource/ui/menus/custom_match_settings.menu
new file mode 100644
index 00000000..f8ed75b4
--- /dev/null
+++ b/Northstar.Client/mod/resource/ui/menus/custom_match_settings.menu
@@ -0,0 +1,2203 @@
+resource/ui/menus/mods_browse.menu
+{
+ menu
+ {
+ ControlName Frame
+ xpos 0
+ ypos 0
+ zpos 3
+ wide f0
+ tall f0
+ autoResize 0
+ visible 1
+ enabled 1
+ pinCorner 0
+ PaintBackgroundType 0
+ infocus_bgcolor_override "0 0 0 0"
+ outoffocus_bgcolor_override "0 0 0 0"
+
+ Vignette
+ {
+ ControlName ImagePanel
+ InheritProperties MenuVignette
+ }
+
+ Title
+ {
+ ControlName Label
+ InheritProperties MenuTitle
+ labelText "#MENU_MATCH_SETTINGS"
+ }
+
+ ImgTopBar
+ {
+ ControlName ImagePanel
+ InheritProperties MenuTopBar
+ }
+
+ ButtonRowAnchor
+ {
+ ControlName Label
+ labelText ""
+
+ xpos 120
+ ypos 160
+ }
+
+ //test
+ //{
+ // ControlName ListPanel
+ // xpos "200"
+ // ypos "200"
+ // zpos 999
+ // wide "312"
+ // tall "340"
+ // autoResize "0"
+ // pinCorner "0"
+ // visible "1"
+ // enabled "1"
+ // tabPosition "0"
+ //}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ //TextEntrySldFOV
+ //{
+ // ControlName TextEntry
+ // xpos 8
+ // zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ // wide 50
+ // tall 30
+ // visible 1
+ // enabled 1
+ // textHidden 0
+ // editable 1
+ // maxchars 3
+ // NumericInputOnly 1
+ // font Default_21
+ // allowRightClickMenu 0
+ // allowSpecialCharacters 0
+ // unicode 0
+ //
+ // pin_to_sibling SldFOV
+ // pin_corner_to_sibling LEFT
+ // pin_to_sibling_corner RIGHT
+ //}
+
+ BtnSetting0
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 0
+ xpos 96
+ ypos 177
+ tabPosition 1
+ navUp BtnSetting0
+ navDown BtnSetting1
+ }
+
+ TextEntrySetting0
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 0
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting0
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting47
+ navDown BtnSetting1
+ }
+
+ BtnSetting1
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 1
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting0
+ navDown BtnSetting2
+
+ pin_to_sibling BtnSetting0
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting1
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 1
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting1
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting0
+ navDown BtnSetting2
+ }
+
+ BtnSetting2
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 2
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting1
+ navDown BtnSetting3
+
+ pin_to_sibling BtnSetting1
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting2
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 2
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting2
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting1
+ navDown BtnSetting3
+ }
+
+ BtnSetting3
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 3
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting2
+ navDown BtnSetting4
+
+ pin_to_sibling BtnSetting2
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting3
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 3
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting3
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting2
+ navDown BtnSetting4
+ }
+
+ BtnSetting4
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 4
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting3
+ navDown BtnSetting5
+
+ pin_to_sibling BtnSetting3
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting4
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 4
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting4
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting3
+ navDown BtnSetting5
+ }
+
+ BtnSetting5
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 5
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting4
+ navDown BtnSetting6
+
+ pin_to_sibling BtnSetting4
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting5
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 5
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting5
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting4
+ navDown BtnSetting6
+ }
+
+ BtnSetting6
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 6
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting5
+ navDown BtnSetting7
+
+ pin_to_sibling BtnSetting5
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting6
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 6
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting6
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting5
+ navDown BtnSetting7
+ }
+
+ BtnSetting7
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 7
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting6
+ navDown BtnSetting8
+
+ pin_to_sibling BtnSetting6
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting7
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 7
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting7
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting6
+ navDown BtnSetting8
+ }
+
+ BtnSetting8
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 8
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting7
+ navDown BtnSetting9
+
+ pin_to_sibling BtnSetting7
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting8
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 8
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting8
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting7
+ navDown BtnSetting9
+ }
+
+ BtnSetting9
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 9
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting8
+ navDown BtnSetting10
+
+ pin_to_sibling BtnSetting8
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting9
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 9
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting9
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting8
+ navDown BtnSetting10
+ }
+
+ BtnSetting10
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 10
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting9
+ navDown BtnSetting11
+
+ pin_to_sibling BtnSetting9
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting10
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 10
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting10
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting9
+ navDown BtnSetting11
+ }
+
+ BtnSetting11
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 11
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting10
+ navDown BtnSetting12
+
+ pin_to_sibling BtnSetting10
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting11
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 11
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting11
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting10
+ navDown BtnSetting12
+ }
+
+ BtnSetting12
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 12
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting11
+ navDown BtnSetting13
+
+ pin_to_sibling BtnSetting11
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting12
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 12
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting12
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting11
+ navDown BtnSetting13
+ }
+
+ BtnSetting13
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 13
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting12
+ navDown BtnSetting14
+
+ pin_to_sibling BtnSetting12
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting13
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 13
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting13
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting12
+ navDown BtnSetting14
+ }
+
+ BtnSetting14
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 14
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting13
+ navDown BtnSetting15
+
+ pin_to_sibling BtnSetting13
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting14
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 14
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting14
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting13
+ navDown BtnSetting15
+ }
+
+ BtnSetting15
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 15
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting14
+ navDown BtnSetting16
+
+ pin_to_sibling BtnSetting14
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting15
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 15
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting15
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting14
+ navDown BtnSetting16
+ }
+
+ BtnSetting16
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 16
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting15
+ navDown BtnSetting17
+
+ pin_to_sibling BtnSetting0
+ pin_corner_to_sibling LEFT
+ pin_to_sibling_corner RIGHT
+ }
+
+ TextEntrySetting16
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 16
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting16
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting15
+ navDown BtnSetting17
+ }
+
+ BtnSetting17
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 17
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting16
+ navDown BtnSetting18
+
+ pin_to_sibling BtnSetting16
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting17
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 17
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting17
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting16
+ navDown BtnSetting18
+ }
+
+ BtnSetting18
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 18
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting17
+ navDown BtnSetting19
+
+ pin_to_sibling BtnSetting17
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting18
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 18
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting18
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting17
+ navDown BtnSetting19
+ }
+
+ BtnSetting19
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 19
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting18
+ navDown BtnSetting20
+
+ pin_to_sibling BtnSetting18
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting19
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 19
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting19
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting18
+ navDown BtnSetting20
+ }
+
+ BtnSetting20
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 20
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting19
+ navDown BtnSetting21
+
+ pin_to_sibling BtnSetting19
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting20
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 20
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting20
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting19
+ navDown BtnSetting21
+ }
+
+ BtnSetting21
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 21
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting20
+ navDown BtnSetting22
+
+ pin_to_sibling BtnSetting20
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting21
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 21
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting21
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting20
+ navDown BtnSetting22
+ }
+
+ BtnSetting22
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 22
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting21
+ navDown BtnSetting23
+
+ pin_to_sibling BtnSetting21
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting22
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 22
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting22
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting21
+ navDown BtnSetting23
+ }
+
+ BtnSetting23
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 23
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting22
+ navDown BtnSetting24
+
+ pin_to_sibling BtnSetting22
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting23
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 23
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting23
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting22
+ navDown BtnSetting24
+ }
+
+ BtnSetting24
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 24
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting23
+ navDown BtnSetting25
+
+ pin_to_sibling BtnSetting23
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting24
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 24
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting24
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting23
+ navDown BtnSetting25
+ }
+
+ BtnSetting25
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 25
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting24
+ navDown BtnSetting26
+
+ pin_to_sibling BtnSetting24
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting25
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 25
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting25
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting24
+ navDown BtnSetting26
+ }
+
+ BtnSetting26
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 26
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting25
+ navDown BtnSetting27
+
+ pin_to_sibling BtnSetting25
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting26
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 26
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting26
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting25
+ navDown BtnSetting27
+ }
+
+ BtnSetting27
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 27
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting26
+ navDown BtnSetting28
+
+ pin_to_sibling BtnSetting26
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting27
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 27
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting27
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting26
+ navDown BtnSetting28
+ }
+
+ BtnSetting28
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 28
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting27
+ navDown BtnSetting29
+
+ pin_to_sibling BtnSetting27
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting28
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 28
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting28
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting27
+ navDown BtnSetting29
+ }
+
+ BtnSetting29
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 29
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting28
+ navDown BtnSetting30
+
+ pin_to_sibling BtnSetting28
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting29
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 29
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting29
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting28
+ navDown BtnSetting30
+ }
+
+ BtnSetting30
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 30
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting29
+ navDown BtnSetting31
+
+ pin_to_sibling BtnSetting29
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting30
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 30
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting30
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting29
+ navDown BtnSetting31
+ }
+
+ BtnSetting31
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 31
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting30
+ navDown BtnSetting32
+
+ pin_to_sibling BtnSetting30
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting31
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 31
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting31
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting30
+ navDown BtnSetting32
+ }
+
+ BtnSetting32
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 32
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting31
+ navDown BtnSetting33
+
+ pin_to_sibling BtnSetting16
+ pin_corner_to_sibling LEFT
+ pin_to_sibling_corner RIGHT
+ }
+
+ TextEntrySetting32
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 32
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting32
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting31
+ navDown BtnSetting33
+ }
+
+ BtnSetting33
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 33
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting32
+ navDown BtnSetting34
+
+ pin_to_sibling BtnSetting32
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting33
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 33
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting33
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting32
+ navDown BtnSetting34
+ }
+
+ BtnSetting34
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 34
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting33
+ navDown BtnSetting35
+
+ pin_to_sibling BtnSetting33
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting34
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 34
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting34
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting33
+ navDown BtnSetting35
+ }
+
+ BtnSetting35
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 35
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting34
+ navDown BtnSetting36
+
+ pin_to_sibling BtnSetting34
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting35
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 35
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting35
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting34
+ navDown BtnSetting36
+ }
+
+ BtnSetting36
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 36
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting35
+ navDown BtnSetting37
+
+ pin_to_sibling BtnSetting35
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting36
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 36
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting36
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting35
+ navDown BtnSetting37
+ }
+
+ BtnSetting37
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 37
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting36
+ navDown BtnSetting38
+
+ pin_to_sibling BtnSetting36
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting37
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 37
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting37
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting36
+ navDown BtnSetting38
+ }
+
+ BtnSetting38
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 38
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting37
+ navDown BtnSetting39
+
+ pin_to_sibling BtnSetting37
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting38
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 38
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting38
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting37
+ navDown BtnSetting39
+ }
+
+ BtnSetting39
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 39
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting38
+ navDown BtnSetting40
+
+ pin_to_sibling BtnSetting38
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting39
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 39
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting39
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting38
+ navDown BtnSetting40
+ }
+
+ BtnSetting40
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 40
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting39
+ navDown BtnSetting41
+
+ pin_to_sibling BtnSetting39
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting40
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 40
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting40
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting39
+ navDown BtnSetting41
+ }
+
+ BtnSetting41
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 41
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting40
+ navDown BtnSetting42
+
+ pin_to_sibling BtnSetting40
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting41
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 41
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting41
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting40
+ navDown BtnSetting42
+ }
+
+ BtnSetting42
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 42
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting41
+ navDown BtnSetting43
+
+ pin_to_sibling BtnSetting41
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting42
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 42
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting42
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting41
+ navDown BtnSetting43
+ }
+
+ BtnSetting43
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 43
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting42
+ navDown BtnSetting44
+
+ pin_to_sibling BtnSetting42
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting43
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 43
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting43
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting42
+ navDown BtnSetting44
+ }
+
+ BtnSetting44
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 44
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting43
+ navDown BtnSetting45
+
+ pin_to_sibling BtnSetting43
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting44
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 44
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting44
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting43
+ navDown BtnSetting45
+ }
+
+ BtnSetting45
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 45
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting44
+ navDown BtnSetting46
+
+ pin_to_sibling BtnSetting44
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting45
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 45
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting45
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting44
+ navDown BtnSetting46
+ }
+
+ BtnSetting46
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 46
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting45
+ navDown BtnSetting47
+
+ pin_to_sibling BtnSetting45
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting46
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 46
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting46
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting45
+ navDown BtnSetting47
+ }
+
+ BtnSetting47
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingButton
+ style DialogListButton
+ scriptID 47
+ //xpos 96
+ //ypos 177
+ tabPosition 1
+ navUp BtnSetting46
+ navDown BtnSetting0
+
+ pin_to_sibling BtnSetting46
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ }
+
+ TextEntrySetting47
+ {
+ ControlName TextEntry
+ classname MatchSettingTextEntry
+ xpos "-35"
+ ypos "-3"
+ zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox.
+ wide 175
+ tall 30
+ scriptID 47
+ textHidden 0
+ editable 1
+ //NumericInputOnly 1
+ font Default_21
+ allowRightClickMenu 0
+ allowSpecialCharacters 0
+ unicode 0
+
+ pin_to_sibling BtnSetting47
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ navUp BtnSetting46
+ navDown BtnSetting0
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ FooterButtons
+ {
+ ControlName CNestedPanel
+ InheritProperties FooterButtons
+ }
+ }
+}
diff --git a/Northstar.Client/mod/resource/ui/menus/custom_match_settings_categories.menu b/Northstar.Client/mod/resource/ui/menus/custom_match_settings_categories.menu
new file mode 100644
index 00000000..b0d7d002
--- /dev/null
+++ b/Northstar.Client/mod/resource/ui/menus/custom_match_settings_categories.menu
@@ -0,0 +1,752 @@
+resource/ui/menus/mods_browse.menu
+{
+ menu
+ {
+ ControlName Frame
+ xpos 0
+ ypos 0
+ zpos 3
+ wide f0
+ tall f0
+ autoResize 0
+ visible 1
+ enabled 1
+ pinCorner 0
+ PaintBackgroundType 0
+ infocus_bgcolor_override "0 0 0 0"
+ outoffocus_bgcolor_override "0 0 0 0"
+
+ Vignette
+ {
+ ControlName ImagePanel
+ InheritProperties MenuVignette
+ }
+
+ Title
+ {
+ ControlName Label
+ InheritProperties MenuTitle
+ labelText "#MENU_MATCH_SETTINGS"
+ }
+
+ ImgTopBar
+ {
+ ControlName ImagePanel
+ InheritProperties MenuTopBar
+ }
+
+ ButtonRowAnchor
+ {
+ ControlName Label
+ labelText ""
+
+ xpos 120
+ ypos 160
+ }
+
+ //test
+ //{
+ // ControlName ListPanel
+ // xpos "200"
+ // ypos "200"
+ // zpos 999
+ // wide "312"
+ // tall "340"
+ // autoResize "0"
+ // pinCorner "0"
+ // visible "1"
+ // enabled "1"
+ // tabPosition "0"
+ //}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ BtnDev0
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 0
+ xpos 96
+ ypos 177
+ tabPosition 1
+ navUp BtnDev47
+ navDown BtnDev1
+ navRight BtnDev15
+ navLeft BtnDev31
+ }
+ BtnDev1
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 1
+ pin_to_sibling BtnDev0
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev0
+ navDown BtnDev2
+ navRight BtnDev16
+ navLeft BtnDev32
+ }
+ BtnDev2
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 2
+ pin_to_sibling BtnDev1
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev1
+ navDown BtnDev3
+ navRight BtnDev17
+ navLeft BtnDev33
+ }
+ BtnDev3
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 3
+ pin_to_sibling BtnDev2
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev2
+ navDown BtnDev4
+ navRight BtnDev18
+ navLeft BtnDev34
+ }
+ BtnDev4
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 4
+ pin_to_sibling BtnDev3
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev3
+ navDown BtnDev5
+ navRight BtnDev19
+ navLeft BtnDev35
+ }
+ BtnDev5
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 5
+ pin_to_sibling BtnDev4
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev4
+ navDown BtnDev6
+ navRight BtnDev20
+ navLeft BtnDev36
+ }
+ BtnDev6
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 6
+ pin_to_sibling BtnDev5
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev5
+ navDown BtnDev7
+ navRight BtnDev21
+ navLeft BtnDev37
+ }
+ BtnDev7
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 7
+ pin_to_sibling BtnDev6
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev6
+ navDown BtnDev8
+ navRight BtnDev22
+ navLeft BtnDev38
+ }
+ BtnDev8
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 8
+ pin_to_sibling BtnDev7
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev7
+ navDown BtnDev9
+ navRight BtnDev23
+ navLeft BtnDev39
+ }
+ BtnDev9
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 9
+ pin_to_sibling BtnDev8
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev8
+ navDown BtnDev10
+ navRight BtnDev24
+ navLeft BtnDev40
+ }
+ BtnDev10
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 10
+ pin_to_sibling BtnDev9
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev9
+ navDown BtnDev11
+ navRight BtnDev25
+ navLeft BtnDev41
+ }
+ BtnDev11
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 11
+ pin_to_sibling BtnDev10
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev10
+ navDown BtnDev12
+ navRight BtnDev26
+ navLeft BtnDev42
+ }
+ BtnDev12
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 12
+ pin_to_sibling BtnDev11
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev11
+ navDown BtnDev13
+ navRight BtnDev27
+ navLeft BtnDev43
+ }
+ BtnDev13
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 13
+ pin_to_sibling BtnDev12
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev12
+ navDown BtnDev14
+ navRight BtnDev28
+ navLeft BtnDev44
+ }
+ BtnDev14
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 14
+ pin_to_sibling BtnDev13
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev13
+ navDown BtnDev47
+ navRight BtnDev29
+ navLeft BtnDev45
+ }
+
+//////////////////////////////////////
+
+ BtnDev15
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 15
+ pin_to_sibling BtnDev0
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner TOP_RIGHT
+ navUp BtnDev30
+ navDown BtnDev16
+ navRight BtnDev31
+ navLeft BtnDev0
+ }
+ BtnDev16
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 16
+ pin_to_sibling BtnDev15
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev15
+ navDown BtnDev17
+ navRight BtnDev32
+ navLeft BtnDev1
+ }
+ BtnDev17
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 17
+ pin_to_sibling BtnDev16
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev16
+ navDown BtnDev18
+ navRight BtnDev33
+ navLeft BtnDev2
+ }
+ BtnDev18
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 18
+ pin_to_sibling BtnDev17
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev17
+ navDown BtnDev19
+ navRight BtnDev34
+ navLeft BtnDev3
+ }
+ BtnDev19
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 19
+ pin_to_sibling BtnDev18
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev18
+ navDown BtnDev20
+ navRight BtnDev35
+ navLeft BtnDev4
+ }
+ BtnDev20
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 20
+ pin_to_sibling BtnDev19
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev19
+ navDown BtnDev21
+ navRight BtnDev36
+ navLeft BtnDev5
+ }
+ BtnDev21
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 21
+ pin_to_sibling BtnDev20
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev20
+ navDown BtnDev22
+ navRight BtnDev37
+ navLeft BtnDev6
+ }
+ BtnDev22
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 22
+ pin_to_sibling BtnDev21
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev21
+ navDown BtnDev23
+ navRight BtnDev38
+ navLeft BtnDev7
+ }
+ BtnDev23
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 23
+ pin_to_sibling BtnDev22
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev22
+ navDown BtnDev24
+ navRight BtnDev39
+ navLeft BtnDev8
+ }
+ BtnDev24
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 24
+ pin_to_sibling BtnDev23
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev23
+ navDown BtnDev25
+ navRight BtnDev40
+ navLeft BtnDev9
+ }
+ BtnDev25
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 25
+ pin_to_sibling BtnDev24
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev24
+ navDown BtnDev26
+ navRight BtnDev41
+ navLeft BtnDev10
+ }
+ BtnDev26
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 26
+ pin_to_sibling BtnDev25
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev25
+ navDown BtnDev27
+ navRight BtnDev42
+ navLeft BtnDev11
+ }
+ BtnDev27
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 27
+ pin_to_sibling BtnDev26
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev26
+ navDown BtnDev28
+ navRight BtnDev43
+ navLeft BtnDev12
+ }
+ BtnDev28
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 28
+ pin_to_sibling BtnDev27
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev27
+ navDown BtnDev29
+ navRight BtnDev44
+ navLeft BtnDev13
+ }
+ BtnDev29
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 29
+ pin_to_sibling BtnDev28
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev28
+ navDown BtnDev30
+ navRight BtnDev45
+ navLeft BtnDev14
+ }
+ BtnDev30
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 30
+ pin_to_sibling BtnDev29
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev29
+ navDown BtnDev15
+ navRight BtnDev46
+ navLeft BtnDev47
+ }
+
+ BtnDev47
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 47
+ pin_to_sibling BtnDev14
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev14
+ navDown BtnDev0
+ navRight BtnDev30
+ navLeft BtnDev46
+ }
+
+//////////////////////////////////////
+
+ BtnDev31
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 31
+ pin_to_sibling BtnDev15
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner TOP_RIGHT
+ navUp BtnDev46
+ navDown BtnDev32
+ navRight BtnDev0
+ navLeft BtnDev15
+ }
+ BtnDev32
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 32
+ pin_to_sibling BtnDev31
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev31
+ navDown BtnDev33
+ navRight BtnDev1
+ navLeft BtnDev16
+ }
+ BtnDev33
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 33
+ pin_to_sibling BtnDev32
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev32
+ navDown BtnDev34
+ navRight BtnDev2
+ navLeft BtnDev17
+ }
+ BtnDev34
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 34
+ pin_to_sibling BtnDev33
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev33
+ navDown BtnDev35
+ navRight BtnDev3
+ navLeft BtnDev18
+ }
+ BtnDev35
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 35
+ pin_to_sibling BtnDev34
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev34
+ navDown BtnDev36
+ navRight BtnDev4
+ navLeft BtnDev19
+ }
+ BtnDev36
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 36
+ pin_to_sibling BtnDev35
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev35
+ navDown BtnDev37
+ navRight BtnDev5
+ navLeft BtnDev20
+ }
+ BtnDev37
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 37
+ pin_to_sibling BtnDev36
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev36
+ navDown BtnDev38
+ navRight BtnDev6
+ navLeft BtnDev21
+ }
+ BtnDev38
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 38
+ pin_to_sibling BtnDev37
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev37
+ navDown BtnDev39
+ navRight BtnDev7
+ navLeft BtnDev22
+ }
+ BtnDev39
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 39
+ pin_to_sibling BtnDev38
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev38
+ navDown BtnDev40
+ navRight BtnDev8
+ navLeft BtnDev23
+ }
+ BtnDev40
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 40
+ pin_to_sibling BtnDev39
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev39
+ navDown BtnDev41
+ navRight BtnDev9
+ navLeft BtnDev24
+ }
+ BtnDev41
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 41
+ pin_to_sibling BtnDev40
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev40
+ navDown BtnDev42
+ navRight BtnDev10
+ navLeft BtnDev25
+ }
+ BtnDev42
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 42
+ pin_to_sibling BtnDev41
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev41
+ navDown BtnDev43
+ navRight BtnDev11
+ navLeft BtnDev26
+ }
+ BtnDev43
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 43
+ pin_to_sibling BtnDev42
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev42
+ navDown BtnDev44
+ navRight BtnDev12
+ navLeft BtnDev27
+ }
+ BtnDev44
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 44
+ pin_to_sibling BtnDev43
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev43
+ navDown BtnDev45
+ navRight BtnDev13
+ navLeft BtnDev28
+ }
+ BtnDev45
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 45
+ pin_to_sibling BtnDev44
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev44
+ navDown BtnDev46
+ navRight BtnDev14
+ navLeft BtnDev29
+ }
+ BtnDev46
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname MatchSettingCategoryButton
+ scriptID 46
+ pin_to_sibling BtnDev45
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnDev45
+ navDown BtnDev31
+ navRight BtnDev47
+ navLeft BtnDev30
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ FooterButtons
+ {
+ ControlName CNestedPanel
+ InheritProperties FooterButtons
+ }
+ }
+}
diff --git a/Northstar.Client/mod/resource/ui/menus/modlist.menu b/Northstar.Client/mod/resource/ui/menus/modlist.menu
new file mode 100644
index 00000000..682f643e
--- /dev/null
+++ b/Northstar.Client/mod/resource/ui/menus/modlist.menu
@@ -0,0 +1,255 @@
+resource/ui/menus/mods_browse.menu
+{
+ menu
+ {
+ ControlName Frame
+ xpos 0
+ ypos 0
+ zpos 3
+ wide f0
+ tall f0
+ autoResize 0
+ visible 1
+ enabled 1
+ pinCorner 0
+ PaintBackgroundType 0
+ infocus_bgcolor_override "0 0 0 0"
+ outoffocus_bgcolor_override "0 0 0 0"
+
+ Vignette
+ {
+ ControlName ImagePanel
+ InheritProperties MenuVignette
+ }
+
+ Title
+ {
+ ControlName Label
+ InheritProperties MenuTitle
+ labelText "#MENU_TITLE_MODS"
+ }
+
+ ImgTopBar
+ {
+ ControlName ImagePanel
+ InheritProperties MenuTopBar
+ }
+
+ ButtonRowAnchor
+ {
+ ControlName Label
+ labelText ""
+
+ xpos 120
+ ypos 160
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ BtnMod1
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 0
+ navUp BtnMod15
+ navDown BtnMod2
+
+ pin_to_sibling ButtonRowAnchor
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner TOP_LEFT
+ }
+ BtnMod2
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 1
+ pin_to_sibling BtnMod1
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnMod1
+ navDown BtnMod3
+ }
+ BtnMod3
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 2
+ pin_to_sibling BtnMod2
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnMod2
+ navDown BtnMod4
+ }
+ BtnMod4
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 3
+ pin_to_sibling BtnMod3
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ //ypos 11
+ navUp BtnMod3
+ navDown BtnMod5
+ }
+ BtnMod5
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 4
+ pin_to_sibling BtnMod4
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnMod4
+ navDown BtnMod6
+ }
+ BtnMod6
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 5
+ pin_to_sibling BtnMod5
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnMod5
+ navDown BtnMod7
+ }
+ BtnMod7
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 6
+ pin_to_sibling BtnMod6
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnMod6
+ navDown BtnMod8
+ }
+ BtnMod8
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 7
+ pin_to_sibling BtnMod7
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnMod7
+ navDown BtnMod9
+ }
+ BtnMod9
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 8
+ pin_to_sibling BtnMod8
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnMod8
+ navDown BtnMod10
+ }
+ BtnMod10
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 9
+ pin_to_sibling BtnMod9
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnMod9
+ navDown BtnMod11
+ }
+ BtnMod11
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 10
+ pin_to_sibling BtnMod10
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnMod10
+ navDown BtnMod12
+ }
+ BtnMod12
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 11
+ pin_to_sibling BtnMod11
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnMod11
+ navDown BtnMod13
+ }
+ BtnMod13
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 12
+ pin_to_sibling BtnMod12
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnMod12
+ navDown BtnMod14
+ }
+ BtnMod14
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 13
+ pin_to_sibling BtnMod13
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnMod13
+ navDown BtnMod15
+ }
+ BtnMod15
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ModButton
+ scriptID 14
+ pin_to_sibling BtnMod14
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnMod14
+ navDown BtnMod1
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ LabelDetails
+ {
+ ControlName RuiPanel
+ xpos 900
+ ypos 160
+ tall 800
+ wide 950
+ rui "ui/knowledgebase_panel.rpak"
+ wrap 1
+ visible 1
+ zpos 1
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ FooterButtons
+ {
+ ControlName CNestedPanel
+ InheritProperties FooterButtons
+ }
+ }
+}
diff --git a/Northstar.Client/mod/resource/ui/menus/server_browser.menu b/Northstar.Client/mod/resource/ui/menus/server_browser.menu
new file mode 100644
index 00000000..90785e46
--- /dev/null
+++ b/Northstar.Client/mod/resource/ui/menus/server_browser.menu
@@ -0,0 +1,338 @@
+resource/ui/menus/mods_browse.menu
+{
+ menu
+ {
+ ControlName Frame
+ xpos 0
+ ypos 0
+ zpos 3
+ wide f0
+ tall f0
+ autoResize 0
+ visible 1
+ enabled 1
+ pinCorner 0
+ PaintBackgroundType 0
+ infocus_bgcolor_override "0 0 0 0"
+ outoffocus_bgcolor_override "0 0 0 0"
+
+ Vignette
+ {
+ ControlName ImagePanel
+ InheritProperties MenuVignette
+ }
+
+ Title
+ {
+ ControlName Label
+ InheritProperties MenuTitle
+ labelText "#MENU_TITLE_SERVER_BROWSER"
+ }
+
+ ImgTopBar
+ {
+ ControlName ImagePanel
+ InheritProperties MenuTopBar
+ }
+
+ ButtonRowAnchor
+ {
+ ControlName Label
+ labelText ""
+
+ xpos 120
+ ypos 160
+ }
+
+ //test
+ //{
+ // ControlName ListPanel
+ // xpos "200"
+ // ypos "200"
+ // zpos 999
+ // wide "312"
+ // tall "340"
+ // autoResize "0"
+ // pinCorner "0"
+ // visible "1"
+ // enabled "1"
+ // tabPosition "0"
+ //}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ BtnServer1
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 0
+ navUp BtnServer15
+ navDown BtnServer2
+
+ pin_to_sibling ButtonRowAnchor
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner TOP_LEFT
+ }
+ BtnServer2
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 1
+ pin_to_sibling BtnServer1
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnServer1
+ navDown BtnServer3
+ }
+ BtnServer3
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 2
+ pin_to_sibling BtnServer2
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnServer2
+ navDown BtnServer4
+ }
+ BtnServer4
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 3
+ pin_to_sibling BtnServer3
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ //ypos 11
+ navUp BtnServer3
+ navDown BtnServer5
+ }
+ BtnServer5
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 4
+ pin_to_sibling BtnServer4
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnServer4
+ navDown BtnServer6
+ }
+ BtnServer6
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 5
+ pin_to_sibling BtnServer5
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnServer5
+ navDown BtnServer7
+ }
+ BtnServer7
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 6
+ pin_to_sibling BtnServer6
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnServer6
+ navDown BtnServer8
+ }
+ BtnServer8
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 7
+ pin_to_sibling BtnServer7
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnServer7
+ navDown BtnServer9
+ }
+ BtnServer9
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 8
+ pin_to_sibling BtnServer8
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnServer8
+ navDown BtnServer10
+ }
+ BtnServer10
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 9
+ pin_to_sibling BtnServer9
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnServer9
+ navDown BtnServer11
+ }
+ BtnServer11
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 10
+ pin_to_sibling BtnServer10
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnServer10
+ navDown BtnServer12
+ }
+ BtnServer12
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 11
+ pin_to_sibling BtnServer11
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnServer11
+ navDown BtnServer13
+ }
+ BtnServer13
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 12
+ pin_to_sibling BtnServer12
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnServer12
+ navDown BtnServer14
+ }
+ BtnServer14
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 13
+ pin_to_sibling BtnServer13
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnServer13
+ navDown BtnServer15
+ }
+ BtnServer15
+ {
+ ControlName RuiButton
+ InheritProperties RuiSmallButton
+ classname ServerButton
+ scriptID 14
+ pin_to_sibling BtnServer14
+ pin_corner_to_sibling TOP_LEFT
+ pin_to_sibling_corner BOTTOM_LEFT
+ navUp BtnServer14
+ navDown BtnServer1
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ LabelDetails
+ {
+ ControlName RuiPanel
+ xpos 900
+ ypos 160
+ tall 800
+ wide 950
+ rui "ui/knowledgebase_panel.rpak"
+ wrap 1
+ visible 1
+ zpos -1
+ }
+
+ NextMapImage
+ {
+ ControlName RuiPanel
+ wide 500
+ tall 288
+ visible 0
+ scaleImage 1
+
+ rui "ui/basic_menu_image.rpak"
+
+ pin_to_sibling LabelDetails
+ pin_corner_to_sibling TOP_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+ }
+ NextMapName
+ {
+ ControlName Label
+ pin_to_sibling NextMapImage
+ pin_corner_to_sibling BOTTOM_RIGHT
+ pin_to_sibling_corner BOTTOM_RIGHT
+
+ xpos -12
+ ypos 0
+ zpos 1
+
+ auto_wide_tocontents 1
+ auto_tall_tocontents 1
+ labelText ""
+ font Default_43_DropShadow
+ allcaps 1
+ fgcolor_override "255 255 255 255"
+ }
+ NextGameModeName
+ {
+ ControlName Label
+ pin_to_sibling NextMapName
+ pin_corner_to_sibling BOTTOM_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+
+ ypos -8
+ zpos 1
+
+ auto_wide_tocontents 1
+ auto_tall_tocontents 1
+ labelText ""
+ use_proportional_insets 1
+ textinsetx 2
+ font Default_28_DropShadow
+ allcaps 1
+ fgcolor_override "255 255 255 255"
+ }
+ NextModeIcon
+ {
+ ControlName RuiPanel
+ wide 72
+ tall 72
+ visible 0
+ scaleImage 1
+ image ""
+ zpos 1
+
+ rui "ui/basic_image_add.rpak"
+
+ pin_to_sibling NextGameModeName
+ pin_corner_to_sibling BOTTOM_RIGHT
+ pin_to_sibling_corner TOP_RIGHT
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ FooterButtons
+ {
+ ControlName CNestedPanel
+ InheritProperties FooterButtons
+ }
+ }
+}
diff --git a/Northstar.Client/scripts/vscripts/ui/menu_lobby.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut
index 3c868aab..3c868aab 100644
--- a/Northstar.Client/scripts/vscripts/ui/menu_lobby.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_lobby.nut
diff --git a/Northstar.Client/scripts/vscripts/ui/menu_map_select.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_map_select.nut
index 7ed0d177..7ed0d177 100644
--- a/Northstar.Client/scripts/vscripts/ui/menu_map_select.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_map_select.nut
diff --git a/Northstar.Client/scripts/vscripts/ui/menu_match_settings.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_match_settings.nut
index fb6cde1a..fb6cde1a 100644
--- a/Northstar.Client/scripts/vscripts/ui/menu_match_settings.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_match_settings.nut
diff --git a/bobthebob.testing/scripts/vscripts/ui/menu_mode_select.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_mode_select.nut
index 23376781..a017fb42 100644
--- a/bobthebob.testing/scripts/vscripts/ui/menu_mode_select.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_mode_select.nut
@@ -48,9 +48,14 @@ void function UpdateVisibleModes()
int modeIndex = i + ( file.currentModePage * MODES_PER_PAGE )
SetButtonRuiText( buttons[ i ], GetGameModeDisplayName( modesArray[ modeIndex ] ) )
- Hud_SetEnabled( buttons[ i ], true )
+
+ Hud_SetEnabled( buttons[ i ], true )
Hud_SetVisible( buttons[ i ], true )
- Hud_SetLocked( buttons[ i ], false )
+
+ if ( !ModeSettings_RequiresAI( modesArray[ modeIndex ] ) )
+ Hud_SetLocked( buttons[ i ], false )
+ else
+ Hud_SetLocked( buttons[ i ], true )
if ( !PrivateMatch_IsValidMapModeCombo( PrivateMatch_GetSelectedMap(), modesArray[ modeIndex ] ) && !IsNorthstarServer() )
{
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_connect_password.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_connect_password.nut
new file mode 100644
index 00000000..e1ed8991
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_connect_password.nut
@@ -0,0 +1,30 @@
+global function AddNorthstarConnectWithPasswordMenu
+
+void function AddNorthstarConnectWithPasswordMenu()
+{
+ AddMenu( "ConnectWithPasswordMenu", $"resource/ui/menus/connect_password.menu", InitConnectWithPasswordMenu, "#MENU_CONNECT" )
+}
+
+void function InitConnectWithPasswordMenu()
+{
+ AddMenuEventHandler( GetMenu( "ConnectWithPasswordMenu" ), eUIEvent.MENU_OPEN, OnConnectWithPasswordMenuOpened )
+ AddMenuFooterOption( GetMenu( "ConnectWithPasswordMenu" ), BUTTON_B, "#B_BUTTON_BACK", "#BACK" )
+
+ AddButtonEventHandler( Hud_GetChild( GetMenu( "ConnectWithPasswordMenu" ), "ConnectButton" ), UIE_CLICK, ConnectWithPassword )
+ RegisterButtonPressedCallback( KEY_ENTER, ConnectWithPassword )
+}
+
+void function OnConnectWithPasswordMenuOpened()
+{
+ UI_SetPresentationType( ePresentationType.KNOWLEDGEBASE_SUB )
+
+ Hud_SetText( Hud_GetChild( GetMenu( "ConnectWithPasswordMenu" ), "Title" ), "#MENU_TITLE_CONNECT_PASSWORD" )
+ Hud_SetText( Hud_GetChild( GetMenu( "ConnectWithPasswordMenu" ), "ConnectButton" ), "#MENU_CONNECT_MENU_CONNECT" )
+ Hud_SetText( Hud_GetChild( GetMenu( "ConnectWithPasswordMenu" ), "EnterPasswordBox" ), "" )
+}
+
+void function ConnectWithPassword( var button )
+{
+ if ( GetTopNonDialogMenu() == GetMenu( "ConnectWithPasswordMenu" ) )
+ thread ThreadedAuthAndConnectToServer( Hud_GetUTF8Text( Hud_GetChild( GetMenu( "ConnectWithPasswordMenu" ), "EnterPasswordBox" ) ) )
+} \ No newline at end of file
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_custom_match_settings.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_custom_match_settings.nut
new file mode 100644
index 00000000..d39b7774
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_custom_match_settings.nut
@@ -0,0 +1,140 @@
+global function AddNorthstarCustomMatchSettingsMenu
+global function SetNextMatchSettingsCategory
+
+const string SETTING_ITEM_TEXT = " " // this is long enough to be the same size as the textentry field
+
+struct {
+ string currentCategory
+
+ table< int, int > enumRealValues
+} file
+
+void function AddNorthstarCustomMatchSettingsMenu()
+{
+ AddMenu( "CustomMatchSettingsMenu", $"resource/ui/menus/custom_match_settings.menu", InitNorthstarCustomMatchSettingsMenu, "#MENU_MATCH_SETTINGS" )
+}
+
+void function SetNextMatchSettingsCategory( string category )
+{
+ file.currentCategory = category
+ print( "Category: " + category )
+
+ file.enumRealValues.clear()
+}
+
+void function InitNorthstarCustomMatchSettingsMenu()
+{
+ AddMenuEventHandler( GetMenu( "CustomMatchSettingsMenu" ), eUIEvent.MENU_OPEN, OnNorthstarCustomMatchSettingsMenuOpened )
+ AddMenuFooterOption( GetMenu( "CustomMatchSettingsMenu" ), BUTTON_B, "#B_BUTTON_BACK", "#BACK" )
+
+ foreach ( var button in GetElementsByClassname( GetMenu( "CustomMatchSettingsMenu" ), "MatchSettingButton" ) )
+ {
+ // it's not possible to clear dialoglists, so we have to hack together stuff that effectively recreates their functionality
+ Hud_DialogList_AddListItem( button, SETTING_ITEM_TEXT, "prev" )
+ Hud_DialogList_AddListItem( button, SETTING_ITEM_TEXT, "main" )
+ Hud_DialogList_AddListItem( button, SETTING_ITEM_TEXT, "next" )
+
+ AddButtonEventHandler( button, UIE_CHANGE, OnSettingButtonPressed )
+ }
+
+ foreach ( var textPanel in GetElementsByClassname( GetMenu( "CustomMatchSettingsMenu" ), "MatchSettingTextEntry" ) )
+ Hud_AddEventHandler( textPanel, UIE_LOSE_FOCUS, SendTextPanelChanges )
+}
+
+void function OnNorthstarCustomMatchSettingsMenuOpened()
+{
+ array<var> buttons = GetElementsByClassname( GetMenu( "CustomMatchSettingsMenu" ), "MatchSettingButton" )
+ array<var> textPanels = GetElementsByClassname( GetMenu( "CustomMatchSettingsMenu" ), "MatchSettingTextEntry" )
+
+ foreach ( var button in buttons )
+ {
+ Hud_SetEnabled( button, false )
+ Hud_SetVisible( button, false )
+ }
+
+ foreach ( var textPanel in textPanels )
+ {
+ Hud_SetEnabled( textPanel, false )
+ Hud_SetVisible( textPanel, false )
+ }
+
+ int i = 0;
+ foreach ( CustomMatchSettingContainer setting in GetPrivateMatchCustomSettingsForCategory( file.currentCategory ) )
+ {
+ Hud_SetEnabled( buttons[ i ], true )
+ Hud_SetVisible( buttons[ i ], true )
+ Hud_SetText( buttons[ i ], setting.localizedName )
+ Hud_SetDialogListSelectionValue( buttons[ i ], "main" )
+
+ Hud_SetEnabled( textPanels[ i ], true )
+ Hud_SetVisible( textPanels[ i ], true )
+
+ // manually resolve default gamemode/playlist vars since game won't do it for us if we aren't using GetCurrentPlaylistVar
+ string gamemode = PrivateMatch_GetSelectedMode()
+ if ( gamemode != "speedball" ) // hack since lf is weird
+ gamemode = GetPlaylistGamemodeByIndex( gamemode, 0 )
+
+ string gamemodeVar = GetGamemodeVarOrUseValue( PrivateMatch_GetSelectedMode(), setting.playlistVar, setting.defaultValue )
+ string playlistVar = GetPlaylistVarOrUseValue( PrivateMatch_GetSelectedMode(), setting.playlistVar, setting.defaultValue )
+
+ if ( playlistVar != gamemodeVar && playlistVar == setting.defaultValue )
+ playlistVar = gamemodeVar
+
+ if ( setting.isEnumSetting )
+ {
+ // setup internal state for enums
+ int enumIndex = int ( max( 0, setting.enumValues.find( playlistVar ) ) )
+
+ file.enumRealValues[ int( Hud_GetScriptID( textPanels[ i ] ) ) ] <- enumIndex
+ Hud_SetText( textPanels[ i ], setting.enumNames[ enumIndex ] )
+ }
+ else
+ Hud_SetText( textPanels[ i ], playlistVar )
+
+ i++
+ }
+}
+
+void function OnSettingButtonPressed( var button )
+{
+ CustomMatchSettingContainer setting = GetPrivateMatchCustomSettingsForCategory( file.currentCategory )[ int( Hud_GetScriptID( button ) ) ]
+ var textPanel = GetElementsByClassname( GetMenu( "CustomMatchSettingsMenu" ), "MatchSettingTextEntry" )[ int( Hud_GetScriptID( button ) ) ]
+
+ if ( setting.isEnumSetting )
+ {
+ string selectionVal = Hud_GetDialogListSelectionValue( button )
+ if ( selectionVal == "main" )
+ return
+
+ int enumVal = file.enumRealValues[ int( Hud_GetScriptID( button ) ) ]
+ if ( selectionVal == "next" ) // enum val += 1
+ enumVal = ( enumVal + 1 ) % setting.enumValues.len()
+ else // enum val -= 1
+ {
+ enumVal--
+ if ( enumVal == -1 )
+ enumVal = setting.enumValues.len() - 1
+ }
+
+ file.enumRealValues[ int( Hud_GetScriptID( button ) ) ] = enumVal
+ Hud_SetText( textPanel, setting.enumNames[ enumVal ] )
+
+ ClientCommand( "PrivateMatchSetPlaylistVarOverride " + setting.playlistVar + " " + setting.enumValues[ enumVal ] )
+ }
+ else
+ {
+ // this doesn't work for some reason
+ Hud_SetFocused( textPanel )
+ }
+
+ Hud_SetDialogListSelectionValue( button, "main" )
+}
+
+void function SendTextPanelChanges( var textPanel )
+{
+ CustomMatchSettingContainer setting = GetPrivateMatchCustomSettingsForCategory( file.currentCategory )[ int( Hud_GetScriptID( textPanel ) ) ]
+
+ // enums don't need to do this
+ if ( !setting.isEnumSetting )
+ ClientCommand( "PrivateMatchSetPlaylistVarOverride " + setting.playlistVar + " " + Hud_GetUTF8Text( textPanel ) )
+} \ No newline at end of file
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_custom_match_settings_categories.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_custom_match_settings_categories.nut
new file mode 100644
index 00000000..711cbbbc
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_custom_match_settings_categories.nut
@@ -0,0 +1,68 @@
+global function AddNorthstarCustomMatchSettingsCategoryMenu
+
+void function AddNorthstarCustomMatchSettingsCategoryMenu()
+{
+ AddMenu( "CustomMatchSettingsCategoryMenu", $"resource/ui/menus/custom_match_settings_categories.menu", InitNorthstarCustomMatchSettingsCategoryMenu, "#MENU_MATCH_SETTINGS" )
+}
+
+void function InitNorthstarCustomMatchSettingsCategoryMenu()
+{
+ AddMenuEventHandler( GetMenu( "CustomMatchSettingsCategoryMenu" ), eUIEvent.MENU_OPEN, OnNorthstarCustomMatchSettingsCategoryMenuOpened )
+ AddMenuFooterOption( GetMenu( "CustomMatchSettingsCategoryMenu" ), BUTTON_B, "#B_BUTTON_BACK", "#BACK" )
+ AddMenuFooterOption( GetMenu( "CustomMatchSettingsCategoryMenu" ), BUTTON_Y, "#Y_BUTTON_RESTORE_DEFAULTS", "#RESTORE_DEFAULTS", ResetMatchSettingsToDefault )
+
+ foreach ( var button in GetElementsByClassname( GetMenu( "CustomMatchSettingsCategoryMenu" ), "MatchSettingCategoryButton" ) )
+ {
+ AddButtonEventHandler( button, UIE_CLICK, SelectPrivateMatchSettingsCategory )
+
+ Hud_SetEnabled( button, false )
+ Hud_SetVisible( button, false )
+ }
+}
+
+void function OnNorthstarCustomMatchSettingsCategoryMenuOpened()
+{
+ array<string> categories = GetPrivateMatchSettingCategories()
+ array<var> buttons = GetElementsByClassname( GetMenu( "CustomMatchSettingsCategoryMenu" ), "MatchSettingCategoryButton" )
+
+ for ( int i = 0, j = 0; j < categories.len() && i < buttons.len(); i++, j++ )
+ {
+ Hud_SetEnabled( buttons[ i ], false )
+ Hud_SetVisible( buttons[ i ], false )
+
+ // skip gamemode/playlist categories for modes that aren't the current one
+ // todo this fucking breaks everything lmao
+ //bool gamemode = categories[ j ].find( "#GAMEMODE_" ) == 0
+ //if ( gamemode || categories[ j ].find( "#PL_" ) == 0 )
+ //{
+ // if ( gamemode )
+ // {
+ // if ( categories[ j ].slice( 10 ) != PrivateMatch_GetSelectedMode() )
+ // {
+ // i--
+ // continue
+ // }
+ // }
+ // else if ( categories[ j ].slice( 4 ) != PrivateMatch_GetSelectedMode() )
+ // {
+ // i--
+ // continue
+ // }
+ //}
+
+ Hud_SetText( buttons[ i ], Localize( categories[ j ] ) + " ->" )
+ Hud_SetEnabled( buttons[ i ], true )
+ Hud_SetVisible( buttons[ i ], true )
+ }
+}
+
+void function SelectPrivateMatchSettingsCategory( var button )
+{
+ SetNextMatchSettingsCategory( GetPrivateMatchSettingCategories()[ int( Hud_GetScriptID( button ) ) ] )
+ AdvanceMenu( GetMenu( "CustomMatchSettingsMenu" ) )
+}
+
+void function ResetMatchSettingsToDefault( var button )
+{
+ ClientCommand( "ResetMatchSettingsToDefault" )
+} \ No newline at end of file
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut
new file mode 100644
index 00000000..4a56891e
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut
@@ -0,0 +1,108 @@
+global function AddNorthstarModMenu
+global function AddNorthstarModMenu_MainMenuFooter
+
+void function AddNorthstarModMenu()
+{
+ AddMenu( "ModListMenu", $"resource/ui/menus/modlist.menu", InitModMenu )
+}
+
+void function AddNorthstarModMenu_MainMenuFooter()
+{
+ AddMenuFooterOption( GetMenu( "MainMenu" ), BUTTON_Y, "#Y_MENU_TITLE_MODS", "#MENU_TITLE_MODS", AdvanceToModListMenu )
+}
+
+void function AdvanceToModListMenu( var button )
+{
+ AdvanceMenu( GetMenu( "ModListMenu" ) )
+}
+
+void function InitModMenu()
+{
+ var menu = GetMenu( "ModListMenu" )
+
+ AddMenuEventHandler( menu, eUIEvent.MENU_OPEN, OnModMenuOpened )
+ AddMenuFooterOption( menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" )
+ AddMenuFooterOption( menu, BUTTON_Y, "#Y_RELOAD_MODS", "#RELOAD_MODS", ReloadMods )
+
+ foreach ( var button in GetElementsByClassname( GetMenu( "ModListMenu" ), "ModButton" ) )
+ AddButtonEventHandler( button, UIE_GET_FOCUS, OnModMenuButtonFocused )
+}
+
+void function OnModMenuOpened()
+{
+ Hud_SetText( Hud_GetChild( GetMenu( "ModListMenu" ), "Title" ), "#MENU_TITLE_MODS" )
+
+ array<var> buttons = GetElementsByClassname( GetMenu( "ModListMenu" ), "ModButton" )
+
+ // disable all buttons, we'll enable the ones we need later
+ foreach ( var button in buttons )
+ {
+ Hud_SetEnabled( button, false )
+ Hud_SetVisible( button, false )
+ }
+
+ array<string> modNames = NSGetModNames()
+ for ( int i = 0; i < modNames.len() && i < buttons.len(); i++ )
+ {
+ Hud_SetEnabled( buttons[ i ], true )
+ Hud_SetVisible( buttons[ i ], true )
+
+ SetButtonRuiText( buttons[ i ], modNames[ i ] + " v" + NSGetModVersionByModName( modNames[ i ] ) )
+ }
+}
+
+void function OnModMenuButtonFocused( var button )
+{
+ string modName = NSGetModNames()[ int ( Hud_GetScriptID( button ) ) ]
+
+ var rui = Hud_GetRui( Hud_GetChild( GetMenu( "ModListMenu" ), "LabelDetails" ) )
+
+ RuiSetGameTime( rui, "startTime", -99999.99 ) // make sure it skips the whole animation for showing this
+ RuiSetString( rui, "headerText", modName )
+ RuiSetString( rui, "messageText", FormatModDescription( modName ) )
+}
+
+string function FormatModDescription( string modName )
+{
+ string ret
+ // version
+ ret += format( "Version %s\n", NSGetModVersionByModName( modName ) )
+
+ // download link
+ string modLink = NSGetModDownloadLinkByModName( modName )
+ if ( modLink.len() != 0 )
+ ret += format( "Download link: \"%s\"\n", modLink )
+
+ // load priority
+ ret += format( "Load Priority: %i\n", NSGetModLoadPriority( modName ) )
+
+ // todo: add ClientRequired here
+
+ // convars
+ array<string> modCvars = NSGetModConvarsByModName( modName )
+ if ( modCvars.len() != 0 )
+ {
+ ret += "ConVars: "
+
+ for ( int i = 0; i < modCvars.len(); i++ )
+ {
+ if ( i != modCvars.len() - 1 )
+ ret += format( "\"%s\", ", modCvars[ i ] )
+ else
+ ret += format( "\"%s\"", modCvars[ i ] )
+ }
+
+ ret += "\n"
+ }
+
+ // description
+ ret += format( "\n%s\n", NSGetModDescriptionByModName( modName ) )
+
+ return ret
+}
+
+void function ReloadMods( var button )
+{
+ NSReloadMods()
+ OnModMenuOpened() // temp, until we start doing uiscript_reset here
+} \ No newline at end of file
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut
new file mode 100644
index 00000000..bbeb0d0b
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut
@@ -0,0 +1,198 @@
+global function AddNorthstarServerBrowserMenu
+global function ThreadedAuthAndConnectToServer
+
+const int BUTTONS_PER_PAGE = 15
+
+struct {
+ int page = 0
+ int lastSelectedServer = 0
+} file
+
+void function AddNorthstarServerBrowserMenu()
+{
+ AddMenu( "ServerBrowserMenu", $"resource/ui/menus/server_browser.menu", InitServerBrowserMenu, "#MENU_SERVER_BROWSER" )
+}
+
+void function InitServerBrowserMenu()
+{
+ AddMenuEventHandler( GetMenu( "ServerBrowserMenu" ), eUIEvent.MENU_OPEN, OnServerBrowserMenuOpened )
+ AddMenuFooterOption( GetMenu( "ServerBrowserMenu" ), BUTTON_B, "#B_BUTTON_BACK", "#BACK" )
+ AddMenuFooterOption( GetMenu( "ServerBrowserMenu" ), BUTTON_Y, "#Y_REFRESH_SERVERS", "#REFRESH_SERVERS", RefreshServers )
+
+ foreach ( var button in GetElementsByClassname( GetMenu( "ServerBrowserMenu" ), "ServerButton" ) )
+ {
+ AddButtonEventHandler( button, UIE_GET_FOCUS, OnServerFocused )
+ AddButtonEventHandler( button, UIE_CLICK, OnServerSelected )
+ }
+}
+
+void function OnServerBrowserMenuOpened()
+{
+ Hud_SetText( Hud_GetChild( GetMenu( "ServerBrowserMenu" ), "Title" ), "#MENU_TITLE_SERVER_BROWSER" )
+ UI_SetPresentationType( ePresentationType.KNOWLEDGEBASE_MAIN )
+
+ file.page = 0
+ // dont rerequest if we came from the connect menu
+ if ( !NSIsRequestingServerList() && uiGlobal.lastMenuNavDirection != MENU_NAV_BACK )
+ {
+ NSClearRecievedServerList()
+ NSRequestServerList()
+ }
+
+ thread WaitForServerListRequest()
+}
+
+void function RefreshServers( var button )
+{
+ if ( NSIsRequestingServerList() )
+ return
+
+ NSClearRecievedServerList()
+ NSRequestServerList()
+
+ thread WaitForServerListRequest()
+}
+
+void function WaitForServerListRequest()
+{
+ var menu = GetMenu( "ServerBrowserMenu" )
+ array<var> serverButtons = GetElementsByClassname( menu, "ServerButton" )
+ foreach ( var button in serverButtons )
+ {
+ Hud_SetEnabled( button, false )
+ Hud_SetVisible( button, false )
+ }
+
+ Hud_SetVisible( Hud_GetChild( menu, "LabelDetails" ), false )
+ Hud_SetVisible( Hud_GetChild( menu, "NextMapImage" ), false )
+ Hud_SetVisible( Hud_GetChild( menu, "NextMapName" ), false )
+ Hud_SetVisible( Hud_GetChild( menu, "NextModeIcon" ), false )
+ Hud_SetVisible( Hud_GetChild( menu, "NextGameModeName" ), false )
+
+ Hud_SetEnabled( serverButtons[ 0 ], true )
+ Hud_SetVisible( serverButtons[ 0 ], true )
+
+ SetButtonRuiText( serverButtons[ 0 ], "#NS_SERVERBROWSER_WAITINGFORSERVERS" )
+
+ // wait for request to complete
+ while ( NSIsRequestingServerList() )
+ WaitFrame()
+
+ if ( !NSMasterServerConnectionSuccessful() )
+ SetButtonRuiText( serverButtons[ 0 ], "#NS_SERVERBROWSER_CONNECTIONFAILED" )
+ else
+ UpdateShownPage()
+}
+
+void function UpdateShownPage()
+{
+ var menu = GetMenu( "ServerBrowserMenu" )
+
+ // hide old ui elements
+ array<var> serverButtons = GetElementsByClassname( menu, "ServerButton" )
+ foreach ( var button in serverButtons )
+ {
+ Hud_SetEnabled( button, false )
+ Hud_SetVisible( button, false )
+ }
+
+ Hud_SetFocused( serverButtons[ serverButtons.len() - 1 ] )
+
+ Hud_SetVisible( Hud_GetChild( menu, "LabelDetails" ), false )
+ Hud_SetVisible( Hud_GetChild( menu, "NextMapImage" ), false )
+ Hud_SetVisible( Hud_GetChild( menu, "NextMapName" ), false )
+ Hud_SetVisible( Hud_GetChild( menu, "NextModeIcon" ), false )
+ Hud_SetVisible( Hud_GetChild( menu, "NextGameModeName" ), false )
+
+ for ( int i = 0; i < NSGetServerCount() && i < serverButtons.len(); i++ )
+ {
+ int serverIndex = file.page * BUTTONS_PER_PAGE + i
+
+ Hud_SetEnabled( serverButtons[ i ], true )
+ Hud_SetVisible( serverButtons[ i ], true )
+ SetButtonRuiText( serverButtons[ i ], NSGetServerName( serverIndex ) )
+ }
+
+ if ( NSGetServerCount() == 0 )
+ {
+ Hud_SetEnabled( serverButtons[ 0 ], true )
+ Hud_SetVisible( serverButtons[ 0 ], true )
+ SetButtonRuiText( serverButtons[ 0 ], "#NS_SERVERBROWSER_NOSERVERS" )
+ }
+}
+
+void function OnServerFocused( var button )
+{
+ if ( NSIsRequestingServerList() || !NSMasterServerConnectionSuccessful() || NSGetServerCount() == 0 )
+ return
+
+ var menu = GetMenu( "ServerBrowserMenu" )
+ int serverIndex = file.page * BUTTONS_PER_PAGE + int ( Hud_GetScriptID( button ) )
+
+ // text panel
+ Hud_SetVisible( Hud_GetChild( menu, "LabelDetails" ), true )
+ var textRui = Hud_GetRui( Hud_GetChild( menu, "LabelDetails" ) )
+ RuiSetGameTime( textRui, "startTime", -99999.99 ) // make sure it skips the whole animation for showing this
+ RuiSetString( textRui, "messageText", FormatServerDescription( serverIndex ) )
+
+ // map name/image
+ string map = NSGetServerMap( serverIndex )
+ Hud_SetVisible( Hud_GetChild( menu, "NextMapImage" ), true )
+ RuiSetImage( Hud_GetRui( Hud_GetChild( menu, "NextMapImage" ) ), "basicImage", GetMapImageForMapName( map ) )
+ Hud_SetVisible( Hud_GetChild( menu, "NextMapName" ), true )
+ Hud_SetText( Hud_GetChild( menu, "NextMapName" ), GetMapDisplayName( map ) )
+
+ // mode name/image
+ string mode = NSGetServerPlaylist( serverIndex )
+ Hud_SetVisible( Hud_GetChild( menu, "NextModeIcon" ), true )
+ RuiSetImage( Hud_GetRui( Hud_GetChild( menu, "NextModeIcon" ) ), "basicImage", GetPlaylistThumbnailImage( mode ) )
+ Hud_SetVisible( Hud_GetChild( menu, "NextGameModeName" ), true )
+
+ string displayName = GetGameModeDisplayName( mode )
+ if ( displayName.len() != 0 )
+ Hud_SetText( Hud_GetChild( menu, "NextGameModeName" ), displayName )
+ else
+ Hud_SetText( Hud_GetChild( menu, "NextGameModeName" ), "#NS_SERVERBROWSER_UNKNOWNMODE" )
+}
+
+string function FormatServerDescription( int server )
+{
+ string ret = "\n\n\n\n"
+
+ ret += NSGetServerName( server ) + "\n"
+ ret += format( "%i/%i players\n", NSGetServerPlayerCount( server ), NSGetServerMaxPlayerCount( server ) )
+ ret += NSGetServerDescription( server ) + "\n"
+
+ return ret
+}
+
+void function OnServerSelected( var button )
+{
+ if ( NSIsRequestingServerList() || !NSMasterServerConnectionSuccessful() )
+ return
+
+ var menu = GetMenu( "ServerBrowserMenu" )
+ int serverIndex = file.page * BUTTONS_PER_PAGE + int ( Hud_GetScriptID( button ) )
+
+ file.lastSelectedServer = serverIndex
+
+ if ( NSServerRequiresPassword( serverIndex ) )
+ AdvanceMenu( GetMenu( "ConnectWithPasswordMenu" ) )
+ else
+ thread ThreadedAuthAndConnectToServer()
+}
+
+void function ThreadedAuthAndConnectToServer( string password = "" )
+{
+ if ( NSIsAuthenticatingWithServer() )
+ return
+
+ print( "trying to authenticate with server " + NSGetServerName( file.lastSelectedServer ) + " with password " + password )
+ NSTryAuthWithServer( file.lastSelectedServer, password )
+
+ while ( NSIsAuthenticatingWithServer() )
+ WaitFrame()
+
+ if ( NSWasAuthSuccessful() )
+ NSConnectToAuthedServer()
+} \ No newline at end of file
diff --git a/Northstar.Client/scripts/vscripts/ui/menu_private_match.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_private_match.nut
index 46599135..b1da22ee 100644
--- a/Northstar.Client/scripts/vscripts/ui/menu_private_match.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_private_match.nut
@@ -224,7 +224,10 @@ void function OnSelectMatchSettings_Activate( var button )
if ( Hud_IsLocked( button ) )
return
- AdvanceMenu( GetMenu( "MatchSettingsMenu" ) )
+ if ( !IsNorthstarServer() )
+ AdvanceMenu( GetMenu( "MatchSettingsMenu" ) )
+ else
+ AdvanceMenu( GetMenu( "CustomMatchSettingsCategoryMenu" ) )
}
void function SetupComboButtons( var menu, var navUpButton, var navDownButton )
@@ -616,13 +619,35 @@ function UpdateLobby()
{
float varOrigVal = float( GetCurrentPlaylistGamemodeByIndexVar( gamemodeIdx, varName, false ) )
float varOverrideVal = float( GetCurrentPlaylistGamemodeByIndexVar( gamemodeIdx, varName, true ) )
- if ( varOrigVal == varOverrideVal )
+ if ( varOrigVal == varOverrideVal && !IsNorthstarServer() ) // stuff seems to break outside of northstar servers since we dont always use private_match playlist
continue
string label = Localize( MatchSettings_PlaylistVarLabels[varName] ) + ": "
string value = MatchSettings_FormatPlaylistVarValue( varName, varOverrideVal )
playlistOverridesDesc = playlistOverridesDesc + label + "`2" + value + " `0\n"
}
+ else
+ {
+ foreach ( string category in GetPrivateMatchSettingCategories() )
+ {
+ foreach ( CustomMatchSettingContainer setting in GetPrivateMatchCustomSettingsForCategory( category ) )
+ {
+ if ( setting.playlistVar == varName )
+ {
+ if ( setting.isEnumSetting )
+ {
+ playlistOverridesDesc += Localize( setting.localizedName ) + ": `2" + setting.enumNames[ setting.enumValues.find( expect string ( GetCurrentPlaylistVar( varName ) ) ) ] + "`0\n"
+ }
+ else
+ playlistOverridesDesc += Localize( setting.localizedName ) + ": `2" + GetCurrentPlaylistVar( varName ) + "`0\n"
+
+ break
+ }
+ }
+ }
+
+ // sorta temp: ideally wanna localise playlist var names in the future
+ }
}
if ( playlistOverridesDesc.len() )
diff --git a/Northstar.Client/scripts/vscripts/ui/panel_mainmenu.nut b/Northstar.Client/mod/scripts/vscripts/ui/panel_mainmenu.nut
index f68c9c12..acd11237 100644
--- a/Northstar.Client/scripts/vscripts/ui/panel_mainmenu.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/panel_mainmenu.nut
@@ -505,12 +505,26 @@ void function OnPlayFDButton_Activate( var button ) // repurposed for launching
//// Lobby_SetFDMode( true )
//thread file.mpButtonActivateFunc()
- ClientCommand( "everything_unlocked 1" ) // todo super temp, need this removed when server autoexecs are good
- ClientCommand( "setplaylist tdm" )
- ClientCommand( "map mp_lobby" )
+ //ClientCommand( "setplaylist tdm" )
+ //ClientCommand( "map mp_lobby" )
+
+ NSTryAuthWithLocalServer()
+ thread TryAuthWithLocalServer()
}
}
+void function TryAuthWithLocalServer()
+{
+ while ( NSIsAuthenticatingWithServer() )
+ WaitFrame()
+
+ if ( NSWasAuthSuccessful() )
+ NSCompleteAuthWithLocalServer()
+
+ ClientCommand( "setplaylist tdm" )
+ ClientCommand( "map mp_lobby" )
+}
+
void function OnPlayMPButton_Activate( var button )
{
if ( file.mpButtonActivateFunc == null )
diff --git a/Northstar.Client/scripts/vscripts/ui/ui_utility.gnut b/Northstar.Client/mod/scripts/vscripts/ui/ui_utility.gnut
index 02d77795..02d77795 100644
--- a/Northstar.Client/scripts/vscripts/ui/ui_utility.gnut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/ui_utility.gnut
diff --git a/Northstar.Client/scripts/vscripts/ui/_menus.nut b/Northstar.Client/scripts/vscripts/ui/_menus.nut
deleted file mode 100644
index ffae9a30..00000000
--- a/Northstar.Client/scripts/vscripts/ui/_menus.nut
+++ /dev/null
@@ -1,2010 +0,0 @@
-untyped
-
-global const bool EDIT_LOADOUT_SELECTS = true
-global const string PURCHASE_SUCCESS_SOUND = "UI_Menu_Store_Purchase_Success"
-
-global function UICodeCallback_CloseAllMenus
-global function UICodeCallback_ActivateMenus
-global function UICodeCallback_LevelInit
-global function UICodeCallback_LevelLoadingStarted
-global function UICodeCallback_LevelLoadingFinished
-global function UICodeCallback_LevelShutdown
-global function UICodeCallback_OnConnected
-global function UICodeCallback_OnFocusChanged
-global function UICodeCallback_NavigateBack
-global function UICodeCallback_ToggleInGameMenu
-global function UICodeCallback_TryCloseDialog
-global function UICodeCallback_UpdateLoadingLevelName
-global function UICodeCallback_ConsoleKeyboardClosed
-global function UICodeCallback_ErrorDialog
-global function UICodeCallback_AcceptInvite
-global function UICodeCallback_OnDetenteDisplayed
-global function UICodeCallback_OnSpLogDisplayed
-global function UICodeCallback_EntitlementsChanged
-global function UICodeCallback_StoreTransactionCompleted
-global function UICodeCallback_GamePurchased
-global function UICodeCallback_PartyUpdated
-global function UICodeCallback_KeyBindOverwritten
-
-global function AdvanceMenu
-global function OpenSubmenu // REMOVE
-global function CloseSubmenu // REMOVE
-global function CloseActiveMenu
-global function CloseActiveMenuNoParms
-global function CloseAllMenus
-global function CloseAllInGameMenus
-global function CloseAllDialogs
-global function CloseAllToTargetMenu
-global function PrintMenuStack
-global function CleanupInGameMenus
-global function GetActiveMenu
-global function GetMenu
-global function GetPanel
-global function GetAllMenuPanels
-global function InitGamepadConfigs
-global function InitMenus
-global function AdvanceMenuEventHandler
-global function PCSwitchTeamsButton_Activate
-global function PCToggleSpectateButton_Activate
-global function AddMenuElementsByClassname
-global function FocusDefault
-global function SetPanelDefaultFocus
-global function PanelFocusDefault
-global function OpenMenuWrapper
-global function CloseMenuWrapper
-global function IsLevelMultiplayer
-global function AddMenuEventHandler
-global function AddPanelEventHandler
-global function AddButtonEventHandler
-global function AddEventHandlerToButton
-global function AddEventHandlerToButtonClass
-global function DisableMusic
-global function EnableMusic
-global function PlayMusic
-global function StopMusic
-global function IsMenuInMenuStack
-global function GetTopNonDialogMenu
-global function IsDialog
-global function IsDialogActive
-global function IsDialogOnlyActiveMenu
-global function SetNavUpDown
-global function SetNavLeftRight
-global function IsTrialPeriodActive
-global function LaunchGamePurchaseOrDLCStore
-global function SetMenuThinkFunc
-
-global function PCBackButton_Activate
-
-global function RegisterMenuVarInt
-global function GetMenuVarInt
-global function SetMenuVarInt
-global function RegisterMenuVarBool
-global function GetMenuVarBool
-global function SetMenuVarBool
-global function RegisterMenuVarVar
-global function GetMenuVarVar
-global function SetMenuVarVar
-global function AddMenuVarChangeHandler
-
-global function InviteFriends
-
-global function HACK_DelayedSetFocus_BecauseWhy
-
-#if DURANGO_PROG
- global function OpenXboxPartyApp
- global function OpenXboxHelp
-#endif // DURANGO_PROG
-
-global function OpenReviewTermsDialog
-global function ClassicMusic_OnChange
-global function IsClassicMusicAvailable
-
-
-void function UICodeCallback_CloseAllMenus()
-{
- printt( "UICodeCallback_CloseAllMenus" )
- CloseAllMenus()
- // This is usually followed by a call to UICodeCallback_ActivateMenus().
-}
-
-// Bringing up the console will cause this, and it probably shouldn't
-void function UICodeCallback_ActivateMenus()
-{
- if ( IsConnected() )
- return
-
- printt( "UICodeCallback_ActivateMenus:", uiGlobal.activeMenu && Hud_GetHudName( uiGlobal.activeMenu ) )
-
- if ( uiGlobal.menuStack.len() == 0 )
- {
- AdvanceMenu( GetMenu( "MainMenu" ) )
- }
-
- if ( uiGlobal.activeMenu == GetMenu( "MainMenu" ) )
- Signal( uiGlobal.signalDummy, "OpenErrorDialog" )
-
- PlayMusic()
-
- #if DURANGO_PROG
- Durango_LeaveParty()
- #endif // DURANGO_PROG
-}
-
-void function UICodeCallback_ToggleInGameMenu()
-{
- if ( !IsFullyConnected() )
- return
-
- var activeMenu = uiGlobal.activeMenu
- bool isMP = IsLevelMultiplayer( GetActiveLevel() )
- bool isLobby = IsLobby()
-
- var ingameMenu
- if ( isMP )
- {
- ingameMenu = GetMenu( "InGameMPMenu" )
- }
- else
- {
- // Disable this callback for this special case menu so players can't skip it.
- var spTitanTutorialMenu = GetMenu( "SPTitanLoadoutTutorialMenu" )
- if ( activeMenu == spTitanTutorialMenu )
- return
-
- ingameMenu = GetMenu( "InGameSPMenu" )
- }
-
- if ( IsDialog( uiGlobal.activeMenu ) )
- {
- // Do nothing if a dialog is showing
- }
- else if ( TeamTitanSelectMenuIsOpen() )
- {
- if ( uiGlobal.activeMenu == GetMenu( "TeamTitanSelectMenu" ) )
- {
- // Do nothing here either
- }
- else
- {
- CloseActiveMenu()
- }
- }
- else if ( ( isMP && !isLobby ) || !isMP )
- {
- if ( !activeMenu )
- AdvanceMenu( ingameMenu )
- else
- CloseAllInGameMenus()
- }
-}
-
-// Return true to show load screen, false to not show load screen.
-// levelname can be "" because the level to load isn't always known when the load screen starts
-bool function UICodeCallback_LevelLoadingStarted( string levelname )
-{
- printt( "UICodeCallback_LevelLoadingStarted: " + levelname )
-
- CloseAllDialogs()
-
- uiGlobal.loadingLevel = levelname
-
- StopMusic()
-
- if ( uiGlobal.playingVideo )
- Signal( uiGlobal.signalDummy, "PlayVideoEnded" )
-
- if ( uiGlobal.playingCredits )
- Signal( uiGlobal.signalDummy, "PlayingCreditsDone" )
-
- // kill lingering postgame summary since persistent data may not be available at this point
- Signal( uiGlobal.signalDummy, "PGDisplay" )
-
-#if CONSOLE_PROG
- if ( !Console_IsSignedIn() )
- return false
-#endif
-
- return true
-}
-
-// Return true to show load screen, false to not show load screen.
-bool function UICodeCallback_UpdateLoadingLevelName( string levelname )
-{
- printt( "UICodeCallback_UpdateLoadingLevelName: " + levelname )
-
-#if CONSOLE_PROG
- if ( !Console_IsSignedIn() )
- return false
-#endif
-
- return true
-}
-
-void function UICodeCallback_LevelLoadingFinished( bool error )
-{
- printt( "UICodeCallback_LevelLoadingFinished: " + uiGlobal.loadingLevel + " (" + error + ")" )
-
- if ( !IsLobby() )
- {
- HudChat_ClearTextFromAllChatPanels()
- ResetActiveChatroomLastModified()
- }
- else
- {
- uiGlobal.lobbyFromLoadingScreen = true
- }
-
- uiGlobal.loadingLevel = ""
- Signal( uiGlobal.signalDummy, "LevelFinishedLoading" )
-}
-
-void function UICodeCallback_LevelInit( string levelname )
-{
- Assert( IsConnected() )
-
- StopVideo()
-
- uiGlobal.loadedLevel = levelname
-
- printt( "UICodeCallback_LevelInit: " + uiGlobal.loadedLevel )
-
- if ( !uiGlobal.loadoutsInitialized )
- {
- string gameModeString = GetConVarString( "mp_gamemode" )
- if ( gameModeString != "solo" )
- {
- InitStatsTables()
- }
- }
-
- InitItems()
-
- if ( IsMultiplayer() )
- {
- ShWeaponXP_Init()
- ShTitanXP_Init()
- ShFactionXP_Init()
- }
- else
- {
- SPObjectiveStringsInit()
- }
-
- #if DEV
- UpdatePrecachedSPWeapons()
- #endif
-
-
- if ( !uiGlobal.loadoutsInitialized )
- {
- string gameModeString = GetConVarString( "mp_gamemode" )
- if ( gameModeString != "solo" )
- {
- DeathHints_Init()
- InitDefaultLoadouts()
- CreateChallenges()
- uiGlobal.loadoutsInitialized = true
- }
- }
-
- if ( IsLevelMultiplayer( levelname ) || IsLobbyMapName( levelname ) )
- {
- thread UpdateCachedLoadouts()
- thread UpdateCachedNewItems()
- thread InitUISpawnLoadoutIndexes()
-
- if ( !uiGlobal.eventHandlersAdded )
- {
- uiGlobal.eventHandlersAdded = true
- }
-
- UI_GetAllChallengesProgress()
-
- bool isLobby = IsLobbyMapName( levelname )
-
- string gameModeString = GetConVarString( "mp_gamemode" )
- if ( gameModeString == "" )
- gameModeString = "<null>"
-
- Assert( gameModeString == GetConVarString( "mp_gamemode" ) )
- Assert( gameModeString != "" )
-
- int gameModeId = GameMode_GetGameModeId( gameModeString )
-
- int mapId = eMaps.invalid
- if ( levelname in getconsttable().eMaps )
- {
- mapId = expect int( getconsttable().eMaps[ levelname ] )
- }
- else
- {
- // Don't worry about this until we have to consider R2 Durango TCRs (10/2015)
- //if ( !IsTestMap() )
- // CodeWarning( "No map named '" + levelname + "' exists in eMaps, all shipping maps should be in this enum" )
- }
-
- int difficultyLevelId = 0
- int roundId = 0
-
- if ( isLobby )
- Durango_OnLobbySessionStart( gameModeId, difficultyLevelId )
- else
- Durango_OnMultiplayerRoundStart( gameModeId, mapId, difficultyLevelId, roundId, 0 )
- }
- else
- {
- // SP loadout stuff
- UI_GetAllChallengesProgress() // TODO: Can this be moved so we don't call it twice? It's called above.
-
- SP_ResetObjectiveStringIndex() // Since this persists thru level load, we need to explicitely clear it.
- }
-
- if ( IsMultiplayer() )
- {
- foreach ( callbackFunc in uiGlobal.onLevelInitCallbacks )
- {
- thread callbackFunc()
- }
-
- }
- thread UpdateMenusOnConnect( levelname )
-
- uiGlobal.previousLevel = uiGlobal.loadedLevel
- uiGlobal.previousPlaylist = GetCurrentPlaylistName()
-}
-
-void function UICodeCallback_LevelShutdown()
-{
- Signal( uiGlobal.signalDummy, "LevelShutdown" )
-
- printt( "UICodeCallback_LevelShutdown: " + uiGlobal.loadedLevel )
-
- StopVideo()
-
- if ( uiGlobal.loadedLevel != "" )
- CleanupInGameMenus()
-
- uiGlobal.loadedLevel = ""
- uiGlobal.mapSupportsMenuModelsUpdated = false
- uiGlobal.sp_showAlternateMissionLog = false
-}
-
-void function UICodeCallback_NavigateBack()
-{
- if ( uiGlobal.activeMenu == null )
- return
-
- if ( IsDialog( uiGlobal.activeMenu ) )
- {
- if ( uiGlobal.menuData[ uiGlobal.activeMenu ].dialogData.noChoice ||
- uiGlobal.menuData[ uiGlobal.activeMenu ].dialogData.forceChoice ||
- Time() < uiGlobal.dialogInputEnableTime )
- return
- }
-
- Assert( uiGlobal.activeMenu in uiGlobal.menuData )
- if ( uiGlobal.menuData[ uiGlobal.activeMenu ].navBackFunc != null )
- {
- thread uiGlobal.menuData[ uiGlobal.activeMenu ].navBackFunc()
- return
- }
-
- if ( uiGlobal.activeMenu.GetType() == "submenu" ) // REMOVE
- {
- CloseSubmenu()
- return
- }
-
- CloseActiveMenu( true )
-}
-
-// Called when IsConnected() will start returning true.
-void function UICodeCallback_OnConnected()
-{
-
-}
-
-void function UICodeCallback_OnFocusChanged( var oldFocusedPanel, var newFocusedPanel )
-{
-
-}
-
-// Accepting an origin invite closes dialogs, or aborts if they can't be closed
-bool function UICodeCallback_TryCloseDialog()
-{
- if ( !IsDialog( uiGlobal.activeMenu ) )
- return true
-
- if ( uiGlobal.menuData[ uiGlobal.activeMenu ].dialogData.forceChoice )
- return false
-
- CloseAllDialogs()
- Assert( !IsDialog( uiGlobal.activeMenu ) )
- return true
-}
-
-void function UICodeCallback_ConsoleKeyboardClosed()
-{
- switch ( uiGlobal.activeMenu )
- {
- case GetMenu( "EditPilotLoadoutMenu" ):
- string oldName = GetPilotLoadoutName( GetCachedPilotLoadout( uiGlobal.editingLoadoutIndex ) )
- string newName = GetPilotLoadoutRenameText()
-
- // strip doesn't work on UTF-8 strings
- // newName = strip( newName ) // Remove leading/trailing whitespace
- if ( newName == "" ) // If all whitespace entered reset to previous name
- newName = oldName
-
- SetPilotLoadoutName( newName )
- SelectPilotLoadoutRenameText()
- if ( newName != oldName )
- EmitUISound( "Menu.Accept" ) // No callback when cancelled so for now assume name was changed
- break
-
- default:
- break
- }
-}
-
-void function UICodeCallback_OnDetenteDisplayed()
-{
-// thread PlayDetentSound()
-//}
-//
-//void function PlayDetentSound()
-//{
-// WaitFrame() // otherwise gets killed off by code pause
-// WaitFrame() // otherwise gets killed off by code pause
-// EmitUISound( "Pilot_Killed_Indicator" )
-}
-
-void function UICodeCallback_OnSpLogDisplayed()
-{
-}
-
-void function UICodeCallback_ErrorDialog( string errorDetails )
-{
- printt( "UICodeCallback_ErrorDialog: " + errorDetails )
- thread OpenErrorDialog( errorDetails )
-}
-
-void function UICodeCallback_AcceptInviteThread( string accesstoken )
-{
- printt( "UICodeCallback_AcceptInviteThread '" + accesstoken + "'")
-
- #if PS4_PROG
- if ( !Ps4_PSN_Is_Loggedin() )
- {
- Ps4_LoginDialog_Schedule();
- while( Ps4_LoginDialog_Running() )
- WaitFrame()
- if ( !Ps4_PSN_Is_Loggedin() )
- return;
- }
-
- if( Ps4_CheckPlus_Schedule() )
- {
- while( Ps4_CheckPlus_Running() )
- WaitFrame()
- if( !Ps4_CheckPlus_Allowed() )
- {
- if( Ps4_CheckPlus_GetLastRequestResults() != 0 )
- {
- return
- }
-
- if( Ps4_ScreenPlusDialog_Schedule() )
- {
- while( Ps4_ScreenPlusDialog_Running() )
- WaitFrame()
- if( !Ps4_ScreenPlusDialog_Allowed() )
- return;
- }
- else
- {
- return;
- }
- }
- }
-
- #endif // #if PS4_PROG
-
- SubscribeToChatroomPartyChannel( accesstoken );
-
-}
-
-
-void function UICodeCallback_AcceptInvite( string accesstoken )
-{
- printt( "UICodeCallback_AcceptInvite '" + accesstoken + "'")
- thread UICodeCallback_AcceptInviteThread( accesstoken )
-}
-
-// TODO: replaceCurrent should not be an option. It should be a different function.
-void function AdvanceMenu( var menu, bool replaceCurrent = false )
-{
- //foreach ( index, menu in uiGlobal.menuStack )
- //{
- // if ( menu != null )
- // printt( "menu index " + index + " is named " + menu.GetDisplayName() )
- //}
-
- if ( uiGlobal.activeMenu )
- {
- // Don't open the same menu again if it's already open
- if ( uiGlobal.activeMenu == menu )
- return
-
- // Opening a normal menu while a dialog is open
- Assert( !IsDialog( uiGlobal.activeMenu ), "Tried opening menu: " + Hud_GetHudName( menu ) + " when uiGlobal.activeMenu was: " + Hud_GetHudName( uiGlobal.activeMenu ) )
- }
-
- if ( uiGlobal.activeMenu && !IsDialog( menu ) ) // Dialogs show on top so don't close existing menu when opening them
- {
- SetBlurEnabled( false )
-
- if ( replaceCurrent )
- {
- CloseMenuWrapper( uiGlobal.activeMenu )
- uiGlobal.menuStack.pop()
- }
- else
- {
- CloseMenu( uiGlobal.activeMenu )
- printt( Hud_GetHudName( uiGlobal.activeMenu ), "menu closed" )
- }
- }
-
- if ( IsDialog( menu ) && uiGlobal.activeMenu )
- SetFooterPanelVisibility( uiGlobal.activeMenu, false )
-
- uiGlobal.menuStack.push( menu )
- uiGlobal.activeMenu = menu
-
- uiGlobal.lastMenuNavDirection = MENU_NAV_FORWARD
-
- if ( uiGlobal.activeMenu )
- {
- if ( !IsLobby() && !uiGlobal.mapSupportsMenuModels )
- SetBlurEnabled( true )
-
- OpenMenuWrapper( uiGlobal.activeMenu, true )
- }
-
- Signal( uiGlobal.signalDummy, "ActiveMenuChanged" )
-}
-
-void function SetFooterPanelVisibility( var menu, bool visible )
-{
- if ( !Hud_HasChild( menu, "FooterButtons" ) )
- return
-
- var panel = Hud_GetChild( menu, "FooterButtons" )
- Hud_SetVisible( panel, visible )
-}
-
-void function OpenSubmenu( var menu, bool updateMenuPos = true )
-{
- Assert( menu )
- Assert( menu.GetType() == "submenu" )
-
- if ( uiGlobal.activeMenu )
- {
- // Don't open the same menu again if it's already open
- if ( uiGlobal.activeMenu == menu )
- return
- }
-
- local submenuPos = Hud_GetAbsPos( GetFocus() )
-
- uiGlobal.menuStack.push( menu )
- uiGlobal.activeMenu = menu
-
- OpenMenuWrapper( uiGlobal.activeMenu, true )
-
- if ( updateMenuPos )
- {
- var vguiButtonFrame = Hud_GetChild( uiGlobal.activeMenu, "ButtonFrame" )
- Hud_SetPos( vguiButtonFrame, submenuPos[0], submenuPos[1] )
- }
-
- uiGlobal.lastMenuNavDirection = MENU_NAV_FORWARD
-
- Signal( uiGlobal.signalDummy, "ActiveMenuChanged" )
-}
-
-void function CloseSubmenu( bool openStackMenu = true )
-{
- if ( !uiGlobal.activeMenu )
- return
-
- if ( uiGlobal.activeMenu.GetType() != "submenu" )
- return
-
- CloseMenuWrapper( uiGlobal.activeMenu )
- uiGlobal.menuStack.pop()
-
- uiGlobal.lastMenuNavDirection = MENU_NAV_FORWARD
-
- if ( uiGlobal.menuStack.len() )
- {
- uiGlobal.activeMenu = uiGlobal.menuStack.top()
-
- // This runs any OnOpen function for the menu and sets focus, but doesn't actually open the menu because it is already open
- if ( openStackMenu )
- OpenMenuWrapper( uiGlobal.activeMenu, false )
- }
- else
- {
- uiGlobal.activeMenu = null
- }
-
- Signal( uiGlobal.signalDummy, "ActiveMenuChanged" )
-}
-
-void function CloseActiveMenuNoParms()
-{
- CloseActiveMenu()
-}
-
-void function CloseActiveMenu( bool cancelled = false, bool openStackMenu = true )
-{
- bool updateBlur = true
- bool wasDialog = false
-
- if ( uiGlobal.activeMenu )
- {
- if ( IsDialog( uiGlobal.activeMenu ) )
- {
- updateBlur = false
- wasDialog = true
- uiGlobal.dialogInputEnableTime = 0.0
-
- if ( uiGlobal.dialogCloseCallback )
- {
- uiGlobal.dialogCloseCallback( cancelled )
- uiGlobal.dialogCloseCallback = null
- }
- }
-
- if ( updateBlur )
- SetBlurEnabled( false )
-
- CloseMenuWrapper( uiGlobal.activeMenu )
- }
-
- uiGlobal.menuStack.pop()
- if ( uiGlobal.menuStack.len() )
- uiGlobal.activeMenu = uiGlobal.menuStack.top()
- else
- uiGlobal.activeMenu = null
-
- uiGlobal.lastMenuNavDirection = MENU_NAV_BACK
-
- if ( wasDialog )
- {
- if ( uiGlobal.activeMenu )
- SetFooterPanelVisibility( uiGlobal.activeMenu, true )
-
- if ( IsDialog( uiGlobal.activeMenu ) )
- openStackMenu = true
- else
- openStackMenu = false
- }
-
- if ( uiGlobal.activeMenu )
- {
- if ( uiGlobal.activeMenu.GetType() == "submenu" )
- {
- Hud_SetFocused( uiGlobal.menuData[ uiGlobal.activeMenu ].lastFocus )
- }
- else if ( openStackMenu )
- {
- OpenMenuWrapper( uiGlobal.activeMenu, false )
-
- if ( updateBlur && !IsLobby() && !uiGlobal.mapSupportsMenuModels )
- SetBlurEnabled( true )
- }
- }
-
- Signal( uiGlobal.signalDummy, "ActiveMenuChanged" )
-}
-
-void function CloseAllMenus()
-{
- if ( IsDialog( uiGlobal.activeMenu ) )
- CloseActiveMenu( true )
-
- if ( uiGlobal.activeMenu && uiGlobal.activeMenu.GetType() == "submenu" )
- CloseSubmenu( false )
-
- if ( uiGlobal.activeMenu )
- {
- SetBlurEnabled( false )
- CloseMenuWrapper( uiGlobal.activeMenu )
- }
-
- uiGlobal.menuStack = []
- uiGlobal.activeMenu = null
-
- uiGlobal.lastMenuNavDirection = MENU_NAV_BACK
-
- Signal( uiGlobal.signalDummy, "ActiveMenuChanged" )
-}
-
-void function CloseAllInGameMenus()
-{
- while ( uiGlobal.activeMenu )
- {
- if ( uiGlobal.activeMenu.GetType() == "submenu" )
- CloseSubmenu( false )
-
- CloseActiveMenu( true, false )
- }
-}
-
-void function CloseAllDialogs()
-{
- while ( IsDialog( uiGlobal.activeMenu ) )
- CloseActiveMenu( true )
-}
-
-void function CloseAllToTargetMenu( var targetMenu )
-{
- while ( uiGlobal.activeMenu != targetMenu )
- CloseActiveMenu( true, false )
-}
-
-void function PrintMenuStack()
-{
- array<var> stack = clone uiGlobal.menuStack
- stack.reverse()
-
- printt( "MENU STACK:" )
-
- foreach ( menu in stack )
- {
- if ( menu )
- printt( " ", Hud_GetHudName( menu ) )
- else
- printt( " null" )
- }
-}
-
-// Happens on any level load
-void function UpdateMenusOnConnect( string levelname )
-{
- EndSignal( uiGlobal.signalDummy, "LevelShutdown" ) // HACK fix because UICodeCallback_LevelInit() incorrectly runs when disconnected by client error. Test with "script_error_client" while a level is loaded.
-
- CloseAllDialogs()
-
- var mainMenu = GetMenu( "MainMenu" )
- if ( IsMenuInMenuStack( mainMenu ) && !IsMenuInMenuStack( null ) )
- CloseAllToTargetMenu( mainMenu )
-
- Assert( uiGlobal.activeMenu != null || uiGlobal.menuStack.len() == 0 )
-
- AdvanceMenu( null )
-
- // TODO: The order things are called in should be predictable so this isn't needed
- while ( !uiGlobal.mapSupportsMenuModelsUpdated )
- {
- //printt( Time(), "beginning waitframe, uiGlobal.mapSupportsMenuModelsUpdated is:", uiGlobal.mapSupportsMenuModelsUpdated )
- WaitFrame()
- //printt( Time(), "ended waitframe, uiGlobal.mapSupportsMenuModelsUpdated is:", uiGlobal.mapSupportsMenuModelsUpdated )
- }
-
- if ( IsLevelMultiplayer( levelname ) )
- {
- bool isLobby = IsLobbyMapName( levelname )
-
- if ( isLobby )
- {
- if ( IsPrivateMatch() )
- {
- AdvanceMenu( GetMenu( "PrivateLobbyMenu" ) )
- }
- else
- {
- AdvanceMenu( GetMenu( "LobbyMenu" ) )
- }
-
- thread UpdateAnnouncementDialog()
- }
- else
- {
- UI_SetPresentationType( ePresentationType.INACTIVE )
- }
- }
-}
-
-bool function IsMenuInMenuStack( var searchMenu )
-{
- foreach ( menu in uiGlobal.menuStack )
- {
- // loading a map pushes a null sentinel onto the menu stack
- if ( !menu )
- continue
-
- if ( menu == searchMenu )
- return true
- }
-
- return false
-}
-
-var function GetTopNonDialogMenu()
-{
- array<var> menuArray = clone uiGlobal.menuStack
- menuArray.reverse()
-
- foreach ( menu in menuArray )
- {
- if ( menu == null || IsDialog( menu ) )
- continue
-
- return menu
- }
-
- return null
-}
-
-void function CleanupInGameMenus()
-{
- Signal( uiGlobal.signalDummy, "CleanupInGameMenus" )
-
- CloseAllInGameMenus()
- Assert( uiGlobal.activeMenu == null )
- if ( uiGlobal.menuStack.len() )
- {
- if ( uiGlobal.loadingLevel == "" )
- CloseActiveMenu() // Disconnected. Remove stack null and open main menu.
- else
- CloseActiveMenu( true, false ) // Level to level transition. Remove stack null and DON'T open main menu.
- }
-}
-
-var function GetActiveMenu()
-{
- return uiGlobal.activeMenu
-}
-
-var function GetMenu( string menuName )
-{
- return uiGlobal.menus[ menuName ]
-}
-
-var function GetPanel( string panelName )
-{
- return uiGlobal.panels[ panelName ]
-}
-
-array<var> function GetAllMenuPanels( var menu )
-{
- array<var> menuPanels
-
- foreach ( panel in uiGlobal.allPanels )
- {
- if ( Hud_GetParent( panel ) == menu )
- menuPanels.append( panel )
- }
-
- return menuPanels
-}
-
-void function InitGamepadConfigs()
-{
- uiGlobal.buttonConfigs = [ { orthodox = "gamepad_button_layout_default.cfg", southpaw = "gamepad_button_layout_default_southpaw.cfg" } ]
- uiGlobal.buttonConfigs.append( { orthodox = "gamepad_button_layout_bumper_jumper.cfg", southpaw = "gamepad_button_layout_bumper_jumper_southpaw.cfg" } )
- uiGlobal.buttonConfigs.append( { orthodox = "gamepad_button_layout_bumper_jumper_alt.cfg", southpaw = "gamepad_button_layout_bumper_jumper_alt_southpaw.cfg" } )
- uiGlobal.buttonConfigs.append( { orthodox = "gamepad_button_layout_pogo_stick.cfg", southpaw = "gamepad_button_layout_pogo_stick_southpaw.cfg" } )
- uiGlobal.buttonConfigs.append( { orthodox = "gamepad_button_layout_button_kicker.cfg", southpaw = "gamepad_button_layout_button_kicker_southpaw.cfg" } )
- uiGlobal.buttonConfigs.append( { orthodox = "gamepad_button_layout_circle.cfg", southpaw = "gamepad_button_layout_circle_southpaw.cfg" } )
- uiGlobal.buttonConfigs.append( { orthodox = "gamepad_button_layout_ninja.cfg", southpaw = "gamepad_button_layout_ninja_southpaw.cfg" } )
- uiGlobal.buttonConfigs.append( { orthodox = "gamepad_button_layout_custom.cfg", southpaw = "gamepad_button_layout_custom.cfg" } )
-
- uiGlobal.stickConfigs = []
- uiGlobal.stickConfigs.append( "gamepad_stick_layout_default.cfg" )
- uiGlobal.stickConfigs.append( "gamepad_stick_layout_southpaw.cfg" )
- uiGlobal.stickConfigs.append( "gamepad_stick_layout_legacy.cfg" )
- uiGlobal.stickConfigs.append( "gamepad_stick_layout_legacy_southpaw.cfg" )
-
- foreach ( key, val in uiGlobal.buttonConfigs )
- {
- VPKNotifyFile( "cfg/" + val.orthodox )
- VPKNotifyFile( "cfg/" + val.southpaw )
- }
-
- foreach ( key, val in uiGlobal.stickConfigs )
- VPKNotifyFile( "cfg/" + val )
-
- ExecCurrentGamepadButtonConfig()
- ExecCurrentGamepadStickConfig()
-
- SetStandardAbilityBindingsForPilot( GetLocalClientPlayer() )
-}
-
-void function InitMenus()
-{
- InitGlobalMenuVars()
- SpShWeaponsInit()
-
- AddMenu( "MainMenu", $"resource/ui/menus/main.menu", InitMainMenu, "#MAIN" )
- AddPanel( GetMenu( "MainMenu" ), "EstablishUserPanel", InitEstablishUserPanel )
- AddPanel( GetMenu( "MainMenu" ), "MainMenuPanel", InitMainMenuPanel )
-
- // stub
- void functionref() InitModMenu = void function(){}
- AddMenu( "ModListMenu", $"resource/ui/menus/modlist.menu", InitModMenu, "#MENU_MODS" )
-
- AddMenu( "PlayVideoMenu", $"resource/ui/menus/play_video.menu", InitPlayVideoMenu )
- AddMenu( "LobbyMenu", $"resource/ui/menus/lobby.menu", InitLobbyMenu, "#LOBBY" )
-
- // stub
- void functionref() InitServerBrowserMenu = void function(){}
- AddMenu( "ServerBrowserMenu", $"resource/ui/menus/server_browser.menu", InitServerBrowserMenu, "#MENU_SERVER_BROWSER" )
-
- AddMenu( "FDMenu", $"resource/ui/menus/playlist_fd.menu", InitFDPlaylistMenu )
- AddMenu( "TeamTitanSelectMenu", $"resource/ui/menus/team_titan_select.menu", InitTeamTitanSelectMenu )
- AddMenu( "PlaylistMenu", $"resource/ui/menus/playlist.menu", InitPlaylistMenu )
- AddMenu( "PlaylistMixtapeMenu", $"resource/ui/menus/playlist_mixtape.menu", InitPlaylistMixtapeMenu )
- AddMenu( "PlaylistMixtapeChecklistMenu", $"resource/ui/menus/playlist_mixtape_checklist.menu", InitPlaylistMixtapeChecklistMenu )
-
- AddMenu( "SinglePlayerDevMenu", $"resource/ui/menus/singleplayer_dev.menu", InitSinglePlayerDevMenu, "SINGLE PLAYER DEV" )
- AddMenu( "SinglePlayerMenu", $"resource/ui/menus/singleplayer.menu", InitSinglePlayerMenu, "SINGLE PLAYER" )
-
- AddMenu( "SearchMenu", $"resource/ui/menus/search.menu", InitSearchMenu )
-
- AddMenu( "GammaMenu", $"resource/ui/menus/gamma.menu", InitGammaMenu, "#BRIGHTNESS" )
-
- AddMenu( "CommunitiesMenu", $"resource/ui/menus/community.menu", InitCommunitiesMenu )
- AddMenu( "Notifications", $"resource/ui/menus/notifications.menu", InitNotificationsMenu )
- AddMenu( "MyNetworks", $"resource/ui/menus/communities_mine.menu", InitMyNetworksMenu )
- AddMenu( "InboxFrontMenu", $"resource/ui/menus/inbox_front.menu", InitInboxFrontMenu )
- AddMenu( "Inbox", $"resource/ui/menus/inbox.menu", InitInboxMenu )
- AddMenu( "BrowseCommunities", $"resource/ui/menus/communities_browse.menu" )
- AddMenu( "CommunityEditMenu", $"resource/ui/menus/community_edit.menu" )
- AddMenu( "CommunityAdminSendMessage", $"resource/ui/menus/community_sendMessage.menu" )
- AddMenu( "CommunityAdminInviteRequestMenu", $"resource/ui/menus/community_inviteRequest.menu" )
-#if NETWORK_INVITE
- AddMenu( "InviteFriendsToNetworkMenu", $"resource/ui/menus/invite_friends.menu", InitInviteFriendsToNetworkMenu )
-#endif
-
- AddMenu( "InGameMPMenu", $"resource/ui/menus/ingame_mp.menu", InitInGameMPMenu )
- AddMenu( "InGameSPMenu", $"resource/ui/menus/ingame_sp.menu", InitInGameSPMenu )
-
- AddMenu( "Dialog", $"resource/ui/menus/dialog.menu", InitDialogMenu )
- AddMenu( "AnnouncementDialog", $"resource/ui/menus/dialog_announcement.menu", InitAnnouncementDialog )
- AddMenu( "ConnectingDialog", $"resource/ui/menus/dialog_connecting.menu", InitConnectingDialog )
- AddMenu( "DataCenterDialog", $"resource/ui/menus/dialog_datacenter.menu", InitDataCenterDialogMenu )
- AddMenu( "EULADialog", $"resource/ui/menus/dialog_eula.menu", InitEULADialog )
- AddMenu( "ReviewTermsDialog", $"resource/ui/menus/dialog_review_terms.menu", InitReviewTermsDialog )
- AddMenu( "RegistrationDialog", $"resource/ui/menus/dialog_registration.menu", InitRegistrationDialog )
- AddMenu( "AdvocateGiftDialog", $"resource/ui/menus/dialog_advocate_gift.menu", InitAdvocateGiftDialog )
-
- AddMenu( "ControlsMenu", $"resource/ui/menus/controls.menu", InitControlsMenu, "#CONTROLS" )
- AddMenu( "ControlsAdvancedLookMenu", $"resource/ui/menus/controls_advanced_look.menu", InitControlsAdvancedLookMenu, "#CONTROLS_ADVANCED_LOOK" )
- AddMenu( "GamepadLayoutMenu", $"resource/ui/menus/gamepadlayout.menu", InitGamepadLayoutMenu )
-#if PC_PROG
- AddMenu_WithCreateFunc( "MouseKeyboardBindingsMenu", $"resource/ui/menus/mousekeyboardbindings.menu", InitMouseKeyboardMenu, CreateKeyBindingMenu )
- AddMenu( "AudioMenu", $"resource/ui/menus/audio.menu", InitAudioMenu, "#AUDIO" )
- AddMenu_WithCreateFunc( "VideoMenu", $"resource/ui/menus/video.menu", InitVideoMenu, CreateVideoOptionsMenu )
-#elseif CONSOLE_PROG
- AddMenu( "AudioVideoMenu", $"resource/ui/menus/audio_video.menu", InitAudioVideoMenu, "#AUDIO_VIDEO" )
-#endif
-
- AddMenu( "AdvancedHudMenu", $"resource/ui/menus/advanced_hud.menu", InitAdvancedHudMenu, "#ADVANCED_HUD" )
-
- AddMenu( "PilotLoadoutsMenu", $"resource/ui/menus/pilotloadouts.menu", InitPilotLoadoutsMenu )
- AddMenu( "TitanLoadoutsMenu", $"resource/ui/menus/titanloadouts.menu", InitTitanLoadoutsMenu )
- AddMenu( "EditPilotLoadoutsMenu", $"resource/ui/menus/pilotloadouts.menu", InitEditPilotLoadoutsMenu )
- AddMenu( "EditTitanLoadoutsMenu", $"resource/ui/menus/titanloadouts.menu", InitEditTitanLoadoutsMenu )
- AddMenu( "EditPilotLoadoutMenu", $"resource/ui/menus/editpilotloadout.menu", InitEditPilotLoadoutMenu )
- AddMenu( "EditTitanLoadoutMenu", $"resource/ui/menus/edittitanloadout.menu", InitEditTitanLoadoutMenu )
-
- AddMenu( "SPTitanLoadoutMenu", $"resource/ui/menus/sptitanloadout.menu", InitSPTitanLoadoutMenu )
- AddMenu( "SPTitanLoadoutTutorialMenu", $"resource/ui/menus/sptitanloadout_tutorial.menu", InitSPTitanLoadoutTutorialMenu )
-
- AddMenu( "SuitSelectMenu", $"resource/ui/menus/suitselect.menu", InitSuitSelectMenu )
- AddMenu( "WeaponSelectMenu", $"resource/ui/menus/weaponselect.menu", InitWeaponSelectMenu )
- AddMenu( "CategorySelectMenu", $"resource/ui/menus/categoryselect.menu", InitCategorySelectMenu )
- AddMenu( "AbilitySelectMenu", $"resource/ui/menus/abilityselect.menu", InitAbilitySelectMenu )
- AddMenu( "PassiveSelectMenu", $"resource/ui/menus/passiveselect.menu", InitPassiveSelectMenu )
- AddSubmenu( "ModSelectMenu", $"resource/ui/menus/modselect.menu", InitModSelectMenu )
- AddMenu( "CamoSelectMenu", $"resource/ui/menus/camoselect.menu", InitCamoSelectMenu )
- AddMenu( "NoseArtSelectMenu", $"resource/ui/menus/noseartselect.menu", InitNoseArtSelectMenu )
- AddMenu( "CallsignCardSelectMenu", $"resource/ui/menus/callsigncardselect.menu", InitCallsignCardSelectMenu )
- AddMenu( "CallsignIconSelectMenu", $"resource/ui/menus/callsigniconselect.menu", InitCallsignIconSelectMenu )
- AddMenu( "BoostStoreMenu", $"resource/ui/menus/booststore.menu", InitBoostStoreMenu )
-
- AddMenu( "PrivateLobbyMenu", $"resource/ui/menus/private_lobby.menu", InitPrivateMatchMenu, "#PRIVATE_MATCH" )
- AddMenu( "MapsMenu", $"resource/ui/menus/map_select.menu", InitMapsMenu )
- AddMenu( "ModesMenu", $"resource/ui/menus/mode_select.menu", InitModesMenu )
- AddMenu( "MatchSettingsMenu", $"resource/ui/menus/match_settings.menu", InitMatchSettingsMenu )
-
- AddMenu( "Advocate_Letter", $"resource/ui/menus/advocate_letter.menu", InitAdvocateLetterMenu )
- AddMenu( "Generation_Respawn", $"resource/ui/menus/generation_respawn.menu", InitGenerationRespawnMenu )
- AddMenu( "ChallengesMenu", $"resource/ui/menus/challenges.menu", InitChallengesMenu )
-
- AddMenu( "ViewStatsMenu", $"resource/ui/menus/viewstats.menu", InitViewStatsMenu, "#PERSONAL_STATS" )
- AddMenu( "ViewStats_Overview_Menu", $"resource/ui/menus/viewstats_overview.menu", InitViewStatsOverviewMenu )
- //AddMenu( "ViewStats_Kills_Menu", $"resource/ui/menus/viewstats_kills.menu", InitViewStatsKillsMenu )
- AddMenu( "ViewStats_Time_Menu", $"resource/ui/menus/viewstats_time.menu", InitViewStatsTimeMenu )
- //AddMenu( "ViewStats_Distance_Menu", $"resource/ui/menus/viewstats_distance.menu", InitViewStatsDistanceMenu )
- AddMenu( "ViewStats_Weapons_Menu", $"resource/ui/menus/viewstats_weapons.menu", InitViewStatsWeaponsMenu )
- AddMenu( "ViewStats_Titans_Menu", $"resource/ui/menus/viewstats_titans.menu", InitViewStatsTitansMenu )
- AddMenu( "ViewStats_Misc_Menu", $"resource/ui/menus/viewstats_misc.menu", InitViewStatsMiscMenu )
- AddMenu( "ViewStats_Maps_Menu", $"resource/ui/menus/viewstats_maps.menu", InitViewStatsMapsMenu )
-
- AddMenu( "PostGameMenu", $"resource/ui/menus/postgame.menu", InitPostGameMenu )
- AddMenu( "EOG_XP", $"resource/ui/menus/eog_xp.menu", InitEOG_XPMenu )
- AddMenu( "EOG_Coins", $"resource/ui/menus/eog_coins.menu", InitEOG_CoinsMenu )
- AddMenu( "EOG_Challenges", $"resource/ui/menus/eog_challenges.menu", InitEOG_ChallengesMenu )
- AddMenu( "EOG_Unlocks", $"resource/ui/menus/eog_unlocks.menu", InitEOG_UnlocksMenu )
- AddMenu( "EOG_Scoreboard", $"resource/ui/menus/eog_scoreboard.menu", InitEOG_ScoreboardMenu )
-
- AddMenu( "CreditsMenu", $"resource/ui/menus/credits.menu", InitCreditsMenu, "#CREDITS" )
-
- AddMenu( "BurnCardMenu", $"resource/ui/menus/burn_cards.menu", InitBurnCardMenu, "#MENU_BURNCARD_MENU" )
- AddMenu( "FactionChoiceMenu", $"resource/ui/menus/faction_choice.menu", InitFactionChoiceMenu, "#FACTION_CHOICE_MENU" )
- AddMenu( "ArmoryMenu", $"resource/ui/menus/armory.menu", InitArmoryMenu, "#ARMORY_MENU" )
-
- AddMenu( "StoreMenu", $"resource/ui/menus/store.menu", InitStoreMenu, "#STORE_MENU" )
- AddMenu( "StoreMenu_NewReleases", $"resource/ui/menus/store_new_releases.menu", InitStoreMenuNewReleases, "#STORE_NEW_RELEASES" )
- AddMenu( "StoreMenu_Limited", $"resource/ui/menus/store_limited.menu", InitStoreMenuLimited, "#STORE_LIMITED" )
- AddMenu( "StoreMenu_Sales", $"resource/ui/menus/store_bundles.menu", InitStoreMenuSales, "#STORE_BUNDLES" )
- AddMenu( "StoreMenu_Titans", $"resource/ui/menus/store_prime_titans.menu", InitStoreMenuTitans, "#STORE_TITANS" ) // reusing store_prime_titans.menu
- AddMenu( "StoreMenu_PrimeTitans", $"resource/ui/menus/store_prime_titans.menu", InitStoreMenuPrimeTitans, "#STORE_PRIME_TITANS" )
- //AddMenu( "StoreMenu_WeaponSelect", $"resource/ui/menus/store_weapon_select.menu", InitStoreMenuWeaponSelect )
- //AddMenu( "StoreMenu_WeaponSkinPreview", $"resource/ui/menus/store_weapon_skin_preview.menu", InitStoreMenuWeaponSkinPreview )
- AddMenu( "StoreMenu_WeaponSkinBundles", $"resource/ui/menus/store_weapon_skin_bundles.menu", InitStoreMenuWeaponSkinBundles )
- AddMenu( "StoreMenu_WeaponSkins", $"resource/ui/menus/store_weapons.menu", InitStoreMenuWeaponSkins )
- AddMenu( "StoreMenu_Customization", $"resource/ui/menus/store_customization.menu", InitStoreMenuCustomization, "#STORE_CUSTOMIZATION_PACKS" )
- AddMenu( "StoreMenu_CustomizationPreview", $"resource/ui/menus/store_customization_preview.menu", InitStoreMenuCustomizationPreview, "#STORE_CUSTOMIZATION_PACKS" )
- AddMenu( "StoreMenu_Camo", $"resource/ui/menus/store_camo.menu", InitStoreMenuCamo, "#STORE_CAMO_PACKS" )
- AddMenu( "StoreMenu_CamoPreview", $"resource/ui/menus/store_camo_preview.menu", InitStoreMenuCamoPreview, "#STORE_CAMO_PACKS" )
- AddMenu( "StoreMenu_Callsign", $"resource/ui/menus/store_callsign.menu", InitStoreMenuCallsign, "#STORE_CALLSIGN_PACKS" )
- AddMenu( "StoreMenu_CallsignPreview", $"resource/ui/menus/store_callsign_preview.menu", InitStoreMenuCallsignPreview, "#STORE_CALLSIGN_PACKS" )
-
- AddMenu( "KnowledgeBaseMenu", $"resource/ui/menus/knowledgebase.menu", InitKnowledgeBaseMenu )
- AddMenu( "KnowledgeBaseMenuSubMenu", $"resource/ui/menus/knowledgebase_submenu.menu", InitKnowledgeBaseMenuSubMenu )
-
- AddMenu( "DevMenu", $"resource/ui/menus/dev.menu", InitDevMenu, "Dev" )
- InitSharedStartPoints()
-
- foreach ( menu in uiGlobal.allMenus )
- {
- if ( uiGlobal.menuData[ menu ].initFunc != null )
- uiGlobal.menuData[ menu ].initFunc()
-
- array<var> elems = GetElementsByClassname( menu, "TabsCommonClass" )
- if ( elems.len() )
- uiGlobal.menuData[ menu ].hasTabs = true
-
- elems = GetElementsByClassname( menu, "EnableKeyBindingIcons" )
- foreach ( elem in elems )
- Hud_EnableKeyBindingIcons( elem )
- }
-
- InitTabs()
-
- var tabbedMenu = GetMenu( "PostGameMenu" )
- AddPanel( tabbedMenu, "PVEPanel", InitPVEPanel )
- AddPanel( tabbedMenu, "SummaryPanel", InitSummaryPanel )
- AddPanel( tabbedMenu, "FDAwardsPanel", InitFDAwardsPanel )
-
- AddPanel( tabbedMenu, "ScoreboardPanel", InitScoreboardPanel )
-
- foreach ( panel in uiGlobal.allPanels )
- {
- if ( uiGlobal.panelData[ panel ].initFunc != null )
- uiGlobal.panelData[ panel ].initFunc()
- }
-
- // A little weird, but GetElementsByClassname() uses menu scope rather than parent scope.
- foreach ( menu in uiGlobal.allMenus )
- {
- array<var> buttons = GetElementsByClassname( menu, "DefaultFocus" )
- foreach ( button in buttons )
- {
- var panel = Hud_GetParent( button )
-
- //Assert( elems.len() == 1, "More than 1 panel element set as DefaultFocus!" )
- Assert( panel != null, "no parent panel found for button " + Hud_GetHudName( button ) )
- Assert( panel in uiGlobal.panelData, "panel " + Hud_GetHudName( panel ) + " isn't in uiGlobal.panelData, but button " + Hud_GetHudName( button ) + " has defaultFocus set!" )
- uiGlobal.panelData[ panel ].defaultFocus = button
- //printt( "Found DefaultFocus, button was:", Hud_GetHudName( button ), "panel was:", Hud_GetHudName( panel ) )
- }
- }
-
- InitFooterOptions()
-
- #if DEV
- if ( Dev_CommandLineHasParm( "-autoprecache_all" ) )
- {
- // repreache all levels
- ExecuteLoadingClientCommands_SetStartPoint( "sp_training" )
- ClientCommand( "map sp_training" )
- CloseAllMenus()
- }
- #endif
-}
-
-void functionref( var ) function AdvanceMenuEventHandler( var menu )
-{
- return void function( var item ) : ( menu )
- {
- if ( Hud_IsLocked( item ) )
- return
-
- AdvanceMenu( menu )
- }
-}
-
-void function PCBackButton_Activate( var button )
-{
- UICodeCallback_NavigateBack()
-}
-
-void function PCSwitchTeamsButton_Activate( var button )
-{
- ClientCommand( "PrivateMatchSwitchTeams" )
-}
-
-void function PCToggleSpectateButton_Activate( var button )
-{
- ClientCommand( "PrivateMatchToggleSpectate" )
-}
-
-void function ToggleButtonStates( var button )
-{
- for ( ;; )
- {
- Hud_SetEnabled( button, true )
- wait 1
- Hud_SetSelected( button, true )
- wait 1
- Hud_SetLocked( button, true )
- wait 1
- Hud_SetNew( button, true )
- wait 1
- Hud_SetNew( button, false )
- wait 1
- Hud_SetLocked( button, false )
- wait 1
- Hud_SetSelected( button, false )
- wait 1
- Hud_SetEnabled( button, false )
- wait 1
- }
-}
-
-void function AddMenuElementsByClassname( var menu, string classname )
-{
- array<var> elements = GetElementsByClassname( menu, classname )
-
- if ( !(classname in menu.classElements) )
- menu.classElements[classname] <- []
-
- menu.classElements[classname].extend( elements )
-}
-
-void function FocusDefault( var menu )
-{
- if (
- menu == GetMenu( "MainMenu" ) ||
- menu == GetMenu( "CategorySelectMenu" ) ||
- menu == GetMenu( "AbilitySelectMenu" ) ||
- menu == GetMenu( "PassiveSelectMenu" ) ||
- menu == GetMenu( "WeaponSelectMenu" ) ||
- menu == GetMenu( "SuitSelectMenu" ) ||
- menu == GetMenu( "CamoSelectMenu" ) ||
- menu == GetMenu( "NoseArtSelectMenu" ) ||
- menu == GetMenu( "FactionChoiceMenu" ) ||
- menu == GetMenu( "BurnCardMenu" ) ||
- menu == GetMenu( "CallsignCardSelectMenu" ) ||
- menu == GetMenu( "CallsignIconSelectMenu" ) )
- {
- }
- else
- {
- //printt( "FocusDefaultMenuItem() called" )
- FocusDefaultMenuItem( menu )
- }
-}
-
-void function SetPanelDefaultFocus( var panel, var button )
-{
- uiGlobal.panelData[ panel ].defaultFocus = button
-}
-
-void function PanelFocusDefault( var panel )
-{
- //printt( "PanelFocusDefault called" )
- if ( uiGlobal.panelData[ panel ].defaultFocus )
- {
- Hud_SetFocused( uiGlobal.panelData[ panel ].defaultFocus )
- //printt( "PanelFocusDefault if passed,", Hud_GetHudName( uiGlobal.panelData[ panel ].defaultFocus ), "focused" )
- }
-}
-
-void function SetMenuThinkFunc( var menu, void functionref() func )
-{
- Assert( uiGlobal.menuData[ menu ].thinkFunc == null )
- uiGlobal.menuData[ menu ].thinkFunc = func
-}
-
-void function AddMenuEventHandler( var menu, int event, void functionref() func )
-{
- if ( event == eUIEvent.MENU_OPEN )
- {
- Assert( uiGlobal.menuData[ menu ].openFunc == null )
- uiGlobal.menuData[ menu ].openFunc = func
- }
- else if ( event == eUIEvent.MENU_CLOSE )
- {
- Assert( uiGlobal.menuData[ menu ].closeFunc == null )
- uiGlobal.menuData[ menu ].closeFunc = func
- }
- else if ( event == eUIEvent.MENU_SHOW )
- {
- Assert( uiGlobal.menuData[ menu ].showFunc == null )
- uiGlobal.menuData[ menu ].showFunc = func
- }
- else if ( event == eUIEvent.MENU_HIDE )
- {
- Assert( uiGlobal.menuData[ menu ].hideFunc == null )
- uiGlobal.menuData[ menu ].hideFunc = func
- }
- else if ( event == eUIEvent.MENU_NAVIGATE_BACK )
- {
- Assert( uiGlobal.menuData[ menu ].navBackFunc == null )
- uiGlobal.menuData[ menu ].navBackFunc = func
- }
- else if ( event == eUIEvent.MENU_TAB_CHANGED )
- {
- Assert( uiGlobal.menuData[ menu ].tabChangedFunc == null )
- uiGlobal.menuData[ menu ].tabChangedFunc = func
- }
- else if ( event == eUIEvent.MENU_ENTITLEMENTS_CHANGED )
- {
- Assert( uiGlobal.menuData[ menu ].entitlementsChangedFunc == null )
- uiGlobal.menuData[ menu ].entitlementsChangedFunc = func
- }
- else if ( event == eUIEvent.MENU_INPUT_MODE_CHANGED )
- {
- Assert( uiGlobal.menuData[ menu ].inputModeChangedFunc == null )
- uiGlobal.menuData[ menu ].inputModeChangedFunc = func
- }
-}
-
-void function AddPanelEventHandler( var panel, int event, void functionref() func )
-{
- if ( event == eUIEvent.PANEL_SHOW )
- uiGlobal.panelData[ panel ].showFunc = func
- else if ( event == eUIEvent.PANEL_HIDE )
- uiGlobal.panelData[ panel ].hideFunc = func
-}
-
-// TODO: Get a real on open event from code?
-void function OpenMenuWrapper( var menu, bool focusDefault )
-{
- OpenMenu( menu )
- printt( Hud_GetHudName( menu ), "menu opened" )
-
- Assert( menu in uiGlobal.menuData )
- if ( uiGlobal.menuData[ menu ].openFunc != null )
- {
- thread uiGlobal.menuData[ menu ].openFunc()
- //printt( "Called openFunc for:", menu.GetHudName() )
- }
-
- if ( focusDefault )
- FocusDefault( menu )
-
- //UpdateMenuTabs()
- UpdateFooterOptions()
-}
-
-void function CloseMenuWrapper( var menu )
-{
- CloseMenu( menu )
- printt( Hud_GetHudName( menu ), "menu closed" )
-
- Assert( menu in uiGlobal.menuData )
- if ( uiGlobal.menuData[ menu ].closeFunc != null )
- {
- thread uiGlobal.menuData[ menu ].closeFunc()
- //printt( "Called closeFunc for:", Hud_GetHudName( menu ) )
- }
-}
-
-bool function IsLevelMultiplayer( string levelname )
-{
- return levelname.find( "mp_" ) == 0
-}
-
-void function AddButtonEventHandler( var button, int event, void functionref( var ) func )
-{
- Hud_AddEventHandler( button, event, func )
-}
-
-void function AddEventHandlerToButton( var menu, string buttonName, int event, void functionref( var ) func )
-{
- var button = Hud_GetChild( menu, buttonName )
- Hud_AddEventHandler( button, event, func )
-}
-
-void function AddEventHandlerToButtonClass( var menu, string classname, int event, void functionref( var ) func )
-{
- array<var> buttons = GetElementsByClassname( menu, classname )
-
- foreach ( button in buttons )
- {
- //printt( "button name:", Hud_GetHudName( button ) )
- Hud_AddEventHandler( button, event, func )
- }
-}
-
-// Added slight delay to main menu music to work around a hitch caused when the game first starts up
-void function PlayMusicAfterDelay()
-{
- wait MAINMENU_MUSIC_DELAY
- if ( uiGlobal.playingMusic )
- EmitUISound( "MainMenu_Music" )
-}
-
-void function DisableMusic()
-{
- EmitUISound( "Movie_MuteAllGameSound" )
-}
-
-void function EnableMusic()
-{
- StopUISoundByName( "Movie_MuteAllGameSound" )
-}
-
-void function PlayMusic()
-{
- if ( !uiGlobal.playingMusic && !uiGlobal.playingVideo && !uiGlobal.playingCredits )
- {
- //printt( "PlayMusic() called. Playing: MainMenu_Music. uiGlobal.playingMusic:", uiGlobal.playingMusic, "uiGlobal.playingVideo:", uiGlobal.playingVideo, "uiGlobal.playingCredits:", uiGlobal.playingCredits )
- uiGlobal.playingMusic = true
- thread PlayMusicAfterDelay()
- }
- else
- {
- //printt( "PlayMusic() called, but doing nothing. uiGlobal.playingMusic:", uiGlobal.playingMusic, "uiGlobal.playingVideo:", uiGlobal.playingVideo, "uiGlobal.playingCredits:", uiGlobal.playingCredits )
- }
-}
-
-void function StopMusic()
-{
- //printt( "StopMusic() called. Stopping: MainMenu_Music" )
- StopUISound( "MainMenu_Music" )
- uiGlobal.playingMusic = false
-}
-
-void function RegisterMenuVarInt( string varName, int value )
-{
- table<string, int> intVars = uiGlobal.intVars
-
- Assert( !( varName in intVars ) )
-
- intVars[varName] <- value
-}
-
-void function RegisterMenuVarBool( string varName, bool value )
-{
- table<string, bool> boolVars = uiGlobal.boolVars
-
- Assert( !( varName in boolVars ) )
-
- boolVars[varName] <- value
-}
-
-void function RegisterMenuVarVar( string varName, var value )
-{
- table<string, var> varVars = uiGlobal.varVars
-
- Assert( !( varName in varVars ) )
-
- varVars[varName] <- value
-}
-
-int function GetMenuVarInt( string varName )
-{
- table<string, int> intVars = uiGlobal.intVars
-
- Assert( varName in intVars )
-
- return intVars[varName]
-}
-
-bool function GetMenuVarBool( string varName )
-{
- table<string, bool> boolVars = uiGlobal.boolVars
-
- Assert( varName in boolVars )
-
- return boolVars[varName]
-}
-
-var function GetMenuVarVar( string varName )
-{
- table<string, var> varVars = uiGlobal.varVars
-
- Assert( varName in varVars )
-
- return varVars[varName]
-}
-
-void function SetMenuVarInt( string varName, int value )
-{
- table<string, int> intVars = uiGlobal.intVars
-
- Assert( varName in intVars )
-
- if ( intVars[varName] == value )
- return
-
- intVars[varName] = value
-
- table<string, array<void functionref()> > varChangeFuncs = uiGlobal.varChangeFuncs
-
- if ( varName in varChangeFuncs )
- {
- foreach ( func in varChangeFuncs[varName] )
- {
- //printt( varName, "changed, calling changeFunc:", string( func ) )
- func()
- }
- }
-}
-
-void function SetMenuVarBool( string varName, bool value )
-{
- table<string, bool> boolVars = uiGlobal.boolVars
-
- Assert( varName in boolVars )
-
- if ( boolVars[varName] == value )
- return
-
- boolVars[varName] = value
-
- table<string, array<void functionref()> > varChangeFuncs = uiGlobal.varChangeFuncs
-
- if ( varName in varChangeFuncs )
- {
- foreach ( func in varChangeFuncs[varName] )
- {
- //printt( varName, "changed, calling changeFunc:", string( func ) )
- func()
- }
- }
-}
-
-void function SetMenuVarVar( string varName, var value )
-{
- table<string, var> varVars = uiGlobal.varVars
-
- Assert( varName in varVars )
-
- if ( varVars[varName] == value )
- return
-
- varVars[varName] = value
-
- table<string, array<void functionref()> > varChangeFuncs = uiGlobal.varChangeFuncs
-
- if ( varName in varChangeFuncs )
- {
- foreach ( func in varChangeFuncs[varName] )
- {
- //printt( varName, "changed, calling changeFunc:", string( func ) )
- func()
- }
- }
-}
-
-void function AddMenuVarChangeHandler( string varName, void functionref() func )
-{
- table<string, array<void functionref()> > varChangeFuncs = uiGlobal.varChangeFuncs
-
- if ( !( varName in varChangeFuncs ) )
- varChangeFuncs[varName] <- []
-
- // TODO: Verify we're not duplicating an existing func
- varChangeFuncs[varName].append( func )
-}
-
-// These are common menu statuses that trigger menu logic any time they change
-// They should become code callbacks, so script doesn't poll
-void function InitGlobalMenuVars()
-{
- RegisterMenuVarVar( "focus", null )
- RegisterMenuVarBool( "isConnected", false )
- RegisterMenuVarBool( "isFullyConnected", false )
- RegisterMenuVarBool( "isPartyLeader", false )
- RegisterMenuVarBool( "isPrivateMatch", false )
- RegisterMenuVarBool( "isGamepadActive", IsControllerModeActive() )
-
- #if CONSOLE_PROG
- RegisterMenuVarBool( "CONSOLE_isOnline", false )
- RegisterMenuVarBool( "CONSOLE_isSignedIn", false )
- #endif // CONSOLE_PROG
-
- #if DURANGO_PROG
- RegisterMenuVarBool( "DURANGO_isGameFullyInstalled", false )
- RegisterMenuVarBool( "DURANGO_canInviteFriends", false )
- RegisterMenuVarBool( "DURANGO_isJoinable", false )
- #elseif PS4_PROG
- RegisterMenuVarBool( "PS4_canInviteFriends", false)
- #elseif PC_PROG
- RegisterMenuVarBool( "ORIGIN_isEnabled", false )
- RegisterMenuVarBool( "ORIGIN_isJoinable", false )
- #endif
-
- thread UpdateFocus()
- thread UpdateIsConnected()
- thread UpdateIsFullyConnected()
- thread UpdateAmIPartyLeader()
- thread UpdateIsPrivateMatch()
- thread UpdateActiveMenuThink()
-
- #if CONSOLE_PROG
- thread UpdateConsole_IsOnline()
- thread UpdateConsole_IsSignedIn()
- #endif // CONSOLE_PROG
-
- #if DURANGO_PROG
- thread UpdateDurango_IsGameFullyInstalled()
- thread UpdateDurango_CanInviteFriends()
- thread UpdateDurango_IsJoinable()
- #elseif PS4_PROG
- thread UpdatePS4_CanInviteFriends()
- #elseif PC_PROG
- thread UpdateOrigin_IsEnabled()
- thread UpdateOrigin_IsJoinable()
- thread UpdateIsGamepadActive()
- #endif
-}
-
-void function UpdateFocus()
-{
- while ( true )
- {
- SetMenuVarVar( "focus", GetFocus() )
- WaitFrame()
- }
-}
-
-void function UpdateActiveMenuThink()
-{
- while ( true )
- {
- var menu = GetActiveMenu()
- if ( menu )
- {
- Assert( menu in uiGlobal.menuData )
- if ( uiGlobal.menuData[ menu ].thinkFunc != null )
- uiGlobal.menuData[ menu ].thinkFunc()
- }
-
- WaitFrame()
- }
-}
-
-void function UpdateIsConnected()
-{
- while ( true )
- {
- SetMenuVarBool( "isConnected", IsConnected() )
- WaitFrame()
- }
-}
-
-void function UpdateIsFullyConnected()
-{
- while ( true )
- {
- SetMenuVarBool( "isFullyConnected", IsFullyConnected() )
- WaitFrame()
- }
-}
-
-void function UpdateAmIPartyLeader()
-{
- while ( true )
- {
- SetMenuVarBool( "isPartyLeader", AmIPartyLeader() )
- WaitFrame()
- }
-}
-
-void function UpdateIsPrivateMatch()
-{
- while ( true )
- {
- SetMenuVarBool( "isPrivateMatch", IsPrivateMatch() )
- WaitFrame()
- }
-}
-
-#if CONSOLE_PROG
- void function UpdateConsole_IsOnline()
- {
- while ( true )
- {
- SetMenuVarBool( "CONSOLE_isOnline", Console_IsOnline() )
- WaitFrame()
- }
- }
-
- void function UpdateConsole_IsSignedIn()
- {
- while ( true )
- {
- SetMenuVarBool( "CONSOLE_isSignedIn", Console_IsSignedIn() )
- WaitFrame()
- }
- }
-#endif // CONSOLE_PROG
-
-
-#if PS4_PROG
- void function UpdatePS4_CanInviteFriends()
- {
- while ( true )
- {
- SetMenuVarBool( "PS4_canInviteFriends", PS4_canInviteFriends() )
- WaitFrame()
- }
- }
-#endif // PS4_PROG
-
-
-
-#if DURANGO_PROG
- void function UpdateDurango_IsGameFullyInstalled()
- {
- while ( true )
- {
- SetMenuVarBool( "DURANGO_isGameFullyInstalled", IsGameFullyInstalled() )
- wait 1 // Poll less frequent
- }
- }
-
- void function UpdateDurango_CanInviteFriends()
- {
- while ( true )
- {
- SetMenuVarBool( "DURANGO_canInviteFriends", Durango_CanInviteFriends() )
- WaitFrame()
- }
- }
-
- void function UpdateDurango_IsJoinable()
- {
- while ( true )
- {
- SetMenuVarBool( "DURANGO_isJoinable", Durango_IsJoinable() )
- WaitFrame()
- }
- }
-#endif // DURANGO_PROG
-
-#if PC_PROG
- void function UpdateOrigin_IsEnabled()
- {
- while ( true )
- {
- SetMenuVarBool( "ORIGIN_isEnabled", Origin_IsEnabled() )
- WaitFrame()
- }
- }
-
- void function UpdateOrigin_IsJoinable()
- {
- while ( true )
- {
- SetMenuVarBool( "ORIGIN_isJoinable", Origin_IsJoinable() )
- WaitFrame()
- }
- }
-
- void function UpdateIsGamepadActive()
- {
- while ( true )
- {
- SetMenuVarBool( "isGamepadActive", IsControllerModeActive() )
- WaitFrame()
- }
- }
-#endif // PC_PROG
-
-void function InviteFriends( var button )
-{
- //AdvanceMenu( GetMenu( "InviteFriendsToPartyMenu" ) )
-
- #if DURANGO_PROG
- Durango_InviteFriends()
- #elseif PS4_PROG
- ClientCommand("session_debug_invite");
- #elseif PC_PROG
- Assert( Origin_IsEnabled() )
- Assert( Origin_IsJoinable() )
-
- Origin_ShowInviteFriendsDialog()
- #endif
-}
-
-#if DURANGO_PROG
-void function OpenXboxPartyApp( var button )
-{
- Durango_OpenPartyApp()
-}
-
-void function OpenXboxHelp( var button )
-{
- Durango_ShowHelpWindow()
-}
-#endif // DURANGO_PROG
-
-void function OpenReviewTermsDialog( var button )
-{
- AdvanceMenu( GetMenu( "ReviewTermsDialog" ) )
-}
-
-void function OpenErrorDialog( string errorDetails )
-{
- DialogData dialogData
- dialogData.header = "#ERROR"
- dialogData.message = errorDetails
- dialogData.image = $"ui/menu/common/dialog_error"
-
-#if PC_PROG
- AddDialogButton( dialogData, "#DISMISS" )
-
- AddDialogFooter( dialogData, "#A_BUTTON_SELECT" )
-#endif // PC_PROG
- AddDialogFooter( dialogData, "#B_BUTTON_DISMISS_RUI" )
-
- while ( uiGlobal.activeMenu != GetMenu( "MainMenu" ) )
- {
- WaitSignal( uiGlobal.signalDummy, "OpenErrorDialog", "ActiveMenuChanged" )
- }
-
- OpenDialog( dialogData )
-}
-
-bool function IsDialog( var menu )
-{
- if ( menu == null )
- return false
-
- return uiGlobal.menuData[ menu ].isDialog
-}
-
-bool function IsDialogActive( DialogData dialogData )
-{
- if ( !IsDialog( uiGlobal.activeMenu ) )
- return false
-
- return uiGlobal.menuData[ uiGlobal.activeMenu ].dialogData == dialogData
-}
-
-bool function IsDialogOnlyActiveMenu()
-{
- if ( !IsDialog( uiGlobal.activeMenu ) )
- return false
-
- int stackLen = uiGlobal.menuStack.len()
- if ( stackLen < 1 )
- return false
-
- if ( uiGlobal.menuStack[stackLen - 1] != uiGlobal.activeMenu )
- return false
-
- if ( stackLen == 1 )
- return true
-
- if ( uiGlobal.menuStack[stackLen - 2] == null )
- return true
-
- return false
-}
-
-void function SetNavUpDown( array<var> buttons, var wrap = true )
-{
- Assert( buttons.len() > 0 )
-
- var first = buttons[0]
- var last = buttons[buttons.len() - 1]
- var prev
- var next
- var button
-
- for ( int i = 0; i < buttons.len(); i++ )
- {
- button = buttons[i]
-
- if ( button == first )
- prev = last
- else
- prev = buttons[i - 1]
-
- if ( button == last )
- next = first
- else
- next = buttons[i + 1]
-
- button.SetNavUp( prev )
- button.SetNavDown( next )
-
- //printt( "SetNavUP for:", Hud_GetHudName( button ), "to:", Hud_GetHudName( prev ) )
- //printt( "SetNavDown for:", Hud_GetHudName( button ), "to:", Hud_GetHudName( next ) )
- }
-}
-
-void function SetNavLeftRight( array<var> buttons, var wrap = true )
-{
- Assert( buttons.len() > 0 )
-
- var first = buttons[0]
- var last = buttons[buttons.len() - 1]
- var prev
- var next
- var button
-
- for ( int i = 0; i < buttons.len(); i++ )
- {
- button = buttons[i]
-
- if ( button == first )
- prev = last
- else
- prev = buttons[i - 1]
-
- if ( button == last )
- next = first
- else
- next = buttons[i + 1]
-
- button.SetNavLeft( prev )
- button.SetNavRight( next )
-
- //printt( "SetNavUP for:", Hud_GetHudName( button ), "to:", Hud_GetHudName( prev ) )
- //printt( "SetNavDown for:", Hud_GetHudName( button ), "to:", Hud_GetHudName( next ) )
- }
-}
-
-void function UICodeCallback_EntitlementsChanged()
-{
- if ( uiGlobal.activeMenu == null )
- return
-
- if ( uiGlobal.menuData[ uiGlobal.activeMenu ].entitlementsChangedFunc != null )
- thread uiGlobal.menuData[ uiGlobal.activeMenu ].entitlementsChangedFunc()
-}
-
-#if PC_PROG
-void function QuitGame()
-{
- ClientCommand( "quit" )
-}
-#endif
-
-void function UICodeCallback_StoreTransactionCompleted()
-{
- // this callback is only supported and needed on PS4 currently
-#if PS4_PROG
- if ( InStoreMenu() )
- OnOpenDLCStore()
-#endif
-}
-
-void function UICodeCallback_GamePurchased()
-{
- // this callback is only supported and needed on PC currently
-#if PC_PROG
- DialogData dialogData
- dialogData.header = "#PURCHASE_GAME_COMPLETE"
- dialogData.message = "#PURCHASE_GAME_RESTART"
- AddDialogButton( dialogData, "#QUIT", QuitGame )
-
- OpenDialog( dialogData )
-#endif
-}
-
-bool function IsTrialPeriodActive()
-{
- return GetConVarBool( "trialPeriodIsActive" )
-}
-
-void function LaunchGamePurchaseOrDLCStore( array<string> menuNames = [ "StoreMenu" ] )
-{
- if ( Script_IsRunningTrialVersion() )
- {
- LaunchGamePurchase()
- }
- else
- {
- void functionref() preOpenFunc = null
-
- foreach ( menuName in menuNames )
- {
- // Special case because this menu needs a few properties set before opening
- if ( menuName == "StoreMenu_WeaponSkins" )
- {
- preOpenFunc = DefaultToDLC11WeaponWarpaintBundle
- break
- }
- }
-
- OpenStoreMenu( menuNames, preOpenFunc )
- }
-}
-
-void function UICodeCallback_PartyUpdated()
-{
- if ( AmIPartyLeader() )
- {
- string activeSearchingPlaylist = GetActiveSearchingPlaylist()
- if ( activeSearchingPlaylist != "" && !CanPlaylistFitMyParty( activeSearchingPlaylist ) )
- {
- CancelMatchSearch()
-
- DialogData dialogData
- dialogData.header = "#MATCHMAKING_CANCELED"
- dialogData.message = "#MATCHMAKING_CANCELED_REASON_PARTY_SIZE"
- AddDialogButton( dialogData, "#OK" )
-
- OpenDialog( dialogData )
- }
- }
-}
-
-
-void function HACK_DelayedSetFocus_BecauseWhy( var item )
-{
- wait 0.1
- if ( IsValid( item ) )
- Hud_SetFocused( item )
-}
-
-void function ClassicMusic_OnChange( var button )
-{
- bool isEnabled = GetConVarBool( "sound_classic_music" )
-
- if ( IsFullyConnected() && IsMultiplayer() && GetUIPlayer() )
- {
- if ( IsItemLocked( GetUIPlayer(), "classic_music" ) )
- SetConVarBool( "sound_classic_music", false )
-
- if ( IsLobby() )
- thread RunClientScript( "OnSoundClassicMusicChanged" )
- }
-}
-
-bool function IsClassicMusicAvailable()
-{
- bool classicMusicAvailable = false
- if ( IsFullyConnected() && IsMultiplayer() && GetUIPlayer() )
- classicMusicAvailable = !IsItemLocked( GetUIPlayer(), "classic_music" )
-
- return classicMusicAvailable
-}
-
-void function UICodeCallback_KeyBindOverwritten( string key, string oldbinding, string newbinding )
-{
- DialogData dialogData
- dialogData.header = Localize( "#MENU_KEYBIND_WAS_BEING_USED", key )
- dialogData.message = Localize( "#MENU_KEYBIND_WAS_BEING_USED_SUB", key, Localize( oldbinding ) )
-
- AddDialogButton( dialogData, "#OK" )
-
- OpenDialog( dialogData )
-} \ No newline at end of file
diff --git a/Northstar.Client/scripts/vscripts/ui/menu_main.nut b/Northstar.Client/scripts/vscripts/ui/menu_main.nut
deleted file mode 100644
index 6ffd0d3a..00000000
--- a/Northstar.Client/scripts/vscripts/ui/menu_main.nut
+++ /dev/null
@@ -1,608 +0,0 @@
-global function InitMainMenu
-global function EULA_Dialog
-global function UpdateDataCenterFooter
-global function LaunchGamePurchase
-global function SP_Trial_LaunchGamePurchase
-global function LaunchSPNew
-global function LaunchSPContinue
-global function LaunchSPMissionSelect
-global function LaunchMP
-global function LaunchGame
-global function LaunchSPTrialMission
-global function GetUserSignInState
-
-struct
-{
- var menu
- var versionDisplay
- var trialLabel
-} file
-
-
-void function InitMainMenu()
-{
- RegisterSignal( "EndOnMainMenu_Open" )
-
- var menu = GetMenu( "MainMenu" )
- file.menu = menu
-
- AddMenuEventHandler( menu, eUIEvent.MENU_OPEN, OnMainMenu_Open )
- AddMenuEventHandler( menu, eUIEvent.MENU_NAVIGATE_BACK, OnMainMenu_NavigateBack )
-
- var titleRui = Hud_GetRui( Hud_GetChild( file.menu, "TitleRui" ) )
- RuiSetImage( titleRui, "basicImage", $"rui/menu/main_menu/title")
-
- file.versionDisplay = Hud_GetChild( menu, "versionDisplay" )
- file.trialLabel = Hud_GetChild( menu, "TrialLabel" )
-
- #if CONSOLE_PROG
- AddMenuFooterOption( menu, BUTTON_A, "#A_BUTTON_SELECT", "", null, IsConsoleSignedIn )
- #if DURANGO_PROG
- AddMenuFooterOption( menu, BUTTON_B, "#B_BUTTON_SWITCH_PROFILE", "", null, IsConsoleSignedIn )
- #endif // DURANGO_PROG
-
- AddMenuVarChangeHandler( "CONSOLE_isSignedIn", UpdateFooterOptions )
- #endif // CONSOLE_PROG
-
- #if PC_PROG
- AddMenuFooterOption( menu, BUTTON_A, "#A_BUTTON_SELECT", "" )
- #endif // PC_PROG
-
- AddMenuFooterOption( menu, BUTTON_X, "#X_BUTTON_INBOX_ACCEPT", "#INBOX_ACCEPT", OpenDataCenterDialog, IsDataCenterFooterValid, UpdateDataCenterFooter )
- AddMenuFooterOption( menu, BUTTON_Y, "#Y_MENU_TITLE_MODS", "#MENU_TITLE_MODS", void function( var button ) { AdvanceMenu( GetMenu( "ModListMenu" ) ) } )
-#if DEV
- if ( DevStartPoints() )
- AddMenuFooterOption( menu, BUTTON_Y, "#Y_BUTTON_DEV_MENU", "#DEV_MENU", OpenSinglePlayerDevMenu )
-#endif // DEV
-}
-
-#if CONSOLE_PROG
- bool function IsConsoleSignedIn()
- {
- return ( GetMenuVarBool( "CONSOLE_isSignedIn" ) )
- }
-#endif // CONSOLE_PROG
-
-void function OnMainMenu_Open()
-{
- Signal( uiGlobal.signalDummy, "EndOnMainMenu_Open" )
- EndSignal( uiGlobal.signalDummy, "EndOnMainMenu_Open" )
-
- UpdatePromoData() // On script restarts this gives us the last data until the new request is complete
- RequestMainMenuPromos() // This will be ignored if there was a recent request. "infoblock_requestInterval"
-
- TryUnlockCollectiblesAchievement()
- TryUnlockCompletedGameAchievements()
-
- Hud_SetText( file.versionDisplay, GetPublicGameVersion() )
- Hud_Show( file.versionDisplay )
-
- thread UpdateTrialLabel()
-
-#if PC_PROG
- ActivatePanel( GetPanel( "MainMenuPanel" ) )
- return
-#endif // PC_PROG
-
- int state
- int lastState = -1
- var panel
- var lastPanel
-
- while ( GetTopNonDialogMenu() == file.menu )
- {
- state = GetUserSignInState()
-
- if ( state != lastState )
- {
- if ( state == userSignInState.SIGNED_IN )
- panel = GetPanel( "MainMenuPanel" )
- else
- panel = GetPanel( "EstablishUserPanel" )
-
- if ( panel != lastPanel )
- {
- ActivatePanel( panel )
- lastPanel = panel
- }
- }
-
- lastState = state
-
- WaitFrame()
- }
-}
-
-void function ActivatePanel( var panel )
-{
- Assert( panel != null )
-
- array<var> elems = GetElementsByClassname( file.menu, "MainMenuPanelClass" )
- foreach ( elem in elems )
- {
- if ( elem != panel && Hud_IsVisible( elem ) )
- HidePanel( elem )
- }
-
- ShowPanel( panel )
-}
-
-void function OnMainMenu_NavigateBack()
-{
-#if DURANGO_PROG
- Durango_ShowAccountPicker()
-#endif // DURANGO_PROG
-}
-
-int function GetUserSignInState()
-{
-#if DURANGO_PROG
- if ( Durango_InErrorScreen() )
- {
- return userSignInState.ERROR
- }
- else if ( Durango_IsSigningIn() )
- {
- return userSignInState.SIGNING_IN
- }
- else if ( !Console_IsSignedIn() && !Console_SkippedSignIn() )
- {
- //printt( "Console_IsSignedIn():", Console_IsSignedIn(), "Console_SkippedSignIn:", Console_SkippedSignIn() )
- return userSignInState.SIGNED_OUT
- }
-
- Assert( Console_IsSignedIn() || Console_SkippedSignIn() )
-#endif
- return userSignInState.SIGNED_IN
-}
-
-void function UpdateDataCenterFooter( InputDef data )
-{
- EndSignal( uiGlobal.signalDummy, "EndFooterUpdateFuncs" )
-
- int index = int( Hud_GetScriptID( data.vguiElem ) )
- int ping
- string name
-
- while ( data.conditionCheckFunc() )
- {
- ping = GetDatacenterPing()
- name = GetDatacenterName()
-
- if ( ping > 0 )
- {
- if ( IsControllerModeActive() )
- SetFooterText( file.menu, index, Localize( "#X_BUTTON_DATACENTER_INFO", name, ping ) )
- else
- SetFooterText( file.menu, index, Localize( "#DATACENTER_INFO", name, ping ) )
- }
- else
- {
- if ( IsControllerModeActive() )
- SetFooterText( file.menu, index, "#X_BUTTON_DATACENTER_CALCULATING" )
- else
- SetFooterText( file.menu, index, "#DATACENTER_CALCULATING" )
- }
-
- WaitFrame()
- }
-}
-
-bool function IsDataCenterFooterValid()
-{
- #if PC_PROG
- return ( uiGlobal.activeMenu == file.menu )
- #else
- return ( uiGlobal.activeMenu == file.menu ) && Console_IsOnline() && Console_IsSignedIn()
- #endif
-}
-
-void function SP_Trial_LaunchGamePurchase()
-{
- Disconnect()
- LaunchGamePurchase()
-}
-
-void function LaunchGamePurchase()
-{
- ShowGamePurchaseStore()
-}
-
-void function LaunchSPNew()
-{
- uiGlobal.launching = eLaunching.SINGLEPLAYER_NEW
- LaunchGame()
-}
-
-void function LaunchSPContinue()
-{
- uiGlobal.launching = eLaunching.SINGLEPLAYER_CONTINUE
- LaunchGame()
-}
-
-void function LaunchSPMissionSelect()
-{
- uiGlobal.launching = eLaunching.SINGLEPLAYER_MISSION_SELECT
- LaunchGame()
-}
-
-void function LaunchSPTrialMission()
-{
- uiGlobal.launching = eLaunching.SINGLEPLAYER_MISSION_SELECT
- SPTrialMission_Start()
-}
-
-void function LaunchMP()
-{
- uiGlobal.launching = eLaunching.MULTIPLAYER
- LaunchGame()
-}
-
-void function LaunchGame()
-{
- Assert( uiGlobal.launching == eLaunching.SINGLEPLAYER_NEW ||
- uiGlobal.launching == eLaunching.SINGLEPLAYER_CONTINUE ||
- uiGlobal.launching == eLaunching.SINGLEPLAYER_MISSION_SELECT ||
- uiGlobal.launching == eLaunching.MULTIPLAYER ||
- uiGlobal.launching == eLaunching.MULTIPLAYER_INVITE )
-
- if ( uiGlobal.activeMenu == GetMenu( "PlayVideoMenu" ) )
- {
- SetVideoCompleteFunc( null )
- CloseActiveMenu()
- }
-
- if ( !IsGamePartiallyInstalled() )
- {
- DoGameNeedsToInstallDialog()
- return
- }
-
- // Because accepting an invite tries to launch the game we need this here
- if ( !IsGameFullyInstalled() )
- {
- printt( "Game is not fully installed." )
-
- if ( uiGlobal.launching == eLaunching.SINGLEPLAYER_CONTINUE )
- {
- string saveName = GetSaveName()
- string mapName = SaveGame_GetMapName( saveName )
- int startPointIndex = SaveGame_GetStartPoint( saveName )
-
- printt( mapName )
- printt( startPointIndex )
-
- bool isInTraining = (mapName == "sp_training" && startPointIndex < 5) // "Titanfall" start point
-
- if ( !isInTraining )
- {
- DoGameNeedsToInstallDialog()
- return
- }
-
- printt( "Allowing 'continue' option to load into training." )
- }
- else if ( uiGlobal.launching != eLaunching.SINGLEPLAYER_NEW )
- {
- DoGameNeedsToInstallDialog()
- return
- }
- }
-
- #if CONSOLE_PROG
- if ( !Console_IsSignedIn() )
- {
- printt( "Not signed in." )
- return
- }
-
- if ( GetEULAVersionAccepted() < 1 ) // Treat as binary for now, as discussed with Preston.
- {
- if ( uiGlobal.activeMenu == GetMenu( "EULADialog" ) )
- return
-
- if ( IsDialog( uiGlobal.activeMenu ) )
- CloseActiveMenu( true )
-
- EULA_Dialog()
- return
- }
-
- if ( Nucleus_GetState() == NUCLEUS_STATE_INACTIVE )
- Nucleus_Login()
-
- if ( !uiGlobal.triedNucleusRegistration && uiGlobal.launching == eLaunching.MULTIPLAYER && !Nucleus_GetSkipRegistration() )
- {
- uiGlobal.triedNucleusRegistration = true
- thread Nucleus_HandleLoginResponse()
- return
- }
-
- if ( !GetConVarBool( "gamma_adjusted" ) )
- {
- if ( IsDialog( uiGlobal.activeMenu ) )
- CloseActiveMenu( true )
-
- AdvanceMenu( GetMenu( "GammaMenu" ) )
- return
- }
- #endif // CONSOLE_PROG
-
- if ( ( uiGlobal.launching == eLaunching.MULTIPLAYER || uiGlobal.launching == eLaunching.MULTIPLAYER_INVITE ) && !IsAdvocateGiftComplete() )
- {
- if ( IsDialog( uiGlobal.activeMenu ) )
- CloseActiveMenu( true )
-
- AdvanceMenu( GetMenu( "AdvocateGiftDialog" ) )
- return
- }
-
- SetMenuWasMultiplayerPlayedLast( true )
- if ( uiGlobal.launching == eLaunching.SINGLEPLAYER_NEW )
- NewGameSelected()
- else if ( uiGlobal.launching == eLaunching.SINGLEPLAYER_CONTINUE )
- LoadLastCheckpoint()
- else if ( uiGlobal.launching == eLaunching.SINGLEPLAYER_MISSION_SELECT )
- AdvanceMenu( GetMenu( "SinglePlayerMenu" ) )
- else
- thread StartSearchForPartyServer()
-
- uiGlobal.launching = eLaunching.FALSE
-}
-
-void function StartSearchForPartyServer()
-{
- printt( "StartSearchForPartyServer" )
-
-#if DURANGO_PROG
- // IMPORTANT: As a safety measure leave any party view we are in at this point.
- // Otherwise, if you are unlucky enough to get stuck in a party view, you will
- // trash its state by pointing it to your private lobby.
- Durango_LeaveParty()
-
- // IMPORTANT: It's possible that you have permission to play multiplayer
- // because your friend is signed in with his gold account on your machine,
- // but once that guy signs out, you shouldn't be able to play like you have
- // xboxlive gold anymore. To fix this, we need to check permissions periodically.
- // One of the places where we do this periodic check is when you press "PLAY"
- printt( "Durango - verifying MP permissions" )
- if ( !Console_HasPermissionToPlayMultiplayer() )
- Durango_VerifyMultiplayerPermissions()
-#endif // DURANGO_PROG
-
- Signal( uiGlobal.signalDummy, "OnCancelConnect" )
- EndSignal( uiGlobal.signalDummy, "OnCancelConnect" )
-
- if ( IsDialog( uiGlobal.activeMenu ) )
- CloseActiveMenu( true )
- OpenConnectingDialog()
-
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "" )
- Hud_SetText( uiGlobal.ConfirmMenuErrorCode, "" )
-
- Hud_Show( uiGlobal.ConfirmMenuMessage )
- Hud_Show( uiGlobal.ConfirmMenuErrorCode )
-
-#if DURANGO_PROG
- if( !Console_IsOnline() )
- {
- printt( "Durango - finding empty party server failed - not online" )
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "#DURANGO_NOT_ONLINE" )
- return
- }
-#endif // DURANGO_PROG
-
-#if PS4_PROG
- if( !Console_IsOnline() )
- {
- printt( "PS4 - finding empty party server failed - not online" )
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "#INTERNET_NOT_FOUND" )
- return
- }
-
- if ( PS4_isNetworkingDown() )
- {
- printt( "PS4 - finding empty party server failed - networking is down" )
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "#PSN_CANNOT_CONNECT" )
- return
- }
-
- if( !PS4_isUserNetworkingEnabled() )
- {
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "#PSN_CHECKING_USABILITY" )
- PS4_ScheduleUserNetworkingEnabledTest()
- WaitFrame()
-
- if( !PS4_isUserNetworkingResolved() )
- {
- printt( "PS4 - finding empty party server stalled - networking isn't resolved yet" )
- // offer cancel ??
- while( !PS4_isUserNetworkingResolved())
- WaitFrame()
- }
-
- if( PS4_getUserNetworkingResolution() == PS4_NETWORK_STATUS_NOT_LOGGED_IN )
- {
- Hud_SetText( uiGlobal.ConfirmMenuErrorCode, string(PS4_getUserNetworkingErrorStatus()) )
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "#PSN_LOGIN" )
-
- Ps4_LoginDialog_Schedule()
- while( Ps4_LoginDialog_Running() )
- WaitFrame()
-
- PS4_ScheduleUserNetworkingEnabledTest()
- WaitFrame()
- if( !PS4_isUserNetworkingResolved() )
- {
- Hud_SetText( uiGlobal.ConfirmMenuErrorCode, "" )
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "#PSN_CHECKING_USABILITY" )
- while( !PS4_isUserNetworkingResolved())
- WaitFrame()
- }
- }
-
- if( PS4_getUserNetworkingResolution() == PS4_NETWORK_STATUS_AGE_RESTRICTION )
- {
- Hud_SetText( uiGlobal.ConfirmMenuErrorCode, string(PS4_getUserNetworkingErrorStatus()) )
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "#MULTIPLAYER_AGE_RESTRICTED" )
- return
- }
-
- if( PS4_getUserNetworkingResolution() == PS4_NETWORK_STATUS_IN_ERROR )
- {
- Hud_SetText( uiGlobal.ConfirmMenuErrorCode, string(PS4_getUserNetworkingErrorStatus()) )
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "#PSN_HAD_ERROR" )
- return
- }
-
- if( !PS4_isUserNetworkingEnabled() )
- {
- Hud_SetText( uiGlobal.ConfirmMenuErrorCode, string(PS4_getUserNetworkingErrorStatus()) )
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "#PSN_NOT_ALLOWED" )
- return
- }
-
- Hud_SetText( uiGlobal.ConfirmMenuErrorCode, "" )
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "" )
- }
-
- if ( !Ps4_PSN_Is_Loggedin() )
- {
- Ps4_LoginDialog_Schedule()
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "#PSN_LOGIN" )
-
- while( Ps4_LoginDialog_Running() )
- WaitFrame()
-
- if ( !Ps4_PSN_Is_Loggedin() )
- return
- }
-
- if( Ps4_CheckPlus_Schedule() )
- {
- while( Ps4_CheckPlus_Running() )
- WaitFrame()
- if( !Ps4_CheckPlus_Allowed() )
- {
- if( Ps4_CheckPlus_GetLastRequestResults() != 0 )
- {
- Hud_SetText( uiGlobal.ConfirmMenuErrorCode, string( Ps4_CheckPlus_GetLastRequestResults()) )
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "#PSN_HAD_ERROR" )
- return
- }
-
- if( Ps4_ScreenPlusDialog_Schedule() )
- {
- while( Ps4_ScreenPlusDialog_Running() )
- WaitFrame()
- if( !Ps4_ScreenPlusDialog_Allowed() )
- {
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "#PSN_MUST_BE_PLUS_USER" )
- return
- }
- }
- else
- {
- return
- }
- }
- }
-
- Hud_SetText( uiGlobal.ConfirmMenuErrorCode, "" )
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "" )
-#endif // #if PS4_PROG
-
- printt( "Checking if this user has permission to play MP\n" )
- if ( !Console_HasPermissionToPlayMultiplayer() )
- {
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "#MULTIPLAYER_NOT_AVAILABLE" )
- return
- }
-
- Plat_ShowUGCRestrictionNotice()
- while ( Plat_IsSystemMessageDialogOpen() )
- WaitFrame()
-
- Plat_ShowChatRestrictionNotice()
- while ( Plat_IsSystemMessageDialogOpen() )
- WaitFrame()
-
-#if PC_PROG
- if ( Origin_IsEnabled() )
- {
- Origin_RequestTicket()
- Hud_SetText( uiGlobal.ConfirmMenuMessage, "#WAITING_FOR_ORIGIN" )
-
- while ( !Origin_IsReady() )
- WaitFrame()
- }
-#endif // PC_PROG
-
- printt( "SearchForPartyServer" )
- SetMenuWasMultiplayerPlayedLast( true )
- SearchForPartyServer()
-
- Hud_SetAutoText( uiGlobal.ConfirmMenuMessage, "", HATT_MATCHMAKING_EMPTY_SERVER_SEARCH_STATE, 0 )
- Hud_SetAutoText( uiGlobal.ConfirmMenuErrorCode, "", HATT_MATCHMAKING_EMPTY_SERVER_SEARCH_ERROR, 0 )
-}
-
-void function EULA_Dialog()
-{
- if ( GetUserSignInState() != userSignInState.SIGNED_IN )
- return
-
- if ( GetEULAVersionAccepted() >= 1 )
- return
-
- AdvanceMenu( GetMenu( "EULADialog" ) )
-}
-
-void function DoGameNeedsToInstallDialog()
-{
- DialogData dialogData
- dialogData.header = "#MENU_WAIT_FOR_INTALL"
-
- int installProgress = int( GetGameFullyInstalledProgress()*100 )
-
- if ( uiGlobal.launching == eLaunching.MULTIPLAYER && IsGamePartiallyInstalled() && !Script_IsRunningTrialVersion() )
- {
- dialogData.message = Localize("#MENU_WAIT_FOR_INTALL_HINT", installProgress )
- AddDialogButton( dialogData, "#YES", LaunchSPNew )
- AddDialogButton( dialogData, "#NO" )
- }
- else
- {
- dialogData.message = Localize("#MENU_WAIT_FOR_INTALL_HINT_NOTRAINING", installProgress )
- AddDialogButton( dialogData, "#OK" )
- }
-
- AddDialogFooter( dialogData, "#A_BUTTON_SELECT" )
- AddDialogFooter( dialogData, "#B_BUTTON_CANCEL" )
-
- OpenDialog( dialogData )
-}
-
-void function UpdateTrialLabel()
-{
- bool isTrialVersion
- bool lastIsTrialVersion = Script_IsRunningTrialVersion()
-
- Hud_SetVisible( file.trialLabel, lastIsTrialVersion )
-
- while ( GetTopNonDialogMenu() == file.menu )
- {
- isTrialVersion = Script_IsRunningTrialVersion()
-
- if ( isTrialVersion != lastIsTrialVersion )
- Hud_SetVisible( file.trialLabel, isTrialVersion )
-
- lastIsTrialVersion = isTrialVersion
-
- WaitFrame()
- }
-}
-
-void function OpenSinglePlayerDevMenu( var button )
-{
- AdvanceMenu( GetMenu( "SinglePlayerDevMenu" ) )
-}
diff --git a/Northstar.Client/scripts/vscripts/ui/menu_mode_select.nut b/Northstar.Client/scripts/vscripts/ui/menu_mode_select.nut
deleted file mode 100644
index 23376781..00000000
--- a/Northstar.Client/scripts/vscripts/ui/menu_mode_select.nut
+++ /dev/null
@@ -1,135 +0,0 @@
-global function InitModesMenu
-
-struct {
- int currentModePage
-} file
-
-const int MODES_PER_PAGE = 15
-
-void function InitModesMenu()
-{
- var menu = GetMenu( "ModesMenu" )
-
- AddMenuEventHandler( menu, eUIEvent.MENU_OPEN, OnOpenModesMenu )
-
- AddEventHandlerToButtonClass( menu, "ModeButton", UIE_GET_FOCUS, ModeButton_GetFocus )
- AddEventHandlerToButtonClass( menu, "ModeButton", UIE_CLICK, ModeButton_Click )
-
- AddMenuFooterOption( menu, BUTTON_A, "#A_BUTTON_SELECT" )
- AddMenuFooterOption( menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" )
-
- AddMenuFooterOption( menu, BUTTON_SHOULDER_LEFT, "#PRIVATE_MATCH_PAGE_PREV", "#PRIVATE_MATCH_PAGE_PREV", CycleModesBack, IsNorthstarServer )
- AddMenuFooterOption( menu, BUTTON_SHOULDER_RIGHT, "#PRIVATE_MATCH_PAGE_NEXT", "#PRIVATE_MATCH_PAGE_NEXT", CycleModesForward, IsNorthstarServer )
-}
-
-void function OnOpenModesMenu()
-{
- UpdateVisibleModes()
-
- if ( level.ui.privatematch_mode == 0 ) // set to the first mode if there's no mode focused
- Hud_SetFocused( GetElementsByClassname( GetMenu( "ModesMenu" ), "ModeButton" )[ 0 ] )
-}
-
-void function UpdateVisibleModes()
-{
- // ensures that we only ever show enough buttons for the number of modes we have
- array<var> buttons = GetElementsByClassname( GetMenu( "ModesMenu" ), "ModeButton" )
- foreach ( var button in buttons )
- {
- Hud_SetEnabled( button, false )
- Hud_SetVisible( button, false )
- }
-
- array<string> modesArray = GetPrivateMatchModes()
- for ( int i = 0; i < MODES_PER_PAGE; i++ )
- {
- if ( i + ( file.currentModePage * MODES_PER_PAGE ) >= modesArray.len() )
- break
-
- int modeIndex = i + ( file.currentModePage * MODES_PER_PAGE )
- SetButtonRuiText( buttons[ i ], GetGameModeDisplayName( modesArray[ modeIndex ] ) )
- Hud_SetEnabled( buttons[ i ], true )
- Hud_SetVisible( buttons[ i ], true )
- Hud_SetLocked( buttons[ i ], false )
-
- if ( !PrivateMatch_IsValidMapModeCombo( PrivateMatch_GetSelectedMap(), modesArray[ modeIndex ] ) && !IsNorthstarServer() )
- {
- Hud_SetLocked( buttons[ i ], true )
- SetButtonRuiText( buttons[ i ], Localize( "#PRIVATE_MATCH_UNAVAILABLE", Localize( GetGameModeDisplayName( modesArray[ modeIndex ] ) ) ) )
- }
- }
-}
-
-void function ModeButton_GetFocus( var button )
-{
- int modeId = int( Hud_GetScriptID( button ) ) + ( file.currentModePage * MODES_PER_PAGE )
-
- var menu = GetMenu( "ModesMenu" )
- var nextModeImage = Hud_GetChild( menu, "NextModeImage" )
- var nextModeIcon = Hud_GetChild( menu, "ModeIconImage" )
- var nextModeName = Hud_GetChild( menu, "NextModeName" )
- var nextModeDesc = Hud_GetChild( menu, "NextModeDesc" )
-
- array<string> modesArray = GetPrivateMatchModes()
-
- if ( modeId > modesArray.len() )
- return
-
- string modeName = modesArray[modeId]
-
- asset playlistImage = GetPlaylistImage( modeName )
- RuiSetImage( Hud_GetRui( nextModeImage ), "basicImage", playlistImage )
- RuiSetImage( Hud_GetRui( nextModeIcon ), "basicImage", GetPlaylistThumbnailImage( modeName ) )
- Hud_SetText( nextModeName, GetGameModeDisplayName( modeName ) )
-
- string mapName = PrivateMatch_GetSelectedMap()
- bool mapSupportsMode = PrivateMatch_IsValidMapModeCombo( mapName, modeName )
- if ( !mapSupportsMode && !IsNorthstarServer() )
- Hud_SetText( nextModeDesc, Localize( "#PRIVATE_MATCH_MODE_NO_MAP_SUPPORT", Localize( GetGameModeDisplayName( modeName ) ), Localize( GetMapDisplayName( mapName ) ) ) )
- else if ( IsFDMode( modeName ) ) // HACK!
- Hud_SetText( nextModeDesc, Localize( "#FD_PLAYERS_DESC", Localize( GetGameModeDisplayHint( modeName ) ) ) )
- else
- Hud_SetText( nextModeDesc, GetGameModeDisplayHint( modeName ) )
-}
-
-void function ModeButton_Click( var button )
-{
- // this never activates on custom servers, but keeping it for parity with official
- if ( !AmIPartyLeader() && GetPartySize() > 1 )
- return
-
- if ( Hud_IsLocked( button ) )
- return
-
- int modeID = int( Hud_GetScriptID( button ) ) + ( file.currentModePage * MODES_PER_PAGE )
-
- array<string> modesArray = GetPrivateMatchModes()
- string modeName = modesArray[ modeID ]
-
- // on modded servers set us to the first map for that mode automatically
- // need this for coliseum mainly which is literally impossible to select without this
- if ( IsNorthstarServer() && !PrivateMatch_IsValidMapModeCombo( PrivateMatch_GetSelectedMap(), modesArray[ modeID ] ) )
- ClientCommand( "SetCustomMap " + GetPrivateMatchMapsForMode( modeName )[ 0 ] )
-
- // set it
- ClientCommand( "PrivateMatchSetMode " + modeName )
- CloseActiveMenu()
-}
-
-void function CycleModesBack( var button )
-{
- if ( file.currentModePage == 0 )
- return
-
- file.currentModePage--
- UpdateVisibleModes()
-}
-
-void function CycleModesForward( var button )
-{
- if ( ( file.currentModePage + 1 ) * MODES_PER_PAGE >= GetPrivateMatchModes().len() )
- return
-
- file.currentModePage++
- UpdateVisibleModes()
-} \ No newline at end of file
diff --git a/Northstar.Coop/mod.json b/Northstar.Coop/mod.json
deleted file mode 100644
index 9f657cdd..00000000
--- a/Northstar.Coop/mod.json
+++ /dev/null
@@ -1,24 +0,0 @@
-disabled{
- "ApiId" : "Northstar.Coop",
- "Name" : "Northstar.Coop",
- "Description" : "Various script patches to fix functionality for coop servers",
- "Authors" : [
- "BobTheBob"
- ],
- "Contacts" : [
- "BobTheBob#1150"
- ],
- "Version" : "0.1",
- "CustomScripts": [
- {
- "Path": "sp/_coop_sp_utils.gnut",
- "RunOn": "SERVER && SP",
- "ServerCallback": "CoopSpUtils_Init"
- },
- {
- "Path": "sp/sh_coop_sp_utils.gnut",
- "RunOn": "( CLIENT || SERVER ) && SP",
- "ServerCallback": "ClCoopSpUtils_Init"
- }
- ]
-} \ No newline at end of file
diff --git a/Northstar.Coop/scripts/vscripts/client/cl_respawnselect_sp.gnut b/Northstar.Coop/scripts/vscripts/client/cl_respawnselect_sp.gnut
deleted file mode 100644
index eab80e98..00000000
--- a/Northstar.Coop/scripts/vscripts/client/cl_respawnselect_sp.gnut
+++ /dev/null
@@ -1,110 +0,0 @@
-global function ShowRespawnSelect_SP
-global function ClRespawnselect_SP_Init
-global function DisableDeathBlur
-global function DisplayRespawnPrompt
-
-struct
-{
- bool deathBlur = false // death blur will stay after respawn if we don't remove it
- bool canRespawn = false
- var respawnHintRui
-} file
-
-
-void function ClRespawnselect_SP_Init()
-{
- Assert( !IsMultiplayer() )
-
- AddCallback_OnPlayerLifeStateChanged( Callback_PlayerLifestateChanged )
- file.respawnHintRui = RuiCreate( $"ui/respawn_hint.rpak", clGlobal.topoFullScreen, RUI_DRAW_HUD, RUI_SORT_SCREENFADE + 100 )
- RuiSetResolutionToScreenSize( file.respawnHintRui )
-
- // register these early so we don't end up registering multiple times and crashing later
- RegisterButtonPressedCallback( KEY_SPACE, PlayerPressed_RespawnPilotSP )
- RegisterButtonPressedCallback( BUTTON_X, PlayerPressed_RespawnPilotSP )
-}
-
-void function Callback_PlayerLifestateChanged( entity player, int oldLifeState, int newLifeState )
-{
- if ( player.GetPlayerSettings() == "spectator" )
- {
- if ( !IsTestMap() )
- {
- ScreenFade( GetLocalViewPlayer(), 0, 0, 0, 255, 0.5, 1.0, FFADE_IN )
- //printt( "cl SCREENFADE: " + 0.5 + " " + 1.0 )
- }
- return
- }
-
- if ( oldLifeState == newLifeState )
- return
-
- if ( player != GetLocalViewPlayer() )
- return
-
- //if ( newLifeState == LIFE_DEAD )
- // thread ShowRespawnSelect_SP()
-}
-
-void function DisableDeathBlur()
-{
- file.deathBlur = false
-}
-
-void function ShowRespawnSelect_SP()
-{
-}
-
-void function PlayerPressed_RespawnPilotSP( entity player )
-{
- if ( file.canRespawn )
- {
- player.ClientCommand( "RespawnNowSP" )
- RuiSetBool( file.respawnHintRui, "isVisible", false )
- file.canRespawn = false
- }
-}
-
-void function DisplayRespawnPrompt()
-{
- // move this out of here since otherwise the client will attempt to bind it multiple times which crashes
- //RegisterButtonPressedCallback( KEY_SPACE, PlayerPressed_RespawnPilotSP )
- //RegisterButtonPressedCallback( BUTTON_X, PlayerPressed_RespawnPilotSP )
-
- // delay this so it coincides with serverside respawn delay
- //RuiSetBool( file.respawnHintRui, "isVisible", true )
-
- print( "DisplayRespawnPrompt()" )
- if ( !AreAllPlayersDead() )
- thread WaitToDisplayRespawnPrompt()
- else
- thread LevelFailedEffect()
-}
-
-void function WaitToDisplayRespawnPrompt()
-{
- print( "waittodisplayrespawnprompt()" )
- // display respawn ui
- RuiSetBool( file.respawnHintRui, "isVisible", true )
-
- entity player = GetLocalViewPlayer()
- RuiSetGameTime( file.respawnHintRui, "nextSpawnTime", expect float( player.nv.nextRespawnTime ) )
-
- // wait until we can respawn
- wait expect float( player.nv.nextRespawnTime ) - Time()
-
- // wait until server will allow a respawn to enable it
- file.canRespawn = true
-}
-
-void function LevelFailedEffect()
-{
- print( "levelfailedeffect()")
- // display the fade that gets displayed in vanilla on death
-
- wait 1.5
- SetScreenBlur( 1.0, 1.0, EASING_LINEAR )
-
- wait 0.25
- ScreenFade( GetLocalViewPlayer(), 0, 0, 0, 255, 0.8, 5, FFADE_OUT )
-} \ No newline at end of file
diff --git a/Northstar.Coop/scripts/vscripts/sp/_base_gametype_sp.gnut b/Northstar.Coop/scripts/vscripts/sp/_base_gametype_sp.gnut
deleted file mode 100644
index bdfa895a..00000000
--- a/Northstar.Coop/scripts/vscripts/sp/_base_gametype_sp.gnut
+++ /dev/null
@@ -1,657 +0,0 @@
-untyped
-global function BaseGametype_Init_MPSP
-global function CodeCallback_OnWeaponAttack
-global function CodeCallback_OnPlayerMatchmakingChanged
-global function CodeCallback_OnClientConnectionCompleted
-global function CodeCallback_OnClientDisconnected
-global function CodeCallback_OnPlayerRespawned
-global function CodeCallback_OnWeaponTouch
-global function CodeCallback_WeaponDropped
-global function DecideRespawnPlayer
-global function ShouldEntTakeDamage_SPMP
-global function ShouldUseReplacementSpawn
-global function TryGameModeAnnouncement
-global function CodeCallback_OnClientConnectionStarted
-global function CodeCallback_OnPlayerKilled
-global function CreateNoSpawnArea
-global function DeleteNoSpawnArea
-global function IsSpawnpointValidDrop
-global function ClientCommand_OpenDifficultyMenu
-global function CodeCallback_PlayerHasBeenConnectedForDuration
-global function OnPlayerKilled_DeathNotify
-global function GetSPLevelEnumForMapname
-
-global void functionref( entity, entity ) hackRespawnPlayerFunc
-
-struct
-{
- float lastObitMsgTime = 0.0
- int wallRunKills = 0
- int slideKills = 0
- float lastMultiKillStartTime = 0.0
- int multiKillCount = 0
-} file
-
-void function BaseGametype_Init_MPSP()
-{
- AddClientCommandCallback( "ClientCommand_OpenDifficultyMenu", ClientCommand_OpenDifficultyMenu )
-
- AddCallback_OnPlayerKilled( OnPlayerKilled_DeathNotify )
- AddCallback_OnPlayerInventoryChanged( RefreshWeaponHighlights )
- AddCallback_OnPilotBecomesTitan( RefreshWeaponHighlightTitanTransfer )
- AddCallback_OnTitanBecomesPilot( RefreshWeaponHighlightTitanTransfer )
-
- if ( GetMapName() != "sp_training" )
- {
- AddDeathCallback( "npc_soldier", OnNPCKilled )
- AddDeathCallback( "npc_spectre", OnNPCKilled )
- AddDeathCallback( "npc_prowler", OnNPCKilled )
- AddDeathCallback( "npc_titan", OnNPCKilled )
- AddDeathCallback( "npc_stalker", OnNPCKilled )
- AddDeathCallback( "npc_drone", OnNPCKilled )
- AddDeathCallback( "npc_frag_drone", OnNPCKilled )
- AddDeathCallback( "npc_turret_sentry", OnNPCKilled )
- }
-
- RegisterSignal( "RevertToRegularHighlight" )
-
- FlagInit( "WeaponDropsAllowed" )
- FlagSet( "WeaponDropsAllowed" )
-
- hackRespawnPlayerFunc = HackRespawnPlayer
-}
-
-void function HackRespawnPlayer( entity player, entity respawnOn )
-{
- player.RespawnPlayer( null )
-}
-
-void function CodeCallback_OnWeaponAttack( entity player, entity weapon, string weaponName, int ammoUsed )
-{
-
-}
-
-void function CodeCallback_OnPlayerMatchmakingChanged( entity player )
-{
-
-}
-
-// playerconnected
-void function CodeCallback_OnClientConnectionCompleted( entity player )
-{
- if ( IsLobby() )
- {
- level.Lobby_OnClientConnectionCompleted( player )
- return
- }
-
- player.hasConnected = true
-
- InitMeleeAnimEventCallbacks( player )
- ZiplineInit( player )
-
- FinishClientScriptInitialization( player )
-
- // Added via AddCallback_OnClientConnected
- foreach ( callbackFunc in svGlobal.onClientConnectedCallbacks )
- {
- callbackFunc( player )
- }
-
- if ( !Flag( "PlayerDidSpawn") )
- {
- __PlayerDidSpawn( player )
- svGlobal.levelEnt.Signal( "PlayerDidSpawn", { player = player } )
- }
-
- // Player was already positioned at info_player_start in SpPlayerConnecting.
- // Don't reposition him, in case movers have already pushed him.
- player.RespawnPlayer( null )
- AddPlayerMovementEventCallback( player, ePlayerMovementEvents.BEGIN_WALLRUN, Callback_WallrunBegin )
-}
-
-void function CodeCallback_OnClientDisconnected( entity player, string reason )
-{
- if ( IsLobby() )
- {
- player.Signal( "_disconnectedInternal" )
- UpdateBadRepPresent()
- return
- }
-
- if ( !player.hasConnected )
- return
-
- // Added via AddCallback_OnClientDisconnected
- foreach ( callbackFunc in svGlobal.onClientDisconnectedCallbacks )
- {
- callbackFunc( player )
- }
-
- player.Disconnected()
- player.p.isDisconnected = true
- player.CleanupMPClasses()
-}
-
-int function GetSPLevelEnumForMapname( string mapName )
-{
- switch ( mapName )
- {
- case "sp_training":
- return eSPLevel.TRAINING
-
- case "sp_crashsite":
- return eSPLevel.WILDS
-
- case "sp_sewers1":
- return eSPLevel.SEWERS
-
- case "sp_boomtown_start":
- case "sp_boomtown":
- case "sp_boomtown_end":
- return eSPLevel.BOOM_TOWN
-
- case "sp_hub_timeshift":
- case "sp_timeshift_spoke02":
- return eSPLevel.TIME_SHIFT
-
- case "sp_beacon":
- case "sp_beacon_spoke0":
- return eSPLevel.BEACON
-
- case "sp_tday":
- return eSPLevel.TDAY
-
- case "sp_s2s":
- return eSPLevel.SHIP2SHIP
-
- case "sp_skyway_v1":
- return eSPLevel.SKYWAY
-
- default:
- return eSPLevel.UNKNOWN
- }
-
- unreachable
-}
-
-bool function ShouldGiveFullGrenades()
-{
- int levelID = GetSPLevelEnumForMapname( GetMapName() )
- if ( levelID == eSPLevel.UNKNOWN )
- return true
-
- LevelTransitionStruct ornull trans = GetLevelTransitionStruct()
- if ( trans == null )
- return true
-
- expect LevelTransitionStruct( trans )
- if ( trans.levelID != levelID )
- return true
-
- return false
-}
-
-void function CodeCallback_OnPlayerRespawned( entity player )
-{
- SetHumanRagdollImpactTable( player )
-
- player.s.respawnCount++
- player.s.respawnTime = Time()
- ClearRecentDamageHistory( player )
-
- player.Signal( "OnRespawned" )
-
- PilotLoadoutDef loadout = GetPilotLoadoutForCurrentMapSP()
- if ( !IsTestMap() )
- PopulatePilotLoadoutFromLevelTrans( loadout )
- GivePilotLoadout( player, loadout )
-
- if ( ShouldGiveFullGrenades() )
- {
- entity ordnanceWeapon = player.GetOffhandWeapon( OFFHAND_ORDNANCE )
- if ( IsValid( ordnanceWeapon ) )
- {
- int maxClip = ordnanceWeapon.GetWeaponPrimaryClipCountMax()
- if ( maxClip > 0 )
- ordnanceWeapon.SetWeaponPrimaryClipCount( maxClip )
- }
- }
-
-
- LevelTransitionStruct ornull trans = GetLevelTransitionStruct()
- if ( trans != null )
- {
- expect LevelTransitionStruct( trans )
- if ( trans.pilotHasBattery )
- {
- entity battery = Rodeo_CreateBatteryPack()
- Rodeo_PilotPicksUpBattery_Silent( player, battery )
- }
- }
-
- NPCTitanInitModeOnPlayerRespawn( player )
-
- // Added via AddCallback_OnPlayerRespawned
- foreach ( callbackFunc in svGlobal.onPlayerRespawnedCallbacks )
- {
- callbackFunc( player )
- }
-
- player.e.lastAttacker = null
-}
-
-void function DecideRespawnPlayer( entity player )
-{
-}
-
-
-// Returns bool or nothing
-function RespawnTitanPilot( entity player )
-{
-}
-
-bool function ShouldEntTakeDamage_SPMP( entity ent, var damageInfo )
-{
- return true
-}
-
-bool function ShouldUseReplacementSpawn( entity player )
-{
- return false
-}
-
-void function TryGameModeAnnouncement( entity player )
-{
-
-}
-
-void function CodeCallback_OnClientConnectionStarted( entity player )
-{
- // not a real player?
- #if DEV
- if ( player.GetPlayerName() == "Replay" )
- return
- #endif
-
- if ( IsLobby() )
- {
- level.Lobby_OnClientConnectionStarted( player )
- return
- }
-
-// ScreenFade( player, 0, 0, 0, 255, 2.0, 0.5, FFADE_IN | FFADE_PURGE )
-
- SetTargetName( player, "player" + player.entindex() )
-
- player.p.controllableProjectiles_scriptManagedID = CreateScriptManagedEntArray()
- player.p.npcFollowersArrayID = CreateScriptManagedEntArray()
-
- player.s = {}
- player.s.attackerInfo <- {}
- player.p.clientScriptInitialized = player.IsBot()
- player.s.inPostDeath <- null
- player.s.respawnCount <- 0
- player.s.respawnTime <- 0
- player.s.lostTitanTime <- 0
- player.s.cloakedShotsAllowed <- 0
- player.s.startDashMeleeTime <- 0
- player.s.respawnSelectionDone <- true // this gets set to false in postdeaththread but we need it to be true when connecting
- player.s.waveSpawnProtection <- false
-
- player.s.nextStatUpdateFunc <- null
-
- player.s.activeTrapArrayId <- CreateScriptManagedEntArray()
-
- player.s.restartBurnCardEffectOnSpawn <- false
- player.s.replacementDropInProgress <- false
-
- player.s.inGracePeriod <- true
-
- // should I just add these when playing coop?
- player.s.usedLoadoutCrate <- false
- player.s.restockAmmoTime <- 0
- player.s.restockAmmoCrate <- null
-
- player.s.autoTitanLastEngageCalloutTime <- 0
- player.s.autoTitanLastEngageCallout <- null
- player.s.lastAIConversationTime <- {} // when was a conversation last played?
-
- player.s.updatedPersistenceOnDisconnect <- false
-
- player.s.lastFriendlySpawnedOn <- null
- player.s.nextWaveSpawnTime <- 0.0
-
- player.s.meleeSlowMoEndTime <- 0.0
-
- Assert( !player._entityVars )
-
- // Added via AddCallback_OnClientConnecting
- foreach ( callbackFunc in svGlobal.onClientConnectingCallbacks )
- {
- callbackFunc( player )
- }
-
- // do this after callbacks so we can define our own player script vars in callbacks
- InitEntityVars( player )
-
- printl( "Player connect started: " + player )
-
- thread PilotHealthRegenThinkSP( player )
-}
-
-void function CodeCallback_OnPlayerKilled( entity player, var damageInfo )
-{
- thread PostDeathThread_SP( player, damageInfo )
-}
-
-function PostDeathThread_SP( entity player, damageInfo )
-{
- if ( player.p.watchingPetTitanKillReplay )
- return
-
- float timeOfDeath = Time()
- player.p.postDeathThreadStartTime = Time()
-
- Assert( IsValid( player ), "Not a valid player" )
- player.EndSignal( "OnDestroy" )
- player.EndSignal( "OnRespawned" )
-
- player.p.deathOrigin = player.GetOrigin()
- player.p.deathAngles = player.GetAngles()
-
- player.s.inPostDeath = true
- player.s.respawnSelectionDone = false
-
- player.cloakedForever = false
- player.stimmedForever = false
- player.SetNoTarget( false )
- player.SetNoTargetSmartAmmo( false )
- player.ClearExtraWeaponMods()
-
- entity attacker = DamageInfo_GetAttacker( damageInfo )
- int methodOfDeath = DamageInfo_GetDamageSourceIdentifier( damageInfo )
-
- player.p.rematchOrigin = player.p.deathOrigin
- if ( IsValid( attacker ) && methodOfDeath == eDamageSourceId.titan_execution )
- {
- // execution can throw you out of the map
- player.p.rematchOrigin = attacker.GetOrigin()
- }
-
- int attackerViewIndex = attacker.GetIndexForEntity()
-
- player.SetPredictionEnabled( false )
- player.Signal( "RodeoOver" )
- player.ClearParent()
- bool showedDeathHint = ShowDeathHintSP( player, damageInfo )
-
- int damageSource = DamageInfo_GetDamageSourceIdentifier( damageInfo )
- if ( damageSource != eDamageSourceId.fall )
- {
- player.StartObserverMode( OBS_MODE_DEATHCAM )
- if ( ShouldSetObserverTarget( attacker ) )
- player.SetObserverTarget( attacker )
- else
- player.SetObserverTarget( null )
- }
-
- foreach( callbackFunc in svGlobal.onPlayerKilledCallbacks )
- {
- callbackFunc( player, attacker, damageInfo )
- }
-
- float reloadExtraDelay
- if ( showedDeathHint )
- reloadExtraDelay = 3.2
-
- ReloadForMissionFailure( reloadExtraDelay )
-}
-
-
-
-
-function FinalPlayerUpdate( entity player )
-{
- // every player runs this either after match/evac, or when they disconnect
-
- // in case you disconnect during final scoreboard
- if ( "ranFinalPlayerUpdate" in player.s )
- return
- player.s.ranFinalPlayerUpdate <- true
-}
-
-/*------------------------------------------------------------------------
-DUMPSITE FROM OTHER FILES
---------------------------------------------------------------------------*/
-
-string function CreateNoSpawnArea( int blockSpecificTeam, int blockEnemiesOfTeam, vector origin, float timeout, float length, width = null, angles = null )
-{
- return ""
-}
-
-void function DeleteNoSpawnArea( string id )
-{
-
-}
-
-
-bool function IsSpawnpointValidDrop( entity spawnpoint, int team )
-{
- return true
-}
-
-bool function ClientCommand_OpenDifficultyMenu( entity player, array<string> args )
-{
- if ( IsValid( player ) )
- Remote_CallFunction_UI( player, "ServerCallback_OpenDifficultyMenu" )
- return true
-}
-
-
-void function CodeCallback_PlayerHasBeenConnectedForDuration( entity player, float durationInSeconds ) //Empty function declaration to stop load error.
-{
-}
-
-void function OnPlayerKilled_DeathNotify( entity player, entity attacker, var damageInfo )
-{
- EmitSoundOnEntity( player, "Player_Death_Begin" )
-}
-
-void function CodeCallback_WeaponDropped( entity weapon )
-{
- if ( !IsValid( weapon ) )
- return
-
- if ( !Flag( "WeaponDropsAllowed" ) )
- {
- weapon.Destroy()
- return
- }
-
- int loadoutIndex = GetSPTitanLoadoutIndexForWeapon( weapon.GetWeaponClassName() )
- if ( loadoutIndex >= 0 )
- {
- if ( IsBTLoadoutUnlocked( loadoutIndex ) )
- {
- weapon.Destroy()
- return
- }
- else
- {
- weapon.MarkAsLoadoutPickup()
- }
- }
-
- SetTeam( weapon, TEAM_UNASSIGNED )
-
- if ( weapon.IsLoadoutPickup() )
- {
- HighlightWeapon( weapon )
- }
- else
- {
- Highlight_SetOwnedHighlight( weapon, "weapon_drop_active" )
- Highlight_SetNeutralHighlight( weapon, "weapon_drop_fresh" )
- thread RevertToRegularHighlight( weapon )
- }
-}
-
-void function RevertToRegularHighlight( entity weapon )
-{
- weapon.Signal( "RevertToRegularHighlight" )
- weapon.EndSignal( "RevertToRegularHighlight" )
- weapon.EndSignal( "OnDestroy" )
- wait 4.0
- HighlightWeapon( weapon )
-}
-
-void function RefreshWeaponHighlightTitanTransfer( entity player, entity titan )
-{
- RefreshWeaponHighlights( player )
-}
-
-void function CodeCallback_OnWeaponTouch( entity player, entity weapon, int ammoRecieved )
-{
- if ( !IsAlive( player ) )
- return
-
- if ( Time() - file.lastObitMsgTime < 0.1 )
- return
-
- if ( ammoRecieved == 0 )
- {
- if ( !PlayerCanUseWeapon( player, weapon.GetWeaponClass() ) )
- return
-
- if ( !PlayerHasWeapon( player, weapon.GetWeaponClassName() ) )
- return
-
- MessageToPlayer( player, eEventNotifications.WEAP_AmmoFull, weapon, ammoRecieved )
- }
- else
- {
- MessageToPlayer( player, eEventNotifications.WEAP_GotAmmo, weapon, ammoRecieved )
- }
-
- file.lastObitMsgTime = Time()
-}
-void function Callback_WallrunBegin( entity player )
-{
- file.wallRunKills = 0
-}
-
-void function OnNPCKilled( entity npc, var damageInfo )
-{
- entity player = DamageInfo_GetAttacker( damageInfo )
-
- if ( !IsValid( player ) )
- return
-
- if ( !player.IsPlayer() )
- return
-
- if ( player.IsTitan() )
- {
- if ( IsTitanCrushDamage( damageInfo ) )
- {
- thread PlayerTitanCrushKill_TryRumble( player, npc )
- }
-
- if ( IsHumanSized( npc ) )
- {
- TryInfantryMultiKill( player )
- }
-
- return
- }
-
- entity weapon = DamageInfo_GetWeapon( damageInfo )
- int damageSource = DamageInfo_GetDamageSourceIdentifier( damageInfo )
- if ( !IsValid( weapon ) )
- return
-
- if ( weapon.IsWeaponOffhand() && damageSource != eDamageSourceId.sp_weapon_arc_tool ) // special case let arc tool through
- return
-
- if ( player.IsWallRunning() )
- file.wallRunKills++
-
- if ( player.IsSliding() )
- {
- if ( file.slideKills == 0 )
- {
- thread TrackSlideEnd( player )
- }
- file.slideKills++
- }
-
- printt( "Wall Run Kills: " + file.wallRunKills )
- printt( "Slide Kills: " + file.slideKills )
-
- if ( file.wallRunKills >= 3 )
- UnlockAchievement( player, achievements.WALLRUN_KILLS )
-
- if ( file.slideKills >= 3 )
- UnlockAchievement( player, achievements.SLIDE_KILLS )
-}
-
-void function PlayerTitanCrushKill_TryRumble( entity player, entity victim )
-{
- player.EndSignal( "OnDeath" )
-
- if ( !IsHumanSized( victim ) && !IsProwler( victim ) )
- return
-
- float rumbleAmplitude = 80.0
- float rumbleFrequency = 150.0
- float rumbleDuration = 0.4
-
- // bigger rumble if victim is tougher than a Grunt
- if ( victim.IsMechanical() || IsProwler( victim ) )
- {
- rumbleAmplitude = 140.0
- rumbleFrequency = 100.0
- rumbleDuration = 0.6
- }
-
- // delay makes it feel better with the SFX
- // (sound starts at same time, but takes a moment to get loud)
- wait 0.1
-
- CreateAirShakeRumbleOnly( player.GetOrigin(), rumbleAmplitude, rumbleFrequency, rumbleDuration )
- //printt( "CRUSH RUMBLE", rumbleAmplitude )
-}
-
-void function TrackSlideEnd( entity player )
-{
- player.EndSignal( "OnDeath" )
-
- OnThreadEnd(
- function() : ( )
- {
- file.slideKills = 0
- }
- )
-
- while ( player.IsSliding() )
- {
- wait 0.1
- }
-}
-
-void function TryInfantryMultiKill( entity player )
-{
- if ( file.lastMultiKillStartTime + 2.0 < Time() )
- {
- file.lastMultiKillStartTime = Time()
- file.multiKillCount = 0
- }
-
- file.multiKillCount++
-
- printt( "Multi Kills: " + file.multiKillCount )
-
- if ( file.multiKillCount >= 25 )
- UnlockAchievement( player, achievements.INFANTRY_MULTIKILL )
-} \ No newline at end of file
diff --git a/Northstar.Coop/scripts/vscripts/sp/_coop_sp_utils.gnut b/Northstar.Coop/scripts/vscripts/sp/_coop_sp_utils.gnut
deleted file mode 100644
index 5783f28f..00000000
--- a/Northstar.Coop/scripts/vscripts/sp/_coop_sp_utils.gnut
+++ /dev/null
@@ -1,177 +0,0 @@
-untyped
-global const float COOP_RESPAWN_DELAY = 5.0
-
-global function CoopSpUtils_Init
-
-global function GetPlayerToSpawnOn
-global function RestartWithoutDroppingPlayers
-global function TeleportToEntitySafe
-global function GetEntitiesByEditorClass
-
-global function GetPlayersInTimeline
-
-void function CoopSpUtils_Init()
-{
- AddCallback_OnClientConnecting( OnClientConnecting )
- AddDeathCallback( "player", OnPlayerDeath )
-}
-
-void function OnClientConnecting( entity player )
-{
- // add custom script vars
- if ( IsPlayingTimeshiftLevel() )
- {
- player.s.timeline <- 1 // TIMEZONE_NIGHT
- player.s.isTimeTraveling <- false
- player.s.lastGoodTimeshiftPosOvergrown <- <0, 0, 0>
- player.s.lastGoodTimeshiftPosPristine <- <0, 0, 0>
- }
-}
-
-void function OnPlayerDeath( entity player, var damageInfo )
-{
- // add respawn delay, use networked entity var for client respawn timer
- player.nv.nextRespawnTime = Time() + COOP_RESPAWN_DELAY
-
- if ( AreAllPlayersDead() )
- thread FailLevel( COOP_RESPAWN_DELAY )
-}
-
-void function FailLevel( float respawnTime )
-{
- wait respawnTime
- RestartWithoutDroppingPlayers()
-}
-
-entity ornull function GetPlayerToSpawnOn()
-{
- array< entity > possiblePlayers
- foreach ( entity player in GetPlayerArray())
- {
- if ( IsAlive( player ))
- possiblePlayers.append( player )
- }
-
- if ( possiblePlayers.len() == 0 )
- return null // everyone is dead
-
- return possiblePlayers[ RandomInt( possiblePlayers.len() ) ]
-}
-
-void function RestartWithoutDroppingPlayers()
-{
- // todo: make this deal with checkpoints/saves
- ServerCommand( "changelevel " + GetMapName() )
-}
-
-void function TeleportToEntitySafe( entity teleported, entity target )
-{
- // teleport to other entities without getting stuck in ceilings and shit
- // PLEASE dont call this often, it's weird when used on living players
- // was designed only to be used on spawn/respawn code
-
- vector targetPos = target.GetOrigin()
-
- // intelligent checks
- // is the spot already valid?
- if ( !PlayerPosInSolidIgnoreOtherPlayers( teleported, targetPos ) )
- {
- print( "TeleportToEntitySafe: pos was valid first time" )
- teleported.SetOrigin( targetPos )
- teleported.SetAngles( target.GetAngles() )
- return
- }
- else if ( target.IsCrouched() && !teleported.IsCrouched() && !PlayerPosInSolidIgnoreOtherPlayers( teleported, targetPos, true ) )
- {
- // teleporting to sliding players while not sliding can cause clipping
- // so if we set the player to be sliding maybe it'll kinda sorta work out
-
- // check if we can just offset ourselves downwards to a valid pos without crouching
- // 25 is the diff in collision height between stood up/crouched
- if ( !PlayerPosInSolidIgnoreOtherPlayers( teleported, targetPos + <0, 0, -25> ) )
- {
- print( "TeleportToEntitySafe: offset to valid position to account for crouch!" )
- teleported.SetOrigin( targetPos + <0, 0, -25> )
- teleported.SetAngles( target.GetAngles() )
- return
- }
- else
- {
- print( "TeleportToEntitySafe: couldn't offset to valid pos for crouch, waiting for crouch to finish" )
- teleported.ForceCrouch()
- }
- }
-
- // last resort - give up and wait for the pos to be valid
- // given this is mainly used for teleporting to players it can probably be abused
-
- float startTime = Time()
- float timeout = 5.0
-
- print( "TeleportToEntitySafe: couldn't get a safe pos with starting conditions, waiting for pos to be valid" )
- while ( PlayerPosInSolidIgnoreOtherPlayers( teleported, target.GetOrigin() ) )
- {
- WaitFrame()
-
- if ( Time() - startTime > timeout )
- {
- // if we take too long, we probably aren't gonna teleport anyway, so why bother wasting cpu time on it
- print( "TeleportToEntitySafe: timed out waiting for successful teleport attempt" )
- return
- }
- }
-
- print( "TeleportToEntitySafe: done waiting for pos to be valid!" )
- teleported.SetOrigin( target.GetOrigin() )
- teleported.SetAngles( target.GetAngles() )
- teleported.UnforceCrouch()
-}
-
-bool function PlayerPosInSolidIgnoreOtherPlayers( entity player, vector targetPos, bool fakeCrouch = false )
-{
- // playerposinsolid by default doesn't ignore other players, only the player they're checking for
- // this reimplements it, but ignores all players
- // don't wanna patch the original function because the original behaviour could be useful
-
- vector maxs = player.GetPlayerMaxs()
-
- if ( maxs.z == 32 )
- maxs.z = 72 // maxs seem broken when connecting so make sure they're normal for this
-
- if ( fakeCrouch )
- maxs.z = 47 // 47 when crouched, 72 uncrouched
-
- TraceResults traceResult = TraceHull( targetPos, targetPos + <0, 0, 1>, player.GetPlayerMins(), maxs, GetPlayerArray(), TRACE_MASK_PLAYERSOLID, TRACE_COLLISION_GROUP_PLAYER )
- return traceResult.startSolid
-}
-
-array< entity > function GetEntitiesByEditorClass( string editorClass )
-{
- array< entity > ret
- for ( int i = 0; i < 2048 /*max ents in source*/; i++ )
- {
- entity ent = GetEntByIndex( i )
- if ( ent == null )
- continue
-
- if ( GetEditorClass( ent ) == editorClass )
- ret.append( ent )
- }
-
- return ret
-}
-
-
-//EFFECT AND CAUSE/TIMESHIFT STUFF
-
-array< entity > function GetPlayersInTimeline( int timeline )
-{
- array< entity > playersInTimeline
- foreach ( entity player in GetPlayerArray() )
- {
- if ( player.s.timeline == timeline )
- playersInTimeline.append( player )
- }
-
- return playersInTimeline
-} \ No newline at end of file
diff --git a/Northstar.Coop/scripts/vscripts/sp/_gamestate_sp.gnut b/Northstar.Coop/scripts/vscripts/sp/_gamestate_sp.gnut
deleted file mode 100644
index ac741370..00000000
--- a/Northstar.Coop/scripts/vscripts/sp/_gamestate_sp.gnut
+++ /dev/null
@@ -1,793 +0,0 @@
-const RESPAWN_TRIG_RECHECK_WAIT = 1
-const DEFAULT_SP_ARRIVAL_TOLERANCE = 200
-const DEFAULT_SP_ASSAULT_TIMEOUT = 0
-
-// move these to auto precache
-global const TEAM_MIL_GRUNT_MODEL = $"models/humans/grunts/mlt_grunt_rifle.mdl"
-global const TEAM_MIL_GRUNT_MODEL_LMG = $"models/humans/grunts/mlt_grunt_lmg.mdl"
-global const TEAM_MIL_GRUNT_MODEL_RIFLE = $"models/humans/grunts/mlt_grunt_rifle.mdl"
-global const TEAM_MIL_GRUNT_MODEL_ROCKET = $"models/humans/grunts/mlt_grunt_rifle.mdl"
-global const TEAM_MIL_GRUNT_MODEL_SHOTGUN = $"models/humans/grunts/mlt_grunt_shotgun.mdl"
-global const TEAM_MIL_GRUNT_MODEL_SMG = $"models/humans/grunts/mlt_grunt_smg.mdl"
-
-
-global function GamemodeSp_Init
-global function GiveBatteryChargeTool
-global function HasBatteryChargeTool
-global function FriendlyFire_MissionFailure
-global function DamageAlwaysLethal
-global function ServerRestartMission
-global function DisableFriendlyHighlight
-global function EnableFriendlyHighlight
-global function SP_PlayerLastSlideTime
-
-//global function CodeCallback_Ping
-
-global function SetGameState
-global function GetGameModeAnnouncement
-
-global function CodeCallback_GamerulesThink
-
-global struct SvGlobalsSP
-{
- int gruntCombatState = eGruntCombatState.IDLE
-
- array<void functionref( entity )> onLoadSaveGameCallbacks
-}
-
-global SvGlobalsSP svGlobalSP
-
-//////////////////////////////
-
-global function DEV_ToggleFriendlyHighlight
-
-//////////////////////////////
-
-struct
-{
- LevelTransitionStruct ornull storedLevelTransitionStruct
- entity spPetTitanStart
- bool friendlyHighlightEnabled = true
- float playerLastSlideTime
-} file
-
-void function GamemodeSp_Init()
-{
- FlagInit( "FriendlyFireStrict" )
- FlagInit( "TitanCanSavePlayer" )
- FlagInit( "TitanDeathPenalityDisabled" )
- FlagInit( "SaveGame_Enabled", true )
- FlagInit( "MissionFailed" )
- RegisterSignal( "TitanSavesPlayer" )
-
- FlagSet( "PilotBot" )
-
- AddSoulDeathCallback( SoulDeath_ReloadOnPetTitanDeath )
- AddClientCommandCallback( "RestartMission", ClientCommand_RestartMission )
-
- SetRoundBased( false )
-
- AddCallback_OnClientConnecting( SpPlayerConnecting )
- AddCallback_OnClientConnected( SpPlayerConnected )
-
- AddSpawnCallback( "npc_soldier", SpNpcCommon )
- AddSpawnCallback( "npc_spectre", SpNpcCommon )
- AddSpawnCallback( "npc_titan", SpNpcCommon )
-
- AddSpawnCallback( "npc_soldier", SpNpcCommonGrunt )
-
- AddSpawnCallbackEditorClass( "info_target", "info_pet_titan_start", PetTitanStartSpawnInit )
- AddCallback_OnPlayerRespawned( GameStateSP_OnPlayerRespawn )
-
- AddDamageCallbackSourceID( eDamageSourceId.damagedef_titan_fall, PreventFriendlyTitanfallDamage )
- AddDamageCallbackSourceID( eDamageSourceId.damagedef_reaper_fall, PreventFriendlyTitanfallDamage )
-
- shGlobal.proto_soldierShieldRegenDelay = 3000.0
- svGlobal.cloakBreaksOnMelee = true
- svGlobal.defaultPilotLeechTime = 2.0
-
- //AddDamageCallback( "player", DiminishPlayerComboDamage )
-
- SPTitanLoadout_SetupForLevelStart()
-
- SpSharedInit()
-
- AddCallback_EntitiesDidLoad( EntitiesDidLoad_SpGameState )
- AddDeathCallback( "npc_soldier", SoldierFriendlyFireCheck_OnKilled )
-
- AddCallback_OnPilotBecomesTitan( PilotBecomesTitanStoreWeaponVar )
-
- // SAVE THIS LEVEL IF IT'S IN THE LEVEL LIST
- var dataTable = GetDataTable( $"datatable/sp_levels.rpak" )
- string mapName = GetMapName()
- string startPoint = GetStartPoint()
- int numRows = GetDatatableRowCount( dataTable )
- int lastLevelNum = 0
-
- int bspCol = GetDataTableColumnByName( dataTable, "level" )
- int levelCol = GetDataTableColumnByName( dataTable, "levelNum" )
-
- for ( int i=0; i<numRows; i++ )
- {
- string levelBsp = GetDataTableString( dataTable, i, bspCol )
- int levelNum = GetDataTableInt( dataTable, i, levelCol )
-
- if ( levelBsp == mapName )
- {
- #if DEV
- printt( "Setting this level as unlocked" )
- printt( "BSP: " + levelBsp )
- printt( "Level Num: " + levelNum )
- #endif
-
- SetConVarInt( "sp_lastMission", levelNum )
- lastLevelNum = levelNum
- break
- }
- }
-
- int farthestLevelUnlocked = GetConVarInt( "sp_unlockedMission" )
-
- if( Script_IsRunningTrialVersion() )
- SetConVarInt( "sp_unlockedMission", 1 ) // Set to sp_crashsite so if they buy the game, it starts there.
- else
- SetConVarInt( "sp_unlockedMission", maxint(farthestLevelUnlocked, lastLevelNum) )
-
- foreach( entity player in GetPlayerArray() )
- UpdateHeroStatsForPlayer( player )
-
- if ( IsTestMap() )
- {
- PilotLoadoutDef loadout = GetPilotLoadoutForCurrentMapSP()
- foreach ( model in GetModelsFromSetFile( loadout.setFile ) )
- {
- PrecacheModel( model )
- }
-
- TitanLoadoutDef titanLoadout = GetTitanLoadoutForCurrentMap()
- foreach ( model in GetModelsFromSetFile( titanLoadout.setFile ) )
- {
- PrecacheModel( model )
- }
- }
-}
-
-
-void function EntitiesDidLoad_SpGameState()
-{
- SetGameState( eGameState.Playing )
- FlagSet( "ReadyToStartMatch" )
-
- file.storedLevelTransitionStruct = GetLevelTransitionStruct()
-
- SetCustomIntroLength( 0 )
-
-// level.nv.replayDisabled = true //HACK - remove once the bug about replay hud is fixed
- level.nv.minimapState = eMinimapState.Hidden
-
- level.nv.replayDisabled = true
- if ( !IsTestMap() )
- level.nv.titanAvailability = eTitanAvailability.Never
-
- ServerCommand( "sv_weapon_despawn_Time 180" )
-}
-
-/************************************************************************************************\
-
- ###### ####### ## ## ## ## ######## ###### ########
-## ## ## ## ### ## ### ## ## ## ## ##
-## ## ## #### ## #### ## ## ## ##
-## ## ## ## ## ## ## ## ## ###### ## ##
-## ## ## ## #### ## #### ## ## ##
-## ## ## ## ## ### ## ### ## ## ## ##
- ###### ####### ## ## ## ## ######## ###### ##
-
-\************************************************************************************************/
-void function SpPlayerConnecting( entity player )
-{
- if ( GetPlayerArray().len() > 1 )
- {
- CodeWarning( "Can't play SP with more or less than 1 player" )
- return
- }
-
- SetTeam( player, TEAM_MILITIA )
- InitPassives( player )
-
- player.SetInventoryChangedCallbackEnabled( true )
-
- entity ornull spawningOn = GetPlayerToSpawnOn()
- if ( spawningOn == null )
- {
- // vanilla spawning logic - spawn first player at the level's spawnpoint
- entity start = GetEnt( "info_player_start" )
- player.SetOrigin( start.GetOrigin() )
- player.SetAngles( start.GetAngles() )
- }
- else
- {
- expect entity( spawningOn )
- // use safe func otherwise we can get stuck in the ceiling and shit
- thread TeleportToEntitySafe( player, spawningOn )
- }
-
- if ( IsValid( file.spPetTitanStart ) )
- {
- CreatePetTitan( player )
- entity titan = player.GetPetTitan()
- if ( titan != null )
- titan.kv.alwaysAlert = false
- }
-}
-
-void function GameStateSP_OnPlayerRespawn( entity player )
-{
- UpdateSpDifficulty( player )
- thread TrackPlayerLastSlideTime( player )
-
- if ( !IsTestMap() )
- {
- CheckPoint_ForcedSilent()
- }
-}
-
-void function SpPlayerConnected( entity player )
-{
- thread SpPlayerConnected_Thread( player )
-}
-
-void function SpPlayerConnected_Thread( entity player )
-{
- player.EndSignal( "OnDestroy" )
-
- if ( IsTestMap() )
- return
-
- string levelName = GetMapName()
- int startIndex = GetStartPointIndexFromName( levelName, GetCurrentStartPoint() )
-
- string startPointEnum = GetStartPointNameFromIndex( levelName, startIndex )
- if ( !StartPointHasDetente( levelName, startPointEnum ) )
- return
-
- var dataTable = GetDataTable( $"datatable/sp_introscreen.rpak" )
- int row = GetDataTableRowMatchingStringValue( dataTable, GetDataTableColumnByName( dataTable, "level" ), levelName )
- if ( row == -1 )
- return
-
- float delay = GetDataTableFloat( dataTable, row, GetDataTableColumnByName( dataTable, "bgFadeDelay" ) )
- float fadeTime = GetDataTableFloat( dataTable, row, GetDataTableColumnByName( dataTable, "bgFadeTime" ) )
-
- printt( "Detent fade in " + delay + " blend " + fadeTime )
-
- WaitFrame()
- WaitFrame() // wait two frames to fix ScreenFade bug
-
- ScreenFade( player, 0, 0, 0, 255, fadeTime, delay, FFADE_IN | FFADE_PURGE )
- //printt( "sv SCREENFADE: " + fadeTime + " " + delay )
-}
-
-float function SP_PlayerLastSlideTime()
-{
- return file.playerLastSlideTime
-}
-
-void function PetTitanStartSpawnInit( entity spawn )
-{
- file.spPetTitanStart = spawn
-}
-
-void function TrackPlayerLastSlideTime( entity player )
-{
- player.EndSignal( "OnDeath" )
-
- for ( ;; )
- {
- if ( player.IsSliding() )
- file.playerLastSlideTime = Time()
- wait 0.5
- }
-}
-
-void function CreatePetTitan( entity player )
-{
- Assert( IsValid( file.spPetTitanStart ) )
- // Player is in his Titan, don't create a titan
- if ( player.IsTitan() )
- return
-
- // Player already has a pet titan, don't create one
- entity petTitan = player.GetPetTitan()
- if ( IsValid( petTitan ) )
- return
-
- // Make a pet titan at the spawn point
- TitanLoadoutDef loadout = GetTitanLoadoutForCurrentMap()
- entity titanStart = file.spPetTitanStart
- entity titan = CreateAutoTitanForPlayer_FromTitanLoadout( player, loadout, titanStart.GetOrigin(), titanStart.GetAngles() )
- DispatchSpawn( titan )
- player.SetPetTitan( titan )
-
- titan.DisableHibernation()
-}
-
-/************************************************************************************************\
-
-######## ### ## ## ### ###### ########
-## ## ## ## ### ### ## ## ## ## ##
-## ## ## ## #### #### ## ## ## ##
-## ## ## ## ## #### ## ## ## ## ### ######
-## ## ######### ## ## ## ######### ## ## ##
-## ## ## ## ## ## ## ## ## ## ##
-######## ## ## ## ## ## ## ###### ########
-
-\************************************************************************************************/
-
-// putting this stuff here for now since it's only for SP at this point
-
-
-
-
-bool function TryTitanSavesPlayer( entity player )
-{
- if ( !Flag( "TitanCanSavePlayer" ) )
- return false
-
- if ( !IsAlive( player.GetPetTitan() ) )
- return false
-
- entity titan = player.GetPetTitan()
- if ( TitanIsCurrentlyEmbarkableForPlayer( player, titan ) )
- {
- thread TitanSavesPlayer( player, titan )
- return true
- }
-
- return false
-}
-
-void function TitanSavesPlayer( entity player, entity titan )
-{
- player.EndSignal( "OnDestroy" )
- titan.EndSignal( "OnDeath" )
-
- player.SetNoTarget( true )
- player.SetInvulnerable()
- titan.SetInvulnerable()
-
- player.DisableWeapon()
- player.FreezeControlsOnServer()
- player.ForceCrouch()
-
- OnThreadEnd(
- function() : ( player, titan )
- {
- if ( IsValid( player ) )
- {
- if ( !IsPlayerEmbarking( player ) )
- {
- player.EnableWeapon()
- }
- player.UnforceCrouch()
- player.UnfreezeControlsOnServer()
- player.ClearInvulnerable()
- player.SetNoTarget( false )
- }
-
- if ( IsValid( titan ) )
- titan.ClearInvulnerable()
- }
- )
-
- wait 0.25
-
- float fadeTime = 2
- float blackTime_pre = 4.0
- float blackTime_post = 1.0
-
- thread ScreenFadeToBlack( player, 2.0, blackTime_pre )
-
- wait blackTime_pre * 0.5
- string titanAlias = GenerateTitanOSAlias( player, "briefCriticalDamage" )
- thread EmitSoundOnEntity( player, titanAlias )
- wait blackTime_pre * 0.5
-
- vector ornull clampedPos = NavMesh_ClampPointForAI( player.GetOrigin(), titan )
- if ( clampedPos != null )
- titan.SetOrigin( expect vector( clampedPos ) )
-
- titan.SetAngles( Vector( 0, player.GetAngles().y, 0 ) )
-
- entity soul = titan.GetTitanSoul()
- SetStanceKneel( soul )
-
- table criteria = {
- embark = "front",
- titanCanStandRequired = false
- }
-
- var embarkAction
- embarkAction = FindEmbarkActionForCriteria( criteria )
- if ( embarkAction == null )
- embarkAction = GetRandomEmbarkAction()
-
- table action = expect table( GenerateEmbarkActionTable( player, titan, embarkAction ) )
- thread PlayerEmbarksTitan( player, titan, action )
- thread ScreenFadeFromBlack( player, 12.0, blackTime_post )
-
- player.Signal( "TitanSavesPlayer" )
-}
-
-bool function DamageAlwaysLethal( var damageInfo )
-{
- const damageMask = DF_INSTANT | DF_IMPACT | DF_TITAN_STEP | DF_KILLSHOT | DF_MELEE // | DF_EXPLOSION
- if ( DamageInfo_GetCustomDamageType( damageInfo ) & damageMask )
- return true
-// not quite sure what this returns. It doesn't seem to be the flags listed in death_package.nut
-// if ( DamageInfo_GetDamageType( damageInfo ) & damageMask )
-// return false
-
- // damage type doesn't seem to be correct for most things so I'm forced to check GetDamageSourceIdentifier -Roger
- switch ( DamageInfo_GetDamageSourceIdentifier( damageInfo ) )
- {
- case damagedef_crush:
- case damagedef_nuclear_core:
- case damagedef_suicide:
- case damagedef_titan_fall:
- case damagedef_titan_hotdrop:
- case eDamageSourceId.bubble_shield:
- case eDamageSourceId.burn:
- case eDamageSourceId.droppod_impact:
- case eDamageSourceId.evac_dropship_explosion:
- case eDamageSourceId.fall:
- case eDamageSourceId.flash_surge:
- case eDamageSourceId.floor_is_lava:
- case eDamageSourceId.human_execution:
- case eDamageSourceId.human_melee:
- case eDamageSourceId.indoor_inferno:
- case eDamageSourceId.outOfBounds:
- case eDamageSourceId.round_end:
- case eDamageSourceId.splat:
- case eDamageSourceId.stuck:
- case eDamageSourceId.submerged:
- case eDamageSourceId.switchback_trap:
- case eDamageSourceId.team_switch:
- case eDamageSourceId.titan_execution:
- case eDamageSourceId.titan_explosion:
- case eDamageSourceId.wall_smash:
-// case eDamageSourceId.grunt_melee:
-// case eDamageSourceId.prowler_melee:
-// case eDamageSourceId.spectre_melee:
- return true
-
- default:
- break
- }
-
- return false
-}
-
-/************************************************************************************************\
-
- ## ## ######## ######
- ### ## ## ## ## ##
- #### ## ## ## ##
- ## ## ## ######## ##
- ## #### ## ##
- ## ### ## ## ##
- ## ## ## ######
-
-\************************************************************************************************/
-void function SpNpcCommon( entity npc )
-{
- if ( npc.GetTeam() == TEAM_MILITIA )
- {
- if ( !npc.IsTitan() )
- HideName( npc )
-
- // this is a temporary stop gap until we get skins
- if ( file.friendlyHighlightEnabled )
- Highlight_SetFriendlyHighlight( npc, "sp_friendly_pilot" )
- }
-}
-
-void function SpNpcCommonGrunt( entity npc )
-{
- // heros clear this setting so they should keep their names
- if ( npc.GetTeam() == TEAM_MILITIA )
- {
-
- string title
- if ( npc.Dev_GetAISettingByKeyField( "IsGenericGrunt" ) == 0 )
- {
- title = npc.GetSettingTitle()
- }
- else
- {
- title = GetMilitiaTitle()
- }
-
- npc.SetTitle( title )
- ShowName( npc )
- }
-}
-
-void function DiminishPlayerComboDamage( entity player, var damageInfo )
-{
- if ( !IsPilot( player ) )
- return
-
-// printt( "damage " + DamageInfo_GetDamage( damageInfo ) )
-// printt( "shield health " + player.GetShieldHealth() )
- if ( player.GetShieldHealth() > 0 )
- return
-
- // blunt damage from combos
- float damage = DamageInfo_GetDamage( damageInfo )
-
- float recentDamage = TotalDamageOverTime_BlendedOut( player, 0.5, 1.5 )
-
- // damage is ramped down based on how much damage was taken recently
- float damageMod = GraphCapped( recentDamage, 70, 140, 1.0, 0.1 )
- DamageInfo_ScaleDamage( damageInfo, damageMod )
-}
-
-void function SoulDeath_ReloadOnPetTitanDeath( entity soul, var damageInfo )
-{
- if ( Flag( "TitanDeathPenalityDisabled" ) )
- return
-
- if ( IsTestMap() )
- return
-
- thread SoulDeath_ReloadOnPetTitanDeath_Thread( soul, damageInfo )
-}
-
-void function SoldierFriendlyFireCheck_OnKilled( entity npc, var damageInfo )
-{
- if ( !Flag( "FriendlyFireStrict" ) )
- return
-
- entity attacker = DamageInfo_GetAttacker( damageInfo )
- if ( !attacker.IsPlayer() )
- return
-
- if ( npc.GetTeam() != attacker.GetTeam() )
- return
-
- thread SoldierFriendlyFireCheck_OnKilledDelayed()
-}
-
-void function SoldierFriendlyFireCheck_OnKilledDelayed()
-{
- FlagClear( "SaveGame_Enabled" ) // no more saving, you have lost
- wait 0.75
- FriendlyFire_MissionFailure()
-}
-
-void function FriendlyFire_MissionFailure()
-{
- if ( Flag( "MissionFailed" ) )
- return
-
- foreach ( player in GetPlayerArray() )
- {
- Remote_CallFunction_NonReplay( player, "ServerCallback_FriendlyFire_MissionFailure" )
- }
-
- ReloadForMissionFailure()
-}
-
-void function SoulDeath_ReloadOnPetTitanDeath_Thread( entity soul, var damageInfo )
-{
- entity player = soul.GetBossPlayer()
-
- if ( !IsValid( player ) )
- return
-
- if ( !level.nv.replayDisabled )
- {
- if ( player.p.watchingPetTitanKillReplay )
- return
-
- player.p.watchingPetTitanKillReplay = true
- }
-
- if ( damageInfo == null )
- {
- printt( "ServerCallback_TitanDied with null sourceid" )
- ReloadForMissionFailure()
- return
- }
-
- int source = DamageInfo_GetDamageSourceIdentifier( damageInfo )
- Remote_CallFunction_NonReplay( player, "ServerCallback_TitanDied", source )
- #if DEV
- printt( "ServerCallback_TitanDied with sourceid " + source + " and source string " + GetObitFromDamageSourceID( source ) )
- #endif
-
- if ( IsInstantDeath( damageInfo ) )
- {
- ReloadForMissionFailure()
- return
- }
- entity attacker = DamageInfo_GetAttacker( damageInfo )
- if ( !IsValid( attacker ) )
- {
- ReloadForMissionFailure()
- return
- }
-
- int index = attacker.GetIndexForEntity()
- entity titan = soul.GetTitan()
-
- FlagClear( "SaveGame_Enabled" ) // no more saving, you have lost
-
- if ( !level.nv.replayDisabled )
- {
- /*
- wait 3.8
- float replayDelay = 6.5
- player.SetKillReplayDelay( replayDelay )
- player.SetViewIndex( index )
-
- if ( IsValid( titan ) )
- player.SetKillReplayVictim( titan )
-
- ReloadForMissionFailure( replayDelay + 2.5 )
- */
- }
- else
- {
- ReloadForMissionFailure() // replayDelay + 2.5
- }
-}
-
-bool function HasBatteryChargeTool( entity player )
-{
- switch ( CHARGE_TOOL )
- {
- case "sp_weapon_proto_battery_charger_offhand":
- return HasOffhandWeapon( player, CHARGE_TOOL )
-
- case "sp_weapon_arc_tool":
- return HasWeapon( player, CHARGE_TOOL )
- }
-
- unreachable
-}
-
-void function GiveBatteryChargeTool( entity player )
-{
- switch ( CHARGE_TOOL )
- {
- case "sp_weapon_proto_battery_charger_offhand":
- player.GiveOffhandWeapon( CHARGE_TOOL, OFFHAND_SPECIAL )
- break
-
- case "sp_weapon_arc_tool":
- player.GiveWeapon( CHARGE_TOOL )
- break
- }
- UpdateArcConnectorHints()
-}
-
-/*
-void function CodeCallback_Ping( entity player )
-{
-
-}
-*/
-
-/* ----------------------------------------------------------------------------------------------
-
-STUFF FORM MP THAT WE WILL SLOWLY GET RID OF
-
--------------------------------------------------------------------------------------------------*/
-
-string function GetGameModeAnnouncement()
-{
- return ""
-}
-
-void function SetGameState( int newState )
-{
- level.nv.gameStartTime = Time()
- level.nv.gameStateChangeTime = Time()
- level.nv.gameState = newState
- svGlobal.levelEnt.Signal( "GameStateChanged" )
-
- foreach ( callbackFunc in svGlobal.gameStateEnterCallbacks[ newState ] )
- {
- callbackFunc()
- }
-}
-
-void function CodeCallback_GamerulesThink()
-{
-
-}
-
-void function DEV_ToggleFriendlyHighlight()
-{
- file.friendlyHighlightEnabled = !file.friendlyHighlightEnabled
- UpdateFriendlyHighlight()
-}
-
-void function DisableFriendlyHighlight()
-{
- file.friendlyHighlightEnabled = false
- UpdateFriendlyHighlight()
-}
-
-void function EnableFriendlyHighlight()
-{
- file.friendlyHighlightEnabled = true
- UpdateFriendlyHighlight()
-}
-
-void function UpdateFriendlyHighlight()
-{
- if ( file.friendlyHighlightEnabled )
- {
- foreach ( npc in GetNPCArrayOfTeam( TEAM_MILITIA ) )
- Highlight_SetFriendlyHighlight( npc, "sp_friendly_pilot" )
- }
- else
- {
- foreach ( npc in GetNPCArrayOfTeam( TEAM_MILITIA ) )
- Highlight_ClearFriendlyHighlight( npc )
- }
-}
-
-bool function ClientCommand_RestartMission( entity player, array<string> args )
-{
- ServerRestartMission( player )
- return true
-}
-
-void function ServerRestartMission( entity player )
-{
- if ( IsTestMap() )
- {
- ServerCommand( "reload" )
- return
- }
-
- string mapName = GetMapName()
- LevelTransitionStruct ornull trans = file.storedLevelTransitionStruct
- if ( trans == null )
- {
- int startIndex = 0
- #if DEV
- string startName = Dev_GetStartCommandLine( mapName )
- if ( startName != "" )
- startIndex = GetStartPointIndexFromName( mapName, startName )
- #endif
- // loaded a level manually in dev or are in sp_training
- ExecuteLoadingClientCommands_SetStartPoint( mapName, startIndex )
- ClientCommand( player, "map " + mapName )
- return
- }
-
- expect LevelTransitionStruct( trans )
- ExecuteLoadingClientCommands_SetStartPoint( mapName, trans.startPointIndex )
- ChangeLevel( mapName, trans )
-}
-
-void function PilotBecomesTitanStoreWeaponVar( entity pilot, entity npc_titan )
-{
- entity weapon = pilot.GetMainWeapons()[0]
- int index = GetTitanLoadoutIndex( weapon.GetWeaponClassName() )
- SetConVarInt( "sp_titanLoadoutCurrent", index )
-}
-
-void function PreventFriendlyTitanfallDamage( entity ent, var damageInfo )
-{
- entity attacker = DamageInfo_GetAttacker( damageInfo )
-
- if ( attacker.GetTeam() == ent.GetTeam() )
- {
- DamageInfo_SetDamage( damageInfo, 0 )
- }
-} \ No newline at end of file
diff --git a/Northstar.Coop/scripts/vscripts/sp/_gauntlet.gnut b/Northstar.Coop/scripts/vscripts/sp/_gauntlet.gnut
deleted file mode 100644
index 4cde3094..00000000
--- a/Northstar.Coop/scripts/vscripts/sp/_gauntlet.gnut
+++ /dev/null
@@ -1,1054 +0,0 @@
-global function Gauntlet_ServerInit
-global function EnableAllGauntlets
-global function DisableAllGauntlets
-global function EnableGauntlet
-global function DisableGauntlet
-global function Gauntlet_HideLeaderboard
-global function Gauntlet_ShowLeaderboard
-global function Gauntlet_NPC_PostSpawn
-global function ClientCommand_Gauntlet_PlayerRestartedFromMenu
-global function Gauntlet_StartGhostPlayback
-global function Gauntlet_StopGhostPlayback
-global function Gauntlet_ChallengeLeaderboardGhosts
-#if DEV
-global function Gauntlet_Player_GhostRecordOrPlayback
-#endif
-
-const float GAUNTLET_ENEMY_MISSED_TIME_PENALTY = 2.0
-const float GAUNTLET_TARGET_DISSOLVE_TIME = 1.0
-const float GAUNTLET_TARGET_DISSOLVE_TIME_MS = GAUNTLET_TARGET_DISSOLVE_TIME * 100
-
-void function Gauntlet_ServerInit()
-{
- AddClientCommandCallback( "Gauntlet_PlayerRestartedFromMenu", ClientCommand_Gauntlet_PlayerRestartedFromMenu )
- AddCallback_EntitiesDidLoad( Gauntlet_PostEntityLoadSetup )
- AddCallback_OnClientConnected( Gauntlet_PlayerConnected )
- AddCallback_OnLoadSaveGame( Gauntlet_OnLoadSaveGame )
-
- RegisterSignal( "trigStart_OnStartTouch" )
- RegisterSignal( "trigStart_OnEndTouch" )
- RegisterSignal( "trigStart2_OnStartTouch" )
- RegisterSignal( "trigStart2_OnEndTouch" )
-
- RegisterSignal( "Gauntlet_PlayerHitStartTrig" )
- RegisterSignal( "Gauntlet_PlayerWentBackwardsThroughStartTrig" )
- RegisterSignal( "Gauntlet_PlayerHitFinishTrig" )
- RegisterSignal( "Gauntlet_CheckpointHit" )
- RegisterSignal( "Gauntlet_ForceRestart" )
- RegisterSignal( "GhostAnimationPlayback_Start" )
- RegisterSignal( "GhostAnimationPlayback_Stop" )
- RegisterSignal( "Gauntlet_PlayerBeatChallengeGhost" )
- RegisterSignal( "Gauntlet_PlayerBeatAllChallengeGhosts" )
- #if DEV
- RegisterSignal( "RecordAnimation_Start")
- RegisterSignal( "Player_StartRecordingGhost_HintStart" )
- #endif
-}
-
-void function Gauntlet_PostEntityLoadSetup()
-{
- foreach ( gauntlet in GetGauntlets() )
- {
- InitGauntlet( gauntlet )
-
- if ( gauntlet.startEnabled )
- EnableGauntlet( gauntlet )
- }
-}
-
-void function Gauntlet_PlayerConnected( entity player )
-{
- foreach ( gauntlet in GetGauntlets() )
- {
- // send ghost duration data to client- only server can read the anim durations
- foreach ( ghost in gauntlet.ghosts )
- Remote_CallFunction_Replay( player, "ScriptCallback_Gauntlet_SetGhostDuration", gauntlet.id, ghost.id, ghost.duration )
-
- if ( gauntlet.showLeaderboard )
- {
- Gauntlet_ShowLeaderboard( gauntlet )
-
- if ( gauntlet.activeGhostID != -1 )
- Gauntlet_RefreshActiveGhostID( gauntlet )
- }
- }
-}
-
-void function Gauntlet_OnLoadSaveGame( entity player )
-{
- thread Gauntlet_OnLoadSaveGame_Thread( player )
-}
-
-void function Gauntlet_OnLoadSaveGame_Thread( entity player )
-{
- wait 1.0
- Gauntlet_PlayerConnected( player )
-}
-
-// turns on a particular gauntlet
-void function EnableGauntlet( GauntletInfo gauntlet )
-{
- Assert( gauntlet.isInited, "Must run InitGauntlet before enabling" )
-
- if ( gauntlet.isEnabled )
- return
-
- Gauntlet_CreateSignalEnt( gauntlet )
-
- foreach ( player in GetPlayerArray() )
- Remote_CallFunction_Replay( player, "ScriptCallback_EnableGauntlet", gauntlet.id )
-
- thread Gauntlet_Think( gauntlet )
-
- gauntlet.isEnabled = true
-}
-
-// turns off a particular gauntlet
-void function DisableGauntlet( GauntletInfo gauntlet )
-{
- if ( !gauntlet.isEnabled )
- return
-
- gauntlet.signalEnt.Signal( "DisableGauntlet" )
-
- Gauntlet_CleanupSignalEnt( gauntlet )
- Gauntlet_ClearSpawnedNPCs( gauntlet )
- thread ClearDroppedWeapons( GAUNTLET_TARGET_DISSOLVE_TIME + 0.1 ) // needs to be longer than gauntlet ghost dissolve time so weapons drop
-
- foreach ( player in GetPlayerArray() )
- Remote_CallFunction_Replay( player, "ScriptCallback_DisableGauntlet", gauntlet.id )
-
- gauntlet.isEnabled = false
-}
-
-void function Gauntlet_HideLeaderboard( GauntletInfo gauntlet )
-{
- Gauntlet_SetLeaderboardEnabled( gauntlet, false )
-
- foreach ( player in GetPlayerArray() )
- Remote_CallFunction_Replay( player, "ScriptCallback_HideLeaderboard", gauntlet.id )
-}
-
-void function Gauntlet_ShowLeaderboard( GauntletInfo gauntlet )
-{
- Gauntlet_SetLeaderboardEnabled( gauntlet, true )
-
- foreach ( player in GetPlayerArray() )
- Remote_CallFunction_Replay( player, "ScriptCallback_ShowLeaderboard", gauntlet.id )
-}
-
-void function Gauntlet_Checkpoints( GauntletInfo gauntlet )
-{
- if ( !gauntlet.checkpoints.len() )
- return
-
- foreach ( trig in gauntlet.checkpoints )
- thread Gauntlet_CheckpointTrig_WaitForPlayer( gauntlet, trig )
-}
-
-void function Gauntlet_CheckpointTrig_WaitForPlayer( GauntletInfo gauntlet, entity trig )
-{
- gauntlet.player.EndSignal( "OnDestroy" )
- gauntlet.player.EndSignal( "Gauntlet_RunStarted" )
- gauntlet.player.EndSignal( "Gauntlet_RunStopped" )
- trig.EndSignal( "OnDestroy" )
-
- table result
- entity activator
-
- while ( 1 )
- {
- result = trig.WaitSignal( "OnStartTouch" )
- activator = expect entity( result.activator )
-
- if ( !activator.IsPlayer() )
- continue
-
- if ( !IsAlive( activator ) )
- continue
-
- if ( activator.IsTitan() )
- continue
-
- break
- }
-
- gauntlet.checkpointsHit++
- activator.Signal( "Gauntlet_CheckpointHit" )
-}
-
-void function Gauntlet_ClearSpawnedNPCs( GauntletInfo gauntlet )
-{
- foreach ( guy in gauntlet.spawned )
- {
- if ( IsAlive( guy ) )
- {
- Gauntlet_UnfreezeNPC( guy )
- guy.Die()
- }
- }
-
- gauntlet.spawned = []
-}
-
-void function Gauntlet_SpawnNPCs( GauntletInfo gauntlet )
-{
- Gauntlet_ClearSpawnedNPCs( gauntlet )
-
- array<entity> spawned = SpawnFromSpawnerArray( gauntlet.spawners )
- foreach ( guy in spawned )
- thread Gauntlet_NPC_PostSpawn( guy, gauntlet )
-
- gauntlet.spawned = spawned
-}
-
-void function Gauntlet_NPC_PostSpawn( entity npc, GauntletInfo gauntlet )
-{
- if ( IsGrunt( npc ) )
- {
- // TODO- pulse as player runs through course, so the effect highlights the different ranges where the enemies are
- Highlight_SetEnemyHighlightWithParam1( npc, "gauntlet_target_highlight", npc.EyePosition() )
-
- npc.SetHealth( 1 )
-
- npc.SetCanBeMeleeExecuted( false )
- }
-
- npc.EndSignal( "OnDeath" )
- thread Gauntlet_NPC_DeathWait( npc, gauntlet )
-
- AddEntityCallback_OnDamaged( npc, Gauntlet_NPC_Damaged )
-
- npc.SetNoTarget( true )
- npc.SetEfficientMode( true )
- npc.SetHologram()
- npc.SetDeathActivity( "ACT_DIESIMPLE" )
-
- wait RandomFloatRange( 0.5, 1.0 ) // This is no good, too variable. TODO put in a pose instead
-
- npc.Freeze()
-}
-
-void function Gauntlet_NPC_Damaged( entity npc, var damageInfo )
-{
- printt( "NPC Damaged!", npc.GetHealth() )
-
- float dmg = DamageInfo_GetDamage( damageInfo )
- float finalHealth = npc.GetHealth() - dmg
-
- if ( finalHealth <= 0 )
- Gauntlet_UnfreezeNPC( npc )
-}
-
-void function Gauntlet_NPC_DeathWait( entity npc, GauntletInfo gauntlet )
-{
- gauntlet.signalEnt.EndSignal( "DisableGauntlet" )
-
- npc.WaitSignal( "OnDeath" )
-
- EmitSoundAtPosition( TEAM_UNASSIGNED, npc.GetOrigin(), "holopilot_impacts_training" )
- npc.Dissolve( ENTITY_DISSOLVE_PHASESHIFT, Vector( 0, 0, 0 ), GAUNTLET_TARGET_DISSOLVE_TIME_MS )
-
- if ( !gauntlet.isActive )
- return
-
- if ( gauntlet.runFinished )
- return
-
- gauntlet.enemiesKilled++
-
- Remote_CallFunction_Replay( gauntlet.player, "ScriptCallback_Gauntlet_SetEnemyInfo", gauntlet.id, gauntlet.spawners.len(), gauntlet.enemiesKilled )
-}
-
-void function Gauntlet_UnfreezeNPC( entity npc )
-{
- if ( !npc.IsFrozen() )
- return
-
- npc.Unfreeze()
-}
-
-string function EnableAllGauntlets()
-{
- foreach ( idx, gauntlet in GetGauntlets() )
- EnableGauntlet( gauntlet )
-
- return( "All gauntlets enabled" )
-}
-
-string function DisableAllGauntlets()
-{
- foreach ( idx, gauntlet in GetGauntlets() )
- DisableGauntlet( gauntlet )
-
- return( "All gauntlets disabled" )
-}
-
-void function Gauntlet_Think( GauntletInfo gauntlet )
-{
- gauntlet.signalEnt.EndSignal( "DisableGauntlet" )
-
- OnThreadEnd(
- function() : ( gauntlet )
- {
- Gauntlet_ResetTrackerStats( gauntlet )
-
- if ( gauntlet.player && !gauntlet.runFinished )
- Gauntlet_AbortRun( gauntlet )
- }
- )
-
- while ( 1 )
- {
- thread Gauntlet_StartTrigThink( gauntlet )
-
- waitthread Gauntlet_WaitForPlayerToStart( gauntlet )
-
- Gauntlet_ResetTrackerStats( gauntlet )
-
- Gauntlet_StartRun( gauntlet )
-
- thread Gauntlet_HandlePlayerForceRestart( gauntlet )
-
- waitthread Gauntlet_WaitForStop( gauntlet )
-
- waitthread Gauntlet_StopRun( gauntlet )
- }
-}
-
-void function Gauntlet_StartRun( GauntletInfo gauntlet )
-{
- printt( "Gauntlet Run Started for player " + gauntlet.player )
-
- RestockPlayerAmmo( gauntlet.player )
- EmitSoundOnEntityOnlyToPlayer( gauntlet.player, gauntlet.player, "training_scr_gaunlet_start" )
-
- gauntlet.isActive = true
- gauntlet.startTime = Time()
- gauntlet.player.Signal( "Gauntlet_RunStarted" )
- gauntlet.signalEnt.Signal( "Gauntlet_RunStarted" )
- level.ui.playerRunningGauntlet = true
-
- Remote_CallFunction_Replay( gauntlet.player, "ScriptCallback_Gauntlet_StartRun", gauntlet.id )
- Remote_CallFunction_Replay( gauntlet.player, "ScriptCallback_Gauntlet_SetEnemyInfo", gauntlet.id, gauntlet.spawners.len(), 0 )
-
- thread Gauntlet_SpawnNPCs( gauntlet )
-
- thread Gauntlet_Checkpoints( gauntlet )
-}
-
-void function Gauntlet_StopRun( GauntletInfo gauntlet )
-{
- gauntlet.isActive = false
- level.ui.playerRunningGauntlet = false
-
- string feedbackSound = ""
-
- ResetPlayerHealthAndStatus( gauntlet.player )
-
- if ( !gauntlet.runFinished )
- {
- Gauntlet_AbortRun( gauntlet )
- feedbackSound = "training_scr_gaunlet_abort"
- }
- else
- {
- Gauntlet_FinishRun( gauntlet )
-
- if ( gauntlet.lastRunDefeatedGhost )
- feedbackSound = "training_scr_gaunlet_high_score"
- else if ( gauntlet.lastRunBestTime )
- feedbackSound = "training_scr_gaunlet_high_score"
- else
- feedbackSound = "training_scr_gaunlet_end"
-
- if ( feedbackSound != "" && IsAlive( gauntlet.player ) )
- EmitSoundOnEntityOnlyToPlayer( gauntlet.player, gauntlet.player, feedbackSound )
- }
-
- wait 0.1 // let the gauntlet finish and count NPCs remaining before killing the remainder
- Gauntlet_ClearSpawnedNPCs( gauntlet )
- thread ClearDroppedWeapons( GAUNTLET_TARGET_DISSOLVE_TIME + 0.1 ) // needs to be longer than gauntlet ghost dissolve time so weapons drop
-
- if ( IsValid( gauntlet.player ) )
- ClearActiveProjectilesForTeam( gauntlet.player.GetTeam() )
-
- // need to wait before firing final signal, so this signal doesn't kill Gauntlet_HandlePlayerForceRestart
- if ( IsValid( gauntlet.player ) )
- gauntlet.player.Signal( "Gauntlet_RunStopped" )
-
- if ( IsValid( gauntlet.signalEnt ) )
- gauntlet.signalEnt.Signal( "Gauntlet_RunStopped" )
-
- wait 0.1 // let other threads catch the signals and check the gauntlet struct before ResetTrackerStats
-}
-
-void function ResetPlayerHealthAndStatus( entity player )
-{
- if ( !IsAlive( player ) )
- return
-
- player.SetHealth( player.GetMaxHealth() )
-
- array<int> statusEffectsToStop = []
- statusEffectsToStop.append( eStatusEffect.emp )
- statusEffectsToStop.append( eStatusEffect.move_slow )
- statusEffectsToStop.append( eStatusEffect.turn_slow )
-
- foreach ( statusEffect in statusEffectsToStop )
- {
- if ( StatusEffect_Get( player, statusEffect ) > 0.0 )
- StatusEffect_StopAll( player, statusEffect ) // arc grenade stun
- }
-}
-
-void function Gauntlet_FinishRun( GauntletInfo gauntlet )
-{
- RestockPlayerAmmo( gauntlet.player )
-
- float elapsedTime = Time() - gauntlet.startTime
- printt( "Gauntlet Run Finished, elapsed time", elapsedTime )
-
- // time penalties for missed enemies
- float enemiesMissedTimePenalty = 0.0
- if ( gauntlet.spawners.len() > gauntlet.enemiesKilled )
- {
- int numEnemiesRemaining = gauntlet.spawners.len() - gauntlet.enemiesKilled
- enemiesMissedTimePenalty = ( numEnemiesRemaining.tofloat() * GAUNTLET_ENEMY_MISSED_TIME_PENALTY )
-
- elapsedTime += enemiesMissedTimePenalty
- }
-
- // check if new best time was set
- gauntlet.lastRunTime = elapsedTime
- if ( gauntlet.bestTime == -1.0 || elapsedTime < gauntlet.bestTime )
- {
- printt( "New best time!" )
- gauntlet.bestTime = elapsedTime
- gauntlet.lastRunBestTime = true
-
- // if there's a player ghost (for leaderboard), update its duration
- if ( gauntlet.hasPlayerGhost )
- {
- // update player ghost
- GauntletGhost playerGhost = Gauntlet_GetPlayerGhost( gauntlet )
- Gauntlet_SetGhostDuration( gauntlet, playerGhost, gauntlet.bestTime )
- }
- }
-
- // did player beat a ghost racer?
- if ( Gauntlet_HasActiveGhost( gauntlet ) )
- {
- GauntletGhost activeGhost = Gauntlet_GetActiveGhost( gauntlet )
-
- if ( gauntlet.lastRunTime < activeGhost.duration )
- {
- printt( "player beat active ghost!" )
- gauntlet.lastRunDefeatedGhost = true
- }
- }
-
- Remote_CallFunction_Replay( gauntlet.player, "ScriptCallback_Gauntlet_FinishRun", gauntlet.id, elapsedTime, gauntlet.bestTime, enemiesMissedTimePenalty )
-}
-
-void function Gauntlet_AbortRun( GauntletInfo gauntlet )
-{
- entity player = gauntlet.player
- if ( !IsValid( player ) )
- return
-
- RestockPlayerAmmo_Silent( gauntlet.player )
-
- EmitSoundOnEntityOnlyToPlayer( player, player, "training_scr_gaunlet_abort" )
-
- Remote_CallFunction_Replay( player, "ScriptCallback_Gauntlet_AbortRun", gauntlet.id )
-}
-
-void function Gauntlet_WaitForPlayerToStart( GauntletInfo gauntlet )
-{
- WaitSignal( gauntlet.signalEnt, "Gauntlet_PlayerHitStartTrig" )
- Assert( IsValid( gauntlet.player ) )
-}
-
-entity function Gauntlet_StartTrigThink( GauntletInfo gauntlet )
-{
- entity trigStart = gauntlet.trigStart
- entity trigStart2 = gauntlet.trigStart2
-
- EndSignal( gauntlet.signalEnt, "OnDestroy" )
- EndSignal( trigStart, "OnDestroy" )
- EndSignal( trigStart2, "OnDestroy" )
- EndSignal( gauntlet.signalEnt, "Gauntlet_RunStopped" )
-
- table result
- string signal
- entity player
-
- //printt( "WaitForPlayerToHitStartTrig started" )
-
- // "trigStart_OnStartTouch", "trigStart_OnEndTouch", "trigStart2_OnStartTouch", "trigStart2_OnEndTouch"
- thread Gauntlet_PlayerStartSignals( gauntlet, trigStart, "trigStart_" )
- thread Gauntlet_PlayerStartSignals( gauntlet, trigStart2, "trigStart2_" )
-
- while ( 1 )
- {
- entity alreadyTouchingEnt = null
- foreach ( p in GetPlayerArray() )
- {
- if ( trigStart.IsTouching( p ) && Gauntlet_EntCanActivateGauntletTrigger( p ) )
- {
- alreadyTouchingEnt = p
- break
- }
- }
-
- if ( IsValid( alreadyTouchingEnt ) )
- {
- player = alreadyTouchingEnt
- }
- else
- {
- //printt( "Waiting for trigStart OnStartTouch" )
-
- result = WaitSignal( trigStart, "OnStartTouch" )
- player = expect entity( result.activator )
- }
-
- if ( !Gauntlet_EntCanActivateGauntletTrigger( player ) )
- continue
-
- if ( !IsAlive( player ) )
- continue
-
- //printt( "WAITING for trigStart_OnEndTouch" )
-
- while ( IsAlive( player ) )
- {
- WaitSignal( player, "trigStart_OnEndTouch" )
-
- //printt( "RECEIVED trigStart_OnEndTouch" )
-
- // player exited start trig without running gauntlet
- if ( !trigStart2.IsTouching( player ) )
- {
- player.Signal( "Gauntlet_PlayerWentBackwardsThroughStartTrig" )
- continue
- }
-
- //printt( "WAITING for trigStart_OnStartTouch or trigStart2_OnEndTouch" )
-
- // player is now in trig2
- result = WaitSignal( player, "trigStart_OnStartTouch", "trigStart2_OnEndTouch" )
- signal = expect string( result.signal )
- if ( signal == "trigStart2_OnEndTouch" )
- {
- //printt( "RECEIVED trigStart2_OnEndTouch" )
-
- // player exited trig2 without touching trig1, so we know they started the gauntlet
- if ( !trigStart.IsTouching( player ) )
- {
- //printt( "SENDING Gauntlet_PlayerHitStartTrig" )
- gauntlet.signalEnt.Signal( "Gauntlet_PlayerHitStartTrig" )
- gauntlet.player = player
- }
- }
- }
- }
-}
-
-void function Gauntlet_PlayerStartSignals( GauntletInfo gauntlet, entity trig, string signalPrefix )
-{
- EndSignal( trig, "OnDestroy" )
- EndSignal( gauntlet.signalEnt, "Gauntlet_RunStopped" )
-
- /*
- OnThreadEnd(
- function() : ( )
- {
- printt( "Gauntlet_PlayerStartSignals ENDED" )
- }
- )
-
- printt( "PlayerStartSignals started" )
- */
-
- while ( 1 )
- {
- table result = WaitSignal( trig, "OnStartTouch", "OnEndTouch" )
- string signal = expect string( result.signal )
- entity activator = expect entity( result.activator )
-
- if ( !Gauntlet_EntCanActivateGauntletTrigger( activator ) )
- continue
-
- string outboundSignal = signalPrefix
- if ( signal == "OnStartTouch" )
- outboundSignal += "OnStartTouch"
- else if ( signal == "OnEndTouch" )
- outboundSignal += "OnEndTouch"
-
- Assert( outboundSignal != signalPrefix )
-
- Signal( activator, outboundSignal )
- }
-}
-
-void function Gauntlet_WaitForStop( GauntletInfo gauntlet )
-{
- gauntlet.player.EndSignal( "OnDeath" )
- gauntlet.player.EndSignal( "Gauntlet_PlayerWentBackwardsThroughStartTrig" )
- gauntlet.player.EndSignal( "Gauntlet_ForceRestart" )
- gauntlet.signalEnt.EndSignal( "DisableGauntlet" )
-
- table result
- entity activator
-
- while ( 1 )
- {
- result = gauntlet.trigFinish.WaitSignal( "OnStartTouch" )
- activator = expect entity( result.activator )
-
- if ( !activator.IsPlayer() )
- continue
-
- if ( activator != gauntlet.player )
- continue
-
- gauntlet.player.Signal( "Gauntlet_PlayerHitFinishTrig" )
-
- gauntlet.runFinished = true
- if ( gauntlet.checkpoints.len() && gauntlet.checkpointsHit < gauntlet.checkpoints.len() )
- gauntlet.runFinished = false
-
- break
- }
-}
-
-bool function Gauntlet_EntCanActivateGauntletTrigger( entity ent )
-{
- if ( !ent.IsPlayer() )
- return false
-
- if ( !IsAlive( ent ) )
- return false
-
- if ( ent.IsTitan() )
- return false
-
- return true
-}
-
-void function Gauntlet_HandlePlayerForceRestart( GauntletInfo gauntlet )
-{
- gauntlet.player.EndSignal( "OnDestroy" )
- gauntlet.player.EndSignal( "Gauntlet_RunStopped" )
-
- gauntlet.player.WaitSignal( "Gauntlet_ForceRestart" )
-
- thread Gauntlet_TeleportPlayerToStart( gauntlet )
-}
-
-void function Gauntlet_TeleportPlayerToStart( GauntletInfo gauntlet )
-{
- entity player = gauntlet.player
- entity startpoint = gauntlet.startpoint
-
- if ( !IsAlive( player ) )
- return
-
- if ( !IsValid( startpoint ) )
- return
-
- EndSignal( player, "OnDestroy" )
-
- // wait for quick death to finish before continuing
- printt( "player doing quick death (1)?", player.p.doingQuickDeath )
- while ( player.p.doingQuickDeath )
- wait 0.1
-
- //printt( "starting reset fade" )
-
- float fadeTime = 0.1
- float holdTime = 0.3
- ScreenFadeToBlack( player, fadeTime, holdTime )
- player.FreezeControlsOnServer()
- player.SetVelocity( <0,0,0> )
-
- OnThreadEnd(
- function() : ( player, gauntlet )
- {
- if ( IsValid( player ) )
- {
- player.UnfreezeControlsOnServer()
- player.UnforceStand()
- thread Gauntlet_TeleportFailsafe( player, gauntlet )
- }
- }
- )
-
- wait fadeTime
-
- // again, wait for quick death to finish before continuing since it could have started during fadeTime
- printt( "player doing quick death (2)?", player.p.doingQuickDeath )
- while ( player.p.doingQuickDeath )
- wait 0.1
-
- printt( "moving player back to start" )
-
- player.FreezeControlsOnServer() // just in case they were unfrozen by quick death ending since we started waiting
- player.SetOrigin( OriginToGround( startpoint.GetOrigin() + <0,0,1> ) )
- player.SetAngles( startpoint.GetAngles() )
- player.SetVelocity( <0,0,0> )
- player.ForceStand()
-
- wait holdTime
-}
-
-// HACK this is in case the quick death teleport happens on the exact same server frame as the gauntlet restart teleport
-void function Gauntlet_TeleportFailsafe( entity player, GauntletInfo gauntlet )
-{
- // HACK this breaks in other levels that don't have the flag trigger
- // in the future set this up as a gauntlet setting
- if ( GetMapName() != "sp_training" )
- return
-
- EndSignal( player, "OnDestroy" )
-
- wait 0.5
-
- if ( !gauntlet.isActive && !Flag( "PlayerInGauntletEntryway" ) )
- {
- printt( "Gauntlet reset FAILSAFE!" )
- thread Gauntlet_TeleportPlayerToStart( gauntlet )
- }
-}
-
-bool function ClientCommand_Gauntlet_PlayerRestartedFromMenu( entity player, array<string> args )
-{
- player.Signal( "Gauntlet_ForceRestart" )
- return true
-}
-
-void function Gauntlet_CreateSignalEnt( GauntletInfo gauntlet )
-{
- Assert( !IsValid( gauntlet.signalEnt ) )
-
- entity signalEnt = CreateEntity( "info_target" )
- DispatchSpawn( signalEnt )
-
- gauntlet.signalEnt = signalEnt
-}
-
-void function Gauntlet_CleanupSignalEnt( GauntletInfo gauntlet )
-{
- gauntlet.signalEnt.Destroy()
- gauntlet.signalEnt = null
-}
-
-
-void function Gauntlet_ResetTrackerStats( GauntletInfo gauntlet )
-{
- gauntlet.startTime = -1
- gauntlet.runFinished = false
- gauntlet.lastRunBestTime = false
- gauntlet.lastRunDefeatedGhost = false
- gauntlet.enemiesKilled = 0
-}
-
-
-// ===== GHOST RECORDINGS =====
-void function Gauntlet_StartGhostPlayback( GauntletInfo gauntlet, string ghostFileName, string ghostDisplayName = "" )//, bool waitForPlayerToStartFirstRun = true )
-{
- gauntlet.signalEnt.Signal( "GhostAnimationPlayback_Start" )
- gauntlet.signalEnt.EndSignal( "GhostAnimationPlayback_Start" )
- gauntlet.signalEnt.EndSignal( "GhostAnimationPlayback_Stop" )
- gauntlet.signalEnt.EndSignal( "DisableGauntlet" )
-
- GauntletGhost ghostInfo = Gauntlet_GetGhostByFileName( gauntlet, ghostFileName )
- var rec = LoadRecordedAnimation( ghostInfo.fileAsset )
- float duration = GetRecordedAnimationDuration( rec )
- printt( "duration is", duration )
-
- Gauntlet_SetActiveGhostID( gauntlet, ghostInfo.id )
-
- entity animRef = gauntlet.startpoint
-
- bool createdIdleRef = false
- entity idleRef
- if ( gauntlet.ghostAttractSpot != null )
- {
- idleRef = gauntlet.ghostAttractSpot
- }
- else
- {
- createdIdleRef = true
- idleRef = CreateScriptMover( animRef.GetOrigin(), animRef.GetAngles() )
- DropToGround( idleRef )
- }
-
- table<int,entity> g = {}
-
- OnThreadEnd(
- function() : ( g, idleRef, createdIdleRef, gauntlet )
- {
- if ( IsValid( g[0] ) )
- {
- g[0].Anim_Stop()
- StopSoundOnEntity( g[0], "PathHologram_Sustain_Loop_3P" )
- DissolveGhost( g[0] )
- }
-
- if ( createdIdleRef && IsValid( idleRef ) )
- idleRef.Destroy()
-
- Gauntlet_ClearActiveGhost( gauntlet )
- }
- )
-
- entity ghost
- entity ghostWeapon
-
- bool isFirstRun = true
-
- while ( 1 )
- {
- if ( IsValid( ghost ) )
- {
- StopSoundOnEntity( ghost, "PathHologram_Sustain_Loop_3P" )
- DissolveGhost( ghost )
- }
-
- ghost = CreateGhost( idleRef.GetOrigin(), ghostDisplayName )
- g[0] <- ghost
- //ghost.SetTitle( "Ghost Runner" )
- //ShowName( ghost ) // not working
-
- ghostWeapon = Ghost_GetWeaponEnt( ghost )
- ghostWeapon.kv.VisibilityFlags = ENTITY_VISIBLE_TO_NOBODY
-
- thread PlayAnimTeleport( ghost, "pt_OG_training_stand", idleRef )
-
- if ( !gauntlet.isActive )
- gauntlet.signalEnt.WaitSignal( "Gauntlet_RunStarted" )
-
- float startTime = Time()
-
- ghostWeapon.kv.VisibilityFlags = ENTITY_VISIBLE_TO_EVERYONE
-
- EmitSoundOnEntity( ghost, "PathHologram_Sustain_Loop_3P" )
-
- ghost.Anim_Stop()
- ghost.PlayRecordedAnimation( rec, <0,0,0>, <0,0,0>, DEFAULT_SCRIPTED_ANIMATION_BLEND_TIME, animRef )
-
- thread GhostPlayback_HideGhostIfPlayerIsNear( ghost, ghostWeapon )
-
- float ghostFadeTime = 1.2
- float waitBeforeFade = duration - ghostFadeTime
- WaitSignalTimeout( gauntlet.signalEnt, waitBeforeFade, "Gauntlet_RunStopped" )
-
- // ended prematurely
- if ( Time() - startTime < waitBeforeFade )
- ghost.Anim_Stop()
-
- isFirstRun = false
- }
-}
-
-void function GhostPlayback_HideGhostIfPlayerIsNear( entity ghost, entity ghostWeapon )
-{
- EndSignal( ghost, "OnDestroy" )
- EndSignal( ghostWeapon, "OnDestroy" )
-
- const float TICK_WAIT = 0.1
-
- while ( 1 )
- {
- wait TICK_WAIT
-
- entity nearbyPlayer
-
- array<entity> players = GetPlayerArray()
- foreach ( player in players )
- {
- if ( !IsAlive( player ) )
- continue
-
- if ( PlayerTooCloseToGhost( player, ghost ) )
- {
- nearbyPlayer = player
- break
- }
- }
-
- if ( IsValid( nearbyPlayer ) )
- {
- ghost.kv.VisibilityFlags = ENTITY_VISIBLE_TO_NOBODY
- ghostWeapon.kv.VisibilityFlags = ENTITY_VISIBLE_TO_NOBODY
-
- while ( PlayerTooCloseToGhost( nearbyPlayer, ghost ) )
- wait TICK_WAIT
-
- ghost.kv.VisibilityFlags = ENTITY_VISIBLE_TO_EVERYONE
- ghostWeapon.kv.VisibilityFlags = ENTITY_VISIBLE_TO_EVERYONE
- }
-
- }
-}
-
-bool function PlayerTooCloseToGhost( entity player, entity ghost )
-{
- if ( !IsAlive( player ) )
- return false
-
- const float CLOSE_DIST = 64.0
-
- if ( Distance( player.EyePosition(), ghost.GetOrigin() ) <= CLOSE_DIST )
- return true
-
- if ( Distance( player.EyePosition(), ghost.EyePosition() ) <= CLOSE_DIST )
- return true
-
- return false
-}
-
-void function Gauntlet_StopGhostPlayback( GauntletInfo gauntlet )
-{
- gauntlet.signalEnt.Signal( "GhostAnimationPlayback_Stop" )
-}
-
-
-// - Player climbs the leaderboard as her best run time improves
-// - Skips challenging ghosts whose times are worse than the player's
-void function Gauntlet_ChallengeLeaderboardGhosts( entity player, GauntletInfo gauntlet, string endFlag )
-{
- if ( Flag( endFlag ) )
- return
-
- FlagEnd( endFlag )
-
- player.EndSignal( "OnDestroy" )
- gauntlet.signalEnt.EndSignal( "OnDestroy" )
-
- GauntletGhost playerGhost = Gauntlet_GetPlayerGhost( gauntlet )
-
- int currPlayerIdx = GAUNTLET_LEADERBOARD_MAX_ENTRIES - 1
- int nextGhostIdx = currPlayerIdx - 1
-
- while ( currPlayerIdx > 0 )
- {
- array<GauntletGhost> leaderboard = Gauntlet_GetLeaderboard( gauntlet )
-
- // get current player leaderboard position
- int maxLeaderboardIdx = leaderboard.len() - 1
- if ( currPlayerIdx >= maxLeaderboardIdx )
- currPlayerIdx = maxLeaderboardIdx
-
- foreach ( idx, leaderboardGhost in leaderboard )
- {
- if ( leaderboardGhost.fileName == playerGhost.fileName )
- currPlayerIdx = idx
- }
-
- // player is top of the leaderboard, stop racing ghosts
- if ( currPlayerIdx <= 0 )
- break
-
- // if player is not top of leaderboard, cue the ghost above player leaderboard position
- int nextGhostIdx = currPlayerIdx - 1
- GauntletGhost ghost = leaderboard[ nextGhostIdx ]
-
- Assert( ghost.fileName != GHOST_NAME_PLAYER, "Can't race against own player ghost- no anim recording asset" )
-
- thread Gauntlet_StartGhostPlayback( gauntlet, ghost.fileName, ghost.displayName )
-
- if ( !gauntlet.isActive )
- WaitSignal( player, "Gauntlet_RunStarted" )
-
- // wait for run to stop
- WaitSignal( player, "Gauntlet_RunStopped" )
- }
-
- Gauntlet_ClearActiveGhost( gauntlet )
-
- gauntlet.allGhostsDefeated = true
-}
-
-#if DEV
-void function Gauntlet_Player_GhostRecordOrPlayback( entity player, GauntletInfo gauntlet, string ghostFileName )
-{
- if ( GetBugReproNum() == 55 )
- {
- thread Gauntlet_Player_StartRecordingGhost( player, gauntlet, ghostFileName )
- }
- else
- {
- thread Gauntlet_StartGhostPlayback( gauntlet, ghostFileName )
-
- GauntletGhost ghost = Gauntlet_GetGhostByFileName( gauntlet, ghostFileName )
- Dev_PrintMessage( player, "Ghost Playback:", "TO RECORD, set bug_reproNum 55", 4.0 )
- wait 4.0
- Dev_PrintMessage( player, ghost.displayName, "TO RECORD, set bug_reproNum 55", 4.0 )
- }
-}
-
-void function Gauntlet_Player_StartRecordingGhost( entity player, GauntletInfo gauntlet, string ghostFileName )
-{
- player.Signal( "RecordAnimation_Start" )
- player.EndSignal( "RecordAnimation_Start" )
- player.EndSignal( "OnDestroy" )
-
- entity animRef = gauntlet.startpoint
- GauntletGhost ghost = Gauntlet_GetGhostByFileName( gauntlet, ghostFileName )
-
- thread Gauntlet_StartGhostPlayback( gauntlet, ghostFileName )
-
- while ( 1 )
- {
- #if PC_PROG
- thread Gauntlet_Player_StartRecordingGhost_Hints( player, gauntlet, ghost )
- #endif
-
- printt( "READY TO RECORD:", ghost.fileName )
-
- player.WaitSignal( "Gauntlet_RunStarted" )
-
- player.StartRecordingAnimation( animRef.GetOrigin(), animRef.GetAngles() )
- printt( "RECORDING STARTED:", ghost.fileName )
-
- player.WaitSignal( "Gauntlet_RunStopped" )
-
- var recording = player.StopRecordingAnimation()
-
- if ( !gauntlet.runFinished )
- continue
-
- if ( gauntlet.enemiesKilled < gauntlet.spawners.len() )
- {
- Dev_PrintMessage( player, "RECORDING NOT SAVED!", "Must kill all the enemies on your run to save.", 7.0 )
- printt( "!!!! RECORDED ANIM NOT SAVED!!!!" )
- continue
- }
-
- #if PC_PROG
- SaveRecordedAnimation( recording, ghost.fileName )
- Dev_PrintMessage( player, "Anim Data Saved", "BAKE and CLEAR BUG REPRO NUM and RELOAD LEVEL to play it back.", 5.5 )
- printt( "RECORDED ANIM SAVED:", ghost.fileName )
-
- wait 5.5
-
- thread Gauntlet_StartGhostPlayback( gauntlet, ghostFileName )
- #endif
- }
-}
-
-void function Gauntlet_Player_StartRecordingGhost_Hints( entity player, GauntletInfo gauntlet, GauntletGhost ghost )
-{
- player.Signal( "Player_StartRecordingGhost_HintStart" )
- player.EndSignal( "Player_StartRecordingGhost_HintStart" )
- player.EndSignal( "OnDestroy" )
-
- Dev_PrintMessage( player, "Ready To Record Ghost:", "FINISH Gauntlet and kill ALL TARGETS to SAVE GHOST.", 3.0 )
- wait 3.0
- Dev_PrintMessage( player, ghost.displayName, "FINISH Gauntlet and kill ALL TARGETS to SAVE GHOST.", 5.0 )
-}
-#endif //DEV \ No newline at end of file
diff --git a/Northstar.Coop/scripts/vscripts/sp/_savegame.gnut b/Northstar.Coop/scripts/vscripts/sp/_savegame.gnut
deleted file mode 100644
index f4f29003..00000000
--- a/Northstar.Coop/scripts/vscripts/sp/_savegame.gnut
+++ /dev/null
@@ -1,860 +0,0 @@
-global function AddCallback_OnLoadSaveGame
-global function CheckPoint
-global function CheckPoint_Forced
-global function CheckPoint_ForcedSilent
-global function CheckPoint_Silent
-global function RestartFromLevelTransition
-global function CodeCallback_IsSaveGameSafeToCommit
-global function CodeCallback_OnLoadSaveGame
-global function CodeCallback_OnSavedSaveGame
-global function InitSaveGame
-global function LoadSaveTimeDamageMultiplier
-global function ReloadForMissionFailure
-global function GetLastCheckPointLoadTime
-global function SafeForCheckPoint
-global function SafeToSpawnAtOrigin
-global function JustLoadedFromCheckpoint
-global function GetFirstPlayer
-
-const float LAST_SAVE_DEBOUNCE = 4.0
-const float TITAN_SAFE_DIST = 1200
-const SAVE_DEBUG = true
-global const SAVE_NEW = false
-global const MAX_SAFELOCATION_DIST = 5000
-global const float SAVE_SPAWN_VOFFSET = 2.0
-
-global struct CheckPointData
-{
- float searchTime = 5.0
- bool onGroundRequired = true
- array<entity> safeLocations
- bool forced
- bool skipDelayedIsAliveCheck
- bool skipSaveToActualPlayerLocation
- bool functionref( entity ) ornull additionalCheck = null
-}
-
-struct
-{
- bool nextSaveSilent
- table signalDummy
- float loadSaveTime
-
- float lastSaveTime
-
- array<StoredWeapon> saveStoredWeapons
- string storedTitanWeapon
-
- vector saveOrigin
- vector saveAngles
- bool saveRestoreResetsPlayer
-
-} file
-
-void function InitSaveGame()
-{
- Assert( MAX_SAFELOCATION_DIST < TIME_ZOFFSET * 0.8 )
-
- RegisterSignal( "StopSearchingForSafeSave" )
- RegisterSignal( "RespawnNow" )
-
- FlagInit( "OnLoadSaveGame_PlayerRecoveryEnabled", true )
- FlagInit( "SaveRequires_PlayerIsTitan" )
- AddClientCommandCallback( "RestartFromLevelTransition", RestartFromLevelTransition )
- AddClientCommandCallback( "RespawnNowSP", RespawnNowSP )
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// GLOBAL COMMANDS
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void function CheckPoint_Silent( CheckPointData ornull checkPointData = null )
-{
- CheckPointData data = GetCheckPointDataOrDefaults( checkPointData )
- CheckPoint_Silent_FromData( data )
-}
-
-void function CheckPoint_Silent_FromData( CheckPointData checkPointData )
-{
- file.nextSaveSilent = true
- CheckPoint( checkPointData )
-}
-
-void function CheckPoint_ForcedSilent()
-{
- file.nextSaveSilent = true
- CheckPoint_Forced()
-}
-
-void function CheckPoint_Forced()
-{
- CheckPointData checkPointData
- checkPointData.forced = true
- CheckPoint_FromData( checkPointData )
-}
-
-void function CheckPoint( CheckPointData ornull checkPointData = null )
-{
- CheckPointData data = GetCheckPointDataOrDefaults( checkPointData )
- thread CheckPoint_FromData( data )
-}
-
-void function CheckPoint_FromData( CheckPointData checkPointData )
-{
- printt( "SAVEGAME: New save attempt (8/3/2016)" )
-
- float searchTime = checkPointData.searchTime
- bool onGroundRequired = checkPointData.onGroundRequired
- bool skipDelayedIsAliveCheck = checkPointData.skipDelayedIsAliveCheck
- bool skipSaveToActualPlayerLocation = checkPointData.skipSaveToActualPlayerLocation
- bool forced = checkPointData.forced
- array<entity> safeLocations = checkPointData.safeLocations
- bool functionref( entity ) ornull additionalCheck = checkPointData.additionalCheck
-
- if ( !Flag( "SaveGame_Enabled" ) )
- {
- printt( "SAVEGAME: failed: Saves are disabled" )
- return
- }
-
- entity player = GetFirstPlayer()
- entity safeLocation
-
- if ( forced )
- {
- printt( "SAVEGAME: creating: Forced" )
- }
- else
- {
- if ( Flag( "SaveRequires_PlayerIsTitan" ) && !player.IsTitan() )
- {
- printt( "SAVEGAME: failed: Flag SaveRequires_PlayerIsTitan and player is not a Titan" )
- return
- }
-
- printt( "SAVEGAME: creating: Safe for check point?" )
- EndSignal( file.signalDummy, "StopSearchingForSafeSave" )
-
- bool regularSafetyCheck = GetBugReproNum() != 184641 // respawned with no UI
- bool functionref( entity ) safeCheck
- if ( onGroundRequired )
- safeCheck = SafeForCheckPoint_OnGround
- else
- safeCheck = SafeForCheckPoint
-
-
- if ( skipSaveToActualPlayerLocation )
- {
- printt( "SAVEGAME: skipSaveToActualPlayerLocation." )
- }
- else
- {
- float rate = 0.333
- int reps = int( searchTime / rate )
-
- if ( regularSafetyCheck )
- {
- // wait a few seconds until it is safe to save
- for ( int i = 0; i < reps; i++ )
- {
- if ( safeCheck( player ) )
- break
-
- wait rate
- }
- }
- else
- {
- printt( "SAVEGAME: regularSafetyCheck disabled for bug repro" )
- }
- }
-
- if ( !regularSafetyCheck || skipSaveToActualPlayerLocation || !safeCheck( player ) )
- {
- printt( "SAVEGAME: Not safe to save actual player position." )
- if ( !safeLocations.len() )
- {
- printt( "SAVEGAME: failed: no alternate safe locations." )
- return
- }
-
- // titan cores do funky stuff with weapons and make it hard to resume to a new position safely
- if ( !IsTitanCoreFiring( player ) )
- safeLocation = GetBestSaveLocationEnt( safeLocations )
-
- if ( safeLocation == null )
- {
- printt( "SAVEGAME: failed: couldn't find a safe location from those provided." )
- return
- }
-
- printt( "SAVEGAME: Found safe location " + safeLocation.GetOrigin() )
- }
- else
- {
- printt( "SAVEGAME: Safe to save at actual player location: " + player.GetOrigin() )
- }
-
- if ( Time() - file.lastSaveTime < 3 )
- {
- printt( "SAVEGAME: failed: last save was too recent." )
- return
- }
-
- if ( additionalCheck != null )
- {
- expect bool functionref(entity)( additionalCheck )
- if ( !additionalCheck( player ) )
- {
- printt( "SAVEGAME: failed: custom check failed." )
- return
- }
- }
- }
-
- if ( IsValid( safeLocation ) )
- {
- printt( "SAVEGAME: saveRestoreResetsPlayer = true" )
- WriteRestoreLocationFromEntity( safeLocation )
- file.saveRestoreResetsPlayer = true
- }
- else
- {
- printt( "SAVEGAME: saveRestoreResetsPlayer = false" )
- file.saveRestoreResetsPlayer = false
- }
-
- int startPointIndex = GetCurrentStartPointIndex()
-
- if ( !IsAlive( player ) )
- {
- printt( "SAVEGAME: failed: Tried to save while player was dead" )
- return
- }
-
- if ( skipDelayedIsAliveCheck || forced )
- {
- printt( "SAVEGAME: SaveGame_Create" )
- file.lastSaveTime = Time()
- SaveGame_Create( GetSaveName(), SAVEGAME_VERSION, startPointIndex )
- }
- else
- {
- printt( "SAVEGAME: SaveGame_CreateWithCommitDelay" )
- file.lastSaveTime = Time()
- SaveGame_CreateWithCommitDelay( GetSaveName(), SAVEGAME_VERSION, 3.5, 1, startPointIndex )
- }
-
- // kill any ongoing attempts to save. Note this also may end this thread, so it is called last.
- Signal( file.signalDummy, "StopSearchingForSafeSave" )
-}
-
-CheckPointData function GetCheckPointDataOrDefaults( CheckPointData ornull checkPointData = null )
-{
- if ( checkPointData != null )
- return expect CheckPointData( checkPointData )
-
- CheckPointData data
- return data
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// CODE CALLBACKS
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-bool function CodeCallback_IsSaveGameSafeToCommit()
-{
- if ( !Flag( "SaveGame_Enabled" ) )
- return false
-
- foreach ( player in GetPlayerArray() )
- {
- if ( !IsAlive( player ) )
- return false
- }
-
- return true
-}
-
-
-void function ClearPlayerVelocityOnContext( entity player )
-{
- if ( player.IsTitan() )
- return
-
- switch ( GetCurrentStartPoint() )
- {
- case "Rising World Jump":
- return
- }
-
- player.SetVelocity( <0,0,0> )
-}
-
-
-void function CodeCallback_OnLoadSaveGame()
-{
- printt( "SaveGame: OnLoadSaveGame" )
- file.loadSaveTime = Time()
-
- UpdateCollectiblesAfterLoadSaveGame()
- array<entity> players = GetPlayerArray()
-
- Assert( players.len() == 1 )
- entity player = players[0]
-
- // restore health on load from save
- if ( !IsAlive( player ) )
- return
-
- ClearPlayerVelocityOnContext( player )
-
- thread UpdateUI( player.IsTitan(), player )
-
- // run on load save game callbacks
- foreach ( callbackFunc in svGlobalSP.onLoadSaveGameCallbacks )
- {
- callbackFunc( player )
- }
-
- thread DelayedOnLoadSetup( player )
-}
-
-void function DelayedOnLoadSetup( entity player )
-{
- player.EndSignal( "OnDeath" )
-
- WaitFrame() // fixes crash bug, also can't issue a remote call on this codecallback until waiting a frame.
-
- Remote_CallFunction_UI( player, "ServerCallback_GetObjectiveReminderOnLoad" ) // show objective reminder
-
- bool forceStanding = file.saveRestoreResetsPlayer
- if ( file.saveRestoreResetsPlayer )
- {
- file.saveRestoreResetsPlayer = false
-
- printt( "SAVEGAME: Restoring player to safe location " + file.saveOrigin )
- player.SetOrigin( file.saveOrigin )
- player.SetAngles( file.saveAngles )
- player.SetVelocity( <0,0,0> )
-
- TakeAllWeapons( player )
-
- player.ForceStand()
-
- if ( IsPilot( player ) )
- {
- GiveWeaponsFromStoredArray( player, file.saveStoredWeapons )
- }
- else
- {
- player.GiveWeapon( file.storedTitanWeapon )
- }
- }
-
- if ( Flag( "OnLoadSaveGame_PlayerRecoveryEnabled" ) )
- {
- if ( player.IsTitan() )
- {
- RestoreTitan( player )
-
- int index = GetConVarInt( "sp_titanLoadoutCurrent" )
- if ( index > -1 && IsBTLoadoutUnlocked( index ) )
- {
- string weapon = GetTitanWeaponFromIndex( index )
- TakeAllWeapons( player )
- player.GiveWeapon( weapon )
- }
- }
- else
- {
- player.SetHealth( player.GetMaxHealth() )
- entity offhand = player.GetOffhandWeapon( OFFHAND_SPECIAL )
- if ( IsValid( offhand ) )
- {
- // restore offhand, so for example, cloak will be ready to use
- int max = offhand.GetWeaponPrimaryClipCountMax()
- offhand.SetWeaponPrimaryClipCount(max)
- }
-
- entity petTitan = player.GetPetTitan()
- if ( IsAlive( petTitan ) )
- {
- RestoreTitan( petTitan )
- }
- }
- }
-
- WaitFrame()
-
- if ( forceStanding )
- player.UnforceStand()
-
-}
-
-void function CodeCallback_OnSavedSaveGame( bool saved )
-{
- printt( "SAVEGAME: Success (OnSavedSaveGame)" )
-
- // failed to save
- if ( !saved )
- return
-
- // tell clients about the save
- foreach ( player in GetPlayerArray() )
- {
- Remote_CallFunction_UI( player, "ServerCallback_ClearObjectiveReminderOnLoad" ) // dont need objective reminder again on load
- }
-
- BroadcastCheckpointMessage()
-}
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// SAVE UTILITIES
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
-
-
-
-entity function GetFirstPlayer()
-{
- foreach ( player in GetPlayerArray() )
- {
- return player
- }
-
- unreachable
-}
-
-bool function SafeToSpawnAtOrigin( entity player, vector origin )
-{
- if ( player.IsTitan() )
- {
- array<entity> titans = GetNPCArrayEx( "npc_titan", TEAM_ANY, TEAM_MILITIA, origin, TITAN_SAFE_DIST )
- if ( titans.len() > 0 )
- return false
-
- array<entity> superSpectres = GetNPCArrayEx( "npc_super_spectre", TEAM_ANY, TEAM_MILITIA, origin, TITAN_SAFE_DIST )
- if ( superSpectres.len() > 0 )
- return false
- }
- else
- {
- array<entity> enemies = GetNPCArrayEx( "any", TEAM_ANY, TEAM_MILITIA, origin, 300 )
- if ( enemies.len() > 0 )
- return false
- }
-
- return IsPlayerSafeFromProjectiles( player, origin )
-}
-
-entity function GetBestSaveLocationEnt( array<entity> safeLocations )
-{
- entity player = GetFirstPlayer()
- vector mins = player.GetBoundingMins()
- vector maxs = player.GetBoundingMaxs()
-
- vector playerOrg = player.GetOrigin()
- array<entity> orderedLocations = ArrayClosest( safeLocations, player.GetOrigin() )
- foreach ( ent in orderedLocations )
- {
- vector org = ent.GetOrigin() + <0,0,SAVE_SPAWN_VOFFSET>
-
- // too far to spawn
- if ( Distance( playerOrg, org ) > MAX_SAFELOCATION_DIST )
- break
-
- if ( !SafeToSpawnAtOrigin( player, ent.GetOrigin() ) )
- continue
-
- // blocked at that origin?
- TraceResults result = TraceHull( org, org + Vector( 0, 0, 1), mins, maxs, [ player ], TRACE_MASK_PLAYERSOLID, TRACE_COLLISION_GROUP_PLAYER )
- if ( result.startSolid )
- continue
- if ( result.fraction != 1.0 )
- continue
-
- return ent
- }
-
- return null
-}
-
-void function WriteRestoreLocationFromEntity( entity safeLocation )
-{
- Assert( safeLocation != null )
- entity player = GetFirstPlayer()
- Assert( IsAlive( player ), "Tried to save while player was dead" )
-
- if ( IsPilot( player ) )
- {
- file.saveStoredWeapons = StoreWeapons( player )
- }
- else
- {
- array<entity> weapons = player.GetMainWeapons()
- Assert( weapons.len() == 1, "Player had multiple titan weapons" )
- file.storedTitanWeapon = weapons[0].GetWeaponClassName()
- }
-
- file.saveOrigin = safeLocation.GetOrigin() + <0,0,SAVE_SPAWN_VOFFSET>
- file.saveAngles = safeLocation.GetAngles()
-}
-
-bool function RestartFromLevelTransition( entity player, array<string> args )
-{
- thread ReloadFromLevelStart()
-
- return true
-}
-
-void function ReloadForMissionFailure( float extraDelay = 0 )
-{
- // prevent automatic restarts
- //thread ReloadForMissionFailure_Thread( extraDelay )
-}
-
-void function ReloadForMissionFailure_Thread( float extraDelay )
-{
- FlagClear( "SaveGame_Enabled" ) // no more saving, you have lost
- FlagSet( "MissionFailed" )
-
- Signal( file.signalDummy, "StopSearchingForSafeSave" )
-
- entity player = GetFirstPlayer()
- if ( IsValid( player ) )
- EmitSoundOnEntityOnlyToPlayer( player, player, "4_second_fadeout" )
-
- wait 1
-
- waitthread WaitForRespawnNowOrTimePass( player, 2.8 + extraDelay )
-
- ReloadFromSave_RestartFallback()
-}
-
-void function WaitForRespawnNowOrTimePass( entity player, float delay )
-{
- player.EndSignal( "RespawnNow" )
- wait delay
-}
-
-void function SkipReloadDelay_Thread( entity player )
-{
- EmitSoundOnEntityOnlyToPlayer( player, player, "1_second_fadeout" )
- ScreenFadeToBlackForever( player, 0.5 )
- wait 1.0
- player.Signal( "RespawnNow" )
-}
-
-bool function RespawnNowSP( entity player, array<string> args )
-{
- // this clientcommand is always bound now so we need to make sure it isn't called while player is alive
- if ( IsAlive( player ))
- return true
-
- // wait a few seconds before we allow respawns
- if ( player.nv.nextRespawnTime > Time() )
- return true
-
- //thread SkipReloadDelay_Thread( player )
-
- // do our respawning code
- entity ornull respawningOn = GetPlayerToSpawnOn()
-
- if ( respawningOn == null )
- {
- // todo: logic for restarting level without dropping clients
- print( "everyone is dead! restarting from last checkpoint..." )
- RestartWithoutDroppingPlayers()
- }
- else
- {
- expect entity( respawningOn )
- // HACK: compiler has a fit if we directly call player.RespawnPlayer in this file
- // so we need to make a functionref in another file that does it
-
- hackRespawnPlayerFunc( player, respawningOn )
- // honestly unsure if the respawningOn arg works with players so manually set pos too
- thread TeleportToEntitySafe( player, respawningOn )
- }
-
-
- return true
-}
-
-void function ReloadFromSave_RestartFallback()
-{
- if ( LoadedFromSave() )
- return
-
- ReloadFromLevelStart()
-}
-
-void function ReloadFromLevelStart()
-{
- array<entity> players = GetPlayerArray()
- Assert( players.len() == 1 )
- entity player = players[0]
- ServerRestartMission( player )
-}
-
-bool function SafeForCheckPoint_OnGround( entity player )
-{
- Assert( player.IsPlayer() )
-
- if ( !player.IsOnGround() )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: !player.IsOnGround()" )
- #endif
- return false
- }
-
- if ( player.IsWallRunning() )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: player.IsWallRunning()" )
- #endif
- return false
- }
-
- return SafeForCheckPoint( player )
-}
-
-bool function SafeForCheckPoint( entity player )
-{
- Assert( player.IsPlayer() )
-
- if ( Flag( "CheckPointDisabled" ) )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: Flag( \"CheckPointDisabled\" )" )
- #endif
- return false
- }
-
- if ( !IsAlive( player ) )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: !IsAlive( player )" )
- #endif
- return false
- }
-
- if ( IsPlayerEmbarking( player ) )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: IsPlayerEmbarking( player )" )
- #endif
- return false
- }
-
- if ( IsPlayerDisembarking( player ) )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: IsPlayerDisembarking( player )" )
- #endif
- return false
- }
-
- if ( player.p.doingQuickDeath )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: player.p.doingQuickDeath" )
- #endif
- return false
- }
-
- if ( EntityIsOutOfBounds( player ) )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: EntityIsOutOfBounds( player )" )
- #endif
- return false
- }
-
-
- float range = 300
- if ( player.IsTitan() )
- {
- range = 1000
-
- // awkward to resume into a core-in-progress
- if ( IsTitanCoreFiring( player ) )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: IsTitanCoreFiring( player )" )
- #endif
- return false
- }
- }
- else
- {
- entity weapon = player.GetActiveWeapon()
- if ( IsValid( weapon ) )
- {
- // cooking grenade?
- if ( player.GetOffhandWeapon( OFFHAND_ORDNANCE ) == weapon )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: Cooking grenade" )
- #endif
- return false
- }
- }
-
- if ( player.IsPhaseShifted() )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: player.IsPhaseShifted()" )
- #endif
- return false
- }
- }
-
- array<entity> enemies = GetNPCArrayEx( "any", TEAM_ANY, TEAM_MILITIA, player.GetOrigin(), range )
- if ( enemies.len() > 0 )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: Enemy within " + range + " units" )
- #endif
- return false
- }
-
- if ( player.IsTitan() )
- {
-
- array<entity> titans = GetNPCArrayEx( "npc_titan", TEAM_ANY, TEAM_MILITIA, player.GetOrigin(), 3000 )
- foreach ( titan in titans )
- {
- if ( titan.GetEnemy() == player )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: Enemy Titan within 3000 units" )
- #endif
- return false
- }
- }
- }
-
- if ( !IsPlayerSafeFromNPCs( player ) )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: !IsPlayerSafeFromNPCs( player )" )
- #endif
- return false
- }
-
- if ( !IsPlayerSafeFromProjectiles( player, player.GetOrigin() ) )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: !IsPlayerSafeFromProjectiles( player )" )
- #endif
- return false
- }
-
- if ( WasRecentlyHitByDamageSourceId( player, eDamageSourceId.toxic_sludge, 3.0 ) )
- {
- #if SAVE_DEBUG
- printt( "SaveGame: Failed: WasRecentlyHitByDamageSourceId( player, eDamageSourceId.toxic_sludge, 3.0 )" )
- #endif
- return false
- }
-
- return true
-}
-
-void function BroadcastCheckpointMessage()
-{
- if ( file.nextSaveSilent )
- {
- file.nextSaveSilent = false
- return
- }
-
- // tell clients about the save
- foreach ( player in GetPlayerArray() )
- {
- if ( !IsAlive( player ) )
- continue
-
- Remote_CallFunction_NonReplay( player, "SCB_CheckPoint" )
- }
-}
-
-
-void function AddCallback_OnLoadSaveGame( void functionref( entity ) callbackFunc )
-{
- Assert( !svGlobalSP.onLoadSaveGameCallbacks.contains( callbackFunc ), "Already added " + string( callbackFunc ) + " with AddCallback_OnLoadSaveGame" )
- svGlobalSP.onLoadSaveGameCallbacks.append( callbackFunc )
-}
-
-// Why does this need to be threaded?? I don't know! But it doesn't work if I don't wait a bit.
-void function UpdateUI( bool isTitan, entity player )
-{
- if ( !IsValid( player ) )
- return
-
- player.EndSignal( "OnDeath" )
-
- wait 0.1
-
- UpdatePauseMenuMissionLog( player )
-
- if ( isTitan )
- {
- UI_NotifySPTitanLoadoutChange( player )
- NotifyUI_ShowTitanLoadout( player, null )
- }
- else
- {
- NotifyUI_HideTitanLoadout( player, null )
- }
-}
-
-float function LoadSaveTimeDamageMultiplier()
-{
- return GraphCapped( Time() - file.loadSaveTime, 2.5, 4.0, 0.0, 1.0 )
-}
-
-float function GetLastCheckPointLoadTime()
-{
- return file.loadSaveTime
-}
-
-bool function JustLoadedFromCheckpoint()
-{
- return Time() - file.loadSaveTime < 1.0
-}
-
-bool function LoadedFromSave()
-{
- printt( "SAVEGAME: Trying to load saveName" )
- if ( !HasValidSaveGame() )
- {
- printt( "SAVEGAME: !HasValidSaveGame" )
- return false
- }
-
- string saveName = GetSaveName()
- printt( "SAVEGAME: Did load " + saveName )
-
- // set the correct loadscreen
- string mapName = SaveGame_GetMapName( saveName )
- int startPointIndex = SaveGame_GetStartPoint( saveName )
-
- array<string> clientCommands = GetLoadingClientCommands( mapName, startPointIndex, DETENT_FORCE_DISABLE, false )
- ExecuteClientCommands( clientCommands )
-
- if ( GetBugReproNum() != 196356 )
- {
- printt( "LOADPROGRESS" )
- ClientCommand( GetFirstPlayer(), "show_loading_progress" )
- WaitFrame()
- }
-
- SaveGame_LoadWithStartPointFallback()
- return true
-}
diff --git a/Northstar.Coop/scripts/vscripts/sp/hubs/sp_timeshift_spoke02.nut b/Northstar.Coop/scripts/vscripts/sp/hubs/sp_timeshift_spoke02.nut
deleted file mode 100644
index bdb291d7..00000000
--- a/Northstar.Coop/scripts/vscripts/sp/hubs/sp_timeshift_spoke02.nut
+++ /dev/null
@@ -1,3891 +0,0 @@
-untyped
-
-global function CodeCallback_MapInit
-global function TransitionSpoke1
-
-const DUMMY_MODEL = $"models/Robots/stalker/robot_stalker.mdl"
-const TIMEZONE_DAY = 0
-const TIMEZONE_NIGHT = 1
-const TIMEZONE_ALL = 2
-
-const ANDERSON_MODEL = $"models/humans/heroes/mlt_hero_anderson.mdl"
-const IMC_CORPSE_MODEL_CIV = $"models/levels_terrain/sp_timeshift/civilian_eng_v2_corpse_static_20.mdl"
-
-//const FX_HUMAN_DOOR_OPEN = $"steam_leak_SM_CH_end"
-const FX_ANDERSON_DEVICE_FX = $"P_timeshift_gauntlet_hld"
-const FX_ARK_LAUNCH_GLOW = $"P_ts_core_hld_sm"
-const FX_ARK_LAUNCH_IN_PLACE = $"P_ts_core_hld_sm_lock"
-
-struct
-{
- int elevatorDudesDead
- array <entity> elevatorAnimNodes
- array <entity> elevatorDoors
-
-} file
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-//
-//
-// TIMESHIFT SPOKE 2 - MAP INIT
-//
-//
-/////////////////////////////////////////////////////////////////////////////////////////
-void function CodeCallback_MapInit()
-{
- ShSpTimeshiftSpoke2CommonInit()
- RegisterSignal( "AnimTimeshift" )
- RegisterSignal( "PlayerInsideCage" )
- RegisterSignal( "ReleaseLabRat")
-
- PrecacheModel( DUMMY_MODEL )
- PrecacheModel( ANDERSON_MODEL )
- PrecacheModel( IMC_CORPSE_MODEL_CIV )
-
- //PrecacheParticleSystem( FX_HUMAN_DOOR_OPEN )
- PrecacheParticleSystem( FX_ARK_LAUNCH_GLOW )
- PrecacheParticleSystem( FX_ARK_LAUNCH_IN_PLACE )
- PrecacheParticleSystem( FX_ANDERSON_DEVICE_FX )
-
- //PrecacheModel( LABRAT_MODEL )
- AddCallback_EntitiesDidLoad( EntitiesDidLoad )
- AddPlayerDidLoad( TimeShiftHub_PlayerDidLoad )
- AddSpawnCallback( "npc_soldier", OnSpawnedLevelNPC )
- AddSpawnCallback( "npc_prowler", OnSpawnedLevelNPC )
- AddSpawnCallback( "npc_spectre", OnSpawnedLevelNPC )
- AddSpawnCallback( "prop_dynamic", OnSpawnedPropDynamic )
-
- AddDeathCallback( "npc_prowler", OnDeathProwlerAcheivement )
-
-
- SPTimeshiftUtilityInit()
-
- //------------------
- // Flags
- //-----------------
- FlagInit( "SwappedToFrozenWorld" )
- FlagInit( "DoneWithFanDropSequence")
- FlagInit( "ProwlerAcheivementUnlocked" )
- FlagInit( "BrokeOutOfFanDropMusicLoop")
- FlagInit( "ProwlerAmbushTriggered" )
- FlagInit( "AndersomHologram2AboutToStart" )
- FlagInit( "AcheivementUnlockedLabProwler" )
- FlagInit( "ForceFlyerTakeoff" )
- FlagInit( "RingVistaSequenceComplete" )
- FlagInit( "AllProwlersSpawnedInHumanControlRoom" )
- FlagInit( "IntelRoom1Finished" )
- FlagInit( "LabRatAcheivementUnlocked" )
- FlagInit( "AllElevatorProwlersSpawned" )
- FlagInit( "player_back_in_amenities_lobby" )
- FlagInit( "StartAndersonHologram1" )
- FlagInit( "StartAndersonHologram2" )
- FlagInit( "StartAndersonHologram3" )
- FlagInit( "StartSphereRoomGunship" )
- FlagInit( "LabBravoEnemiesDead" )
- FlagInit( "human_bridge_soldiers_dead" )
- FlagInit( "CampusReturnConversationFinished" )
- FlagInit( "PlayerPickingUpDevice" )
- FlagInit( "HidePlayerWeaponsDuringShifts")
- FlagInit( "AllElevatorDudesDead" )
- FlagInit( "ElevatorDudesDead1" )
- FlagInit( "ElevatorDudesDead2" )
- FlagInit( "ElevatorDudesDead3" )
- FlagInit( "ElevatorDudesDead4" )
- FlagInit( "CinematicTimeshiftSequenceFinished")
- FlagInit( "retract_bridge_human_01" )
- FlagInit( "retract_bridge_control_panel_pressed" )
- FlagInit( "door_open_amenities_lobby_return_pristine" )
- FlagInit( "finishedHumanVistaSequence" )
- FlagInit( "spawnHumanBridgeEnemies" )
- FlagInit( "player_looking_at_reactor_window" )
- FlagInit( "open_door_lobby_main_overgrown" )
- FlagInit( "PlayerLookingTowardsElevators" )
- FlagInit( "ConcoursePanelHacked01" )
- FlagInit( "ConcoursePanelHacked02" )
- FlagInit( "PlayerPickedUpTimeshiftDevice" )
- FlagInit( "FirstSpectreDeployedLobbyReduxPristine" )
- FlagInit( "FirstSpectreDeployedLobbyReduxOvergrown" )
- FlagInit( "SeveralElevatorDudesDead" )
- FlagInit( "ShowMobilityGhostTurretFirepit" )
- FlagInit( "ShowMobilityGhostElevatorShaft" )
- FlagInit( "ShowMobilityGhostTurretFlank" )
- FlagInit( "ShowMobilityGhostHumanLillypad01" )
- FlagInit( "ShowMobilityGhostHumanLillypad02" )
- FlagInit( "ShowMobilityGhostHumanWallrunChain" )
- FlagInit( "ShowMobilityGhostPowertech" )
-
- //------------------
- // Start points
- //------------------
- //startPoint, mainFunc, setupFunc skipFunc
- AddStartPoint( "Timeshift Device", AA_TimeshiftDeviceThread, TimeshiftDeviceStartPointSetup, TimeshiftDeviceSkipped )
- AddStartPoint( "WILDLIFE RESEARCH", AA_WildlifeResearchThread, WildlifeResearchStartPointSetup, WildlifeResearchSkipped )
- AddStartPoint( "First Timeshift Fight", AA_FirstTimeshiftFightThread, FirstTimeshiftFightStartPointSetup, FirstTimeshiftFightSkipped )
- AddStartPoint( "Elevator Fight", AA_ElevatorFightThread, ElevatorFightStartPointSetup, ElevatorFightSkipped )
- AddStartPoint( "HUMAN RESEARCH", AA_ElevatorTopThread, ElevatorTopStartPointSetup, ElevatorTopSkipped )
- AddStartPoint( "Sphere Room", AA_SphereRoomThread, SphereRoomStartPointSetup, SphereRoomSkipped ) //checkpointIntelRoom2
- AddStartPoint( "Human Room", AA_HumanResearchThread, HumanResearchStartPointSetup, HumanResearchSkipped )
- AddStartPoint( "CAMPUS RETURN", AA_CampusReturnThread, CampusReturnStartPointSetup, CampusReturnSkipped )
- AddStartPoint( "Fan Drop", AA_FanDropThread, FanDropStartPointSetup, FanDropSkipped )
- AddStartPoint( "Fan Drop End", AA_FanDropEndThread, FanDropEndStartPointSetup, FanDropEndSkipped )
-
- AddMobilityGhost( $"anim_recording/timeshift_turret_firepit_overgrown.rpak", "ShowMobilityGhostTurretFirepit" )
- AddMobilityGhost( $"anim_recording/timeshift_elevator_shaft_overgrown.rpak", "ShowMobilityGhostElevatorShaft" )
- AddMobilityGhost( $"anim_recording/timeshift_elevator_shaft_pristine.rpak", "ShowMobilityGhostElevatorShaft" )
- AddMobilityGhost( $"anim_recording/timeshift_turret_flank_overgrown.rpak", "ShowMobilityGhostTurretFlank" )
- AddMobilityGhost( $"anim_recording/timeshift_lillypad01_overgrown.rpak", "ShowMobilityGhostHumanLillypad01" )
- AddMobilityGhost( $"anim_recording/timeshift_lillypad01_pristine.rpak", "ShowMobilityGhostHumanLillypad01" )
- AddMobilityGhost( $"anim_recording/timeshift_lillypad02_overgrown.rpak", "ShowMobilityGhostHumanLillypad02" )
- AddMobilityGhost( $"anim_recording/timeshift_lillypad02_pristine.rpak", "ShowMobilityGhostHumanLillypad02" )
- AddMobilityGhost( $"anim_recording/timeshift_wallchain_overgrown.rpak", "ShowMobilityGhostHumanWallrunChain" )
- AddMobilityGhost( $"anim_recording/timeshift_wallchain_pristine.rpak", "ShowMobilityGhostHumanWallrunChain" )
- AddMobilityGhost( $"anim_recording/timeshift_powertech_overgrown.rpak", "ShowMobilityGhostPowertech" )
- AddMobilityGhost( $"anim_recording/timeshift_powertech_pristine.rpak", "ShowMobilityGhostPowertech" )
-
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function EntitiesDidLoad()
-{
- FlagSet( "retract_bridge_human_01" )
-
- HideStuff( "human_bridge_overgrown" )
- HideStuff( "elevator_doors_upper_overgrown" )
- HideStuff( "blocker_fandrop_pristine" )
- HideStuff( "blocker_fandrop_overgrown" )
-
-
- thread SkyboxStart()
- thread RingsThink()
-
- array <entity> elevatorAnimNodesLocal = GetEntArrayByScriptName( "node_elevator_anim" )
- Assert( elevatorAnimNodesLocal.len() == 4 )
- file.elevatorAnimNodes = elevatorAnimNodesLocal
-
- array <entity> elevatorDoorsLocal = GetEntArrayByScriptName( "elevator_door_exec_housing_access" )
- Assert( elevatorDoorsLocal.len() == 4 )
- file.elevatorDoors = elevatorDoorsLocal
-
-
- //navmesh sep to keep prowlers away from half-open elevators
- entity navmesh_blocker_elevator_overgrown = GetEntByScriptName( "navmesh_blocker_elevator_overgrown" )
- navmesh_blocker_elevator_overgrown.NotSolid() //ok if it's notsolid, will still disconnect the navmesh
-
-
- //CleanupEnts( "triggers_instadeath_humanroom" )
- //CleanupEnts( "triggers_quickdeath_humanroom" )
- //CleanupEnts( "trigger_quickdeath_checkpoint_humanroom" )
-
- thread AndersonSetup()
-
- // coop code: fuck with entities so we can prevent some weird flags
- //array< entity > doors =
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function TimeShiftHub_PlayerDidLoad( entity player )
-{
- /*
- This will run before any start points run.
- Useful for doing common player-specific setup,
- saving you from having to put a common player
- setup function in each of your start points
- */
-
- //---------------------
- // Timeshift thread
- //----------------------
- thread TimeshiftPlayerThink( player )
-
-
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-████████╗██╗███╗ ███╗███████╗███████╗██╗ ██╗██╗███████╗████████╗ ██████╗ ███████╗██╗ ██╗██╗ ██████╗███████╗
-╚══██╔══╝██║████╗ ████║██╔════╝██╔════╝██║ ██║██║██╔════╝╚══██╔══╝ ██╔══██╗██╔════╝██║ ██║██║██╔════╝██╔════╝
- ██║ ██║██╔████╔██║█████╗ ███████╗███████║██║█████╗ ██║ ██║ ██║█████╗ ██║ ██║██║██║ █████╗
- ██║ ██║██║╚██╔╝██║██╔══╝ ╚════██║██╔══██║██║██╔══╝ ██║ ██║ ██║██╔══╝ ╚██╗ ██╔╝██║██║ ██╔══╝
- ██║ ██║██║ ╚═╝ ██║███████╗███████║██║ ██║██║██║ ██║ ██████╔╝███████╗ ╚████╔╝ ██║╚██████╗███████╗
- ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═══╝ ╚═╝ ╚═════╝╚══════╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-████████╗██╗███╗ ███╗███████╗███████╗██╗ ██╗██╗███████╗████████╗ ██████╗ ███████╗██╗ ██╗██╗ ██████╗███████╗
-╚══██╔══╝██║████╗ ████║██╔════╝██╔════╝██║ ██║██║██╔════╝╚══██╔══╝ ██╔══██╗██╔════╝██║ ██║██║██╔════╝██╔════╝
- ██║ ██║██╔████╔██║█████╗ ███████╗███████║██║█████╗ ██║ ██║ ██║█████╗ ██║ ██║██║██║ █████╗
- ██║ ██║██║╚██╔╝██║██╔══╝ ╚════██║██╔══██║██║██╔══╝ ██║ ██║ ██║██╔══╝ ╚██╗ ██╔╝██║██║ ██╔══╝
- ██║ ██║██║ ╚═╝ ██║███████╗███████║██║ ██║██║██║ ██║ ██████╔╝███████╗ ╚████╔╝ ██║╚██████╗███████╗
- ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═══╝ ╚═╝ ╚═════╝╚══════╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-████████╗██╗███╗ ███╗███████╗███████╗██╗ ██╗██╗███████╗████████╗ ██████╗ ███████╗██╗ ██╗██╗ ██████╗███████╗
-╚══██╔══╝██║████╗ ████║██╔════╝██╔════╝██║ ██║██║██╔════╝╚══██╔══╝ ██╔══██╗██╔════╝██║ ██║██║██╔════╝██╔════╝
- ██║ ██║██╔████╔██║█████╗ ███████╗███████║██║█████╗ ██║ ██║ ██║█████╗ ██║ ██║██║██║ █████╗
- ██║ ██║██║╚██╔╝██║██╔══╝ ╚════██║██╔══██║██║██╔══╝ ██║ ██║ ██║██╔══╝ ╚██╗ ██╔╝██║██║ ██╔══╝
- ██║ ██║██║ ╚═╝ ██║███████╗███████║██║ ██║██║██║ ██║ ██████╔╝███████╗ ╚████╔╝ ██║╚██████╗███████╗
- ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═══╝ ╚═╝ ╚═════╝╚══════╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-████████╗██╗███╗ ███╗███████╗███████╗██╗ ██╗██╗███████╗████████╗ ██████╗ ███████╗██╗ ██╗██╗ ██████╗███████╗
-╚══██╔══╝██║████╗ ████║██╔════╝██╔════╝██║ ██║██║██╔════╝╚══██╔══╝ ██╔══██╗██╔════╝██║ ██║██║██╔════╝██╔════╝
- ██║ ██║██╔████╔██║█████╗ ███████╗███████║██║█████╗ ██║ ██║ ██║█████╗ ██║ ██║██║██║ █████╗
- ██║ ██║██║╚██╔╝██║██╔══╝ ╚════██║██╔══██║██║██╔══╝ ██║ ██║ ██║██╔══╝ ╚██╗ ██╔╝██║██║ ██╔══╝
- ██║ ██║██║ ╚═╝ ██║███████╗███████║██║ ██║██║██║ ██║ ██████╔╝███████╗ ╚████╔╝ ██║╚██████╗███████╗
- ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═══╝ ╚═╝ ╚═════╝╚══════╝
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-void function TimeshiftDeviceStartPointSetup( entity player )
-{
- TeleportPlayerToEnt( player, GetEntByScriptName( "checkpointTimeshiftDevice" ) )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function TimeshiftDeviceSkipped( entity player )
-{
- FlagSet( "open_creature_door_start_pristine" )
- FlagSet( "PlayerPickedUpTimeshiftDevice" )
- GiveTimeshiftAbility( player )
- FlagClear( "open_skybridge_door_end_pristine" )
- FlagClear( "open_skybridge_door_end_overgrown" )
- FlagSet( "CinematicTimeshiftSequenceFinished")
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function AA_TimeshiftDeviceThread( entity player )
-{
- InitBoyleAudioLogs()
-
- //FlagSet( "open_skybridge_door_end_overgrown" )
- //FlagSet( "open_creature_door_start_pristine" )
- //-----------------------------------------
- // Get timeshift device
- //-----------------------------------------
- wait 1
-
- thread MusicGetTimeshiftDevice( player )
- thread DialogueCreatureLabAnderson( player )
-
- thread PickupTimeShiftDevice( player )
-
-
-
- FlagWait( "PlayerPickedUpTimeshiftDevice" )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function MusicGetTimeshiftDevice( entity player )
-{
- StopMusic()
- PlayMusic( "music_timeshift_15_gettemporaldevice" )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function DialogueCreatureLabAnderson( entity player )
-{
- entity anderson = GetEntByScriptName( "anderson_other_half" )
- local attach_id = anderson.LookupAttachment( "L_HAND" )
- vector objectivePos = anderson.GetAttachmentOrigin( attach_id )
-
- TimeshiftSetObjectiveSilent( player, "#TIMESHIFT_OBJECTIVE_TAKE_TIME_DEVICE", objectivePos )
-
-/*
-██████╗ ██╗ █████╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗
-██╔══██╗██║██╔══██╗██║ ██╔═══██╗██╔════╝ ██║ ██║██╔════╝
-██║ ██║██║███████║██║ ██║ ██║██║ ███╗██║ ██║█████╗
-██║ ██║██║██╔══██║██║ ██║ ██║██║ ██║██║ ██║██╔══╝
-██████╔╝██║██║ ██║███████╗╚██████╔╝╚██████╔╝╚██████╔╝███████╗
-╚═════╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
-*/
-
- wait 10
-
- if ( Flag( "PlayerPickingUpDevice" ) )
- return
-
-
- Objective_Remind()
- //timeshift device nags
- string nagAlias
- int nextNagNumber = 1
-
-
- while( !Flag( "PlayerPickingUpDevice") )
- {
- wait( RandomFloatRange( 35, 45 ) )
-
- if ( Flag( "PlayerPickingUpDevice" ) )
- break
-
-
- if ( nextNagNumber == 1 )
- {
- //BT Well done, Pilot. You located the wrist mounted device. SRS intel suggests if equipped you can withstand and manipulate the temporal shifts.
- nagAlias = "diag_sp_wildlifeStudy_TS191_01_01_mcor_bt"
- }
-
- if ( nextNagNumber == 2 )
- {
- //BT Pilot, recommend you equip the device.
- nagAlias = "diag_sp_wildlifeStudy_TS191_09_01_mcor_bt"
- }
- else if ( nextNagNumber == 3 )
- {
- //BT The wrist mounted device may be useful. Recommend you equip the device.
- nagAlias = "diag_sp_wildlifeStudy_TS191_10_01_mcor_bt"
- }
- else if ( nextNagNumber == 4 )
- {
- //BT Advisory: Pilot, I recommend you equip the wrist mounted device.
- nagAlias = "diag_sp_wildlifeStudy_TS191_11_01_mcor_bt"
- }
-
- waitthread PlayBTDialogue( nagAlias )
-
- if ( Flag( "PlayerPickingUpDevice" ) )
- break
- Objective_Remind()
- //Objective_Clear()
- //TimeshiftSetObjective( player, "#TIMESHIFT_OBJECTIVE_TAKE_TIME_DEVICE", objectivePos )
- nextNagNumber++
- if ( nextNagNumber > 4 )
- nextNagNumber = 1
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function AndersonSetup()
-{
- entity node = GetEntByScriptName( "org_get_device_sequence" )
- entity anderson = GetEntByScriptName( "anderson_other_half" )
- anderson.SetModel( ANDERSON_MODEL )
- thread PlayAnimTeleport( anderson, "pt_timeshift_device_equip_corpse_sequence_idle", node )
-
- entity AndersonDeviceFX = PlayLoopFXOnEntity( FX_ANDERSON_DEVICE_FX, anderson, "L_BACKHAND" )
-
-
- int bodyGroupIndex = anderson.FindBodyGroup( "watch" )
- anderson.SetBodygroup( bodyGroupIndex, 1 )
-
- bodyGroupIndex = anderson.FindBodyGroup( "watch_ts" )
- anderson.SetBodygroup( bodyGroupIndex, 1 )
-
- FlagWait( "PlayerPickingUpDevice")
-
- wait 1
-
- if ( IsValid( AndersonDeviceFX ) )
- {
- StopFX( AndersonDeviceFX )
- EntFireByHandle( AndersonDeviceFX, "Stop", "", 0, null, null )
- AndersonDeviceFX.Destroy()
- }
-
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function PickupTimeShiftDevice( entity player )
-{
- entity node = GetEntByScriptName( "org_get_device_sequence" )
- entity anderson = GetEntByScriptName( "anderson_other_half" )
-
- wait 0.5
-
- local attach_id = anderson.LookupAttachment( "L_HAND" )
- vector origin = anderson.GetAttachmentOrigin( attach_id )
- vector angles = anderson.GetAttachmentAngles( attach_id )
-
-
- //entity useDummy = CreatePropDynamic( TempModel, origin, angles, 6 ) // 0 = no collision, 2 = bounding box, 6 = use vPhysics, 8 = hitboxes only
- entity useDummy = CreatePropDynamic( DUMMY_MODEL, origin, Vector( 0, 0, 0 ), 2 ) // 0 = no collision, 2 = bounding box, 6 = use vPhysics, 8 = hitboxes only
- useDummy.SetOrigin( origin )
-
- useDummy.SetUsable()
- useDummy.Hide()
- useDummy.SetUsableByGroup( "pilot" )
- useDummy.SetUsePrompts( "#TIMESHIFT_HINT_TAKE_DEVICE" , "#TIMESHIFT_HINT_TAKE_DEVICE_PC" )
-
- local playerActivator
- while( true )
- {
- playerActivator = useDummy.WaitSignal( "OnPlayerUse" ).player
- if ( IsValid( playerActivator ) && playerActivator.IsPlayer() && !playerActivator.IsTitan() )
- {
- // set player to whoever actually picked up the device, not host
- expect entity( playerActivator )
- player = playerActivator
- break
- }
- }
-
- //Cooper: Sorry Anderson
- FlagSet( "PlayerPickingUpDevice" )
-
- Objective_Clear()
- delaythread ( 1 ) PlayDialogue( "diag_sp_extra_GB101_65_01_mcor_player", player )
-
-
- useDummy.UnsetUsable()
- useDummy.Destroy()
-
- player.DisableWeaponWithSlowHolster()
- player.SetInvulnerable()
- //player.FreezeControlsOnServer()
- player.ContextAction_SetBusy()
-
- FlagSet( "DoingCinematicTimeshift" )
-
- //----------------------------------
- // Player takes device off Anderson
- //------------------------------------
- entity mover = CreateOwnedScriptMover( node ) //need a mover for first person sequence
-
- FirstPersonSequenceStruct sequenceTakeDevice
- //sequenceTakeDevice.blendTime = 1
- sequenceTakeDevice.attachment = "ref"
- sequenceTakeDevice.firstPersonAnim = "ptpov_timeshift_device_equip_sequence"
- sequenceTakeDevice.thirdPersonAnim = "pt_timeshift_device_equip_sequence"
- sequenceTakeDevice.viewConeFunction = ViewConeTight
-
- thread PlayAndersonCorpseAnims( anderson, node )
- waitthread FirstPersonSequence( sequenceTakeDevice, player, mover )
-
- FlagSet( "PlayerPickedUpTimeshiftDevice" )
- //---------------------------
- // Player equips device
- //----------------------------
- player.ClearParent()
- mover.Destroy()
- entity mover2 = CreateOwnedScriptMover( node ) //need a mover for first person sequence
-
- FirstPersonSequenceStruct sequenceEquipDevice
- sequenceEquipDevice.blendTime = 0
- sequenceEquipDevice.attachment = "ref"
- sequenceEquipDevice.firstPersonAnim = "ptpov_timeshift_device_equip_sequence_02"
- sequenceEquipDevice.thirdPersonAnim = "pt_timeshift_device_equip_sequence_02"
- sequenceEquipDevice.viewConeFunction = ViewConeTight
-
- //WaitFrame()
-
- GiveTimeshiftAbility( player )
- thread TimeshiftSequenceShifts( player, mover2 )
-
- entity proxy = player.GetFirstPersonProxy()
- int bodyGroupIndex = proxy.FindBodyGroup( "glove_default" )
- proxy.SetBodygroup( bodyGroupIndex, 1 ) // 0 = show, 1 = hide
-
- int bodyGroupIndex2 = proxy.FindBodyGroup( "glove_animated" )
- proxy.SetBodygroup( bodyGroupIndex2, 1 ) // 0 = show, 1 = hide
-
- waitthread FirstPersonSequence( sequenceEquipDevice, player, mover2 )
-
- SetTimeshiftArmDeviceSkin( 1 )
-
- //player.UnfreezeControlsOnServer()
- player.ClearInvulnerable()
- player.Anim_Stop()
- player.ClearParent()
- ClearPlayerAnimViewEntity( player )
- if ( player.ContextAction_IsBusy() )
- player.ContextAction_ClearBusy()
- player.EnableWeaponWithSlowDeploy()
-
- FlagClear( "DoingCinematicTimeshift" )
-
- FlagSet( "CinematicTimeshiftSequenceFinished")
-
-
- proxy = player.GetFirstPersonProxy()
- if ( proxy == null )
- return
-
- bodyGroupIndex = proxy.FindBodyGroup( "glove_default" )
- proxy.SetBodygroup( bodyGroupIndex, 0 ) // 0 = show, 1 = hide
-
- //bodyGroupIndex2= proxy.FindBodyGroup( "glove_animated" )
- //proxy.SetBodygroup( bodyGroupIndex2, 1 ) // 0 = show, 1 = hide
-
-}
-
-void function PlayAndersonCorpseAnims( entity anderson, entity node )
-{
- waitthread PlayAnim( anderson, "pt_timeshift_device_equip_corpse_sequence", node )
-
- //watch
- //int bodyGroupIndex = anderson.FindBodyGroup( "watch" )
- //anderson.SetBodygroup( bodyGroupIndex, 1 )
-
- int bodyGroupIndex = anderson.FindBodyGroup( "watch_ts" )
- anderson.SetBodygroup( bodyGroupIndex, 0 )
-
- thread PlayAnim( anderson, "pt_timeshift_device_equip_corpse_sequence_02", node )
-
-}
-void function TimeshiftSequenceShifts( entity player, entity node )
-{
- player.EndSignal( "OnDeath" )
- entity proxy = player.GetFirstPersonProxy()
- vector nodeOrigin = node.GetOrigin()
- vector playerOrigin = player.GetOrigin()
-
-
- WaitSignal( proxy, "AnimTimeshift" )
- SwapTimelines( player, TIMEZONE_DAY )
- node.SetAbsOrigin( Vector( nodeOrigin.x, nodeOrigin.y, nodeOrigin.z + TIME_ZOFFSET ) )
- //player.SetAbsOrigin( Vector( playerOrigin.x, playerOrigin.y, playerOrigin.z + TIME_ZOFFSET ) )
-
- wait 0.1
- //EmitSoundOnEntity( player, "Pilot_PhaseShift_End_3P" )
-
- WaitSignal( proxy, "AnimTimeshift" )
- SwapTimelines( player, TIMEZONE_NIGHT )
- node.SetAbsOrigin( nodeOrigin )
- //player.SetAbsOrigin( playerOrigin )
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-██╗ ██╗██╗██╗ ██████╗ ██╗ ██╗███████╗███████╗ ██████╗ ███████╗███████╗███████╗ █████╗ ██████╗ ██████╗██╗ ██╗
-██║ ██║██║██║ ██╔══██╗██║ ██║██╔════╝██╔════╝ ██╔══██╗██╔════╝██╔════╝██╔════╝██╔══██╗██╔══██╗██╔════╝██║ ██║
-██║ █╗ ██║██║██║ ██║ ██║██║ ██║█████╗ █████╗ ██████╔╝█████╗ ███████╗█████╗ ███████║██████╔╝██║ ███████║
-██║███╗██║██║██║ ██║ ██║██║ ██║██╔══╝ ██╔══╝ ██╔══██╗██╔══╝ ╚════██║██╔══╝ ██╔══██║██╔══██╗██║ ██╔══██║
-╚███╔███╔╝██║███████╗██████╔╝███████╗██║██║ ███████╗ ██║ ██║███████╗███████║███████╗██║ ██║██║ ██║╚██████╗██║ ██║
- ╚══╝╚══╝ ╚═╝╚══════╝╚═════╝ ╚══════╝╚═╝╚═╝ ╚══════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
- */
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-██╗ ██╗██╗██╗ ██████╗ ██╗ ██╗███████╗███████╗ ██████╗ ███████╗███████╗███████╗ █████╗ ██████╗ ██████╗██╗ ██╗
-██║ ██║██║██║ ██╔══██╗██║ ██║██╔════╝██╔════╝ ██╔══██╗██╔════╝██╔════╝██╔════╝██╔══██╗██╔══██╗██╔════╝██║ ██║
-██║ █╗ ██║██║██║ ██║ ██║██║ ██║█████╗ █████╗ ██████╔╝█████╗ ███████╗█████╗ ███████║██████╔╝██║ ███████║
-██║███╗██║██║██║ ██║ ██║██║ ██║██╔══╝ ██╔══╝ ██╔══██╗██╔══╝ ╚════██║██╔══╝ ██╔══██║██╔══██╗██║ ██╔══██║
-╚███╔███╔╝██║███████╗██████╔╝███████╗██║██║ ███████╗ ██║ ██║███████╗███████║███████╗██║ ██║██║ ██║╚██████╗██║ ██║
- ╚══╝╚══╝ ╚═╝╚══════╝╚═════╝ ╚══════╝╚═╝╚═╝ ╚══════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
- */
-/////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////
-/*
-██╗ ██╗██╗██╗ ██████╗ ██╗ ██╗███████╗███████╗ ██████╗ ███████╗███████╗███████╗ █████╗ ██████╗ ██████╗██╗ ██╗
-██║ ██║██║██║ ██╔══██╗██║ ██║██╔════╝██╔════╝ ██╔══██╗██╔════╝██╔════╝██╔════╝██╔══██╗██╔══██╗██╔════╝██║ ██║
-██║ █╗ ██║██║██║ ██║ ██║██║ ██║█████╗ █████╗ ██████╔╝█████╗ ███████╗█████╗ ███████║██████╔╝██║ ███████║
-██║███╗██║██║██║ ██║ ██║██║ ██║██╔══╝ ██╔══╝ ██╔══██╗██╔══╝ ╚════██║██╔══╝ ██╔══██║██╔══██╗██║ ██╔══██║
-╚███╔███╔╝██║███████╗██████╔╝███████╗██║██║ ███████╗ ██║ ██║███████╗███████║███████╗██║ ██║██║ ██║╚██████╗██║ ██║
- ╚══╝╚══╝ ╚═╝╚══════╝╚═════╝ ╚══════╝╚═╝╚═╝ ╚══════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
- */
-/////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////
-/*
-██╗ ██╗██╗██╗ ██████╗ ██╗ ██╗███████╗███████╗ ██████╗ ███████╗███████╗███████╗ █████╗ ██████╗ ██████╗██╗ ██╗
-██║ ██║██║██║ ██╔══██╗██║ ██║██╔════╝██╔════╝ ██╔══██╗██╔════╝██╔════╝██╔════╝██╔══██╗██╔══██╗██╔════╝██║ ██║
-██║ █╗ ██║██║██║ ██║ ██║██║ ██║█████╗ █████╗ ██████╔╝█████╗ ███████╗█████╗ ███████║██████╔╝██║ ███████║
-██║███╗██║██║██║ ██║ ██║██║ ██║██╔══╝ ██╔══╝ ██╔══██╗██╔══╝ ╚════██║██╔══╝ ██╔══██║██╔══██╗██║ ██╔══██║
-╚███╔███╔╝██║███████╗██████╔╝███████╗██║██║ ███████╗ ██║ ██║███████╗███████║███████╗██║ ██║██║ ██║╚██████╗██║ ██║
- ╚══╝╚══╝ ╚═╝╚══════╝╚═════╝ ╚══════╝╚═╝╚═╝ ╚══════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
- */
-/////////////////////////////////////////////////////////////////////////////////////////
-void function WildlifeResearchStartPointSetup( entity player )
-{
- TeleportPlayerToEnt( player, GetEntByScriptName( "checkpointWildlifeResearch" ) )
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function WildlifeResearchSkipped( entity player )
-{
- CleanupEnts( "flyer_lab" )
- CleanupEnts( "civilian_evac_firehall" )
- //thread MusicWildlifeResearch( player )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function AA_WildlifeResearchThread( entity player )
-{
- FlagWait( "CinematicTimeshiftSequenceFinished")
-
- vector objectivePos = GetEntByScriptName( "obj_creature_labs_after_fire_hall" ).GetOrigin()
- TimeshiftSetObjectiveSilent( player, "#TIMESHIFT_OBJECTIVE_LAB_EXPLORE", objectivePos )
-
- Remote_CallFunction_NonReplay( player, "ServerCallback_PlayGloveGlow", TIMEZONE_NIGHT )
-
- CheckPoint_Forced()
-
- thread MusicWildlifeResearch( player )
- //CheckPoint()
-
- wait 1
-
- thread DisplayOnscreenHint( player, "timeshift_hint_default", 3.0 )
-
- //failsafeFlagToStart lookAtEnt = null
- thread QuickSkit( player, GetEntByScriptName( "node_evac_firehall01" ), "headed_into_fire_hall" )
- thread QuickSkit( player, GetEntByScriptName( "node_evac_firehall02" ), "headed_into_fire_hall" )
- thread QuickSkit( player, GetEntByScriptName( "node_creature_soldiers_surprised" ), "open_door_creature_labs_part2" )
-
- //-------------------------------------------------
- // Use timeshift to get past electricity
- //------------------------------------------------
- thread DialogueTimeShiftEquipped( player )
- thread DialogueCivilianEvacCreatureLabs( player )
- thread DialogueCreaturLabsIMC( player )
-
- thread TimeshiftHint( player, TIMEZONE_NIGHT, "player_entered_creature_lab", "timeshift_hint_default", GetEntByScriptName( "trig_player_near_first_ts_hazard" ) )
-
-
- FlagWait( "player_entered_creature_lab" )
- CleanupEnts( "civilian_walker_courtyard" )
- CleanupEnts( "civilian_actor_firehall01" )
- CleanupEnts( "civilian_actor_firehall02" )
-
-
- // remove this so we don't softlock other players lol
- //FlagClear( "open_creature_door_start_pristine" )
-
- objectivePos = GetEntByScriptName( "objective_spoke1_breadcrumb000" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- CheckPoint_Forced()
-
- thread TimeshiftHint( player, TIMEZONE_DAY, "player_past_creature_first_laser", "timeshift_hint_default", GetEntByScriptName( "trig_player_near_creature_hazard" ) )
-
- thread ObjectiveRemindUntilFlag( "player_past_creature_first_laser" )
-
- FlagWait( "player_past_creature_first_laser" )
-
- objectivePos = GetEntByScriptName( "objective_spoke1_breadcrumb00" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- thread TimeshiftHint( player, TIMEZONE_NIGHT, "player_past_creature_second_obstacle", "timeshift_hint_default", GetEntByScriptName( "trig_player_near_creature_hazard2" ) )
-
- CheckPoint_Forced()
-
- //lookAtEnt
- thread QuickSkit( player, GetEntByScriptName( "node_evac_creaturelabs_2dudes" ), "player_past_creature_second_obstacle" )
- thread QuickSkit( player, GetEntByScriptName( "node_evac_creaturelabs_bench2" ), "player_past_creature_second_obstacle" )
-
- thread ObjectiveRemindUntilFlag( "player_past_creature_second_obstacle" )
-
- FlagWait( "player_past_creature_second_obstacle" )
-
-
- thread TimeshiftHint( player, TIMEZONE_DAY, "player_entered_creature_fans", "timeshift_hint_default", GetEntByScriptName( "trig_player_near_creature_fan_hazard" ) )
-
- objectivePos = GetEntByScriptName( "objective_spoke1_breadcrumb00aa" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
-
- //---------------------------------------
- // Get past laser door in pristine via fans
- //---------------------------------------
-
- thread ObjectiveRemindUntilFlag( "player_exited_creature_labs" )
-
- FlagWait( "player_entered_creature_fans" )
-
- CleanupEnts( "civilian_evac_firehall" )
- thread TimeshiftHint( player, TIMEZONE_NIGHT, "player_exited_creature_labs", "timeshift_hint_default", GetEntByScriptName( "trig_player_near_creature_fan_blockage" ) )
-
- FlagWait( "player_exited_creature_labs" )
-
-
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function MusicWildlifeResearch( entity player )
-{
- if ( Flag( "entered_amenities_elevator_room" ) )
- return
-
- FlagEnd( "entered_amenities_elevator_room" )
-
-
- //waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- StopMusic()
- SetGlobalNetBool( "music14LoopPausable", false )
- PlayMusicThatCantBeStopped( "music_timeshift_14_pastloop" )
-
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_NIGHT )
- //Until the elevator fight, whenever the player switches in the PRESENT - Play music_timeshift_16_explorepresent
- thread PlayMusicInTimezoneUntilFlag( "music_timeshift_16_explorepresent", TIMEZONE_NIGHT, "entered_amenities_elevator_room" )
-
-}
-
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function OnDeathProwlerAcheivement( entity npc, var damageInfo )
-{
- if ( Flag( "ProwlerAcheivementUnlocked" ) )
- return
-
- if ( Flag( "crossed_elevator_fire_chasm" ) )
- return
-
- entity attacker = DamageInfo_GetAttacker( damageInfo )
-
- if ( !IsValid ( attacker ) )
- return
-
- if ( !attacker.IsPlayer() )
- return
-
- entity player = attacker
-
- string classname = npc.GetClassName()
-
- if ( !npc.HasKey( "script_noteworthy") )
- return
-
- string scriptNoteworthy = expect string( npc.kv.script_noteworthy )
-
- if ( scriptNoteworthy != "prowler_acheivement" )
- return
-
- FlagSet( "ProwlerAcheivementUnlocked" )
- UnlockAchievement( player, achievements.TIMESHIFT_PROWLER )
-
-}
-
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function DialogueTimeShiftEquipped( entity player )
-{
- FlagWait( "player_entered_creature_lab" )
-
- wait 1
-
- //BT Pilot Cooper, I have transferred some of my AI functions to the device, in order to permit communication across temporal shifts.
- thread PlayBTDialogue( "diag_sp_wildlifeStudy_TS191_12_01_mcor_bt" )
-
- FlagWait( "player_nearing_creature_fans" )
-
- array <entity> grunts
- entity gruntSpeaker
- int gruntLines = 6
- int gruntLinesPlayed = 0
- string gruntAlias
-
- while( true )
- {
- if ( gruntLinesPlayed >= gruntLines )
- break
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_NIGHT )
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
- gruntSpeaker = GetClosestGrunt( player, TIMEZONE_DAY )
- if ( !IsValid( gruntSpeaker ) )
- continue
- if ( Distance( player.GetOrigin(), gruntSpeaker.GetOrigin() ) > 512 )
- continue
-
- switch( gruntLinesPlayed )
- {
- case 0:
- //IMC Grunt 2 (Radio) What the hell? He was just over there!
- gruntAlias = "diag_sp_wildlifeStudy_TS191_17_01_imc_grunt2"
- break
- case 1:
- //security3 (radio comms, agitated): Who has visual?
- gruntAlias = "diag_sp_securityComs_TS104_01_01_imc_security3"
- break
- case 2:
- //security1 (radio comms, agitated): Can't track him, he's bouncing all over the place.
- gruntAlias = "diag_sp_securityComs_TS104_02_01_imc_security1"
- break
- case 3:
- //security1 (radio comms, agitated): Someone give me a location on this guy!
- gruntAlias = "diag_sp_securityComs_TS106_01_01_imc_security1"
- break
- case 4:
- //security3 (radio comms, agitated): Where the hell did he go?
- gruntAlias = "diag_sp_securityComs_TS106_03_01_imc_security3"
- break
- case 5:
- //security2 (radio comms, agitated): Watch your back! Watch your back!
- gruntAlias = "diag_sp_securityComs_TS106_02_01_imc_security2"
- break
- }
-
- waitthread PlayTimeShiftDialogue( player, gruntSpeaker, gruntAlias )
- gruntLinesPlayed++
-
- //Don't do next line till you hit elevator fight
- FlagWait( "crossed_elevator_fire_chasm" )
-
- }
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function DialogueCivilianEvacCreatureLabs( entity player )
-{
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- entity soundEnt = CreateBestLoudspeakerEnt( player, TIMEZONE_DAY )
-
- //IMC Security 3 - PA ...ask that all non-combat personnel and research teams proceed directly to the nearest
- //Emergency Shelter access point due to a minor security breach. Please remain calm and contact the nearest automated security personnel for assistance.
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_wildlifeStudy_TS191_13_01_imc_security3" )
-
- wait 1
-
- soundEnt.Destroy()
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function DialogueCreaturLabsIMC( entity player )
-{
- FlagWait( "player_past_creature_first_laser" )
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- entity soundEnt = CreateBestLoudspeakerEnt( player, TIMEZONE_DAY )
-
- SetGlobalForcedDialogueOnly( true )
-
- //IMC Grunt 1 (Radio) ….last spotted him headed towards Wildlife research. Get the rest of the eggheads evacuated and set up a choke point.
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_wildlifeStudy_TS191_14_01_imc_grunt1" )
-
- SetGlobalForcedDialogueOnly( false )
-
- FlagWait( "player_past_creature_second_obstacle" )
- //IMC Base (Radio) Additional laser meshes coming online. Let's box him in.
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_wildlifeStudy_TS191_15_01_imc_command" )
-
- FlagWait( "player_entered_creature_fans" )
-
- SetGlobalForcedDialogueOnly( true )
-
- //IMC Grunt 3 (Radio) Control, we have initiated contact with the intruder but his movement is...erratic.
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_wildlifeStudy_TS191_18_01_imc_grunt3" )
-
- SetGlobalForcedDialogueOnly( false )
-
- soundEnt.Destroy()
-}
-
-
-void function CourtyardSoldiersThink( entity npc )
-{
- if ( Flag( "player_entered_creature_lab") )
- return
- FlagEnd( "player_entered_creature_lab" )
- npc.EnableNPCFlag( NPC_IGNORE_ALL )
- npc.SetNoTarget( true )
-
- OnThreadEnd(
- function() : ( npc )
- {
- if ( IsValid( npc ) )
- npc.Destroy()
- }
- )
-
- WaitSignal( npc, "OnFinishedAssault" )
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██╗██████╗ ███████╗████████╗ ████████╗██╗███╗ ███╗███████╗███████╗██╗ ██╗██╗███████╗████████╗ ███████╗██╗ ██████╗ ██╗ ██╗████████╗
-██╔════╝██║██╔══██╗██╔════╝╚══██╔══╝ ╚══██╔══╝██║████╗ ████║██╔════╝██╔════╝██║ ██║██║██╔════╝╚══██╔══╝ ██╔════╝██║██╔════╝ ██║ ██║╚══██╔══╝
-█████╗ ██║██████╔╝███████╗ ██║ ██║ ██║██╔████╔██║█████╗ ███████╗███████║██║█████╗ ██║ █████╗ ██║██║ ███╗███████║ ██║
-██╔══╝ ██║██╔══██╗╚════██║ ██║ ██║ ██║██║╚██╔╝██║██╔══╝ ╚════██║██╔══██║██║██╔══╝ ██║ ██╔══╝ ██║██║ ██║██╔══██║ ██║
-██║ ██║██║ ██║███████║ ██║ ██║ ██║██║ ╚═╝ ██║███████╗███████║██║ ██║██║██║ ██║ ██║ ██║╚██████╔╝██║ ██║ ██║
-╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██╗██████╗ ███████╗████████╗ ████████╗██╗███╗ ███╗███████╗███████╗██╗ ██╗██╗███████╗████████╗ ███████╗██╗ ██████╗ ██╗ ██╗████████╗
-██╔════╝██║██╔══██╗██╔════╝╚══██╔══╝ ╚══██╔══╝██║████╗ ████║██╔════╝██╔════╝██║ ██║██║██╔════╝╚══██╔══╝ ██╔════╝██║██╔════╝ ██║ ██║╚══██╔══╝
-█████╗ ██║██████╔╝███████╗ ██║ ██║ ██║██╔████╔██║█████╗ ███████╗███████║██║█████╗ ██║ █████╗ ██║██║ ███╗███████║ ██║
-██╔══╝ ██║██╔══██╗╚════██║ ██║ ██║ ██║██║╚██╔╝██║██╔══╝ ╚════██║██╔══██║██║██╔══╝ ██║ ██╔══╝ ██║██║ ██║██╔══██║ ██║
-██║ ██║██║ ██║███████║ ██║ ██║ ██║██║ ╚═╝ ██║███████╗███████║██║ ██║██║██║ ██║ ██║ ██║╚██████╔╝██║ ██║ ██║
-╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██╗██████╗ ███████╗████████╗ ████████╗██╗███╗ ███╗███████╗███████╗██╗ ██╗██╗███████╗████████╗ ███████╗██╗ ██████╗ ██╗ ██╗████████╗
-██╔════╝██║██╔══██╗██╔════╝╚══██╔══╝ ╚══██╔══╝██║████╗ ████║██╔════╝██╔════╝██║ ██║██║██╔════╝╚══██╔══╝ ██╔════╝██║██╔════╝ ██║ ██║╚══██╔══╝
-█████╗ ██║██████╔╝███████╗ ██║ ██║ ██║██╔████╔██║█████╗ ███████╗███████║██║█████╗ ██║ █████╗ ██║██║ ███╗███████║ ██║
-██╔══╝ ██║██╔══██╗╚════██║ ██║ ██║ ██║██║╚██╔╝██║██╔══╝ ╚════██║██╔══██║██║██╔══╝ ██║ ██╔══╝ ██║██║ ██║██╔══██║ ██║
-██║ ██║██║ ██║███████║ ██║ ██║ ██║██║ ╚═╝ ██║███████╗███████║██║ ██║██║██║ ██║ ██║ ██║╚██████╔╝██║ ██║ ██║
-╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function FirstTimeshiftFightStartPointSetup( entity player )
-{
- TeleportPlayerToEnt( player, GetEntByScriptName( "checkpointFirstTimeshiftFight" ) )
- vector objectivePos = GetEntByScriptName( "objective_amenities_elevator_fight" ).GetOrigin()
- TimeshiftSetObjectiveSilent( player, "#TIMESHIFT_OBJECTIVE_LAB_EXPLORE", objectivePos )
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function FirstTimeshiftFightSkipped( entity player )
-{
- FlagClear( "ShowMobilityGhostTurretFirepit" )
- CleanupEnts( "flyer_lab" )
- CleanupEnts( "lab_prowlers" )
- thread LoudspeakerThread( player )
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function AA_FirstTimeshiftFightThread( entity player )
-{
- FlagWait( "player_exited_creature_labs" )
-
- vector objectivePos = GetEntByScriptName( "objective_spoke1_breadcrumb01" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
-
- thread LoudspeakerThread( player )
- FlagSet( "ShowMobilityGhostTurretFirepit" )
-
- CheckPoint()
-
- thread DialogueToElevatorFight( player )
- thread SecurityRoom( player )
- //-------------------------------
- // Hallway turret setup
- //-------------------------------
-
- array <entity> turrets = GetEntArrayByScriptName( "turrets_hallway_to_elevators" )
- foreach( turret in turrets )
- {
- //bool hasShield = true
- //thread HACK_DisableTurret( turret, hasShield )
- turret.SetDumbFireMode( true )
- }
-
- FlagWait( "open_door_elevator_fight_hallway_both" )
-
- CheckPoint()
-
- objectivePos = GetEntByScriptName( "objective_amenities_elevator_fight" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- //-------------------------------
- // Hallway turret flank
- //-------------------------------
-
- foreach( turret in turrets )
- {
- //bool hasShield = true
- //thread HACK_EnableTurret( turret )
- }
-
- FlagWait( "player_entered_turret_to_elevator_hallway" )
-
- FlagWait( "crossed_elevator_fire_chasm" )
-
- //FlagClear( "open_door_elevator_fight_hallway_both" )
- FlagClear( "ShowMobilityGhostTurretFirepit" )
- CleanupEnts( "flyer_lab" )
- CleanupEnts( "lab_prowlers" )
-
- FlagWait( "entered_amenities_elevator_room" )
-
-}
-
-
-void function CreatureSurprisedSoldiersThink( entity npc )
-{
- npc.EndSignal( "OnDeath" )
-
- FlagWait( "player_past_creature_second_obstacle" )
-
- npc.Anim_Stop()
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function SecurityRoom( entity player )
-{
- player.EndSignal( "OnDeath" )
-
- entity deadCivilian = CreatePropDynamic( IMC_CORPSE_MODEL_CIV, Vector( 3686, -3820, -764 ), Vector( 0, 29.0586, 0 ), 0 ) // 0 = no collision, 2 = bounding box, 6 = use vPhysics, 8 = hitboxes only
-
- deadCivilian.Hide()
- int shiftCount = 0
- int shiftRequirement = 88
- entity triggerOvergrown = GetEntByScriptName( "trigger_security_underground_overgrown" )
- entity triggerPristine = GetEntByScriptName( "trigger_security_underground_pristine" )
-
- while( true )
- {
- wait 0.1
- if ( shiftCount >= shiftRequirement )
- break
- FlagWait( "in_fire_pit" )
-
- if ( level.timeZone == TIMEZONE_DAY )
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_NIGHT )
- else
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
-
- if ( ( triggerOvergrown.IsTouching( player ) ) || ( triggerPristine.IsTouching( player ) ) )
- shiftCount++
- else
- continue
- }
-
- FlagSet( "open_door_security_underground" )
-
- deadCivilian.Show()
-
-
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██╗ ███████╗██╗ ██╗ █████╗ ████████╗ ██████╗ ██████╗ ███████╗██╗ ██████╗ ██╗ ██╗████████╗
-██╔════╝██║ ██╔════╝██║ ██║██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗ ██╔════╝██║██╔════╝ ██║ ██║╚══██╔══╝
-█████╗ ██║ █████╗ ██║ ██║███████║ ██║ ██║ ██║██████╔╝ █████╗ ██║██║ ███╗███████║ ██║
-██╔══╝ ██║ ██╔══╝ ╚██╗ ██╔╝██╔══██║ ██║ ██║ ██║██╔══██╗ ██╔══╝ ██║██║ ██║██╔══██║ ██║
-███████╗███████╗███████╗ ╚████╔╝ ██║ ██║ ██║ ╚██████╔╝██║ ██║ ██║ ██║╚██████╔╝██║ ██║ ██║
-╚══════╝╚══════╝╚══════╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██╗ ███████╗██╗ ██╗ █████╗ ████████╗ ██████╗ ██████╗ ███████╗██╗ ██████╗ ██╗ ██╗████████╗
-██╔════╝██║ ██╔════╝██║ ██║██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗ ██╔════╝██║██╔════╝ ██║ ██║╚══██╔══╝
-█████╗ ██║ █████╗ ██║ ██║███████║ ██║ ██║ ██║██████╔╝ █████╗ ██║██║ ███╗███████║ ██║
-██╔══╝ ██║ ██╔══╝ ╚██╗ ██╔╝██╔══██║ ██║ ██║ ██║██╔══██╗ ██╔══╝ ██║██║ ██║██╔══██║ ██║
-███████╗███████╗███████╗ ╚████╔╝ ██║ ██║ ██║ ╚██████╔╝██║ ██║ ██║ ██║╚██████╔╝██║ ██║ ██║
-╚══════╝╚══════╝╚══════╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██╗ ███████╗██╗ ██╗ █████╗ ████████╗ ██████╗ ██████╗ ███████╗██╗ ██████╗ ██╗ ██╗████████╗
-██╔════╝██║ ██╔════╝██║ ██║██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗ ██╔════╝██║██╔════╝ ██║ ██║╚══██╔══╝
-█████╗ ██║ █████╗ ██║ ██║███████║ ██║ ██║ ██║██████╔╝ █████╗ ██║██║ ███╗███████║ ██║
-██╔══╝ ██║ ██╔══╝ ╚██╗ ██╔╝██╔══██║ ██║ ██║ ██║██╔══██╗ ██╔══╝ ██║██║ ██║██╔══██║ ██║
-███████╗███████╗███████╗ ╚████╔╝ ██║ ██║ ██║ ╚██████╔╝██║ ██║ ██║ ██║╚██████╔╝██║ ██║ ██║
-╚══════╝╚══════╝╚══════╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██╗ ███████╗██╗ ██╗ █████╗ ████████╗ ██████╗ ██████╗ ███████╗██╗ ██████╗ ██╗ ██╗████████╗
-██╔════╝██║ ██╔════╝██║ ██║██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗ ██╔════╝██║██╔════╝ ██║ ██║╚══██╔══╝
-█████╗ ██║ █████╗ ██║ ██║███████║ ██║ ██║ ██║██████╔╝ █████╗ ██║██║ ███╗███████║ ██║
-██╔══╝ ██║ ██╔══╝ ╚██╗ ██╔╝██╔══██║ ██║ ██║ ██║██╔══██╗ ██╔══╝ ██║██║ ██║██╔══██║ ██║
-███████╗███████╗███████╗ ╚████╔╝ ██║ ██║ ██║ ╚██████╔╝██║ ██║ ██║ ██║╚██████╔╝██║ ██║ ██║
-╚══════╝╚══════╝╚══════╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-void function ElevatorFightStartPointSetup( entity player )
-{
- TeleportPlayerToEnt( player, GetEntByScriptName( "checkpointElevatorFight" ) )
- vector objectivePos = GetEntByScriptName( "objective_amenities_elevator_fight" ).GetOrigin()
- TimeshiftSetObjectiveSilent( player, "#TIMESHIFT_OBJECTIVE_LAB_EXPLORE", objectivePos )
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function ElevatorFightSkipped( entity player )
-{
- FlagClear( "ShowMobilityGhostElevatorShaft" )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function AA_ElevatorFightThread( entity player )
-{
-
- FlagWait( "entered_amenities_elevator_room" )
-
- thread DialogueElevatorRoom( player )
-
- FlagSet( "ShowMobilityGhostElevatorShaft" )
-
- thread MusicElevatorFight( player )
-
- //FlagClear( "open_door_elevator_fight_hallway_both" )
-
- CheckPoint()
-
- vector objectivePos = GetEntByScriptName( "objective_amenities_elevator" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
-
- thread SetFlagWhenPlayerLookingAtEnt( player, "PlayerLookingTowardsElevators", GetEntByScriptName( "elevator_look_target"), GetEntByScriptName( "trigger_look_elevators" ) )
-
- array< entity > propSpawners = GetEntArrayByScriptNameInInstance( "spectre_door_spawner", "spectre_spawner_amenities_elevator_overgrown_upper_02" )
- float delayMin = 0.5
- float delayMax = 0.6
- int maxToSpawn = 1
- string flagToAbort = ""
- thread SpawnShowcaseGroupWhenInRange( player, propSpawners, maxToSpawn, flagToAbort, "", delayMin, delayMax )
-
- FlagWait( "time_shifted_to_elevator_room_past" )
-
- //-------------------------------
- // Elevator fight
- //-------------------------------
- thread OpenElevatorDoorsOvergrownThink()
- thread TurretEnemiesComeIntoElevatorRoom()
- FlagWait( "PlayerLookingTowardsElevators" )
-
- thread AllElevatorDudesDead()
- FlagSet( "DisplayTheDamageHint" )
- thread ElevatorObjectiveReminder( player )
- //-------------------------------
- // Token prowlers elevator room
- //-------------------------------
- int difficulty = GetSpDifficulty()
- if ( difficulty < DIFFICULTY_MASTER )
- maxToSpawn = 5 //max for this room is 10
- else
- maxToSpawn = 8 //max for this room is 10
-
- propSpawners = GetEntArrayByScriptName( "prowler_spawnvents_elevator_room" )
- delayMin = 3.5
- delayMax = 6
- maxToSpawn = 5 //max for this room is 10
- flagToAbort = "AllElevatorDudesDead"
- string flagToSetWhenAllAreSpawned = "AllElevatorProwlersSpawned"
- bool requiresLookAt = true
- thread SpawnShowcaseGroupWhenInRange( player, propSpawners, maxToSpawn, flagToAbort, flagToSetWhenAllAreSpawned, delayMin, delayMax, "", requiresLookAt )
-
- //------------------------------------------
- // Player figures out elevator time puzzle
- //-------------------------------------------
- FlagWait( "entered_amenities_elevator" )
-
- objectivePos = GetEntByScriptName( "objective_elevator_top" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- FlagClear( "DisplayTheDamageHint" )
-
- FlagWait( "at_elevatorshaft_top" )
-
- FlagClear( "ShowMobilityGhostElevatorShaft" )
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function DialogueElevatorRoom( entity player )
-{
-
-
-/*
-██████╗ ██╗ █████╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗
-██╔══██╗██║██╔══██╗██║ ██╔═══██╗██╔════╝ ██║ ██║██╔════╝
-██║ ██║██║███████║██║ ██║ ██║██║ ███╗██║ ██║█████╗
-██║ ██║██║██╔══██║██║ ██║ ██║██║ ██║██║ ██║██╔══╝
-██████╔╝██║██║ ██║███████╗╚██████╔╝╚██████╔╝╚██████╔╝███████╗
-╚═════╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
-*/
-
- FlagWait( "entered_amenities_elevator" )
-
- entity soundEnt = CreateBestLoudspeakerEnt( player, TIMEZONE_DAY )
-
- if( Flag( "exited_elevator_run") )
- return
- FlagEnd( "exited_elevator_run" )
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
-
- if ( Flag( "AllElevatorDudesDead" ) )
- {
-
- //IMC Base (Radio) Security, Beta 4, do you copy? Beta 4! What is your position?
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_wildlifeStudy_TS191_16_01_imc_command" )
- }
- else
- {
- //IMC Base (Radio) Has the intruder been neutralized?
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_wildlifeStudy_TS191_22_01_imc_command" )
-
- //IMC Grunt 6 (Radio) Standby, we can't get a lock on his position
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_wildlifeStudy_TS191_23_01_imc_grunt6" )
- }
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function HallwayTurretDudesThink( entity npc )
-{
- npc.EndSignal( "OnDeath" )
-
- //Kill these guys if player has finished elevator fight
- FlagWait( "AllElevatorDudesDead" )
-
- array <entity> players = GetPlayerArray()
- if ( players.len() <= 0 )
- return
- entity player = players[ 0 ]
- thread DeleteNpcWhenOutOfSight( npc, player )
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function ElevatorObjectiveReminder( entity player )
-{
- if( Flag( "at_elevatorshaft_top") )
- return
- FlagEnd( "at_elevatorshaft_top" )
-
- FlagWait( "AllElevatorDudesDead" )
-
- wait 5
-
- while( true )
- {
- if ( level.timeZone == TIMEZONE_DAY )
- Objective_Remind()
- else if ( ( level.timeZone == TIMEZONE_NIGHT ) && ( !Flag( "enemies_inside_elevator_room_trigger_overgrown") ) )
- Objective_Remind()
-
- wait ( RandomFloatRange( 30, 40 ) )
- }
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function GruntElevatorThink( entity npc )
-{
- if ( !IsValid( npc ) )
- return
- npc.EndSignal( "OnDeath" )
-
- npc.EnableNPCFlag( NPC_NO_MOVING_PLATFORM_DEATH )
-
- OnThreadEnd(
- function() : ( )
- {
- file.elevatorDudesDead++
- if ( file.elevatorDudesDead >= 4 )
- FlagSet( "SeveralElevatorDudesDead" )
- }
- )
-
- if ( npc.HasKey( "script_noteworthy") )
- {
- string anim = expect string( npc.kv.script_noteworthy )
- string animIdle = anim + "_idle"
- entity node = GetClosest( file.elevatorAnimNodes, npc.GetOrigin() )
- Assert( IsValid( node ) )
- thread PlayAnimTeleport( npc, animIdle, node )
-
- entity elevatorDoor = GetClosest( file.elevatorDoors, npc.GetOrigin() )
- Assert( IsValid( elevatorDoor ) )
-
- string flagToWaitFor = expect string( elevatorDoor.kv.script_flag )
-
- if ( !Flag( flagToWaitFor ) )
- {
- FlagWait( flagToWaitFor )
- //wait 0.5
- }
-
- thread PlayAnimTeleport( npc, anim, node )
-
- }
-
- WaitForever()
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function TurretEnemiesComeIntoElevatorRoom()
-{
- /*
- entity goal_lobby_middle = GetEntByScriptName( "goal_lobby_middle" )
- array <entity> grunts = GetNPCArrayBySquad( "kfiejfff" )
- foreach( grunt in grunts )
- {
- if ( !IsAlive( grunt ) )
- continue
- grunt.AssaultPoint( goal_lobby_middle.GetOrigin() )
- }
- */
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function OpenElevatorDoorsOvergrownThink()
-{
- FlagWait( "AllElevatorDudesDead" )
- HideStuff( "doors_and_blockers_elevator_overgrown" )
- entity navmesh_blocker_elevator_overgrown = GetEntByScriptName( "navmesh_blocker_elevator_overgrown" )
- navmesh_blocker_elevator_overgrown.Hide()
- navmesh_blocker_elevator_overgrown.NotSolid()
- ToggleNPCPathsForEntity( navmesh_blocker_elevator_overgrown, true )
-
-
-//ToggleNPCPathsForEntity( GetEntByScriptName( "navmesh_blocker_elevator_overgrown" ), true )
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function MusicElevatorFight( entity player )
-{
- FlagWait( "entered_amenities_elevator_room" )
-
- wait 0.1
-
- StopMusic()
- PlayMusic( "music_timeshift_17_enterelevatorarea" )
-
- FlagWait( "elevator_open_d" )
-
- StopMusic()
- PlayMusic( "music_timeshift_18_startelevatorfight" )
- SetGlobalNetBool( "music14LoopPausable", true )
-
- if( Flag( "entered_amenities_elevator") )
- return
-
- FlagEnd( "entered_amenities_elevator" )
-
-
- //When you climb out of the roof of the elevator - Play music_timeshift_21b_climboutofelevator
- //also need to stop the old music_timeshift_14_pastloop - Just play music_timeshift_21c_pastloop_stop
- OnThreadEnd(
- function() : ( player )
- {
- StopMusic()
- PlayMusicThatCantBeStopped( "music_timeshift_21c_pastloop_stop" )
- if ( IsValid( player ) )
- StopSoundOnEntity( player, "music_timeshift_21_combatpresentdone" )
- PlayMusic( "music_timeshift_21b_climboutofelevator" )
- if ( IsValid( player ) )
- {
- StopSoundOnEntity( player, "music_timeshift_14_pastloop" )
- printl( "manually stopping music: music_timeshift_14_pastloop")
- }
- SetGlobalNetBool( "music14LoopPausable", false )
- }
- )
-
-
-
-
-
- //-----------------------------------------------------------------------------------------------
- // Don't start playing different time period-specific tracks till the player starts time traveling
- //-----------------------------------------------------------------------------------------------
- if ( level.timeZone == TIMEZONE_NIGHT )
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
- else
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_NIGHT )
-
-
- while( true )
- {
-
-
- if ( level.timeZone == TIMEZONE_NIGHT )
- {
- //----------------------
- // Enemies still alive TIMEZONE_NIGHT
- //----------------------
- if ( ( Flag( "enemies_inside_elevator_room_trigger_overgrown") ) || ( !Flag( "AllElevatorProwlersSpawned" ) ) )
- {
- //During the combat, if the player switches to PRESENT - Play music_timeshift_20_combatpresent
- //StopMusic()
- StopMusicTrack( "music_timeshift_18_startelevatorfight" )
- PlayMusicThatCantBeStopped( "music_timeshift_20_combatpresent" )
-
- //While in TIMEZONE_DAY, check to see when all are dead, so we can stop combat music
- while( level.timeZone == TIMEZONE_NIGHT )
- {
- wait 0.1
- if ( ( !Flag( "enemies_inside_elevator_room_trigger_overgrown" ) )
- && ( Flag( "AllElevatorProwlersSpawned" ) )
- )
- break
- }
- }
-
- //------------------------------------------------
- // If all enemies spawned and dead in TIMEZONE_NIGHT, play the "done" track
- //------------------------------------------------
- if ( ( !Flag( "enemies_inside_elevator_room_trigger_overgrown") ) && ( Flag( "AllElevatorProwlersSpawned" ) ) && ( level.timeZone == TIMEZONE_NIGHT ) )
- {
- //Each time the player switches to the PRESENT where there are no more enemies - Play music_timeshift_21_combatpresentdone
- //StopMusic()
- if ( IsValid( player ) )
- StopSoundOnEntity( player, "music_timeshift_21_combatpresentdone" )
- PlayMusicThatCantBeStopped( "music_timeshift_21_combatpresentdone" )
- }
-
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
- }
- else //TIMEZONE_DAY
- {
- //----------------------
- // Enemies still alive TIMEZONE_DAY
- //----------------------
- if ( ( !Flag( "AllElevatorDudesDead" ) ) && ( level.timeZone == TIMEZONE_DAY ) )
- {
- //During the combat, if the player switches to PAST - Play music_timeshift_19_combatpast
- PlayMusic( "music_timeshift_19_combatpast" )
-
- //While in TIMEZONE_DAY, check to see when all are dead, so we can stop combat music
- while( level.timeZone == TIMEZONE_DAY )
- {
- wait 0.1
- if ( Flag( "AllElevatorDudesDead" ) )
- break
- }
-
- }
-
- //------------------------------------------------
- //If all enemies dead in TIMEZONE_DAY, play the "done" track
- //------------------------------------------------
- if ( ( Flag( "AllElevatorDudesDead" ) ) && ( level.timeZone == TIMEZONE_DAY ) )
- {
- //Each time the player switches to the PAST where there are no more enemies - Play music_timeshift_21a_combatpastdone
- //StopMusic()
- PlayMusic( "music_timeshift_21a_combatpastdone" )
- }
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_NIGHT )
- }
- }
-
-
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void function DialogueToElevatorFight( entity player )
-{
- player.EndSignal( "OnDeath" )
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- entity soundEnt = CreateBestLoudspeakerEnt( player, TIMEZONE_DAY )
-
- FlagWait( "open_door_elevator_fight_hallway_both" )
-
- SetGlobalForcedDialogueOnly( true )
-
- //IMC Grunt 8 (Radio) In position. Activating turrets at south-east corridor.
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_wildlifeStudy_TS191_26_01_imc_grunt8" )
-
- //IMC Base (Radio) We have an intruder, heavily armed and dangerous. All units in the area proceed to the south-east elevator banks on level 4 to intercept.
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_wildlifeStudy_TS191_19_01_imc_command" )
-
-
- if ( !Flag( "entered_amenities_elevator_room" ) )
- {
- //IMC Grunt 4 (Radio) Copy that, control!
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_wildlifeStudy_TS191_20_01_imc_grunt4" )
-
- }
-
- if ( !Flag( "entered_amenities_elevator_room" ) )
- {
- //IMC Grunt 5 (Radio) On our way, control!
- thread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_wildlifeStudy_TS191_21_01_imc_grunt5" )
-
- }
-
- FlagWait( "SeveralElevatorDudesDead" )
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- soundEnt = CreateBestLoudspeakerEnt( player, TIMEZONE_DAY )
-
- if ( Flag( "entered_amenities_elevator" ) || Flag( "AllElevatorDudesDead" ) )
- {
- SetGlobalForcedDialogueOnly( false )
- return
- }
-
- //IMC Base (Radio) Sitrep on the unknown target.
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_wildlifeStudy_TS191_24_01_imc_command" )
-
-
- if ( Flag( "entered_amenities_elevator" ) || Flag( "AllElevatorDudesDead" ) )
- {
- SetGlobalForcedDialogueOnly( false )
- return
- }
-
- entity soldier = GetClosestGrunt( player, TIMEZONE_DAY, "grunts_elevator" )
-
- if ( IsValid( soldier ) )
- {
- //IMC Grunt 7 (Radio) We're getting our asses kicked out here, that's the bloody SitRep!
- waitthread PlayTimeShiftDialogue( player, soldier, "diag_sp_wildlifeStudy_TS191_25_01_imc_grunt7" )
- }
-
- SetGlobalForcedDialogueOnly( false )
-
- soundEnt.Destroy()
-
-}
-
-void function AllElevatorDudesDead()
-{
- FlagWaitAll( "ElevatorDudesDead1", "ElevatorDudesDead2", "ElevatorDudesDead3", "ElevatorDudesDead4" )
- FlagSet( "AllElevatorDudesDead" )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██╗ ███████╗██╗ ██╗ █████╗ ████████╗ ██████╗ ██████╗ ████████╗ ██████╗ ██████╗
-██╔════╝██║ ██╔════╝██║ ██║██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗ ╚══██╔══╝██╔═══██╗██╔══██╗
-█████╗ ██║ █████╗ ██║ ██║███████║ ██║ ██║ ██║██████╔╝ ██║ ██║ ██║██████╔╝
-██╔══╝ ██║ ██╔══╝ ╚██╗ ██╔╝██╔══██║ ██║ ██║ ██║██╔══██╗ ██║ ██║ ██║██╔═══╝
-███████╗███████╗███████╗ ╚████╔╝ ██║ ██║ ██║ ╚██████╔╝██║ ██║ ██║ ╚██████╔╝██║
-╚══════╝╚══════╝╚══════╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██╗ ███████╗██╗ ██╗ █████╗ ████████╗ ██████╗ ██████╗ ████████╗ ██████╗ ██████╗
-██╔════╝██║ ██╔════╝██║ ██║██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗ ╚══██╔══╝██╔═══██╗██╔══██╗
-█████╗ ██║ █████╗ ██║ ██║███████║ ██║ ██║ ██║██████╔╝ ██║ ██║ ██║██████╔╝
-██╔══╝ ██║ ██╔══╝ ╚██╗ ██╔╝██╔══██║ ██║ ██║ ██║██╔══██╗ ██║ ██║ ██║██╔═══╝
-███████╗███████╗███████╗ ╚████╔╝ ██║ ██║ ██║ ╚██████╔╝██║ ██║ ██║ ╚██████╔╝██║
-╚══════╝╚══════╝╚══════╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██╗ ███████╗██╗ ██╗ █████╗ ████████╗ ██████╗ ██████╗ ████████╗ ██████╗ ██████╗
-██╔════╝██║ ██╔════╝██║ ██║██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗ ╚══██╔══╝██╔═══██╗██╔══██╗
-█████╗ ██║ █████╗ ██║ ██║███████║ ██║ ██║ ██║██████╔╝ ██║ ██║ ██║██████╔╝
-██╔══╝ ██║ ██╔══╝ ╚██╗ ██╔╝██╔══██║ ██║ ██║ ██║██╔══██╗ ██║ ██║ ██║██╔═══╝
-███████╗███████╗███████╗ ╚████╔╝ ██║ ██║ ██║ ╚██████╔╝██║ ██║ ██║ ╚██████╔╝██║
-╚══════╝╚══════╝╚══════╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void function ElevatorTopStartPointSetup( entity player )
-{
- TeleportPlayerToEnt( player, GetEntByScriptName( "checkpointElevatorTop" ) )
- vector objectivePos = GetEntByScriptName( "objective_intel_data_panel01" ).GetOrigin()
- TimeshiftSetObjectiveSilent( player, "#TIMESHIFT_OBJECTIVE_LAB_EXPLORE", objectivePos )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function ElevatorTopSkipped( entity player )
-{
- FlagSet( "LabBravoEnemiesDead" )
- FlagSet( "entered_hallways_to_human_research" )
- FlagSet( "open_door_elevator_top_lab" )
- FlagSet( "StartAndersonHologram1" )
- FlagClear( "open_door_lab_civilian_escape_01" )
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function AA_ElevatorTopThread( entity player )
-{
- FlagWait( "at_elevatorshaft_top" )
- FlagClear( "open_door_elevator_top_lab" )
- //failsafeFlagToStart
- thread QuickSkit( player, GetEntByScriptName( "node_holo1_evac" ), "exited_elevator_run" )
-
- thread LabSoldierA( player )
-
- FlagWait( "exited_elevator_run" )
-
- SetGlobalForcedDialogueOnly( true )
-
- thread MusicElevatorTop( player )
- thread DialogueLabAlphaEvac( player )
- thread DialogueLabAlpha( player )
- thread ProwlerGagLabAlpha( player )
- thread AndersonHologramSequence( player, "node_hologram_lab1", "StartAndersonHologram1" )
- thread AchievementAndersonsFirstLog( player )
-
- vector objectivePos = GetEntByScriptName( "objective_intel_data_panel01" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- CheckPoint()
-
- FlagWait( "open_door_elevator_top_lab" )
-
- CheckPoint()
-
- CleanupEnts( "grunts_elevator" )
-
- thread CleanupAI( player )
-
- ShowStuff( "elevator_doors_upper_overgrown" )
-
- wait 2
-
- SetGlobalForcedDialogueOnly( false )
-
- FlagClear( "open_door_lab_civilian_escape_01" )
-
- FlagWait( "AndersonHologram1Finished" )
-
-
- FlagSet( "IntelRoom1Finished" )
-
- if ( !Flag( "back_in_hall_after_anderson_first_log" ) )
- CheckPoint()
-
- objectivePos = GetEntByScriptName( "objective_sphere_room_breadcrumb01" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- thread ObjectiveRemindUntilFlag( "entered_hallways_to_human_research" )
-
- FlagWait( "entered_hallways_to_human_research" )
-
-}
-
-void function AchievementAndersonsFirstLog( entity player )
-{
- FlagWait( "AndersonHologram1Playing" )
- UnlockAchievement( player, achievements.VIEW_LOG )
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void function LabSoldierA( entity player )
-{
- entity node = GetEntByScriptName( "node_sandtable_soldier_react" )
- Assert( IsValid( node ) )
- entity spawner = GetEntByScriptName( "labA_soldier" )
- Assert( IsValid( spawner ) )
- entity npc = spawner.SpawnEntity()
- DispatchSpawn( npc )
- Assert( IsValid( npc ) )
-
- npc.EndSignal( "OnDeath" )
-
- if( Flag( "open_door_elevator_top_lab") )
- return
- FlagEnd( "open_door_elevator_top_lab" )
-
- OnThreadEnd(
- function() : ( npc )
- {
- if ( IsValid( npc ) )
- npc.Destroy()
- }
- )
-
- npc.EnableNPCFlag( NPC_IGNORE_ALL )
- npc.SetNoTarget( true )
- thread PlayAnimTeleport( npc, "pt_cloak_react_app_far_point_timeshift_idle", node )
-
- FlagWait( "exited_elevator_run" )
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- waitthread PlayAnim( npc, "pt_cloak_react_app_far_point_timeshift", node )
- npc.AssaultPoint( Vector( 4804.74, -3668.88, 11744 ) )
-
- WaitSignal( npc, "OnFinishedAssault" )
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function MusicElevatorTop( entity player )
-{
- FlagWait( "exited_elevator_run" )
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- StopMusic()
- PlayMusicThatCantBeStopped( "music_timeshift_22_panicburst" )
-
- FlagWait( "StartAndersonHologram1" )
-
- StopMusic()
- PlayMusic( "music_timeshift_23_andersonlog02" )
-
- thread MusicHologram1Ambush()
-
- FlagWait( "AndersonHologram1Finished" )
-
-
- SetGlobalNetBool( "music14LoopPausable", false )
- PlayMusicThatCantBeStopped( "music_timeshift_14_pastloop" )
- //Following the ambush, when the player switches to the PRESENT - Play music_timeshift_16_explorepresent
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_NIGHT )
- thread PlayMusicInTimezoneUntilFlag( "music_timeshift_16_explorepresent", TIMEZONE_NIGHT, "StartAndersonHologram2" )
-
-
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function MusicHologram1Ambush()
-{
- //Ambush could happen in either past of present
- FlagWaitAny( "open_door_lab_reinforcements_pristine", "ProwlerAmbushTriggered" )
-
- //StopMusic()
- PlayMusicThatCantBeStopped( "music_timeshift_24_ambush" )
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function ProwlerGagLabAlpha( entity player )
-{
- entity door = GetEntByScriptName( "door_prowler_lab_a" )
- entity spawner = GetEntByScriptName( "prowler_lab_a" )
- vector origin = door.GetOrigin()
- vector angles = door.GetAngles()
-
- entity prowler = spawner.SpawnEntity()
- DispatchSpawn( prowler )
-
- prowler.EnableNPCFlag( NPC_NO_MOVING_PLATFORM_DEATH )
- prowler.Hide()
- prowler.NotSolid()
- MakeInvincible( prowler )
-
- thread PlayAnimTeleport( prowler, "pr_timeshift_door_tease_01_idle", origin, angles )
- thread PlayAnimTeleport( door, "door_door_spawn_core_idle", origin, angles )
-
- string animDoor
- string animProwler
-
- FlagWait( "near_lab_alpha_prowler_skit" )
-
- if ( !Flag( "IntelRoom1Finished" ) )
- {
- prowler.Show()
- prowler.Solid()
- thread PlayAnimTeleport( door, "door_timeshift_prowler_tease_01", origin, angles )
- waitthread PlayAnimTeleport( prowler, "pr_timeshift_door_tease_01", origin, angles )
- prowler.Hide()
- prowler.NotSolid()
- thread PlayAnimTeleport( prowler, "pr_timeshift_door_tease_01_idle", origin, angles )
- thread PlayAnimTeleport( door, "door_door_spawn_core_idle", origin, angles )
- FlagWait( "AndersonHologram1Finished" )
- FlagWait( "near_lab_alpha_prowler_skit" )
- }
-
- FlagSet( "ProwlerAmbushTriggered" )
- prowler.Show()
- prowler.Solid()
- ClearInvincible( prowler )
- thread PlayAnimTeleport( prowler, "pr_timeshift_door_spawn_01", origin, angles )
- thread PlayAnimTeleport( door, "door_timeshift_prowler_spawn_01", origin, angles )
- DisableNavmeshSeperatorTargetedByEnt( door )
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DialogueLabAlphaEvac( entity player )
-{
- if( Flag( "open_door_elevator_top_lab") )
- return
- FlagEnd( "open_door_elevator_top_lab" )
-
-
- //entity panel_intel_room1 = GetEntByScriptName( "panel_intel_room1" )
- entity loudspeakerEnt1 = CreateLoudspeakerEnt( Vector( 5488,-3718, 11736 ) )
- entity loudspeakerEnt2 = CreateLoudspeakerEnt( Vector( 5488,-3718, 11736 ) )
- entity loudspeakerEnt3 = CreateLoudspeakerEnt( Vector( 5488,-3718, 11736 ) )
-
-
- OnThreadEnd(
- function() : ( loudspeakerEnt1, loudspeakerEnt2, loudspeakerEnt3 )
- {
- loudspeakerEnt1.Destroy()
- loudspeakerEnt2.Destroy()
- loudspeakerEnt3.Destroy()
- }
- )
-
-
-/*
-██████╗ ██╗ █████╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗
-██╔══██╗██║██╔══██╗██║ ██╔═══██╗██╔════╝ ██║ ██║██╔════╝
-██║ ██║██║███████║██║ ██║ ██║██║ ███╗██║ ██║█████╗
-██║ ██║██║██╔══██║██║ ██║ ██║██║ ██║██║ ██║██╔══╝
-██████╔╝██║██║ ██║███████╗╚██████╔╝╚██████╔╝╚██████╔╝███████╗
-╚═════╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
-*/
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- //Scientist 1 What about the intruder?!
- //thread PlayTimeShiftDialogue( player, loudspeakerEnt1, "diag_sp_humanStudy_TS201_03_01_imc_scientist1" )
-
- wait 0.5
-
- //He's here!
- //thread PlayTimeShiftDialogue( player, loudspeakerEnt, "diag_sp_humanStudy_TS202_01_01_imc_scientist1" )
-
-
- //Grunt: Intruder spotted! Code 83!
- thread PlayTimeShiftDialogue( player, loudspeakerEnt2, "diag_sp_humanStudy_TS201_14_01_imc_security1" )
-
- wait 1.8
-
- //Scientist 2 We have to leave!
- thread PlayTimeShiftDialogue( player, loudspeakerEnt3, "diag_sp_humanStudy_TS201_04_01_imc_scientist2" )
-
- wait 1
-
-
- //General Marder We're going forward with this. The test must be completed.
- waitthread PlayTimeShiftDialogue( player, player, "diag_sp_humanStudy_TS201_01_01_imc_genMarder" )
-
-
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DialogueLabAlpha( entity player )
-{
- FlagWait( "open_door_elevator_top_lab" )
-
- wait 1
-
-
-
-/*
-██████╗ ██╗ █████╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗
-██╔══██╗██║██╔══██╗██║ ██╔═══██╗██╔════╝ ██║ ██║██╔════╝
-██║ ██║██║███████║██║ ██║ ██║██║ ███╗██║ ██║█████╗
-██║ ██║██║██╔══██║██║ ██║ ██║██║ ██║██║ ██║██╔══╝
-██████╔╝██║██║ ██║███████╗╚██████╔╝╚██████╔╝╚██████╔╝███████╗
-╚═════╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
-*/
-
- FlagSet( "StartAndersonHologram1" )
-
- //BT Pilot, a fragment of Anderson's damaged log may be relevant here. Activating log playback...
- waitthread PlayBTDialogue( "diag_sp_humanStudy_TS201_11_01_imc_bt" )
-
-
-
- FlagWaitAny( "AndersonHologram1Finished" )
-
- wait 0.5
-
-
- FlagWait( "entered_hallways_to_human_research" )
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
- if ( !Flag( "player_inside_intel_room2" ) )
- {
- entity soundEnt = CreateBestLoudspeakerEnt( player, TIMEZONE_DAY )
- //General Marder If we don't test the Sculptor Core now we may never have another chance. Zulu Team, prep the Sculptor Core for delivery.
- waitthread PlayTimeShiftDialogue( player, player, "diag_sp_humanStudy_TS201_02_01_imc_genMarder" )
- }
-
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function LabAlphaScientistThink( entity npc )
-{
- npc.EndSignal( "OnDeath" )
- thread DestroyNPCOnFlag( npc, "open_door_elevator_top_lab" )
-
- WaitSignal( npc, "OnFinishedAssault" )
-
- if ( IsValid( npc ) )
- npc.Destroy()
-
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██████╗ ██╗ ██╗███████╗██████╗ ███████╗ ██████╗ ██████╗ ██████╗ ███╗ ███╗
-██╔════╝██╔══██╗██║ ██║██╔════╝██╔══██╗██╔════╝ ██╔══██╗██╔═══██╗██╔═══██╗████╗ ████║
-███████╗██████╔╝███████║█████╗ ██████╔╝█████╗ ██████╔╝██║ ██║██║ ██║██╔████╔██║
-╚════██║██╔═══╝ ██╔══██║██╔══╝ ██╔══██╗██╔══╝ ██╔══██╗██║ ██║██║ ██║██║╚██╔╝██║
-███████║██║ ██║ ██║███████╗██║ ██║███████╗ ██║ ██║╚██████╔╝╚██████╔╝██║ ╚═╝ ██║
-╚══════╝╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██████╗ ██╗ ██╗███████╗██████╗ ███████╗ ██████╗ ██████╗ ██████╗ ███╗ ███╗
-██╔════╝██╔══██╗██║ ██║██╔════╝██╔══██╗██╔════╝ ██╔══██╗██╔═══██╗██╔═══██╗████╗ ████║
-███████╗██████╔╝███████║█████╗ ██████╔╝█████╗ ██████╔╝██║ ██║██║ ██║██╔████╔██║
-╚════██║██╔═══╝ ██╔══██║██╔══╝ ██╔══██╗██╔══╝ ██╔══██╗██║ ██║██║ ██║██║╚██╔╝██║
-███████║██║ ██║ ██║███████╗██║ ██║███████╗ ██║ ██║╚██████╔╝╚██████╔╝██║ ╚═╝ ██║
-╚══════╝╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██████╗ ██╗ ██╗███████╗██████╗ ███████╗ ██████╗ ██████╗ ██████╗ ███╗ ███╗
-██╔════╝██╔══██╗██║ ██║██╔════╝██╔══██╗██╔════╝ ██╔══██╗██╔═══██╗██╔═══██╗████╗ ████║
-███████╗██████╔╝███████║█████╗ ██████╔╝█████╗ ██████╔╝██║ ██║██║ ██║██╔████╔██║
-╚════██║██╔═══╝ ██╔══██║██╔══╝ ██╔══██╗██╔══╝ ██╔══██╗██║ ██║██║ ██║██║╚██╔╝██║
-███████║██║ ██║ ██║███████╗██║ ██║███████╗ ██║ ██║╚██████╔╝╚██████╔╝██║ ╚═╝ ██║
-╚══════╝╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void function SphereRoomStartPointSetup( entity player )
-{
- TeleportPlayerToEnt( player, GetEntByScriptName( "checkpointIntelRoom2" ) )
- vector objectivePos = GetEntByScriptName( "objective_intel_data_panel02" ).GetOrigin()
- TimeshiftSetObjectiveSilent( player, "#TIMESHIFT_OBJECTIVE_LAB_EXPLORE", objectivePos )
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function SphereRoomSkipped( entity player )
-{
- FlagSet( "RingsShouldBeSpinning" )
- FlagSet( "player_inside_intel_room2" )
- //thread HumanPodsThink( "biodoors_terminal01_pristine", "biodoors_terminal01_overgrown", player )
- //thread HumanPodsThinkNoHack( "biodoors_terminal01_pristine", "biodoors_terminal02_overgrown", player )
- //thread HumanPodsThinkNoHack( "biodoors_terminal02_pristine", "biodoors_terminal02_overgrown", player )
-
- FlagClear( "ShowMobilityGhostTurretFlank" )
- thread QuickSkit( player, GetEntByScriptName( "node_reactor_flyers" ) )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function AA_SphereRoomThread( entity player )
-{
- FlagWait( "entered_hallways_to_human_research" )
-
- FlagSet( "ShowMobilityGhostTurretFlank" )
-
- thread MusicSphereRoom( player )
- thread DialogueLabBravo( player )
- thread DialogueHumanAnteroom( player )
- thread DialogueGunshipDeploys( player )
- thread GunshipPadSequenceWait( player )
- thread GunshipSequence( "gunship_pad", player, "node_gunship_intel_room_2", "pad", "StartSphereRoomGunship" )
- thread AndersonHologramSequence( player, "node_hologram_lab2", "StartAndersonHologram2" )
-
- CheckPoint()
-
- FlagWait( "dropped_into_fire_hallways" )
- vector objectivePos = GetEntByScriptName( "objective_intel_data_panel02" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- FlagWait( "player_inside_intel_room2" )
-
- thread TurretNotargetHack( player )
- FlagWait( "AndersonHologram2Finished" )
- CheckPoint()
- FlagSet( "open_door_diorama2_exit_pristine" )
- FlagSet( "open_door_diorama2_exit_overgrown" )
-
- thread CheckpointSphereRoomOvergrown( player )
- thread CheckpointSphereRoomPristine( player )
-
- objectivePos = GetEntByScriptName( "objective_human_research_breadcrumb_01a" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- thread ObjectiveRemindUntilFlag( "exited_intel_room2" )
-
- FlagWait( "exited_intel_room2" )
-
- objectivePos = GetEntByScriptName( "objective_human_research_breadcrumb_02" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- FlagWait( "entering_human_hallway_room" )
-
- //thread HumanPodsThink( "biodoors_terminal01_pristine", "biodoors_terminal01_overgrown", player )
- //thread HumanPodsThinkNoHack( "biodoors_terminal01_pristine", "biodoors_terminal02_overgrown", player )
- //thread HumanPodsThinkNoHack( "biodoors_terminal02_pristine", "biodoors_terminal02_overgrown", player )
-
- //-------------------------------
- // Token stalkers
- //-------------------------------
- array< entity > propSpawners = GetEntArrayByScriptName( "stalker_spawnvents_human_hallway_room" )
- float delayMin = 1.3
- float delayMax = 3
- int maxToSpawn = 3
- string flagToAbort = "entering_human_main_room"
- string flagToSetWhenAllAreSpawned = ""
- bool requiresLookAt = false
- thread SpawnShowcaseGroupWhenInRange( player, propSpawners, maxToSpawn, flagToAbort, flagToSetWhenAllAreSpawned, delayMin, delayMax, "", requiresLookAt )
-
- FlagWait( "past_human_hall_turrets" )
- thread QuickSkit( player, GetEntByScriptName( "node_reactor_flyers" ) )
- CheckPoint()
-
- FlagClear( "ShowMobilityGhostTurretFlank" )
-
-
- FlagWait( "entering_human_anteroom" )
-
- //entity rings_pristine = GetEntByScriptName( "rings_pristine" )
-
- //Spawn a sound dummy model to attach the sound to since doing it on an info_target
- //or "AtPosition" is unreliable with Timeshift teleports (can get culled)
- entity lookEnt = GetEntByScriptName( "lookent_rings" )
- EmitSoundAtPosition( TEAM_UNASSIGNED, lookEnt.GetOrigin(), "timeshift_scr_rings_spin_slow_lp" )
-
- FlagSet( "RingsShouldBeSpinning" )
-
- CheckPoint()
-
-
- objectivePos = GetEntByScriptName( "objective_human_research_main_door" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- FlagWait( "entering_human_main_room" )
-
-}
-
-
-
-
-
-
-void function GruntsSphereRoomThink( entity npc )
-{
- //TODO: make these guys constanly get the player as an enemy
- if ( !IsValid( npc ) )
- return
-
- npc.EndSignal( "OnDeath" )
-
- while( true )
- {
- AttackPlayer( npc )
- wait RandomFloatRange( 2, 5 )
- }
-
-
-
-}
-void function CheckpointSphereRoomOvergrown( entity player )
-{
- FlagEnd( "entering_human_anteroom" )
- FlagWait( "sphere_room_stalkers_dead" )
- CheckPoint()
-}
-
-void function CheckpointSphereRoomPristine( entity player )
-{
- FlagEnd( "entering_human_anteroom" )
- FlagWait( "sphere_room_pristine_enemies_dead" )
- CheckPoint()
-}
-
-void function DialogueHumanAnteroom( entity player )
-{
- FlagWait( "entering_human_anteroom" )
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- entity soundEnt = CreateBestLoudspeakerEnt( player, TIMEZONE_DAY )
-
- //General Marder - Radio Spin up the outer rings. Test sequence will commence once Sculptor Core is in place.
- thread PlayTimeShiftDialogue( player, player, "diag_sp_miniSculptor_TS221_02_01_imc_genMarder" )
-
-
-}
-
-void function TurretNotargetHack( entity player )
-{
- if( Flag( "entering_human_main_room") )
- return
- FlagEnd( "entering_human_main_room" )
- OnThreadEnd(
- function() : ( player )
- {
- if ( IsValid( player ) )
- player.SetNoTarget( false )
- }
- )
- while( true )
- {
- FlagWait( "player_no_target" )
- player.SetNoTarget( true )
- FlagWaitClear( "player_no_target" )
- player.SetNoTarget( false )
- }
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function MusicSphereRoom( entity player )
-{
- FlagWait( "StartAndersonHologram2" )
-
- //FlagWait( "AndersonHologram2Playing" )
-
- // When the third Anderson log starts - Play music_timeshift_25_andersonlog03
- // At the same time - Play music_timeshift_21c_pastloop_stop
- StopMusic()
- PlayMusic( "music_timeshift_25_andersonlog03" )
-
- if ( IsValid( player ) )
- {
- StopSoundOnEntity( player, "music_timeshift_14_pastloop" )
- printl( "manually stopping music: music_timeshift_14_pastloop")
- }
-
- PlayMusicThatCantBeStopped( "music_timeshift_21c_pastloop_stop" )
-
- //When the door drops down revealing the dudes
- FlagWaitAny( "open_door_diorama2_exit_pristine", "open_door_diorama2_exit_overgrown" )
-
- StopMusic()
- PlayMusicThatCantBeStopped( "music_timeshift_24_ambush" )
- SetGlobalNetBool( "music14LoopPausable", false )
- PlayMusicThatCantBeStopped( "music_timeshift_14_pastloop" )
-
- // Following the ambush, when the player switches to the PRESENT - Play music_timeshift_16_explorepresent
- FlagWait( "AndersonHologram2Finished" )
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_NIGHT )
-
- thread PlayMusicInTimezoneUntilFlag( "music_timeshift_16_explorepresent", TIMEZONE_NIGHT, "entering_human_anteroom" )
-
-
- FlagWait( "entering_human_anteroom" )
-
- // When you enter human testing - Play music_timeshift_26_humanresearch
- // At the same time - Play music_timeshift_21c_pastloop_stop
-
- wait 0.1
-
- StopMusic()
- if ( IsValid( player ) )
- {
- StopSoundOnEntity( player, "music_timeshift_14_pastloop" )
- printl( "manually stopping music: music_timeshift_14_pastloop")
- }
-
- PlayMusicThatCantBeStopped( "music_timeshift_21c_pastloop_stop" )
-
- PlayMusic( "music_timeshift_26_humanresearch" )
-
-
-
-}
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DialogueLabBravo( entity player )
-{
- FlagWaitAny( "LabBravoEnemiesDead", "player_near_intel_room_2_landing_pad" )
-
- FlagWait( "player_inside_intel_room2" )
-
- FlagWait( "player_inside_intel_room2_halfway" )
-
- FlagClear( "open_doors_sphere_room_entrance_all" )
-
-
-/*
-██████╗ ██╗ █████╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗
-██╔══██╗██║██╔══██╗██║ ██╔═══██╗██╔════╝ ██║ ██║██╔════╝
-██║ ██║██║███████║██║ ██║ ██║██║ ███╗██║ ██║█████╗
-██║ ██║██║██╔══██║██║ ██║ ██║██║ ██║██║ ██║██╔══╝
-██████╔╝██║██║ ██║███████╗╚██████╔╝╚██████╔╝╚██████╔╝███████╗
-╚═════╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
-*/
-
- FlagSet( "StartAndersonHologram2" )
- FlagSetDelayed( "AndersomHologram2AboutToStart", 3)
-
-
- FlagWait( "AndersonHologram2Finished" )
-
- wait 0.5
-
-
-
-}
-
-
-void function DialogueGunshipDeploys( entity player )
-{
-
- /*
- FlagWaitAny( "LabBravoEnemiesDead", "player_inside_intel_room2_halfway" )
-
-
- //FlagWait( "LookingAtPad" )
-
- entity soundEnt = CreateLoudspeakerEnt( GetEntByScriptName( "lookent_pad" ).GetOrigin() )
-
- FlagWait( "AndersonHologram2Finished" )
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- //waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- if ( !Flag( "AndersomHologram2AboutToStart" ) )
- {
- //Scientist 5 (Radio) Sculptor Core prepped for delivery and en route to the test chamber.
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_miniSculptor_TS221_01_01_imc_scientist5" )
- }
-
- */
-
- FlagWait( "StartSphereRoomGunship")
-
- wait 1
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
- entity soundEnt = CreateLoudspeakerEnt( GetEntByScriptName( "lookent_pad" ).GetOrigin() )
-
- //Scientist 5 (Radio) Sculptor Core prepped for delivery and en route to the test chamber.
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_miniSculptor_TS221_01_01_imc_scientist5" )
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function GunshipPadSequenceWait( entity player )
-{
- FlagEnd( "exited_intel_room2" )
-
- FlagWait( "AndersonHologram2Finished" )
-
- entity lookEnt = GetEntByScriptName( "lookent_pad" )
- //doTrace degrees minDist timeOut trigger, failsafeFlag )
- waitthread WaitTillLookingAt( player, lookEnt, false, 30, 0, 0, null, "player_near_intel_room_2_landing_pad" )
-
- FlagSet( "StartSphereRoomGunship" )
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-██╗ ██╗██╗ ██╗███╗ ███╗ █████╗ ███╗ ██╗ ██████╗ ███████╗███████╗███████╗ █████╗ ██████╗ ██████╗██╗ ██╗
-██║ ██║██║ ██║████╗ ████║██╔══██╗████╗ ██║ ██╔══██╗██╔════╝██╔════╝██╔════╝██╔══██╗██╔══██╗██╔════╝██║ ██║
-███████║██║ ██║██╔████╔██║███████║██╔██╗ ██║ ██████╔╝█████╗ ███████╗█████╗ ███████║██████╔╝██║ ███████║
-██╔══██║██║ ██║██║╚██╔╝██║██╔══██║██║╚██╗██║ ██╔══██╗██╔══╝ ╚════██║██╔══╝ ██╔══██║██╔══██╗██║ ██╔══██║
-██║ ██║╚██████╔╝██║ ╚═╝ ██║██║ ██║██║ ╚████║ ██║ ██║███████╗███████║███████╗██║ ██║██║ ██║╚██████╗██║ ██║
-╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-██╗ ██╗██╗ ██╗███╗ ███╗ █████╗ ███╗ ██╗ ██████╗ ███████╗███████╗███████╗ █████╗ ██████╗ ██████╗██╗ ██╗
-██║ ██║██║ ██║████╗ ████║██╔══██╗████╗ ██║ ██╔══██╗██╔════╝██╔════╝██╔════╝██╔══██╗██╔══██╗██╔════╝██║ ██║
-███████║██║ ██║██╔████╔██║███████║██╔██╗ ██║ ██████╔╝█████╗ ███████╗█████╗ ███████║██████╔╝██║ ███████║
-██╔══██║██║ ██║██║╚██╔╝██║██╔══██║██║╚██╗██║ ██╔══██╗██╔══╝ ╚════██║██╔══╝ ██╔══██║██╔══██╗██║ ██╔══██║
-██║ ██║╚██████╔╝██║ ╚═╝ ██║██║ ██║██║ ╚████║ ██║ ██║███████╗███████║███████╗██║ ██║██║ ██║╚██████╗██║ ██║
-╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////
-/*
-██╗ ██╗██╗ ██╗███╗ ███╗ █████╗ ███╗ ██╗ ██████╗ ███████╗███████╗███████╗ █████╗ ██████╗ ██████╗██╗ ██╗
-██║ ██║██║ ██║████╗ ████║██╔══██╗████╗ ██║ ██╔══██╗██╔════╝██╔════╝██╔════╝██╔══██╗██╔══██╗██╔════╝██║ ██║
-███████║██║ ██║██╔████╔██║███████║██╔██╗ ██║ ██████╔╝█████╗ ███████╗█████╗ ███████║██████╔╝██║ ███████║
-██╔══██║██║ ██║██║╚██╔╝██║██╔══██║██║╚██╗██║ ██╔══██╗██╔══╝ ╚════██║██╔══╝ ██╔══██║██╔══██╗██║ ██╔══██║
-██║ ██║╚██████╔╝██║ ╚═╝ ██║██║ ██║██║ ╚████║ ██║ ██║███████╗███████║███████╗██║ ██║██║ ██║╚██████╗██║ ██║
-╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////
-/*
-██╗ ██╗██╗ ██╗███╗ ███╗ █████╗ ███╗ ██╗ ██████╗ ███████╗███████╗███████╗ █████╗ ██████╗ ██████╗██╗ ██╗
-██║ ██║██║ ██║████╗ ████║██╔══██╗████╗ ██║ ██╔══██╗██╔════╝██╔════╝██╔════╝██╔══██╗██╔══██╗██╔════╝██║ ██║
-███████║██║ ██║██╔████╔██║███████║██╔██╗ ██║ ██████╔╝█████╗ ███████╗█████╗ ███████║██████╔╝██║ ███████║
-██╔══██║██║ ██║██║╚██╔╝██║██╔══██║██║╚██╗██║ ██╔══██╗██╔══╝ ╚════██║██╔══╝ ██╔══██║██╔══██╗██║ ██╔══██║
-██║ ██║╚██████╔╝██║ ╚═╝ ██║██║ ██║██║ ╚████║ ██║ ██║███████╗███████║███████╗██║ ██║██║ ██║╚██████╗██║ ██║
-╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-void function HumanResearchStartPointSetup( entity player )
-{
- TeleportPlayerToEnt( player, GetEntByScriptName( "checkpointHumanResearch" ) )
- vector objectivePos = GetEntByScriptName( "objective_human_research_vista" ).GetOrigin()
- TimeshiftSetObjectiveSilent( player, "#TIMESHIFT_OBJECTIVE_LAB_EXPLORE", objectivePos )
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function HumanResearchSkipped( entity player )
-{
- FlagClear( "ShowMobilityGhostHumanLillypad01" )
- FlagClear( "ShowMobilityGhostHumanLillypad02" )
- thread ElectricalScreenEffects( player, "inside_human_control_room" )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function AA_HumanResearchThread( entity player )
-{
-
- FlagWait( "entering_human_main_room" )
- FlagSet( "ShowMobilityGhostHumanLillypad01" )
- FlagSet( "ShowMobilityGhostHumanLillypad02" )
-
- //thread DebugX( player )
-
- thread FlyersHumanRoom()
- thread MusicHumanRoom( player )
- thread DialogueHumanRoomStart( player )
- vector objectivePos = GetEntByScriptName( "objective_human_research_tower1" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- //thread HumanPanelHacks( player )
- CheckPoint()
-
- delaythread ( 60 ) TimeshiftHint( player, TIMEZONE_DAY, "reached_concourse_tower1", "timeshift_hint_default", GetEntByScriptName( "trig_player_near_first_liilypad_puzzle_pristine" ) )
-
-
- FlagWait( "reached_concourse_tower1" )
-
- objectivePos = GetEntByScriptName( "objective_human_research_fight" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- thread ElectricalScreenEffects( player, "inside_human_control_room" )
-
- FlagClear( "ShowMobilityGhostHumanLillypad01" )
-
-
- CheckPoint()
-
- FlagWait( "inside_human_control_room" )
-
- objectivePos = GetEntByScriptName( "objective_human_research_tower2" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- FlagSet( "DisplayTheDamageHint" )
- thread HumanRoomCheckpointSoldiers()
- thread HumanRoomCheckpointProwlers()
-
- CheckPoint()
-
- //-------------------------------
- // Token prowlers
- //-------------------------------
- array< entity > propSpawners = GetEntArrayByScriptName( "prowler_spawnvents_human_control_room" )
- float delayMin = 2.5
- float delayMax = 5
- int maxToSpawn = 1
- string flagToAbort = "reached_concourse_tower2"
- string flagToSetWhenAllAreSpawned = "AllProwlersSpawnedInHumanControlRoom"
- bool requiresLookAt = true
- thread SpawnShowcaseGroupWhenInRange( player, propSpawners, maxToSpawn, flagToAbort, flagToSetWhenAllAreSpawned, delayMin, delayMax, "", requiresLookAt )
-
- FlagWait( "reached_concourse_tower2" )
-
- FlagClear( "DisplayTheDamageHint" )
- FlagClear( "ShowMobilityGhostHumanLillypad02" )
-}
-
-void function FlyersHumanRoom()
-{
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_NIGHT )
- FlagSet( "ForceFlyerTakeoff")
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function HumanRoomCheckpointSoldiers()
-{
- FlagWait( "inside_human_control_room" )
- if ( Flag( "reached_concourse_tower2") )
- return
- FlagEnd( "reached_concourse_tower2" )
- FlagWait( "human_room_soldiers_dead" )
- CheckPoint()
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function HumanRoomCheckpointProwlers()
-{
- FlagWait( "inside_human_control_room" )
- if ( Flag( "reached_concourse_tower2") )
- return
- FlagEnd( "reached_concourse_tower2" )
-
- FlagWait( "AllProwlersSpawnedInHumanControlRoom" )
- FlagWaitClear( "prowlers_alive_in_human_control_room")
-
- CheckPoint()
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function MusicHumanRoom( entity player )
-{
-
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void function GunshipRingSequenceWait( entity player )
-{
- FlagWait( "crossed_wallrun_chain" )
-
- wait 0.25
-
- entity lookEnt = GetEntByScriptName( "lookent_rings" )
- //doTrace degrees minDist timeOut trigger, failsafeFlag )
- waitthread WaitTillLookingAt( player, lookEnt, false, 30, 0, 0, null, "player_crossing_human_bridge" )
-
- FlagSet( "player_looking_at_reactor_window" )
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function DialogueHumanRoomStart( entity player )
-{
-
-/*
-██████╗ ██╗ █████╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗
-██╔══██╗██║██╔══██╗██║ ██╔═══██╗██╔════╝ ██║ ██║██╔════╝
-██║ ██║██║███████║██║ ██║ ██║██║ ███╗██║ ██║█████╗
-██║ ██║██║██╔══██║██║ ██║ ██║██║ ██║██║ ██║██╔══╝
-██████╔╝██║██║ ██║███████╗╚██████╔╝╚██████╔╝╚██████╔╝███████╗
-╚═════╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
-*/
-
-
- FlagWait( "entering_human_main_room" )
-
- //wait 1
- //Player Option A Were they doing experiments on these people?
- //BT Option A SRS files indicated large-scale cryogenic stasis for testing on humans for unknown reasons. They are likely not volunteers.
-
- //Player Option B Who are these people?
- //BT Option B Scanning... The genetic makeup matches those captured from the distant planet Colony led by former Militia leader MacAllan.
- //waitthread PlayerConversation( "TsHumanExperiments", player )
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-void function HumanPanelHacks( entity player )
-{
- //--------------------------------------------
- // Override all security terminals (optional)
- //----------------------------------------------
- array< entity > controlPanels
- controlPanels.append( GetEntByScriptName( "security_panel_concourse_01" ) )
- //controlPanels.append( GetEntByScriptName( "security_panel_concourse_02" ) )
- foreach( panel in controlPanels )
- thread SecurityPanelConcourseThink( panel, player )
-
-
-}
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-void function SecurityPanelConcourseThink( entity panel, entity player )
-{
- panel.WaitSignal( "PanelReprogram_Success" )
-
- string flagToSetWhenHacked
-
- string scriptName = panel.GetScriptName()
- string laserMeshInstanceName
- if ( scriptName == "security_panel_concourse_01" )
- {
- laserMeshInstanceName = "laser_mesh_concourse_terminal_01"
- flagToSetWhenHacked = "ConcoursePanelHacked01"
- }
- else if ( scriptName == "security_panel_concourse_02" )
- {
- laserMeshInstanceName = "laser_mesh_concourse_terminal_02"
- flagToSetWhenHacked = "ConcoursePanelHacked02"
- }
- else
- Assert( 0, "Can't find lasermesh trigger associated with " + scriptName )
-
- FlagSet( flagToSetWhenHacked )
-
- if ( !Flag( "LabRatAcheivementUnlocked" ) )
- {
- FlagSet( "LabRatAcheivementUnlocked" )
- Dev_PrintMessage( player, "#TIMESHIFT_ACHEIVEMENT_HEADING", "#TIMESHIFT_ACHEIVEMENT_TEXT_LAB_RATS", 5 )
- }
-
- wait 1.5
-
- CheckPoint()
-
- LaserMeshDestroyByInstanceName( laserMeshInstanceName )
- Remote_CallFunction_NonReplay( player, "ServerCallback_LabRatLasers" )
-
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-void function HumanPodsThink( string instanceNamePristine, string instanceNameOvergrown, entity player )
-{
- array< entity > doorsPristine = GetEntArrayByScriptNameInInstance( "bio_pod_door", instanceNamePristine )
- array< entity > doorsOvergrown = GetEntArrayByScriptNameInInstance( "bio_pod_door", instanceNameOvergrown )
- Assert( doorsPristine.len() == 4 )
- Assert( doorsOvergrown.len() == 4 )
-
- string flagToReleasePrisoners = "security_concourse_01_hacked"
- //Militia Prisoner 1 What? What where am I?
- string prisonerDialogue = "diag_sp_humanStudy_TS202_03_01_mcor_prisoner1"
- if ( instanceNamePristine == "biodoors_terminal02_pristine" )
- {
- //Militia Prisoner 2 What's going on? This isn't Colony....
- string prisonerDialogue = "diag_sp_humanStudy_TS202_04_01_mcor_prisoner2"
- flagToReleasePrisoners = "security_concourse_02_hacked"
-
- }
-
- entity dialogueEnt
-
- foreach( door in doorsPristine )
- {
- if ( !IsValid( dialogueEnt ) )
- dialogueEnt = CreateLoudspeakerEnt( door.GetOrigin() )
- thread HumanPodThinkPristine( door )
- }
- foreach( door in doorsOvergrown )
- thread HumanPodThinkOvergrown( door )
-
- FlagWait( flagToReleasePrisoners )
-
- foreach( door in doorsOvergrown )
- door.Signal( "ReleaseLabRat")
- foreach( door in doorsPristine )
- door.Signal( "ReleaseLabRat")
-
- wait 5
-
- thread PlayTimeShiftDialogue( player, dialogueEnt, prisonerDialogue )
-}
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-void function HumanPodsThinkNoHack( string instanceNamePristine, string instanceNameOvergrown, entity player )
-{
- array< entity > spawners = GetEntArrayByScriptNameInInstance( "bio_pod_body", instanceNamePristine )
- foreach( spawner in spawners )
- thread HumanPodThinkPristine( null, spawner )
-}
-&*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-void function HumanPodThinkPristine( entity door = null, entity bodySpawner = null )
-{
- entity spawner
- if ( !bodySpawner )
- spawner = door.GetLinkEnt()
- else
- spawner = bodySpawner
- string animIdle
- string animWakeUp
- string animIdleEnd
- entity labRat = spawner.SpawnEntity()
- DispatchSpawn( labRat )
- Assert( IsValid( labRat) )
- entity node = CreateScriptRef( labRat.GetOrigin(), labRat.GetAngles() )
- vector originOffset = PositionOffsetFromEnt( node, -15, 0, 0 )
- node.SetOrigin( originOffset )
-
- MakeInvincible( labRat )
- MakeCivilian( labRat )
- labRat.SetNoTarget( true )
- SetTeam( labRat, TEAM_MILITIA )
- labRat.SetModel( LABRAT_MODEL )
- Assert( labRat.HasKey( "script_noteworthy") )
- animIdle = labRat.kv.script_noteworthy + "_start_idle"
- animWakeUp = labRat.kv.script_noteworthy + "_start"
- animIdleEnd = labRat.kv.script_noteworthy + "_end_idle"
-
- thread PlayAnimTeleport( labRat, animIdle, node )
-
- if ( !door )
- return
-
- door.WaitSignal( "ReleaseLabRat" )
-
- waitthread OpenLabRatDoor( door, labRat )
-
- labRat.EndSignal( "OnDeath" )
- wait 0.25
-
- ClearInvincible( labRat )
- labRat.e.forceRagdollDeath = true
-
- waitthread PlayAnim( labRat, animWakeUp, node )
- thread PlayAnim( labRat, animIdleEnd, node )
-}
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-void function HumanPodThinkOvergrown( entity door )
-{
- entity body = door.GetLinkEnt()
-
- door.WaitSignal( "ReleaseLabRat" )
-
- body.Destroy()
- OpenLabRatDoor( door, body )
-}
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-void function OpenLabRatDoor( entity door, entity body )
-{
- entity soundDummy = CreateInfoTarget( body.GetOrigin() + Vector( 0, 0, 72 ), Vector( 0, 0, 0 ) )
- vector soundOrigin = soundDummy.GetOrigin()
- entity lookEnt = CreateInfoTarget( body.GetOrigin() + Vector( 0, 0, 72 ), Vector( 0, 0, 0 ) )
- vector originOffset = PositionOffsetFromEnt( lookEnt, 15, 0, 0 )
- lookEnt.SetOrigin( originOffset )
-
- vector fxOrigin = body.GetOrigin()
- vector fxAngles = body.GetAngles()
-
- bool snapToOpen = false
- if ( GetEntityTimelinePosition( door ) == TIMEZONE_NIGHT )
- snapToOpen = true
-
- vector startPos = door.GetOrigin()
- vector endPos = startPos + Vector( 0, 0, -105 )
-
- if ( snapToOpen == true )
- {
- door.SetOrigin( endPos )
- return
- }
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- array <entity> players = GetPlayerArray()
- if ( players.len() <= 0 )
- return
- entity player = players[ 0 ]
- player.EndSignal( "OnDeath" )
-
- //WaitTillLookingAt( entity player, entity ent, bool doTrace, float degrees, float minDist = 0, float timeOut = 0, entity trigger = null, string failsafeFlag = "" )
- waitthread WaitTillLookingAt( player, lookEnt, true, 45, 0, 3 )
-
- wait( RandomFloatRange( 0, 0.75 ) )
- entity mover = CreateScriptMover( door.GetOrigin(), door.GetAngles() )
- door.SetParent( mover )
- float moveTime = 5
-
- mover.NonPhysicsMoveTo( endPos, moveTime, moveTime*0.4, moveTime*0.4 )
-
-
- EmitSoundAtPosition( TEAM_UNASSIGNED, soundOrigin, "Timeshift_Scr_LabRatPodDoor_Open" )
- //EmitSoundOnEntity( soundDummy, "door_open_loop" )
- PlayFX( FX_HUMAN_DOOR_OPEN, fxOrigin, fxAngles )
-
- wait moveTime
-
- //StopSoundOnEntity( soundDummy, "door_open_loop" )
- //EmitSoundAtPosition( TEAM_UNASSIGNED, soundOrigin, "door_stop" )
-
-}
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
- ██████╗ █████╗ ███╗ ███╗██████╗ ██╗ ██╗███████╗ ██████╗ ███████╗████████╗██╗ ██╗██████╗ ███╗ ██╗
-██╔════╝██╔══██╗████╗ ████║██╔══██╗██║ ██║██╔════╝ ██╔══██╗██╔════╝╚══██╔══╝██║ ██║██╔══██╗████╗ ██║
-██║ ███████║██╔████╔██║██████╔╝██║ ██║███████╗ ██████╔╝█████╗ ██║ ██║ ██║██████╔╝██╔██╗ ██║
-██║ ██╔══██║██║╚██╔╝██║██╔═══╝ ██║ ██║╚════██║ ██╔══██╗██╔══╝ ██║ ██║ ██║██╔══██╗██║╚██╗██║
-╚██████╗██║ ██║██║ ╚═╝ ██║██║ ╚██████╔╝███████║ ██║ ██║███████╗ ██║ ╚██████╔╝██║ ██║██║ ╚████║
- ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
- ██████╗ █████╗ ███╗ ███╗██████╗ ██╗ ██╗███████╗ ██████╗ ███████╗████████╗██╗ ██╗██████╗ ███╗ ██╗
-██╔════╝██╔══██╗████╗ ████║██╔══██╗██║ ██║██╔════╝ ██╔══██╗██╔════╝╚══██╔══╝██║ ██║██╔══██╗████╗ ██║
-██║ ███████║██╔████╔██║██████╔╝██║ ██║███████╗ ██████╔╝█████╗ ██║ ██║ ██║██████╔╝██╔██╗ ██║
-██║ ██╔══██║██║╚██╔╝██║██╔═══╝ ██║ ██║╚════██║ ██╔══██╗██╔══╝ ██║ ██║ ██║██╔══██╗██║╚██╗██║
-╚██████╗██║ ██║██║ ╚═╝ ██║██║ ╚██████╔╝███████║ ██║ ██║███████╗ ██║ ╚██████╔╝██║ ██║██║ ╚████║
- ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
- ██████╗ █████╗ ███╗ ███╗██████╗ ██╗ ██╗███████╗ ██████╗ ███████╗████████╗██╗ ██╗██████╗ ███╗ ██╗
-██╔════╝██╔══██╗████╗ ████║██╔══██╗██║ ██║██╔════╝ ██╔══██╗██╔════╝╚══██╔══╝██║ ██║██╔══██╗████╗ ██║
-██║ ███████║██╔████╔██║██████╔╝██║ ██║███████╗ ██████╔╝█████╗ ██║ ██║ ██║██████╔╝██╔██╗ ██║
-██║ ██╔══██║██║╚██╔╝██║██╔═══╝ ██║ ██║╚════██║ ██╔══██╗██╔══╝ ██║ ██║ ██║██╔══██╗██║╚██╗██║
-╚██████╗██║ ██║██║ ╚═╝ ██║██║ ╚██████╔╝███████║ ██║ ██║███████╗ ██║ ╚██████╔╝██║ ██║██║ ╚████║
- ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝
- */
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
- ██████╗ █████╗ ███╗ ███╗██████╗ ██╗ ██╗███████╗ ██████╗ ███████╗████████╗██╗ ██╗██████╗ ███╗ ██╗
-██╔════╝██╔══██╗████╗ ████║██╔══██╗██║ ██║██╔════╝ ██╔══██╗██╔════╝╚══██╔══╝██║ ██║██╔══██╗████╗ ██║
-██║ ███████║██╔████╔██║██████╔╝██║ ██║███████╗ ██████╔╝█████╗ ██║ ██║ ██║██████╔╝██╔██╗ ██║
-██║ ██╔══██║██║╚██╔╝██║██╔═══╝ ██║ ██║╚════██║ ██╔══██╗██╔══╝ ██║ ██║ ██║██╔══██╗██║╚██╗██║
-╚██████╗██║ ██║██║ ╚═╝ ██║██║ ╚██████╔╝███████║ ██║ ██║███████╗ ██║ ╚██████╔╝██║ ██║██║ ╚████║
- ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝
- */
-/////////////////////////////////////////////////////////////////////////////////////////
-
-
-void function CampusReturnStartPointSetup( entity player )
-{
- TeleportPlayerToEnt( player, GetEntByScriptName( "checkpointCampusReturn" ) )
- vector objectivePos = GetEntByScriptName( "objective_human_research_vista" ).GetOrigin()
- TimeshiftSetObjectiveSilent( player, "#TIMESHIFT_OBJECTIVE_LAB_EXPLORE", objectivePos )
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function CampusReturnSkipped( entity player )
-{
- FlagSet( "CampusReturnConversationFinished" )
- FlagClear( "ShowMobilityGhostHumanWallrunChain" )
- FlagClear( "ShowMobilityGhostPowertech" )
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function AA_CampusReturnThread( entity player )
-{
- FlagWait( "reached_concourse_tower2" )
-
- vector objectivePos = GetEntByScriptName( "objective_human_research_vista" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- thread ObjectiveRemindUntilFlag( "crossed_wallrun_chain" )
-
- FlagSet( "ShowMobilityGhostHumanWallrunChain" )
- FlagSet( "ShowMobilityGhostPowertech" )
-
- CheckPoint()
- thread ArtifactLaunchThink( player )
- thread BridgeThink()
- thread MusicCampusReturn( player )
- thread GunshipRingSequenceWait( player )
- thread GunshipSequence( "gunship_rings", player, "node_gunship_rings", "rings", "player_looking_at_reactor_window" )
-
- FlagWait( "crossed_wallrun_chain" )
-
- wait 0.25
-
- //Checkpoint done with a trigger with safe spot here
-
- objectivePos = GetEntByScriptName( "objective_return_breadcrumb00" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- thread DialogueHumanRoomEnd( player )
-
- FlagSet( "finishedHumanVistaSequence" )
-
-
- thread HumanBridgeEnemies( player )
- thread HumanBridgeOvergrownThink( player )
-
-
- FlagWait( "entered_powertech_return" )
-
- objectivePos = GetEntByScriptName( "objective_return_breadcrumb01" ).GetOrigin()
- TimeshiftSetObjective( player, "#TIMESHIFT_OBJECTIVE_RETURN", objectivePos )
-
- CheckPoint()
-
- FlagWait( "approaching_fan_drop" )
-}
-
-void function BridgeThink()
-{
- FlagWait( "bridge_control_panel_pressed" )
- FlagClear( "retract_bridge_human_01" )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function HumanBridgeOvergrownThink( entity player )
-{
- //Show it when enemies extend it in other time zone
- FlagWaitClear( "retract_bridge_human_01" )
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- ShowStuff( "human_bridge_overgrown" )
-
-
- //Hide it again if player manually retracts it
- //FlagWait( "retract_bridge_human_01" )
-
- //waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- //HideStuff( "human_bridge_overgrown" )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function MusicCampusReturn( entity player )
-{
- FlagWait( "crossing_wallrun_chain" )
-
- StopMusic()
- PlayMusic( "music_timeshift_27_towardthemachine" )
-
- FlagWait( "spawnHumanBridgeEnemies" )
-
- //Only play drone spawn music if player is actually in the trigger spawning the drones
-
- if ( !Flag( "player_touching_drone_spawn_area_bridge_pristine") )
- return
-
- StopMusic()
- PlayMusic( "music_timeshift_28_bridge" )
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void function ArtifactLaunchThink( entity player )
-{
- entity arkShell = GetEntByScriptName( "core_model_pristine" )
- entity arkSphere = GetEntByScriptName( "core_glow_model_pristine" )
- vector startPos = arkShell.GetOrigin()
- vector startAng = arkShell.GetAngles()
- vector endPos = GetEntByScriptName( "artifact_ring_startpoint" ).GetOrigin()
-
- entity fxLaunchGlow = PlayLoopFXOnEntity( FX_ARK_LAUNCH_GLOW, arkShell )
- entity mover = CreateScriptMover( startPos, startAng )
- arkSphere.SetParent( arkShell )
- arkShell.SetParent( mover )
- float moveTime = 2
-
- FlagWait( "crossed_wallrun_chain" )
-
- wait 0.25
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
- wait 0.1
-
- mover.NonPhysicsMoveTo( endPos, moveTime, moveTime*0.4, moveTime*0.4 )
- EmitSoundOnEntity( player, "timeshift_scr_core_rise_start" )
-
- wait moveTime
-
- entity fxLaunchInPlace = PlayFXOnEntity( FX_ARK_LAUNCH_IN_PLACE, arkShell )
-
- //StopSoundOnEntity( player, "timeshift_scr_core_rise_start" )
- EmitSoundAtPosition( TEAM_UNASSIGNED, endPos, "timeshift_scr_core_rise_end" )
- EmitSoundAtPosition( TEAM_UNASSIGNED, endPos, "timeshift_scr_core_pulse" )
- //CreateShake( vector org, float amplitude = 16, float frequency = 150, float duration = 1.5, float radius = 2048 )
- thread CreateAirShake( startPos, 32, 200, 1.5, 10000 )
- thread CreateShakeWhileFlagSet( 0.5, 0.5, 1, "player_near_rings", "DoneWithFanDropSequence" )
-
- FlagSet( "RingVistaSequenceComplete" )
-
-}
-
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function DialogueHumanRoomEnd( entity player )
-{
-
-
-/*
-██████╗ ██╗ █████╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗
-██╔══██╗██║██╔══██╗██║ ██╔═══██╗██╔════╝ ██║ ██║██╔════╝
-██║ ██║██║███████║██║ ██║ ██║██║ ███╗██║ ██║█████╗
-██║ ██║██║██╔══██║██║ ██║ ██║██║ ██║██║ ██║██╔══╝
-██████╔╝██║██║ ██║███████╗╚██████╔╝╚██████╔╝╚██████╔╝███████╗
-╚═════╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
-*/
-
- FlagWait( "crossed_wallrun_chain" )
-
- wait 0.25
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
- entity soundEnt = CreateBestLoudspeakerEnt( player, TIMEZONE_DAY )
-
- //Scientist 5 PA Ark successfully delivered to fold weapon rings. Commencing test run.
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_humanStudy_TS203_01_01_imc_sci" )
-
- //FlagWaitAny( "human_bridge_soldiers_dead", "entered_powertech_return" )
-
- FlagWaitAny( "RingVistaSequenceComplete", "player_crossing_human_bridge" )
-
-
- //BT: Pilot, the rings at my location contain a large amount of residual energy. This was the Ark's final destination.
- waitthread PlayBTDialogue( "diag_sp_targeting_TS231_01_01_mcor_bt" )
-
- //BT: Anderson's plan indicated a recon mission within close proximity to the center of the active rings.
- waitthread PlayBTDialogue( "diag_sp_targeting_TS231_07_01_mcor_bt" )
-
- if ( !Flag( "approaching_fan_drop" ) )
- {
- // Player (Option A) You want me to do what?
- // Player (Option B) Are you sure I'll be safe over there? (diag_sp_pristine_TS242_03_01_mcor_player)
-
- // BT (Option A) If we can obtain the Ark's energy signature, the Militia fleet will be able to track its current location in the present day.
- // BT (Option B) No. But a true Militia Pilot takes risks for the welfare of others. As did Major Anderson and Captain Lastimosa before you. (diag_sp_pristine_TS242_04_01_mcor_bt)
-
- waitthread PlayerConversationStopOnFlag( "TsSeeingCoreFlownToRings", player, "entered_powertech_return" )
- }
-
- FlagSet( "CampusReturnConversationFinished" )
-
- FlagSet( "spawnHumanBridgeEnemies" )
-
-
-}
-
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function HumanBridgeEnemies( entity player )
-{
- FlagWait( "finishedHumanVistaSequence" )
-
- entity lookEnt = GetEntByScriptName( "look_ent_human_bridge" )
- entity trigger = GetEntByScriptName( "trig_player_at_human_vista_pristine" )
- //doTrace degrees minDist timeOut trigger, failsafeFlag )
- waitthread WaitTillLookingAt( player, lookEnt, true, 30, 0, 0, trigger, "player_crossing_human_bridge" )
-
-
- //entity triggerBridgeVolume = GetEntByScriptName( "trigger_bridge_human_volume" )
- //entity bridge = GetEntByScriptName( "human_bridge" )
- //FlagSet( "spawnHumanBridgeEnemies" )
-
- /*
- //FlagClearDelayed( "retract_bridge_human_01", 3 )
-
- FlagWait( "retract_bridge_control_panel_pressed" )
- FlagSet( "retract_bridge_human_01" )
- bridge.NotSolid()
-
- SetGlobalForcedDialogueOnly( true )
- bool screamPlayed = false
- array<entity> ai = GetNPCArrayByClass( "npc_soldier" )
- entity tempNode
- float delayTime = 0
- string floorDropAnim = "pt_react_bridgedrop_A"
- foreach( guy in ai )
- {
- if ( !triggerBridgeVolume.IsTouching( guy ) )
- continue
-
- if ( IsAlive( guy ) )
- {
- //guy.NotSolid()
- if ( screamPlayed == false )
- {
- EmitSoundOnEntity( guy, "Grunt_DroppedByFlyer" )
- screamPlayed = true
- }
- if ( CoinFlip() )
- floorDropAnim = "pt_react_bridgedrop_B"
- tempNode = CreateScriptMover( guy.GetOrigin(), guy.GetAngles() )
- guy.SetParent( tempNode )
- delayTime = RandomFloatRange( 0, 0.3 )
- delaythread ( delayTime ) PlayAnim( guy, floorDropAnim, tempNode )
- //guy.TakeDamage( guy.GetHealth() / 2, null, null, { damageSourceId=damagedef_suicide } )
- }
- }
- if ( screamPlayed == true )
- {
- delaythread ( 2 ) Dev_PrintMessage( player, "#TIMESHIFT_ACHEIVEMENT_HEADING", "#TIMESHIFT_ACHEIVEMENT_TEXT_BRIDGE_FALL", 5 )
- }
-
- wait 1
-
- SetGlobalForcedDialogueOnly( false )
-
- DestroyIfValid( "human_bridge" )
- */
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗ █████╗ ███╗ ██╗ ██████╗ ██████╗ ██████╗ ██████╗
-██╔════╝██╔══██╗████╗ ██║ ██╔══██╗██╔══██╗██╔═══██╗██╔══██╗
-█████╗ ███████║██╔██╗ ██║ ██║ ██║██████╔╝██║ ██║██████╔╝
-██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██║██╔══██╗██║ ██║██╔═══╝
-██║ ██║ ██║██║ ╚████║ ██████╔╝██║ ██║╚██████╔╝██║
-╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗ █████╗ ███╗ ██╗ ██████╗ ██████╗ ██████╗ ██████╗
-██╔════╝██╔══██╗████╗ ██║ ██╔══██╗██╔══██╗██╔═══██╗██╔══██╗
-█████╗ ███████║██╔██╗ ██║ ██║ ██║██████╔╝██║ ██║██████╔╝
-██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██║██╔══██╗██║ ██║██╔═══╝
-██║ ██║ ██║██║ ╚████║ ██████╔╝██║ ██║╚██████╔╝██║
-╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗ █████╗ ███╗ ██╗ ██████╗ ██████╗ ██████╗ ██████╗
-██╔════╝██╔══██╗████╗ ██║ ██╔══██╗██╔══██╗██╔═══██╗██╔══██╗
-█████╗ ███████║██╔██╗ ██║ ██║ ██║██████╔╝██║ ██║██████╔╝
-██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██║██╔══██╗██║ ██║██╔═══╝
-██║ ██║ ██║██║ ╚████║ ██████╔╝██║ ██║╚██████╔╝██║
-╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗ █████╗ ███╗ ██╗ ██████╗ ██████╗ ██████╗ ██████╗
-██╔════╝██╔══██╗████╗ ██║ ██╔══██╗██╔══██╗██╔═══██╗██╔══██╗
-█████╗ ███████║██╔██╗ ██║ ██║ ██║██████╔╝██║ ██║██████╔╝
-██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██║██╔══██╗██║ ██║██╔═══╝
-██║ ██║ ██║██║ ╚████║ ██████╔╝██║ ██║╚██████╔╝██║
-╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void function FanDropStartPointSetup( entity player )
-{
- //entity temp = CreateInfoTarget( Vector( 3536, -4641, -127), Vector( 35.5, -90, 0 ) )
- //TeleportPlayerToEnt( player, temp )
-
- TeleportPlayerToEnt( player, GetEntByScriptName( "checkpointFanDrop" ) )
- vector objectivePos = GetEntByScriptName( "objective_concourse_panel" ).GetOrigin()
- TimeshiftSetObjectiveSilent( player, "#TIMESHIFT_OBJECTIVE_RETURN", objectivePos )
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function FanDropSkipped( entity player )
-{
- CleanupEnts( "rings_pristine" )
- FlagSet( "approaching_fan_drop" )
- FlagSet( "DoneWithFanDropSequence" )
- thread QuickSkit( player, GetEntByScriptName( "node_labC_deathpose_overgrown" ), "approaching_fan_drop" )
- thread QuickSkit( player, GetEntByScriptName( "node_labC_deathpose_pristine" ), "approaching_fan_drop" )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function AA_FanDropThread( entity player )
-{
- FlagWait( "approaching_fan_drop" )
-
- thread MusicFanDrop( player )
- thread FanDropTeleport( player )
- thread QuickSkit( player, GetEntByScriptName( "node_labC_deathpose_overgrown" ), "approaching_fan_drop" )
- thread QuickSkit( player, GetEntByScriptName( "node_labC_deathpose_pristine" ), "approaching_fan_drop" )
- thread FanDropLanding( player )
-
- vector objectivePos = GetEntByScriptName( "objective_return_breadcrumb01" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
-
-
- FlagWait( "doing_fan_drop_pristine" )
-
-
- while( true )
- {
- FlagWait( "exited_fan_drop" )
-
- WaitEndFrame() //even if player hit the "exited_fan_drop", he might already be starting a quickDeath
-
- if ( player.p.doingQuickDeath )
- {
- printl( "player doing quickDeath...waiting 2 secs")
- wait 2
- printl( "Waiting to exit fan drop..." )
- continue
- }
- else
- {
- if ( IsAlive( player ) )
- thread FanDropQuickdeathFailsafe( player )
- break
- }
-
- }
-
-
- FlagSet( "DoneWithFanDropSequence" )
-
-}
-
-void function FanDropQuickdeathFailsafe( entity player )
-{
- player.EndSignal( "OnDeath" )
- //If player gets into a state where the game thinks he has exited the fan sequence, but is in fact doing a quick death, restart from last checkpoint
- wait 0.5
- if ( player.p.doingQuickDeath )
- player.TakeDamage( 9999, null, null, { damageSourceId=damagedef_suicide } )
-}
-
-void function FanDropLanding( entity player )
-{
-
- entity node = GetEntByScriptName( "checkpointFanDropEnd" )
- entity nodePristine = CreateScriptRef( node.GetOrigin() + Vector( 0, 0, TIME_ZOFFSET ), node.GetAngles() )
-
- FlagWait( "DoneWithFanDropSequence" )
-
-
-
- printl( "Done with fan drop...playing land anim" )
-
- player.FreezeControlsOnServer()
- level.allowTimeTravel = false
- ShowStuff( "blocker_fandrop_pristine" )
- ShowStuff( "blocker_fandrop_overgrown" )
-
- player.DisableWeapon()
- player.ForceStand()
-
-
- waitthread AdjustPlayerTimelineHack( player, true )
-
- WaitFrame()
- if ( GetEntityTimelinePosition( player ) == TIMEZONE_NIGHT )
- waitthread PlayerDropLand( player, node, true )
- else
- waitthread PlayerDropLand( player, nodePristine, true )
-
- waitthread AdjustPlayerTimelineHack( player )
-
- wait 0.5
- player.UnfreezeControlsOnServer()
- level.allowTimeTravel = true
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function AdjustPlayerTimelineHack( entity player, bool isBeforePlayerLandAnim = false )
-{
- vector newPos
- var playerCurrentTimeline = GetEntityTimelinePosition( player )
-
- if ( playerCurrentTimeline != level.timeZone )
- {
- printl( "*********WARNING***************" )
- printl( "Rare bug: Player timeline and level timeline don't match....adjusting player pos" )
- printl( "Adjusting before player land animation: " + isBeforePlayerLandAnim )
- printl( "*******************************" )
- newPos = GetPosInOtherTimeline( player.GetOrigin() )
- player.SetOrigin( newPos )
- }
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function FanDropTeleport( entity player )
-{
- player.EndSignal( "OnDeath" )
- FlagEnd( "DoneWithFanDropSequence" )
- entity orgFanDropOvergrownMain = GetEntByScriptName( "fandrop_start_overgrown_main" )
- entity orgFanDropOvergrownAlt = GetEntByScriptName( "fandrop_start_overgrown_alt" )
- vector vectorOffset = orgFanDropOvergrownAlt.GetOrigin() - orgFanDropOvergrownMain.GetOrigin()
-
-
- while( true )
- {
- //wait till player timeshifts past first fire
- FlagWait( "doing_fan_drop_pristine" )
-
- //now wait till he switches back to dodge the spinning fan
- FlagWait( "past_first_spinning_fan_and_back_in_overgrown" )
- //WaittillPlayerSwitchesTimezone( TIMEZONE_NIGHT )
-
- //if we haven't died yet, do the teleport while in overgrown
- if ( CanDoFanTeleport( player, vectorOffset ) )
- player.SetOrigin( player.GetOrigin() + vectorOffset )
-
- //otherwise, we died, wait for player to be in reset pos
- else
- FlagWait( "standing_at_top_of_fan" )
-
- }
-
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-bool function CanDoFanTeleport( entity player, vector vectorOffset )
-{
- //trying to teleport while in overgrown
-
- if ( !IsValid( player ) )
- return false
-
- player.EndSignal( "OnDeath" )
-
- if ( Flag( "standing_at_top_of_fan" ) )
- return false
- if ( !Flag( "dropping_down_fan" ) )
- return false
- if ( player.p.doingQuickDeath )
- return false
- if ( GetEntityTimelinePosition( player ) != TIMEZONE_NIGHT )
- return false
- if ( GetTimelinePosition( player.GetOrigin() + vectorOffset ) != TIMEZONE_NIGHT )
- return false
-
- return true
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function MusicFanDrop( entity player )
-{
- if ( Flag( "StartAndersonHologram3") )
- return
-
- FlagEnd( "StartAndersonHologram3")
-
- OnThreadEnd(
- function() : ()
- {
- FlagSet( "BrokeOutOfFanDropMusicLoop")
- }
- )
- while( true )
- {
- FlagWait( "dropping_down_fan" )
- StopMusic()
- PlayMusic( "music_timeshift_29_downtherabbithole" )
- wait 2
- FlagWait( "standing_at_top_of_fan" )
- StopMusic()
-
- }
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗ █████╗ ███╗ ██╗ ██████╗ ██████╗ ██████╗ ██████╗ ███████╗███╗ ██╗██████╗
-██╔════╝██╔══██╗████╗ ██║ ██╔══██╗██╔══██╗██╔═══██╗██╔══██╗ ██╔════╝████╗ ██║██╔══██╗
-█████╗ ███████║██╔██╗ ██║ ██║ ██║██████╔╝██║ ██║██████╔╝ █████╗ ██╔██╗ ██║██║ ██║
-██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██║██╔══██╗██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║██║ ██║
-██║ ██║ ██║██║ ╚████║ ██████╔╝██║ ██║╚██████╔╝██║ ███████╗██║ ╚████║██████╔╝
-╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝╚═════╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗ █████╗ ███╗ ██╗ ██████╗ ██████╗ ██████╗ ██████╗ ███████╗███╗ ██╗██████╗
-██╔════╝██╔══██╗████╗ ██║ ██╔══██╗██╔══██╗██╔═══██╗██╔══██╗ ██╔════╝████╗ ██║██╔══██╗
-█████╗ ███████║██╔██╗ ██║ ██║ ██║██████╔╝██║ ██║██████╔╝ █████╗ ██╔██╗ ██║██║ ██║
-██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██║██╔══██╗██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║██║ ██║
-██║ ██║ ██║██║ ╚████║ ██████╔╝██║ ██║╚██████╔╝██║ ███████╗██║ ╚████║██████╔╝
-╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝╚═════╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗ █████╗ ███╗ ██╗ ██████╗ ██████╗ ██████╗ ██████╗ ███████╗███╗ ██╗██████╗
-██╔════╝██╔══██╗████╗ ██║ ██╔══██╗██╔══██╗██╔═══██╗██╔══██╗ ██╔════╝████╗ ██║██╔══██╗
-█████╗ ███████║██╔██╗ ██║ ██║ ██║██████╔╝██║ ██║██████╔╝ █████╗ ██╔██╗ ██║██║ ██║
-██╔══╝ ██╔══██║██║╚██╗██║ ██║ ██║██╔══██╗██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║██║ ██║
-██║ ██║ ██║██║ ╚████║ ██████╔╝██║ ██║╚██████╔╝██║ ███████╗██║ ╚████║██████╔╝
-╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝╚═════╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-
-
-void function FanDropEndStartPointSetup( entity player )
-{
- TeleportPlayerToEnt( player, GetEntByScriptName( "checkpointFanDropEnd" ) )
- vector objectivePos = GetEntByScriptName( "objective_concourse_panel" ).GetOrigin()
- TimeshiftSetObjectiveSilent( player, "#TIMESHIFT_OBJECTIVE_RETURN", objectivePos )
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function FanDropEndSkipped( entity player )
-{
-
- CleanupEnts( "triggers_instadeath_humanroom" )
- CleanupEnts( "triggers_quickdeath_humanroom" )
- CleanupEnts( "trigger_quickdeath_checkpoint_humanroom" )
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function AA_FanDropEndThread( entity player )
-{
- FlagWait( "DoneWithFanDropSequence" )
-
-
- CleanupEnts( "rings_pristine" )
- CleanupEnts( "triggers_instadeath_humanroom" )
- CleanupEnts( "triggers_quickdeath_humanroom" )
- CleanupEnts( "trigger_quickdeath_checkpoint_humanroom" )
-
- Remote_CallFunction_Replay( player, "ServerCallback_ShowHologramTitles" )
- thread MusicFanDropEnd( player)
- thread StalkerDoorSequences( player )
- thread DialogueLabCharlie( player )
- thread DialogueTransitionHall( player )
- delaythread ( 1 ) AndersonHologramSequence( player, "node_hologram_lab3", "StartAndersonHologram3" )
-
- vector objectivePos = GetEntByScriptName( "objective_concourse_panel_breadcrumb_01" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
-
- wait 2
-
- CheckPoint()
-
-
- FlagWait( "exited_intel_room3" )
-
- objectivePos = GetEntByScriptName( "objective_concourse_panel" ).GetOrigin()
- TimeshiftUpdateObjective( player, objectivePos )
-
- //-------------------------------
- // Token overgrown/pristine wall Spectres
- //-------------------------------
- array< entity > propSpawners = GetEntArrayByScriptNameInInstance( "spectre_door_spawner", "spectre_spawner_return_overgrown" )
- float delayMin = 0
- float delayMax = 0.4
- int maxToSpawn = 1
- string flagToAbort = "transition_hallway_return_finished"
- string flagToSetWhenSpectreSpawned = ""
- bool requiresLookAt = true
- thread SpawnShowcaseGroupWhenInRange( player, propSpawners, maxToSpawn, flagToAbort, "", delayMin, delayMax, flagToSetWhenSpectreSpawned, requiresLookAt )
-
- propSpawners = GetEntArrayByScriptNameInInstance( "spectre_door_spawner", "spectre_spawner_return_pristine" )
- delayMin = 0
- delayMax = 0.4
- maxToSpawn = 1
- flagToAbort = "transition_hallway_return_finished"
- flagToSetWhenSpectreSpawned = ""
- requiresLookAt = true
- thread SpawnShowcaseGroupWhenInRange( player, propSpawners, maxToSpawn, flagToAbort, "", delayMin, delayMax, flagToSetWhenSpectreSpawned, requiresLookAt )
-
-
- FlagWait( "transition_hallway_return_finished" )
-
-
-
- //ScreenFadeToBlack( player, 1.5, 5 )
- //wait 1.5
- //player.SetInvulnerable()
- //player.FreezeControlsOnServer()
-
- thread TransitionSpoke1()
-}
-
-
-void function TransitionSpoke1()
-{
- LevelTransitionStruct trans = SaveBoyleAudioLogs()
- if ( level.timeZone == TIMEZONE_NIGHT )
- trans.timeshiftMostRecentTimeline = 1
- else
- trans.timeshiftMostRecentTimeline = 0
-
- PickStartPoint( "sp_hub_timeshift", "PRISTINE CAMPUS", trans )
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function MusicFanDropEnd( entity player )
-{
- FlagWait( "StartAndersonHologram3" )
- FlagWait( "BrokeOutOfFanDropMusicLoop" )
-
- //FlagWait( "AndersonHologram3Playing" )
-
- //StopMusic()
- PlayMusicThatCantBeStopped( "music_timeshift_30_andersonlog04")
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function StalkerDoorSequences( entity player )
-{
-
- thread QuickSkit( player, GetEntByScriptName( "node_intel_room3_stalker_door_overgrown" ), "player_near_intel3_exit", GetEntByScriptName( "intel3_exit_overgrown_look_ent" ), GetEntByScriptName( "trig_approaching_lab3_exit_overgrown" ) )
- thread QuickSkit( player, GetEntByScriptName( "node_intel_room3_stalker_door_pristine" ), "player_near_intel3_exit", GetEntByScriptName( "intel3_exit_pristine_look_ent" ), GetEntByScriptName( "trig_approaching_lab3_exit_pristine" ) )
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function DialogueLabCharlie( entity player )
-{
-
-
-/*
-██████╗ ██╗ █████╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗
-██╔══██╗██║██╔══██╗██║ ██╔═══██╗██╔════╝ ██║ ██║██╔════╝
-██║ ██║██║███████║██║ ██║ ██║██║ ███╗██║ ██║█████╗
-██║ ██║██║██╔══██║██║ ██║ ██║██║ ██║██║ ██║██╔══╝
-██████╔╝██║██║ ██║███████╗╚██████╔╝╚██████╔╝╚██████╔╝███████╗
-╚═════╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
-*/
-
- FlagWait( "DoneWithFanDropSequence" )
-
- wait 1.5
-
- FlagSet( "StartAndersonHologram3" )
-
-
- FlagWaitAny( "AndersonHologram3Finished", "exited_intel_room3" )
-
- wait 0.75
-
- //That was Major Anderson's final recording.
- waitthread PlayBTDialogue( "diag_sp_targeting_TS232_02_01_mcor_bt" )
-
- while( true )
- {
- wait 0.25
- if ( IsAudioLogPlaying( player ) )
- continue
-
- else
- {
- //Cooper, based on your recon of this facility, I may have a plan. Meet me outside. diag_sp_targeting_TS232_03_01_mcor_bt
- waitthread PlayBTDialogue( "diag_sp_targeting_TS232_03_01_mcor_bt" )
- Objective_Remind()
- break
- }
- }
-
- thread ObjectiveRemindUntilFlag( "transition_hallway_return_finished" )
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function DialogueTransitionHall( entity player )
-{
-
-
-/*
-██████╗ ██╗ █████╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗
-██╔══██╗██║██╔══██╗██║ ██╔═══██╗██╔════╝ ██║ ██║██╔════╝
-██║ ██║██║███████║██║ ██║ ██║██║ ███╗██║ ██║█████╗
-██║ ██║██║██╔══██║██║ ██║ ██║██║ ██║██║ ██║██╔══╝
-██████╔╝██║██║ ██║███████╗╚██████╔╝╚██████╔╝╚██████╔╝███████╗
-╚═════╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
-*/
-
-
- FlagWaitAny( "player_near_intel3_exit_overgrown", "player_near_intel3_exit_pristine" )
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
- entity soundEnt = CreateBestLoudspeakerEnt( player, TIMEZONE_DAY )
-
- wait 1.5
-
- //Security - PA Attention. Automated security personnel have now been deployed in all non-combatant sectors.
- //Please display security credentials clearly to avoid accidental termination. Thank you.
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_targeting_TS231_12_01_imc_facilityPA" )
-
- wait 3
-
- soundEnt = CreateBestLoudspeakerEnt( player, TIMEZONE_DAY )
-
- //Security -PA Automated security personnel: Please target all non-IMC military subjects.
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_targeting_TS231_11_01_imc_facilityPA" )
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██╗ ██╗ █████╗ ██████╗ ███████╗██████╗
-██╔════╝██║ ██║██╔══██╗██╔══██╗██╔════╝██╔══██╗
-███████╗███████║███████║██████╔╝█████╗ ██║ ██║
-╚════██║██╔══██║██╔══██║██╔══██╗██╔══╝ ██║ ██║
-███████║██║ ██║██║ ██║██║ ██║███████╗██████╔╝
-╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═════╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██╗ ██╗ █████╗ ██████╗ ███████╗██████╗
-██╔════╝██║ ██║██╔══██╗██╔══██╗██╔════╝██╔══██╗
-███████╗███████║███████║██████╔╝█████╗ ██║ ██║
-╚════██║██╔══██║██╔══██║██╔══██╗██╔══╝ ██║ ██║
-███████║██║ ██║██║ ██║██║ ██║███████╗██████╔╝
-╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═════╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██╗ ██╗ █████╗ ██████╗ ███████╗██████╗
-██╔════╝██║ ██║██╔══██╗██╔══██╗██╔════╝██╔══██╗
-███████╗███████║███████║██████╔╝█████╗ ██║ ██║
-╚════██║██╔══██║██╔══██║██╔══██╗██╔══╝ ██║ ██║
-███████║██║ ██║██║ ██║██║ ██║███████╗██████╔╝
-╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═════╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-███████╗██╗ ██╗ █████╗ ██████╗ ███████╗██████╗
-██╔════╝██║ ██║██╔══██╗██╔══██╗██╔════╝██╔══██╗
-███████╗███████║███████║██████╔╝█████╗ ██║ ██║
-╚════██║██╔══██║██╔══██║██╔══██╗██╔══╝ ██║ ██║
-███████║██║ ██║██║ ██║██║ ██║███████╗██████╔╝
-╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═════╝
-
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void function OnSpawnedPropDynamic( entity propDynamic )
-{
- string scriptName = propDynamic.GetScriptName()
-
- if ( scriptName == "flyer_lab" )
- thread LabCreatureThink( propDynamic )
-
- if ( scriptName == "labrats_idlers" )
- thread LabRatIdlerThink( propDynamic )
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function LabRatIdlerThink( entity propDynamic )
-{
- entity node = CreateScriptRef( propDynamic.GetOrigin(), propDynamic.GetAngles() )
- vector originOffset = PositionOffsetFromEnt( node, -15, 0, 0 )
- node.SetOrigin( originOffset )
- thread PlayAnimTeleport( propDynamic, propDynamic.kv.script_noteworthy, node )
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function OnSpawnedLevelNPC( entity npc )
-{
- string scriptName = npc.GetScriptName()
-
- if ( scriptName == "lab_prowlers" )
- {
- thread LabCreatureThink( npc )
-
- }
-
- if ( scriptName == "soldiers_human_room_fight_01" )
- AttackPlayer( npc )
-
-
- //if ( scriptName == "doctor_science_intel_room_01" )
- //thread LabAlphaDoctorScienceThink( npc )
-
- if ( scriptName == "civilian_walker_evac_elevator_labs" )
- thread LabAlphaScientistThink( npc )
-
- if ( scriptName == "labA_dudes" )
- thread LabAlphaScientistThink( npc )
-
- if ( scriptName == "grunts_elevator" )
- thread GruntElevatorThink( npc )
-
- if ( scriptName == "prowlers_courtyard" )
- thread ProwlersAmbientThink( npc )
-
- if ( scriptName == "courtyard_responders" )
- thread CourtyardSoldiersThink( npc )
-
- if ( scriptName == "civilian_walker_courtyard" )
- thread CourtyardSoldiersThink( npc )
-
- if ( scriptName == "creature_surprised_dudes" )
- thread CreatureSurprisedSoldiersThink( npc )
-
- if ( scriptName == "elevator_turret_dudes" )
- thread HallwayTurretDudesThink( npc )
-
- if ( scriptName == "sphere_room_dudes" )
- thread GruntsSphereRoomThink( npc )
-
- if ( scriptName == "first_timeshift_soldiers" )
- AttackPlayer( npc )
-
-
-
-}
-
-
-void function LabCreatureThink( entity creature )
-{
- creature.EndSignal( "PlayerInsideCage" )
- creature.EndSignal( "OnDeath" )
- creature.EndSignal( "OnDestroy" )
-
- thread AnimalCrueltyAcheivement( creature )
- wait 1 //need to wait for player to spawn, otherwise it may early out
-
- if ( creature.IsNPC() )
- creature.SetNoTarget( true )
-
- entity trigger
- entity node
- array <entity> linkedEnts = creature.GetLinkEntArray()
- foreach ( entity ent in linkedEnts )
- {
- if ( ent.GetClassName() == "script_ref" )
- {
- node = ent
- continue
- }
- if ( ent.GetClassName() == "trigger_multiple" )
- {
- trigger = ent
- continue
- }
- }
- //if ( creature.IsNPC() )
- //Assert( IsValid( trigger ), "creature at " + creature.GetOrigin() + " is not linked to a trigger" )
-
- Assert( IsValid( node ), "creature at " + creature.GetOrigin() + " is not linked to a node" )
-
-
- string animIdle = ""
- string animBreakout = ""
- string animAggroLoop = ""
-
- switch ( node.GetScriptName() )
- {
- case "variant01":
- animIdle = "pr_timeshift_caged_sleeping_01"
- animBreakout = "pr_timeshift_caged_sleeping_01_interrupt"
- animAggroLoop = "pr_timeshift_caged_small_aggro_01"
- break
- case "variant02":
- animIdle = "pr_timeshift_caged_sleeping_02"
- animBreakout = "pr_timeshift_caged_sleeping_02_interrupt"
- animAggroLoop = "pr_timeshift_caged_small_aggro_02"
- break
- case "variant03":
- animIdle = "pr_timeshift_caged_sleeping_03"
- animBreakout = "pr_timeshift_caged_sleeping_03_interrupt"
- animAggroLoop = "pr_timeshift_caged_small_aggro_03"
- break
- case "variant04":
- animIdle = "pr_timeshift_caged_laying_01"
- animBreakout = "pr_timeshift_caged_laying_01_interrupt"
- animAggroLoop = "pr_timeshift_caged_small_aggro_04"
- break
- case "variant05":
- animIdle = "pr_timeshift_caged_sitting_01"
- animBreakout = "pr_timeshift_caged_sitting_01_interrupt"
- animAggroLoop = "pr_timeshift_caged_small_aggro_05"
- break
- case "variant06":
- animIdle = "pr_timeshift_caged_standing_01"
- animBreakout = "pr_timeshift_caged_standing_01_interrupt"
- animAggroLoop = "pr_timeshift_caged_small_aggro_03"
- break
- case "variant07":
- animIdle = "pr_timeshift_caged_long_14"
- animBreakout = ""
- animAggroLoop = ""
- break
- case "variantCageTogeterA1":
- animIdle = "pr_timeshift_caged_long_06"
- animBreakout = ""
- animAggroLoop = ""
- break
- case "variantCageTogeterA2":
- animIdle = "pr_timeshift_caged_long_07"
- animBreakout = ""
- animAggroLoop = ""
- break
- case "variantCageTogeterA3":
- animIdle = "pr_timeshift_caged_long_08"
- animBreakout = ""
- animAggroLoop = ""
- break
- case "variantCageTogeterA4":
- animIdle = "pr_timeshift_caged_long_09"
- animBreakout = ""
- animAggroLoop = ""
- break
- case "variantCageTogeterA5":
- animIdle = "pr_timeshift_caged_long_10"
- animBreakout = ""
- animAggroLoop = ""
- break
- case "variantCageTogeterA6":
- animIdle = "pr_timeshift_caged_long_11"
- animBreakout = ""
- animAggroLoop = ""
- break
- case "variantCageTogeterA7":
- animIdle = "pr_timeshift_caged_long_12"
- animBreakout = ""
- animAggroLoop = ""
- break
- case "variantCageTogeterA8":
- animIdle = "pr_timeshift_caged_long_13"
- animBreakout = ""
- animAggroLoop = ""
- break
- case "variantCageTogeterB1":
- animIdle = "pr_timeshift_caged_long_01"
- animBreakout = ""
- animAggroLoop = ""
- break
- case "variantCageTogeterB2":
- animIdle = "pr_timeshift_caged_long_02"
- animBreakout = ""
- animAggroLoop = ""
- break
- case "variantCageTogeterB3":
- animIdle = "pr_timeshift_caged_long_03"
- animBreakout = ""
- animAggroLoop = ""
- break
- case "variantCageTogeterB4":
- animIdle = "pr_timeshift_caged_long_04"
- animBreakout = ""
- animAggroLoop = ""
- break
- case "variantCageTogeterB5":
- animIdle = "pr_timeshift_caged_long_05"
- animBreakout = ""
- animAggroLoop = ""
- break
- case "variantLab01":
- animIdle = "fl_timeshift_caged_tall_laying_01"
- animBreakout = "fl_timeshift_caged_tall_interrupt_01"
- animAggroLoop = "fl_timeshift_caged_tall_aggro_01"
- break
- case "variantLab02":
- animIdle = "fl_timeshift_caged_tall_laying_02"
- animBreakout = "fl_timeshift_caged_tall_interrupt_02"
- animAggroLoop = "fl_timeshift_caged_tall_aggro_02"
- break
- case "variantLab03":
- animIdle = "fl_timeshift_caged_tall_laying_03"
- animBreakout = "fl_timeshift_caged_tall_interrupt_03"
- animAggroLoop = "fl_timeshift_caged_tall_aggro_03"
- break
- case "variantLab04":
- animIdle = "fl_timeshift_caged_tall_laying_04"
- animBreakout = "fl_timeshift_caged_tall_interrupt_04"
- animAggroLoop = "fl_timeshift_caged_tall_aggro_04"
- break
- case "variantCylinder01":
- animIdle = "fl_timeshift_caged_cylinder_01"
- animBreakout = ""
- animAggroLoop = ""
- thread PlayDeathAnimWhenShot( creature, "fl_timeshift_caged_cylinder_death_01" )
- break
- case "variantCylinder02":
- animIdle = "fl_timeshift_caged_cylinder_02"
- animBreakout = ""
- animAggroLoop = ""
- thread PlayDeathAnimWhenShot( creature, "fl_timeshift_caged_cylinder_death_01" )
- break
- default:
- Assert( 0, "creatureNode at " + node.GetOrigin() + " has an unhandled script_name" )
-
- }
-
- //-------------------------------------------------------------
- // Go back into AI if this thread ends (player inside cage)
- //--------------------------------------------------------------
-
- OnThreadEnd(
- function() : ( creature )
- {
- if ( !IsAlive( creature ) )
- return
- creature.Anim_Stop()
- }
- )
-
- //------------------------------------------
- // Play chill idle
- //------------------------------------------
- thread PlayAnimTeleport( creature, animIdle, node )
-
- array <entity> players = GetPlayerArray()
- if ( players.len() <= 0 )
- return
- entity player = players[ 0 ]
-
- if ( ( creature.IsNPC() ) && ( trigger != null ) )
- thread LabProwlerPlayerInsideCage( creature, trigger, player )
-
- while( !PlayerInRange( player.GetOrigin(), creature.GetOrigin(), 256 ) )
- wait 0.2
-
- wait ( RandomFloatRange( 0, 0.8 ) )
-
- //------------------------------------------
- // Player close, breakout into aggro idle
- //------------------------------------------
- if ( animBreakout != "" )
- waitthread PlayAnim( creature, animBreakout, node )
-
- if ( animAggroLoop != "" )
- thread PlayAnim( creature, animAggroLoop, node )
-
-
- WaitForever()
-}
-
-
-void function AnimalCrueltyAcheivement( creature )
-{
- if ( Flag( "AcheivementUnlockedLabProwler") )
- return
- if ( !creature.IsNPC() )
- return
- if ( creature.GetClassName() != "npc_prowler" )
- return
-
- if ( Flag( "AcheivementUnlockedLabProwler") )
- return
-
- FlagEnd( "AcheivementUnlockedLabProwler" )
-
-
- //To do: detect if killed by the player
- //creature.WaitSignal( "OnDeath" )
-
-
-}
-void function PlayDeathAnimWhenShot( entity propCreature, string anim )
-{
-
-
-
-
-}
-
-void function LabProwlerPlayerInsideCage( entity prowler, entity trigger, entity player )
-{
- prowler.EndSignal( "OnDeath" )
- player.EndSignal( "OnDeath" )
-
- trigger.WaitSignal( "OnTrigger" )
-
- prowler.Signal( "PlayerInsideCage" )
-
-}
-
-
-void function PlayMusicInTimezoneUntilFlag( string track, var timeZone, string flagToAbort )
-{
- if ( Flag( flagToAbort ) )
- return
-
- FlagEnd( flagToAbort )
-
- var otherTimeZone
- if ( timeZone == TIMEZONE_NIGHT )
- otherTimeZone = TIMEZONE_DAY
- else
- otherTimeZone = TIMEZONE_NIGHT
-
- while( true )
- {
-
- waitthread WaittillPlayerSwitchesTimezone( timeZone )
-
- StopMusic()
- PlayMusic( track )
-
- waitthread WaittillPlayerSwitchesTimezone( otherTimeZone )
- }
-}
-
-
-
-
-void function DebugX( entity player )
-{
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- entity soundEnt = CreateBestLoudspeakerEnt( player, TIMEZONE_DAY )
-
- waitthread PlayTimeShiftDialogue( player, soundEnt, "diag_sp_wildlifeStudy_TS191_18_01_imc_grunt3" )
-} \ No newline at end of file
diff --git a/Northstar.Coop/scripts/vscripts/sp/hubs/sp_timeshift_utility.nut b/Northstar.Coop/scripts/vscripts/sp/hubs/sp_timeshift_utility.nut
deleted file mode 100644
index 29b2cfc3..00000000
--- a/Northstar.Coop/scripts/vscripts/sp/hubs/sp_timeshift_utility.nut
+++ /dev/null
@@ -1,7253 +0,0 @@
-untyped
-
-global function IsAudioLogPlaying
-global function SaveBoyleAudioLogs
-global function InitBoyleAudioLogs
-global function SetFlagWhenPlayerWithinRangeOfEnt
-global function DeleteUnnecessaryFlyers
-global function GetPosInOtherTimeline
-global function ObjectiveRemindUntilFlag
-global function PlayAnimThenDelete
-global function LoudspeakerThread
-global function GivePropForAnim
-global function ElectricalScreenEffects
-global function GetTimelinePosition
-global function DisableNavmeshSeperatorTargetedByEnt
-global function DropshipSpawnAndRepeat
-global function DeleteNpcWhenOutOfSight
-global function TitanTimeshiftHint
-global function CreateShakeWhileFlagSet
-global function CreateShakeTimeshift
-global function RingsLocalExplosionNormal
-global function RingsLocalExplosionBig
-global function PlayerDropLand
-global function ProwlersAmbientThink
-global function PlayerConversationStopOnFlagImmediate
-global function FlagSetDelayed
-global function FlagClearDelayed
-global function PlayerConversationStopOnFlag
-global function HideCritTimeshift
-global function TitanRackSpawnersThink
-global function TitanRackDeploy
-global function SpawnAutoSecurityGroup
-global function SpawnPristineStalkersWithDopplegangers
-global function TitanTimeshiftLoadout
-global function AndersonHologramSequence
-global function GunshipSequence
-global function GetTimeshiftPlayer
-global function GetClosestGrunt
-global function EmitSoundAtPositionHack
-global function FreezeNPC
-global function UnFreezeNPC
-global function MakeCivilian
-global function DestroyNPCOnFlag
-global function AttackPlayer
-global function HideStuff
-global function ShowStuff
-global function SwapTimelinesScripted
-global function TS_WithinPlayerFOV
-global function SetFlagWhenPlayerLookingAtEnt
-global function PlayerInRange
-global function HideWeaponsAndAmmoTillFlag
-global function DataStab
-//global function MakeSpectreOwnedByPlayer
-global function SkyboxStart
-global function TimeshiftSetObjective
-global function TimeshiftSetObjectiveSilent
-global function TimeshiftUpdateObjective
-global function SPTimeshiftUtilityInit
-global function GetSpectreDoorSwitchByDummyName
-global function DropHangingOgre
-global function DropHangingOgreOnFlag
-global function DestroyArray
-global function LaserMeshDeactivateByInstanceName
-global function LaserMeshDestroyByInstanceName
-global function LaserMeshActivateByInstanceName
-global function SetCurrentObjectivePos
-global function MoveEntityToOppositeTimePeriod
-global function HackPlayLoopEffectOnEntity
-//global function CreateSoundRefHack
-global function DeleteFireHazards
-global function DestroyFuncBrushBreakable
-//global function SpawnWallSpectreGroupWhenInRange
-global function SpawnShowcaseGroupWhenInRange
-global function RemoveBlocker
-global function RestoreBlocker
-global function TempExplosion
-global function DestroyEntByScriptName
-global function SwapTimelines
-global function WaittillSomeDudesAreDead
-global function WaittillPlayerSwitchesTimezone
-global function TimeshiftPlayerThink
-global function TimeshiftHint
-global function DestroyInstancesByScriptInstanceName
-global function HACK_DisableTurret
-global function HACK_EnableTurret
-global function GetNpcByScriptName
-global function CreateLoudspeakerEnt
-global function GiveTimeshiftAbility
-global function SetFlagWhenBreakablesDestroyed
-global function DestroyIfValid
-global function GetEntityTimelinePosition
-global function SleepingSpectreFX
-global function CleanupAI
-global function CleanupEnts
-global function CreateBestLoudspeakerEnt
-global function GiveLowAmmo
-//global function DeleteWaponsWithScriptname
-global function QuickSkit
-global function KillMyInterdimensionalBrother
-global function RingsThink
-global function SetLectureHallLineDuration
-
-
-
-global struct EntityLevelStruct
-{
- bool npcMarkedForCleanup
-}
-
-struct
-{
- array< entity > flagSetEntities
- array< entity > spectreDoorPanels
- array< entity > spectreDoorTriggers,
- array< entity > spawnProps
- array< entity > spectreSpawnDoors
- array< entity > loudspeakerEnts
- vector currentObjectivePos
- vector lastGoodTimeshiftPosOvergrown
- vector lastGoodTimeshiftPosPristine
- bool isDisplayingDamageText
- float lectureHallTimeBeforePlayerInterrupts
- array<entity> npcsPresent
- array<entity> npcsPast
- entity currentObjectiveEntity
- entity titanCorpseOrg
- entity stalkerCorpseOrg
- array< entity > titanCorpsePieces
- array< entity > stalkerCorpsePieces
- array<string> deathPoses
- bool isDisplayingTimeshiftHint
- bool loudspeakerThreadRunning
- array< entity > ambientDeletableFlyers
- int[5] boyleAudioLogNumberAssignments = [ 0, 0, 0, 0, 0 ]
- int boyleAudioLogsCollected = 0
- bool debugAudioLogs = false
- array< entity > audioLogModels
-
-} file
-
-//---------------------------
-// GLOBALS
-//---------------------------
-const FLYER_TIMESHIFT_HEALTH = 500
-const TIME_ZOFFSET_TOEXPLOSION_FROM_PRISTINE = -22144
-const TIME_ZOFFSET_TOEXPLOSION_FROM_OVERGROWN = -10624
-const TIMEZONE_DAY = 0
-const TIMEZONE_NIGHT = 1
-const TIMEZONE_ALL = 2
-const TIMEZONE_FROZEN = 3
-
-const BREAKABLE_TYPE_SATCHEL_DEBRIS_MEDIUM = 0
-const BREAKABLE_TYPE_SATCHEL_DEBRIS_MEDIUM_WIDE = 1
-const BREAKABLE_TYPE_AQUARIUM = 2
-
-const DIST_TO_NOT_CARE_ABOUT_AUDIOLOGS = 1500
-const MODEL_CIV01 = $"models/Humans/civilian/civilian_sci_v1.mdl"
-const MODEL_CIV02 = $"models/Humans/civilian/civilian_sci_v2.mdl"
-const MODEL_CIV03 = $"models/Humans/civilian/civilian_sci_v3.mdl"
-const MODEL_CIV04 = $"models/Humans/civilian/civilian_sci_v4.mdl"
-const MODEL_BUTTON = $"models/props/global_access_panel_button/global_access_panel_button_wall.mdl"
-const MODEL_BUTTON_LARGE = $"models/props/global_access_panel_button/global_access_panel_button_console.mdl"
-const IMC_CORPSE_MODEL_LMG = $"models/Humans/grunts/imc_grunt_lmg_corpse.mdl"
-const IMC_CORPSE_MODEL_RIFLE = $"models/Humans/grunts/imc_grunt_rifle_corpse.mdl"
-const IMC_CORPSE_MODEL_SHOTGUN = $"models/Humans/grunts/imc_grunt_shotgun_corpse.mdl"
-const IMC_CORPSE_MODEL_SMG = $"models/Humans/grunts/imc_grunt_smg_corpse.mdl"
-const IMC_CORPSE_MODEL_HEAVY = $"models/Humans/grunts/imc_grunt_lmg_corpse.mdl"
-const HOLOGRAM_KNIFE_MODEL = $"models/weapons/combat_knife/w_combat_knife.mdl"
-const ANDERSON_HOLOGRAM_MODEL = $"models/humans/heroes/mlt_hero_anderson.mdl"
-const ANDERSON_MODEL = $"models/humans/heroes/mlt_hero_anderson.mdl"
-const SARAH_HOLOGRAM_MODEL = $"models/humans/heroes/mlt_hero_jack.mdl"
-const ENEMY_HOLOGRAM_MODEL = $"models/humans/grunts/imc_grunt_rifle.mdl"
-const ANDERSON_PISTOL_MODEL = $"models/Weapons/b3wing/b3_wingman_ab_01.mdl"
-const HOLOGRAM_ENEMY_GUN_MODEL = $"models/Weapons/b3wing/b3_wingman_ab_01.mdl"
-const MODEL_IPAD = $"models/props/tablet/tablet.mdl"
-const MODEL_COFFEE = $"models/domestic/mug_coffee_white.mdl"
-const MARVIN_MODEL_OVERGROWN = $"models/robots/marvin/marvin_mossy.mdl"
-
-//---------------------------
-// FX
-//---------------------------
-const FX_DLIGHT_LIGHT_FLICKER = $"interior_Dlight_blue_MED"
-const FX_TIMESHIFT_ENTITY_MARKER = $"P_ts_entity"
-const FX_GREEN_BLINKIE = $"runway_light_green"
-const FX_FIRE_HYDRAULIC = $"P_fire_small_FULL"
-const FX_DOOR_SCANNER = $"scan_laser_beam_mdl" //scan_laser_beam_mdl_sm
-const FX_TIME_PORTAL = $"P_ts_portal"
-const FX_BREAKABLE_SATCHEL_DEBRIS_MEDIUM = $"xo_exp_death"
-const FX_BREAKABLE_SATCHEL_DEBRIS_MEDIUM_WIDE = $"xo_exp_death"
-const FX_FIRE_MEDIUM = $"P_fire_rooftop"
-const FX_FIRE_SMALL = $"P_fire_rooftop"
-const FX_FIRE_HUGE = $"P_fire_512"
-const FX_ELECTRICITY = $"P_elec_arc_LG_1"
-//const FX_SPARKS = $"P_sparks_omni_SM_cheap" //this effect stopped working a few weeks ago and no one knows why
-const FX_SPARKS = $"xo_sparks_large_trail_cheap"
-const FX_LASER = $"P_security_laser"
-const FX_RADIATION = $"env_ground_smoke_1024"
-const FX_GENERATOR_LOOP_ACTIVE = $"P_drone_cloak_beam"
-const FX_GENERATOR_LOOP_DORMANT = $"P_elec_arc_LG_1"
-const FX_IMPACT_TABLE_TIMESHIFT = "timeshift_impact"
-const FX_HOLOGRAM_FLASH_EFFECT = $"P_ar_holopilot_flash"
-const FX_HOLOGRAM_HEX_EFFECT = $"P_ar_holopilot_hextrail"
-const FX_HOLO_SCAN_ENVIRONMENT = $"P_ar_holopulse_CP"
-
-
-
-
-//---------------------------
-// SOUND
-//---------------------------
-const SOUND_HOLOGRAM_FLICKER = "Timeshift_Scr_AndersonHolo_FlickerIn"
-const SOUND_HYDRAULIC_EXPLOSION = "Goblin_Dropship_Explode"
-const SOUND_SCANNER_SPECTRE_DOOR = "SpectreDoorScanner" //LaserScanner.ScanSound_3P"
-const SOUND_SCANNER_SPECTRE_DOOR_UNLOCK = "SpectreDoorUnlock"
-const SOUND_SCANNER_SPECTRE_DOOR_FAIL = "SpectreDoorFail"
-const SOUND_TIME_PORTAL_LOOP = "Time_Vortex_Loop"
-const SOUND_BREAKABLE_SATCHEL_DEBRIS_MEDIUM = "Goblin_Dropship_Explode"
-const SOUND_BREAKABLE_SATCHEL_DEBRIS_MEDIUM_WIDE = "Goblin_Dropship_Explode"
-const SOUND_ELECTRICITY = "electricity_loop"
-const SOUND_FIRE_MEDIUM = "amb_colony_fire_medium"
-const SOUND_FIRE_HUGE = "amb_colony_fire_medium"
-const SOUND_SPARKS = "Timeshift_Emit_Sparks" //
-const SOUND_LASER_LOOP = "Timeshift_LaserMesh_Loop"
-const SOUND_LASER_DAMAGE = "Timeshift_LaserMesh_Damage"
-const SOUND_FAN_DAMAGE = "flesh_fanblade_damage_1p"
-const SOUND_LIGHT_FLICKER = "marvin_weld_short"
-
-//---------------------------
-// STRINGS
-//---------------------------
-const HINT_STRING_SPECTRE_REQUIRED = "Security Personnel Required"
-const HINT_STRING_SATCHEL_REQUIRED = "Satchel Charge Required"
-
-//----------------------------
-// MODELS
-//-----------------------------
-const POV_MODEL_TIMESHIFT = $"models/weapons/arms/pov_mlt_hero_jack_ts.mdl"
-
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function SPTimeshiftUtilityInit()
-{
- FlyersShared_Init()
- Temp_InitTimeshiftDialogue()
-
- Riff_ForceSetSpawnAsTitan( eSpawnAsTitan.Never )
- Riff_ForceTitanAvailability( eTitanAvailability.Never )
- AddCallback_EntitiesDidLoad( EntitiesDidLoad )
- AddCallback_OnPlayerRespawned( PlayerSpawned )
- AddDamageCallback( "player", OnPlayerDamage_TimeShift )
-
-
- PrecacheModel( MODEL_CIV01 )
- PrecacheModel( MODEL_CIV02 )
- PrecacheModel( MODEL_CIV03 )
- PrecacheModel( MODEL_CIV04 )
- PrecacheModel( MODEL_BUTTON )
- PrecacheModel( MODEL_BUTTON_LARGE )
- PrecacheModel( MODEL_IPAD )
- PrecacheModel( MODEL_COFFEE )
- PrecacheModel( POV_MODEL_TIMESHIFT )
- PrecacheModel( SARAH_HOLOGRAM_MODEL )
- PrecacheModel( ANDERSON_HOLOGRAM_MODEL )
- PrecacheModel( ENEMY_HOLOGRAM_MODEL )
- PrecacheModel( ANDERSON_PISTOL_MODEL )
- PrecacheModel( HOLOGRAM_ENEMY_GUN_MODEL )
- PrecacheModel( IMC_CORPSE_MODEL_LMG )
- PrecacheModel( IMC_CORPSE_MODEL_RIFLE )
- PrecacheModel( IMC_CORPSE_MODEL_SHOTGUN )
- PrecacheModel( IMC_CORPSE_MODEL_SMG )
- PrecacheModel( IMC_CORPSE_MODEL_HEAVY )
- PrecacheModel( HOLOGRAM_KNIFE_MODEL )
- PrecacheModel( ANDERSON_MODEL )
- PrecacheModel( MARVIN_MODEL_OVERGROWN )
-
-
- PrecacheImpactEffectTable( FX_IMPACT_TABLE_TIMESHIFT )
-
- PrecacheParticleSystem( FX_HOLOGRAM_FLASH_EFFECT )
- PrecacheParticleSystem( FX_HOLOGRAM_HEX_EFFECT )
- PrecacheParticleSystem( FX_HOLO_SCAN_ENVIRONMENT )
- PrecacheParticleSystem( FX_DLIGHT_LIGHT_FLICKER )
- PrecacheParticleSystem( FX_FIRE_HYDRAULIC )
- PrecacheParticleSystem( FX_DOOR_SCANNER )
- PrecacheParticleSystem( FX_TIME_PORTAL )
- PrecacheParticleSystem( FX_BREAKABLE_SATCHEL_DEBRIS_MEDIUM )
- PrecacheParticleSystem( FX_BREAKABLE_SATCHEL_DEBRIS_MEDIUM_WIDE )
- PrecacheParticleSystem( FX_RADIATION )
- PrecacheParticleSystem( FX_FIRE_MEDIUM )
- PrecacheParticleSystem( FX_FIRE_SMALL )
- PrecacheParticleSystem( FX_ELECTRICITY )
- PrecacheParticleSystem( FX_SPARKS )
- PrecacheParticleSystem( FX_LASER )
- PrecacheParticleSystem( FX_TIMESHIFT_ENTITY_MARKER )
- PrecacheParticleSystem( FX_GENERATOR_LOOP_ACTIVE )
- PrecacheParticleSystem( FX_GENERATOR_LOOP_DORMANT )
- PrecacheParticleSystem( FX_GREEN_BLINKIE )
-
- //spawn callbacks
- AddSpectreRackCallback( RackSpawnCallback )
- AddSpawnCallback( "info_target", OnSpawnedInfoTarget )
- AddSpawnCallback( "func_brush", OnSpawnedFuncBrush )
- AddSpawnCallback( "trigger_multiple", OnSpawnedTrigger)
- AddSpawnCallback( "trigger_once", OnSpawnedTrigger )
- AddSpawnCallbackEditorClass( "trigger_multiple", "trigger_quickdeath", OnSpawnedTriggerQuickdeath )
-
-
-
- AddSpawnCallback( "npc_turret_sentry", OnSpawnedNPC )
- AddSpawnCallback( "npc_drone", OnSpawnedNPC )
- AddSpawnCallback( "npc_soldier", OnSpawnedNPC )
- AddSpawnCallback( "npc_titan", OnSpawnedNPC )
- AddSpawnCallback( "npc_spectre", OnSpawnedNPC )
- AddSpawnCallback( "npc_stalker", OnSpawnedNPC )
- AddSpawnCallback( "npc_stalker_zombie", OnSpawnedNPC )
- AddSpawnCallback( "npc_stalker_zombie_mossy", OnSpawnedNPC )
- AddSpawnCallback( "npc_stalker_crawling_mossy", OnSpawnedNPC )
- AddSpawnCallback( "npc_prowler", OnSpawnedNPC )
- AddSpawnCallback( "npc_marvin", OnSpawnedNPC )
- AddSpawnCallback( "npc_frag_drone", OnSpawnedNPC )
- AddSpawnCallback( "npc_super_spectre", OnSpawnedNPC )
- //AddSpawnCallback( "env_fog_controller", OnSpawnedFogController )
- AddSpawnCallback( "info_spawnpoint_marvin", OnSpawnedMarvinSpawner )
- AddSpawnCallback( "prop_dynamic", OnSpawnedPropDynamic )
- AddSpawnCallback( "prop_dynamic_lightweight", OnSpawnedPropDynamic )
- AddSpawnCallbackEditorClass( "prop_dynamic", "script_switch", OnSpawnedScriptedSwitch )
- //AddSpawnCallbackEditorClass( "script_ref", "script_pickup_weapon", WeaponPickupHack )
-
-
- //death callbacks
- //AddDeathCallback( "player", TS_PlayerDeath )
- AddDeathCallback( "npc_soldier", TS_OnDeathNPC )
- AddDeathCallback( "npc_spectre", TS_OnDeathNPC )
- AddDeathCallback( "npc_prowler", TS_OnDeathNPC )
- AddDeathCallback( "npc_titan", TS_OnDeathNPC )
- AddDeathCallback( "npc_stalker", TS_OnDeathNPC )
- AddDeathCallback( "npc_marvin", TS_OnDeathNPC )
-
- AddCallback_OnTimeShiftAbilityUsed( OnTimeShiftAbilityUsed )
- AddCallback_OnTimeShiftTitanAbilityUsed( OnTimeShiftAbilityUsed )
- AddCallback_OnSatchelPlanted( OnSatchelPlanted )
-
- AddDamageCallback( "func_brush", OnDamagedFuncBrush )
-
- FlagInit( "AudioLogPlaying" )
- FlagInit( "ShouldPlayGlobalLoudspeker" )
- FlagInit( "ForceFlyerTakeoff" )
- FlagInit( "AndersonHologram1Playing" )
- FlagInit( "AndersonHologram2Playing" )
- FlagInit( "AndersonHologram3Playing" )
- FlagInit( "PlayerInterruptedLecture" )
- FlagInit( "AndersonHologram1Finished" )
- FlagInit( "AndersonHologram2Finished" )
- FlagInit( "AndersonHologram3Finished" )
- FlagInit( "DisplayTheDamageHint" )
- FlagInit( "RingsShouldBeSpinning" )
- FlagSet( "DisableDropships" )
- FlagInit( "PlayerHasTimeTraveledInsideBT" )
- FlagInit( "DoingCinematicTimeshift" )
- FlagInit( "TurretsNearBunkerFenceActivated" )
- FlagInit( "PlayerObtainedC4" )
- FlagInit( "PlayerHasBioCreds")
- FlagInit( "AtLeastOneBunkerTurretRestored" )
- FlagInit( "bunker_battery_teleport" )
- RegisterSignal( "BreakableDestroyed" )
- RegisterSignal( "PropSpawnerActivate" )
- RegisterSignal( "Frozen" )
- RegisterSignal( "UnFrozen" )
- RegisterSignal( "DisplayingSatchelHint" )
- RegisterSignal( "DisplayingDamageHint" )
- RegisterSignal( "PauseLasermesh" )
- RegisterSignal( "AndersonTimeshifts" )
- RegisterSignal( "AndersonEnemyShow" )
- RegisterSignal( "AndersonHideGun" )
- RegisterSignal( "AndersonEnemyShowKnife" )
- RegisterSignal( "FlyerTakeoffOverride" )
- RegisterSignal( "StopCoreEffects" )
- RegisterSignal( "AudioLogDebugDraw" )
- RegisterSignal( "StopAudioLog" )
-
-
-
- file.isDisplayingDamageText = false
- file.isDisplayingTimeshiftHint = false
-
- level.allowTimeTravel <- false
- //level.isTimeTraveling <- false
- level.timeZone <- TIMEZONE_NIGHT
- level.fogController <- null
- //level.playerSpawn <- null
-
- SetTimeshiftTimeOfDay_Night()
-
- if ( file.debugAudioLogs )
- thread AudioLogDebug()
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function AudioLogDebug()
-{
- while ( true )
- {
- wait 1
-
- printl( "*******************************************************" )
- printt( "boyleAudioLogsCollected: ", file.boyleAudioLogsCollected )
- printt( "boyleAudioLogNumberAssignments:" )
- for ( int i = 0 ; i < file.boyleAudioLogNumberAssignments.len(); i++ )
- {
- printt( i, " = ", file.boyleAudioLogNumberAssignments[ i ] )
- }
-
- }
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function EntitiesDidLoad()
-{
-
- array <entity> flyerSpawners = GetEntArrayByScriptName( "flyer_ambient" )
- array <entity> ambientFlyers
- entity flyer
- foreach( spawner in flyerSpawners )
- {
- flyer = CreatePerchedFlyer( spawner.GetOrigin(), spawner.GetAngles() )
- //flyer.s.health = FLYER_TIMESHIFT_HEALTH
- if ( spawner.HasKey( "script_noteworthy") )
- {
- file.ambientDeletableFlyers.append( flyer )
- }
- ambientFlyers.append( flyer )
-
- spawner.Destroy()
- thread FlyerAmbientThink( flyer )
- }
-
-
-
- array <entity> spawners = GetSpawnerArrayByClassName( "npc_prowler" )
- spawners.extend( GetSpawnerArrayByClassName( "npc_stalker" ) )
- spawners.extend( GetSpawnerArrayByClassName( "npc_stalker_zombie" ) )
- spawners.extend( GetSpawnerArrayByClassName( "npc_stalker_zombie_mossy" ) )
- spawners.extend( GetSpawnerArrayByClassName( "npc_stalker_crawling_mossy" ) )
- spawners.extend( GetSpawnerArrayByClassName( "npc_marvin" ) )
- Assert( spawners.len() > 0 )
- foreach( spawner in spawners )
- {
- if ( IsSpawner( spawner ) )
- spawner.kv.spawnflags = SF_NPC_ALLOW_SPAWN_SOLID //setting this for all spawners because the error is retarded
- }
-
- thread PlayerIndorsStatus()
-
- entity titanCorpseOrg = GetEntByScriptName( "titan_gibs_org" )
- entity stalkerCorpseOrg = GetEntByScriptName( "stalker_gibs_org" )
- Assert( IsValid( titanCorpseOrg ) )
- Assert( IsValid( stalkerCorpseOrg ) )
- thread CorpseSetup( titanCorpseOrg )
- thread CorpseSetup( stalkerCorpseOrg )
-
- array <string> deathPosesLocal
-
- deathPosesLocal.append( "pt_timeshift_deathpose_back_01" )
- deathPosesLocal.append( "pt_timeshift_deathpose_back_02" )
- deathPosesLocal.append( "pt_timeshift_deathpose_back_03" )
- deathPosesLocal.append( "pt_timeshift_deathpose_front_01" )
- file.deathPoses = deathPosesLocal
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function DeleteUnnecessaryFlyers()
-{
- wait 1
- foreach( flyer in file.ambientDeletableFlyers )
- {
- if ( IsValid( flyer ) )
- flyer.Destroy()
- }
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function CorpseSetup( entity corpseOrg )
-{
- array< entity > linkedEnts = corpseOrg.GetLinkEntArray()
- Assert( linkedEnts.len() > 0 )
- string scriptName = corpseOrg.GetScriptName()
-
- foreach( entity ent in linkedEnts )
- {
- ent.SetParent( corpseOrg )
- ent.Hide()
- ent.NotSolid()
-
- if ( scriptName == "titan_gibs_org" )
- file.titanCorpsePieces.append( ent )
- if ( scriptName == "stalker_gibs_org" )
- file.stalkerCorpsePieces.append( ent )
- }
-
- if ( scriptName == "titan_gibs_org" )
- file.titanCorpseOrg = corpseOrg
- else if ( scriptName == "stalker_gibs_org" )
- file.stalkerCorpseOrg = corpseOrg
- else
- Assert( 0, "Unhandled script_name: " + scriptName )
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function TimeshiftSetObjectiveSilent( entity player, string objectiveString, vector objectivePos = < 0, 0, 0 >, entity objectiveEntity = null, silent = false )
-{
- TimeshiftSetObjective( player, objectiveString, objectivePos, objectiveEntity, true )
-}
-
-void function TimeshiftSetObjective( entity player, string objectiveString, vector objectivePos = < 0, 0, 0 >, entity objectiveEntity = null, silent = false )
-{
- if ( objectiveEntity == null )
- {
- SetCurrentObjectivePos( objectivePos )
- if ( silent )
- Objective_SetSilent( objectiveString, objectivePos )
- else
- Objective_Set( objectiveString, objectivePos )
- file.currentObjectiveEntity = null
- }
- else
- {
- if ( silent )
- Objective_SetSilent( objectiveString, < 0, 0, 0 >, objectiveEntity )
- else
- Objective_Set( objectiveString, < 0, 0, 0 >, objectiveEntity )
- file.currentObjectiveEntity = objectiveEntity
- }
-
- ObjectiveCompensate( player, objectiveEntity )
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function TimeshiftUpdateObjective( entity player, vector objectivePos, entity objectiveEntity = null )
-{
- if ( objectiveEntity == null )
- {
- SetCurrentObjectivePos( objectivePos )
- Objective_Update( objectivePos )
- file.currentObjectiveEntity = null
- }
- else
- {
- Objective_Update( < 0, 0, 0 >, objectiveEntity )
- file.currentObjectiveEntity = objectiveEntity
- }
-
- ObjectiveCompensate( player, objectiveEntity )
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function SetCurrentObjectivePos( vector pos )
-{
- Assert( pos.z != 0 )
- file.currentObjectivePos = pos
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function ObjectiveCompensate( entity player, entity objectiveEntity = null )
-{
- vector newPos
-
- if ( !IsValid( objectiveEntity ) )
- {
- if ( GetTimelinePosition( file.currentObjectivePos ) == level.timeZone )
- newPos = file.currentObjectivePos
- else
- newPos = GetPosInOtherTimeline( file.currentObjectivePos )
-
- Objective_Update( newPos )
- }
- else
- {
- if ( GetEntityTimelinePosition( objectiveEntity ) == level.timeZone )
- Objective_Update( < 0, 0, 0 >, objectiveEntity )
- else
- Objective_Update( GetPosInOtherTimeline( objectiveEntity.GetOrigin() ) )
- }
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-vector function GetPosInOtherTimeline( vector pos )
-{
- int zOffset
- if ( GetTimelinePosition( pos ) == TIMEZONE_NIGHT )
- zOffset = TIME_ZOFFSET
- else
- zOffset = TIME_ZOFFSET * -1
-
- return Vector( pos.x, pos.y, pos.z + ( zOffset ) )
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-function DamagedBreakableHydraulic( func_brush, damageInfo )
-{
- int damageSourceID = DamageInfo_GetDamageSourceIdentifier( damageInfo )
- entity attacker = DamageInfo_GetAttacker( damageInfo )
- local damageAmount = DamageInfo_GetDamage( damageInfo )
- local entName = func_brush.GetTargetName()
-
- if ( damageSourceID != eDamageSourceId.mp_weapon_satchel )
- {
- Dev_PrintMessage( attacker, "#BLANK_TEXT", "#HINT_STRING_SATCHEL_REQUIRED", 3.0 )
- return
- }
-
- Signal( func_brush, "BreakableDestroyed" )
-}
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-void function PlayerSpawned( entity player )
-{
- //Need to decide whether we are in past/present based on level.struct
- Remote_CallFunction_NonReplay( player, "ServerCallback_TimeFlipped", TIMEZONE_NIGHT )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function GiveTimeshiftAbility( entity __player )
-{
- //give it to everyone, not just the player
- foreach( entity player in GetPlayerArray() )
- {
- player.SetPlayerSettings( "pilot_solo_timeshift" )
- if ( IsValid( player.GetOffhandWeapon( OFFHAND_SPECIAL ) ) )
- player.TakeOffhandWeapon( OFFHAND_SPECIAL )
- player.GiveOffhandWeapon( "mp_ability_timeshift", 1 )
-
- entity viewModel = player.GetFirstPersonProxy()
- viewModel.SetSkin( 1 )
- Remote_CallFunction_NonReplay( player, "ServerCallback_TimeDeviceAcquired" )
- }
- level.allowTimeTravel = true
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function DataStab( entity player, entity ref )
-{
- vector playerStartPos = player.GetOrigin()
- vector playerStartAng = player.GetAngles()
-
- vector origin = ref.GetOrigin()
- vector angles = ref.GetAngles()
-
-
- ref.SetAngles( ref.GetAngles() + Vector( 0, 0, 18 ) )
-
- FirstPersonSequenceStruct sequenceStart
- sequenceStart.blendTime = 1.0
- sequenceStart.attachment = "ref"
- sequenceStart.firstPersonAnim = "ptpov_data_core_leech_start"
- sequenceStart.thirdPersonAnim = "pt_core_console_leech_start"
- sequenceStart.viewConeFunction = ViewConeZero
-
- FirstPersonSequenceStruct sequenceMid
- sequenceMid.blendTime = 0.0
- sequenceMid.attachment = "ref"
- sequenceMid.firstPersonAnim = "ptpov_data_knife_console_leech_idle"
- sequenceMid.thirdPersonAnim = "pt_data_knife_console_leech_idle"
- sequenceMid.viewConeFunction = ViewConeTight
-
-
- FirstPersonSequenceStruct sequenceEnd
- sequenceEnd.blendTime = 0.0
- sequenceEnd.attachment = "ref"
- sequenceEnd.firstPersonAnim = "ptpov_core_scan_end"
- sequenceEnd.thirdPersonAnim = "pt_core_scan_end"
- sequenceEnd.viewConeFunction = ViewConeTight
-
- player.DisableWeaponWithSlowHolster()
- player.ContextAction_SetBusy()
- //player.FreezeControlsOnServer()
-
- //thread GiveDataknifeForDuration( player, 5 )
-
- //entity fpProxy = player.GetFirstPersonProxy()
- //int attachID = fpProxy.LookupAttachment( "KNIFE" )
- //entity weaponModel = CreatePropDynamic( DATA_KNIFE_MODEL )
- //weaponModel.SetParent( player.GetFirstPersonProxy(), "PROPGUN", false, 0.0 )
-
-
- entity viewModel = player.GetFirstPersonProxy()
- viewModel.Hide()
- Remote_CallFunction_NonReplay( player, "ServerCallback_StopGloveGlow" )
-
- thread CoreHudHighlight( player )
-
-
- //delaythread ( 1 ) KnifePopOut( weaponModel )
- waitthread FirstPersonSequence( sequenceStart, player, ref )
-
-
- //EmitSoundOnEntity( player, "dataknife_loopable_beep" )
-
-
- FlagEnd( "PlayerAtLevelEnd" )
-
- OnThreadEnd(
- function() : ( player, viewModel )
- {
- if ( !IsValid( player ) )
- return
- player.Anim_Stop()
- player.ClearParent()
- ClearPlayerAnimViewEntity( player )
- if ( player.ContextAction_IsBusy() )
- player.ContextAction_ClearBusy()
- player.EnableWeapon()
-
- if ( IsValid( viewModel ) )
- viewModel.Show()
- }
- )
-
- thread FirstPersonSequence( sequenceMid, player, ref )
- wait 0.5
- //EmitSoundOnEntity( player, "Player.Hitbeep_headshot.Kill.Human_3P_vs_1P" )
- wait 0.5
- //EmitSoundOnEntity( player, "dataknife_ring1" )
- wait 1
- //EmitSoundOnEntity( player, "dataknife_ring2" )
- wait 1
- //EmitSoundOnEntity( player, "dataknife_ring1" )
- wait 15.5
- //EmitSoundOnEntity( player, "dataknife_complete" )
- //EmitSoundOnEntity( player, "Player.Hitbeep_headshot.Kill.Human_3P_vs_1P" )
- waitthread FirstPersonSequence( sequenceEnd, player, ref )
-
- //StopSoundOnEntity( player, "dataknife_loopable_beep" )
-
-
-
-
-}
-
-//////////////////////////////////////////////////////////////////////
-void function CoreHudHighlight( entity player )
-{
- entity core_dummy = GetEntByScriptName( "core_dummy" )
-
- //core_dummy.Show()
- //SetTeam( core_dummy, TEAM_IMC )
- //core_dummy.Highlight_ShowInside( 1.0 )
- //core_dummy.Highlight_ShowOutline( 1.0 )
- //Highlight_SetEnemyHighlight( core_dummy, "enemy_sonar" )
-
-
-
-
-
-}
-//////////////////////////////////////////////////////////////////////
-function KnifePopOut( entity knife )
-{
- knife.Anim_Play( "data_knife_console_leech_start" )
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-function GiveDataknifeForDuration( entity player, float time )
-{
-
- entity fpProxy = player.GetFirstPersonProxy()
- int attachID = fpProxy.LookupAttachment( "KNIFE" )
- entity weaponModel = CreatePropDynamic( DATA_KNIFE_MODEL, fpProxy.GetAttachmentOrigin( attachID ), fpProxy.GetAttachmentAngles( attachID ) )
- weaponModel.SetParent( player.GetFirstPersonProxy(), "KNIFE", false, 0.0 )
-
- OnThreadEnd(
- function() : ( weaponModel )
- {
- if ( IsValid( weaponModel ) )
- weaponModel.Destroy()
- }
- )
-
- player.EndSignal( "OnDeath" )
-
- wait time
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function OnSpawnedInfoTarget( entity info_target )
-{
- string entName = info_target.GetTargetName()
- string scriptName = info_target.GetScriptName()
-
- if ( scriptName == "loudspeaker_ent" )
- {
- file.loudspeakerEnts.append( info_target )
- info_target.kv.spawnflags = SF_INFOTARGET_ALWAYS_TRANSMIT_TO_CLIENT
- }
-
- if ( ( entName.find( "flagSetEntity" ) != null ) || ( entName.find( "FlagSetEntity" ) != null ) )
- {
- file.flagSetEntities.append( info_target )
- string flagToSet = info_target.GetScriptName()
- FlagInit( flagToSet )
- }
-
- //breakables
- /*
- if ( entName.find( "breakable" ) != null )
- thread BreakableSetup( info_target )
- */
-
- //generic sparks
- if ( scriptName == "sparks" )
- thread GenericSparks( info_target )
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function OnSpawnedFuncBrush( entity func_brush )
-{
-
-
-
-
-}
-
-/*
-/////////////////////////////////////////////////////////////////////////////////////////
-void function TempDoorThink( entity info_target )
-{
- entity doorController = info_target
- vector origin = doorController.GetOrigin()
- array< entity > linkedEnts = info_target.GetLinkEntArray()
- Assert( linkedEnts.len() > 0, "Door controller at " + info_target.GetOrigin() + " has no linked ents" )
- string classname
- array< entity > doors
- foreach( entity ent in linkedEnts )
- {
- classname = ent.GetClassName()
- if ( classname == "func_brush" )
- doors.append( ent )
- }
- Assert( doors.len() > 0 )
-
- string entName
-
- foreach( door in doors )
- {
- linkedEnts = door.GetLinkEntArray()
- foreach( ent in linkedEnts )
- {
- entName = ent.GetTargetName()
- if ( entName.find( "start" ) != null )
- door.s.startEnt <- ent
- if ( entName.find( "end" ) != null )
- door.s.endEnt <- ent
- }
- Assert( IsValid( door.s.startEnt ) )
- Assert( IsValid( door.s.endEnt ) )
-
- entity mover = TSCreateScriptMoverLight( expect entity( door.s.startEnt ), door.s.startEnt.GetOrigin(), door.s.startEnt.GetAngles() )
- door.s.mover <- mover
- door.SetParent( mover )
- door.s.openPos <- door.s.endEnt.GetOrigin()
- }
-
- wait 1
-
- entity flagEnt = GetClosest( file.flagSetEntities, doorController.GetOrigin() )
- Assert( IsValid( flagEnt ) )
- Assert( Distance( flagEnt.GetOrigin(), doorController.GetOrigin() ) < 50, "No flag entity within 50 units of doorController at " + doorController.GetOrigin() )
- string flagToWaitFor = flagEnt.GetScriptName()
-
- FlagWait( flagToWaitFor )
-
- EmitSoundAtPosition( TEAM_UNASSIGNED, origin, "door_stop" )
- EmitSoundOnEntity( doors[ 0 ], "door_open_loop" )
- foreach( door in doors )
- door.s.mover.NonPhysicsMoveTo( door.s.openPos, 2, 0.0, 0.0 )
-
- wait 2
-
- StopSoundOnEntity( doors[ 0 ], "door_open_loop" )
- EmitSoundAtPosition( TEAM_UNASSIGNED, origin, "door_stop" )
-
-}
-*/
-/////////////////////////////////////////////////////////////////////////////////////////
-
-/*
-void function OnSpawnedFogController( entity fogController )
-{
- if ( GetBugReproNum() != 007 )
- {
- fogController.Destroy()
- return
- }
-
- level.fogController = fogController
- ChangeFog( TIMEZONE_NIGHT )
-}
-*/
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function OnSpawnedPropDynamic( entity propDynamic )
-{
- int contextId = 0
- string entName = propDynamic.GetTargetName()
- string scriptName = propDynamic.GetScriptName()
-
- if ( scriptName == "button_overgrown_large" )
- thread ButtonOvergrownThink( propDynamic, "large" )
-
- if ( scriptName == "button_overgrown" )
- thread ButtonOvergrownThink( propDynamic, "small" )
-
- if ( scriptName == "spectre_door_spawner" )
- thread SpectreDoorSpawnerThink( propDynamic )
-
- if ( scriptName == "door_out_of_order" )
- thread DoorOutOfOrderThink( propDynamic )
-
-
- if ( scriptName == "light_flicker" )
- thread LightFlickerThink( propDynamic )
-
- //----------------------------------------------------
- // Objective highlighting needs to be done onSpawn
- //----------------------------------------------------
- if (
- ( scriptName.find( "helmet_dogtag" ) != null ) ||
- ( scriptName.find( "core_dummy" ) != null ) ||
- ( scriptName.find( "anderson_first_half" ) != null )
-
- )
- {
- Highlight_ClearEnemyHighlight( propDynamic )
- propDynamic.Highlight_SetFunctions( contextId, 0, true, HIGHLIGHT_OUTLINE_INTERACT_BUTTON, 1, 0, false )
- propDynamic.Highlight_SetParam( contextId, 0, HIGHLIGHT_COLOR_INTERACT )
- propDynamic.Highlight_SetCurrentContext( contextId )
- propDynamic.Highlight_ShowInside( 0 )
- propDynamic.Highlight_ShowOutline( 0 )
-
- Objective_InitEntity( propDynamic )
- }
-
- if ( scriptName == "audio_log_model" )
- {
- propDynamic.Highlight_SetFunctions( contextId, 0, true, HIGHLIGHT_OUTLINE_INTERACT_BUTTON, 1, 0, false )
- propDynamic.Highlight_SetParam( contextId, 0, HIGHLIGHT_COLOR_INTERACT )
- propDynamic.Highlight_SetCurrentContext( contextId )
- propDynamic.Highlight_ShowInside( 0 )
- propDynamic.Highlight_ShowOutline( 0 )
- thread AudioLogModelThink( propDynamic )
- }
-
- /*
- asset modelName = propDynamic.GetModelName()
- if (
- ( modelName == SARAH_HOLOGRAM_MODEL ) ||
- ( modelName == ANDERSON_HOLOGRAM_MODEL ) ||
- ( modelName == ENEMY_HOLOGRAM_MODEL )
- )
- {
- propDynamic.SetSkin( 1 )
- }
- */
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function SpectreDoorSpawnerThink( entity spawnProp )
-{
- asset modelName = spawnProp.GetModelName()
- file.spawnProps.append( spawnProp )
- entity spawnerRack
- entity spawnerSpectre
- array< entity > linkedEnts = spawnProp.GetLinkEntArray()
- Assert( linkedEnts.len() > 0 )
- string editorClassname
- string classname
-
- foreach( entity ent in linkedEnts )
- {
- editorClassname = GetEditorClass( ent )
- classname = ent.GetClassName()
-
- if ( editorClassname == "npc_spectre_rack_wall" )
- spawnerRack = ent
- if ( classname == "spawner" )
- spawnerSpectre = ent
- }
-
- Assert( IsValid( spawnerRack ) )
- Assert( IsValid( spawnerSpectre ) )
-
- entity mover
-
- vector origin = spawnProp.GetOrigin()
- vector angles = spawnProp.GetAngles()
- vector originOffset
- vector reverseOriginOffset
-
- string sound
- float doorOpenTime
- float zHeight
- entity ref = CreateEntity( "info_target" )
- ref.SetOrigin( origin )
- ref.SetAngles( angles )
- DispatchSpawn( ref )
-
- var doorOpenDelayTime
- float spawnDelayTime
- if ( spawnProp.HasKey( "script_delay" ) )
- doorOpenDelayTime = spawnProp.kv.script_delay
- else
- doorOpenDelayTime = 0
-
- mover = TSCreateScriptMoverLight( ref, origin, angles )
- spawnProp.SetParent( mover )
-
- switch( modelName )
- {
-
- case $"models/levels_terrain/sp_timeshift/door_custom_timeshift_lobby_01.mdl":
- file.spectreSpawnDoors.append( spawnProp )
- originOffset = PositionOffsetFromEnt( spawnProp, 0, 2, 0 )
- reverseOriginOffset = PositionOffsetFromEnt( spawnProp, 0, -2, 0 )
- sound = "Timeshift_Scr_StalkerPodOpen"
- doorOpenTime = 0.5
- spawnDelayTime = 0.1
- zHeight = 72
- break
- case $"models/levels_terrain/sp_timeshift/door_custom_timeshift_concourse_01.mdl":
- file.spectreSpawnDoors.append( spawnProp )
- originOffset = PositionOffsetFromEnt( spawnProp, 4, 0, 0 )
- reverseOriginOffset = PositionOffsetFromEnt( spawnProp, -4, 0, 0 )
- sound = "Timeshift_Scr_StalkerPodOpen"
- doorOpenTime = 2
- spawnDelayTime = 0.1
- zHeight = 85
- break
- case $"models/timeshift/timeshift_column_panel_09_destroyed.mdl":
- case $"models/timeshift/timeshift_column_panel_09.mdl":
- case $"models/timeshift/timeshift_column_panel_10_destroyed.mdl":
- case $"models/timeshift/timeshift_column_panel_10.mdl":
- file.spectreSpawnDoors.append( spawnProp )
- originOffset = PositionOffsetFromEnt( spawnProp, 0, 2, 0 )
- reverseOriginOffset = PositionOffsetFromEnt( spawnProp, 0, -2, 0 )
- sound = "Timeshift_Scr_StalkerPodOpen"
- doorOpenTime = 0.5
- spawnDelayTime = 0.1
- zHeight = 88
- break
- default:
- Assert( 0, "Unhandled spectre door type at " + spawnProp.GetOrigin() )
- break
- }
-
- while( true )
- {
- spawnProp.WaitSignal( "PropSpawnerActivate" )
-
- wait doorOpenDelayTime
-
- EmitSoundAtPosition( TEAM_UNASSIGNED, origin, sound )
- mover.NonPhysicsMoveTo( originOffset, 0.5, 0.0, 0.0 )
- wait 0.5
- mover.NonPhysicsMoveTo( spawnProp.GetOrigin() + Vector( 0, 0, zHeight ), doorOpenTime, 0.0, 0.0 )
- delaythread ( spawnDelayTime ) SpawnFromStalkerRack( spawnerRack )
-
- wait doorOpenTime + 3
-
- mover.NonPhysicsMoveTo( spawnProp.GetOrigin() + Vector( 0, 0, -zHeight ), doorOpenTime, 0.0, 0.0 )
- //EmitSoundAtPosition( TEAM_UNASSIGNED, origin, sound )
- EmitSoundOnEntity( mover, "Timeshift_Scr_StalkerPodClose" )
- wait doorOpenTime
- mover.NonPhysicsMoveTo( reverseOriginOffset, 0.5, 0.0, 0.0 )
-
- }
-
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function DoorControlPanelSpectreDisable( entity doorSwitch )
-{
- doorSwitch.s.enabled = false
- doorSwitch.s.hintTrigger.kv.enabled = 0
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function DoorControlPanelSpectreEnable( entity doorSwitch )
-{
- doorSwitch.s.enabled = true
- doorSwitch.s.hintTrigger.kv.enabled = 1
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-bool function IsDoorHacking( playerSpectre )
-{
- if ( !( "doorHacking" in playerSpectre.s ) )
- return false
- if ( playerSpectre.s.doorHacking )
- return true
- return false
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-void function DoorControlPanelSpectreTryToHack( playerSpectre, entity doorSwitch )
-{
- playerSpectre.EndSignal( "OnDeath" )
-
- if ( !( "doorHacking" in playerSpectre.s ) )
- playerSpectre.s.doorHacking <- null
- playerSpectre.s.doorHacking = true
-
- //playerSpectre.SetTouchTriggers( false )
- playerSpectre.DisableBehavior( "Follow" )
- playerSpectre.EnableBehavior( "Assault" )
- playerSpectre.EnableNPCFlag( NPC_ALLOW_PATROL | NPC_ALLOW_INVESTIGATE | NPC_USE_SHOOTING_COVER )
-
- var animEnt = doorSwitch.s.animEnt
- animEnt.SetAngles( animEnt.GetAngles() + Vector( 0, 0, 0 ) )
- waitthread RunToAndPlayAnim( playerSpectre, "sp_casual_idle", animEnt.GetOrigin(), false, animEnt.GetAngles() )
- thread PlayAnim( playerSpectre, "sp_casual_idle", animEnt.GetOrigin(), animEnt.GetAngles() )
-
- bool scanSuccess = true
- waitthread DoorControlPanelSpectreScan( doorSwitch, scanSuccess )
-
- //if we make it this far, unlock the door
- doorSwitch.s.unlocked = true
-}
-
-*/
-
-
-void function OnSpawnedTriggerQuickdeath( entity trigger )
-{
-
- vector triggerOrigin = trigger.GetOrigin()
- var timelinePositionTrigger = GetTimelinePosition( triggerOrigin )
- if ( timelinePositionTrigger == TIMEZONE_FROZEN )
- return
-
- var timelinePositionPlayer
- trigger.EndSignal( "OnDestroy" )
- vector playerRespawnOrigin
- var timelinePositionRespawnOrg
- entity player
- var result
-
-
- while ( IsValid( trigger) )
- {
- player = null
- result = trigger.WaitSignal( "OnTrigger" )
-
- if ( !IsValid( result.activator ) )
- continue
-
- if ( !result.activator.IsPlayer() )
- continue
-
- player = expect entity( result.activator )
- player.WaitSignal( "QuickDeathPlayerTeleported" )
-
- timelinePositionPlayer = GetEntityTimelinePosition( player )
- playerRespawnOrigin = player.GetOrigin()
- timelinePositionRespawnOrg = GetTimelinePosition( playerRespawnOrigin )
-
-
- // player respawn origin matches the timeZone he's supposed to be in
- if ( timelinePositionRespawnOrg == level.timeZone )
- continue
-
- player.FreezeControlsOnServer()
- if ( ( level.timeZone == TIMEZONE_NIGHT ) && ( timelinePositionRespawnOrg == TIMEZONE_DAY ) )
- {
- player.SetOrigin( playerRespawnOrigin + Vector( 0, 0, TIME_ZOFFSET * -1 ) )
- }
- else
- {
- player.SetOrigin( playerRespawnOrigin + Vector( 0, 0, TIME_ZOFFSET ) )
- }
- player.UnfreezeControlsOnServer()
-
-
- /*
- if ( timelinePositionPlayer == timelinePositionTrigger )
- continue
-
-
- if ( timelinePositionTrigger == TIMEZONE_DAY )
- player.SetOrigin( playerRespawnOrigin + Vector( 0, 0, TIME_ZOFFSET ) ) //player hit a pristine death trig but respawned in overgrown
- else
- player.SetOrigin( playerRespawnOrigin + Vector( 0, 0, ( TIME_ZOFFSET * -1 ) ) ) //player hit a overgrown death trig but respawned in pristine
- */
- }
-
-
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function OnSpawnedTrigger( entity trigger )
-{
- local entName = trigger.GetTargetName()
- string scriptName = trigger.GetScriptName()
-
-
- //laser mesh
- if ( scriptName == "trig_propspawner" )
- thread TriggerShowcaseSpawnInit( trigger )
-
-
- //spectre wall spawner
- //if ( scriptName.find( "trig_spectre_wall_spawner" ) != null )
- //thread TriggerSpectreWallSpawnerThink( trigger )
-
- //laser mesh
- if ( scriptName == "laser_mesh" )
- thread TriggerPushbackDamageThink( trigger )
-
- //laser mesh
- if ( scriptName == "spinning_fan" )
- thread TriggerPushbackDamageThink( trigger )
-
- //Dudes spawning in elevators
- if ( scriptName == "trigger_elevator_npc" )
- thread trigger_elevator_npc_think( trigger )
-
- /*
- if ( scriptName == "trigger_time_hint" )
- thread TriggerTimehintThink( trigger )
- */
-
-
- //Spectre activated door panel triggers
- if ( scriptName.find( "trigger_spectre_door_control" ) != null )
- file.spectreDoorTriggers.append( trigger )
-
-
- //HACK: need to switch over to script_name for these ones
-
-
- //Spectre activated door panel triggers
- if ( entName.find( "trigger_spectre_door_control" ) != null )
- file.spectreDoorTriggers.append( trigger )
-
-
- //Hazard triggers
- if ( entName.find( "trigger_hazard" ) != null )
- thread TriggerHazardThink( trigger )
-
-
-
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function trigger_elevator_npc_think( entity trigger )
-{
- trigger.EndSignal( "OnDestroy" )
-
- vector soundOrigin
- entity door
- entity elevatorLightEntity
- //entity button
- string classname
- string editorClassname
-
- array< entity > linkedEnts = trigger.GetLinkEntArray()
- Assert( linkedEnts.len() > 0 )
- foreach( entity ent in linkedEnts )
- {
- classname = ent.GetClassName()
- editorClassname = GetEditorClass( ent )
-
- if ( classname == "info_target" )
- {
- elevatorLightEntity = ent
- continue
- }
- if ( editorClassname == "script_door" )
- {
- door = ent
- continue
- }
- /*if ( editorClassname == "script_switch" )
- {
- button = ent
- continue
- }
- */
- }
- Assert( IsValid( door ) )
- Assert( IsValid( elevatorLightEntity ) )
- //Assert( IsValid( button ) )
-
- string flagToOpenDoor = expect string( door.kv.script_flag )
- Assert( flagToOpenDoor != "" )
- soundOrigin = elevatorLightEntity.GetOrigin()
- //elevatorLightEntity.kv.spawnflags = SF_INFOTARGET_ALWAYS_TRANSMIT_TO_CLIENT
-
- //---------------------------------------
- // Guys spawn inside elevator, bell dings
- //---------------------------------------
- trigger.WaitSignal( "OnTrigger" )
-
- EmitSoundAtPosition( TEAM_UNASSIGNED, soundOrigin, "Timeshift_ElevatorBell" )
- entity fxHandle = PlayFX( FX_GREEN_BLINKIE, elevatorLightEntity.GetOrigin() )
-
- OnThreadEnd(
- function() : ( fxHandle )
- {
- if ( !IsValid( fxHandle) )
- return
- fxHandle.Fire( "Stop" )
- fxHandle.Fire( "DestroyImmediately" )
- }
- )
-
- wait 1.25
-
- //--------------
- // Door opens
- //--------------
- FlagSet( flagToOpenDoor )
-
- wait 5
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function TriggerPushbackDamageThink( entity trigger )
-{
- trigger.EndSignal( "OnDestroy" )
- trigger.EndSignal( "PauseLasermesh" )
-
- string scriptName = trigger.GetScriptName()
-
- vector triggerOrigin = trigger.GetOrigin()
- vector soundOrigin = triggerOrigin
-
- array< entity > linkedEnts = trigger.GetLinkEntArray()
- Assert( linkedEnts.len() > 0, "Laser mesh trigger at " + trigger.GetOrigin() + " not linked to anything" )
- entity centerEnt
- entity blockerBrush
- foreach( entity ent in linkedEnts )
- {
- if ( ent.GetClassName() == "info_target" )
- centerEnt = ent
- if ( ent.GetClassName() == "func_brush" )
- blockerBrush = ent
- }
-
- Assert( IsValid( centerEnt ) )
- Assert( IsValid( blockerBrush ), "trigger at " + trigger.GetOrigin() + " does not link to a valid blockerbrush" )
-
- //In case this was deactivated and we are re-activating it now
- blockerBrush.Solid()
-
-
- vector centerEntOrigin = centerEnt.GetOrigin()
-
-
- //DebugDrawLine( topCorner, topCornerConnect, 255, 255, 0, true, 60.0 )
- //DebugDrawSphere( topCorner, 10.0, 255, 200, 0, true, 60.0 )
- //DebugDrawSphere( topCornerConnect, 10.0, 0, 255, 0, true, 60.0 )
- //DebugDrawSphere( botCorner, 10.0, 255, 200, 0, true, 60.0 )
- //DebugDrawBox( triggerOrigin, triggerMins, triggerMaxs, 255, 255, 0, 1, 60.0 )
-
- string soundLoop
- string soundDeactivate
- string soundDamage
-
- int damageID
-
- switch ( scriptName )
- {
- case "laser_mesh":
- //soundLoop = SOUND_LASER_LOOP //doing this on the client
- soundDamage = SOUND_LASER_DAMAGE
- damageID = eDamageSourceId.lasergrid
- break
- case "spinning_fan":
- soundDamage = SOUND_FAN_DAMAGE
- damageID = eDamageSourceId.burn
- break
- }
-
- int statusEffectHandle
- entity maxsCornerEnt
-
- //-------------------
- // setup laser mesh
- //-------------------
- if ( scriptName == "laser_mesh" )
- {
- // Get the trigger bounds
- vector triggerMins = trigger.GetBoundingMins()
- vector triggerMaxs = trigger.GetBoundingMaxs()
- vector topCorner = PositionOffsetFromEnt( trigger, triggerMaxs.x, triggerMaxs.y, triggerMaxs.z )
- vector topCornerConnect = PositionOffsetFromEnt( trigger, triggerMins.x, triggerMins.y, triggerMaxs.z )
- vector botCorner = PositionOffsetFromEnt( trigger, triggerMaxs.x, triggerMaxs.y, triggerMins.z )
-
- maxsCornerEnt = CreateEntity( "info_target" )
- maxsCornerEnt.SetOrigin( trigger.GetOrigin() + triggerMaxs )
- entity minsCornerEnt = CreateEntity( "info_target" )
- minsCornerEnt.SetOrigin( trigger.GetOrigin() + triggerMins )
- maxsCornerEnt.LinkToEnt( minsCornerEnt )
-
- maxsCornerEnt.kv.spawnflags = SF_INFOTARGET_ALWAYS_TRANSMIT_TO_CLIENT
- minsCornerEnt.kv.spawnflags = SF_INFOTARGET_ALWAYS_TRANSMIT_TO_CLIENT
- maxsCornerEnt.EnableNetworkedEntityLinks()
- DispatchSpawn( maxsCornerEnt )
- DispatchSpawn( minsCornerEnt )
-
- statusEffectHandle = StatusEffect_AddEndless( maxsCornerEnt, eStatusEffect.laser_mesh, 1.0 )
- }
-
-
- if ( soundLoop != "" )
- thread EmitSoundAtPositionHack( TEAM_UNASSIGNED, soundOrigin, soundLoop )
-
- var scriptTypeMask = damageTypes.dissolve | DF_STOPS_TITAN_REGEN
- entity player
- var result
- vector playerOriginXYonly
- vector triggerOriginXYonly = Vector( centerEntOrigin.x, centerEntOrigin.y, 0 )
- vector vecToEnt
-
- //---------------------------
- // Cleanup when destroyed
- //---------------------------
- OnThreadEnd(
- function() : ( trigger, maxsCornerEnt, soundOrigin, blockerBrush, soundLoop, soundDeactivate, statusEffectHandle )
- {
- //------------------------------------------------
- //Don't destroy blocker brush if we are just pausing
- //------------------------------------------------
- if ( IsValid( trigger ) )
- {
- blockerBrush.NotSolid()
- blockerBrush.Hide()
- blockerBrush.MakeInvisible()
- }
- else
- blockerBrush.Destroy()
-
- if ( IsValid( maxsCornerEnt ) )
- StatusEffect_Stop( maxsCornerEnt, statusEffectHandle )
-
- //--------------------------------------------------------------------------------
- // Stop and destroy all sounds and particles regardless of pausing or destroying
- //--------------------------------------------------------------------------------
- if ( soundLoop != "" )
- StopSoundAtPosition( soundOrigin, soundLoop )
-
- if ( soundDeactivate != "" )
- EmitSoundAtPosition( TEAM_UNASSIGNED, soundOrigin, soundDeactivate )
- }
- )
-
-
- //---------------------------
- // Wait to do damage
- //---------------------------
- while ( IsValid( trigger) )
- {
- player = null
- result = trigger.WaitSignal( "OnStartTouch" )
-
- //if ( level.isTimeTraveling )
- // continue
-
- if ( !IsValid( result.activator ) )
- continue
-
- if ( result.activator.IsNPC() )
- {
- thread LaserMeshDamageNPC( expect entity( result.activator ) )
- continue
- }
- if ( !result.activator.IsPlayer() )
- continue
-
- //Damage and pushback player
- player = expect entity( result.activator )
-
- if ( player.s.isTimeTraveling )
- continue
-
- player.TakeDamage( 50, svGlobal.worldspawn, svGlobal.worldspawn, { origin = player.GetOrigin(), scriptType = scriptTypeMask, damageSourceId = damageID } )
- CreateShakeRumbleOnly( player.GetOrigin(), 10, 105, 1 )
-
- playerOriginXYonly = player.GetOrigin()
- playerOriginXYonly = Vector( playerOriginXYonly.x, playerOriginXYonly.y, 0 )
-
- vecToEnt = ( playerOriginXYonly - triggerOriginXYonly )
- vecToEnt = Normalize( vecToEnt )
-
- printt( "vecToEnt: ", vecToEnt )
- player.SetVelocity( vecToEnt * 1000 )
- printt( "Velocity: ", vecToEnt * 1000 )
-
- EmitSoundOnEntity( player, soundDamage )
-
-
- //DebugDrawSphere( playerOriginXYonly, 16, 255, 0, 0, true, 3 )
- //DebugDrawSphere( triggerOriginXYonly, 16, 255, 0, 0, true, 3 )
-
- //SetVelocity( Normalize( triigerOrigin - playerOrigin ) * 1000 )
-
- }
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function LaserMeshDamageNPC( entity npc )
-{
- if ( !IsAlive( npc ) )
- return
-
- if ( npc.GetClassName() == "npc_marvin" )
- return
-
- if ( npc.GetClassName() == "npc_stalker" )
- return
-
- npc.Gib( < 0, 0, 100> )
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function LaserMeshDeactivateByInstanceName( string instanceName )
-{
- array< entity > triggers = GetEntArrayByScriptNameInInstance( "laser_mesh", instanceName )
- foreach( trigger in triggers )
- {
- if( IsValid( trigger ) )
- trigger.Signal( "PauseLasermesh" )
-
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function LaserMeshDestroyByInstanceName( string instanceName )
-{
- array< entity > triggers = GetEntArrayByScriptNameInInstance( "laser_mesh", instanceName )
- foreach( trigger in triggers )
- {
- if( IsValid( trigger ) )
- trigger.Destroy()
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function LaserMeshActivateByInstanceName( string instanceName )
-{
- array< entity > lasermeshTriggers = GetEntArrayByScriptNameInInstance( "laser_mesh", instanceName )
- foreach( trigger in lasermeshTriggers )
- {
- if( IsValid( trigger ) )
- thread TriggerPushbackDamageThink( trigger )
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-var function CreateLaserMeshBeam( startPos, endPos )
-{
- entity cpoint = CreateEntity( "info_placement_helper" )
- cpoint.SetOrigin( endPos )
- SetTargetName( cpoint, UniqueString( "controlpoint" ) )
- DispatchSpawn( cpoint )
-
- entity serverEffect = CreateEntity( "info_particle_system" )
- serverEffect.SetOrigin( startPos )
- serverEffect.SetValueForEffectNameKey( FX_LASER )
- serverEffect.kv.start_active = 1
- serverEffect.SetControlPointEnt( 1, cpoint )
-
- DispatchSpawn( serverEffect )
-
- return serverEffect
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-void function TriggerSpectreWallSpawnerThink( entity trigger )
-{
- trigger.EndSignal( "OnDeath" )
-
- entity spectreSpawnDoor
- array< entity > linkedEnts = trigger.GetLinkEntArray()
- Assert( linkedEnts.len() > 0, "Trigger at " + trigger.GetOrigin() + " is not linked to any spectre spawn doors" )
- entity spectreRack
- //entity spawner
-
- vector hackRackOrigin
-
- foreach( entity ent in linkedEnts )
- {
- spectreSpawnDoor = ent
- Assert( spectreSpawnDoor.GetClassName() == "prop_dynamic" )
- spectreRack = spectreSpawnDoor.GetLinkEnt()
- Assert( IsValid( spectreRack ), "Spectre door at " + spectreSpawnDoor.GetOrigin() + " with angles: " + spectreSpawnDoor.GetAngles() + " needs to target a valid spectre rack." )
- //spawner = spectreRack.GetLinkEnt()
- //Assert( IsValid( spawner ), "spectreRack at " + spectreRack.GetOrigin() + " needs to target a valid spectre spawner." )
-
- //push racks back a bit so they don't clip thru doors...too difficult to do all in LevelEd...another reason we need instance_names!
- hackRackOrigin = PositionOffsetFromEnt( spectreRack, -8, 0, 0 )
- spectreRack.SetOrigin( hackRackOrigin )
-
- thread PropSpawnerThink( trigger, spectreSpawnDoor, spectreRack )
- }
-
-}
-*/
-
-/////////////////////////////////////////////////////////////////////////////////////////
-int function GetPlayerSatchelCount( var player )
-{
-
- return 0
-
- /*
- int numSatchels
-
- local weapon = player.GetOffhandWeapon( 0 )
- if ( !IsValid( weapon ) )
-
- if ( weapon )
- local clipCount = player.GetWeaponAmmoMaxLoaded( weapon )
-
-
- return numSatchels
-
- */
-}
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function SwapTimelines( entity player, var timeZone )
-{
- //needs to be threaded off since need to do a
- //WaitEndFrame()...player will take damage from random hazard triggers otherwise
- thread SwapTimelinesThread( player, timeZone )
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DeviceUsedInFrozenWorld( entity player )
-{
- const float EFFECT_DURATION_TOTAL = 0.5
- const float EFFECT_DURATION_EASE_OUT = 0.5
- StatusEffect_AddTimed( player, eStatusEffect.timeshift_visual_effect, 1.0, EFFECT_DURATION_TOTAL, EFFECT_DURATION_EASE_OUT )
-
- //StopSoundOnEntity( player, "Timeshift_Scr_DeviceShift2Past" )
- //EmitSoundOnEntity( player, "Timeshift_Scr_DeviceShift2Present" )
- StopSoundOnEntity( player, "Timeshift_Scr_BrokenDeviceUse" )
- EmitSoundOnEntity( player, "Timeshift_Scr_BrokenDeviceUse" )
-
- //entity timeShiftOffhand = player.GetFirstPersonProxy()
- //timeShiftOffhand.SetSkin( 0 )
-
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function SwapTimelinesThread( entity player, var timeZoneDestination )
-{
- if ( !CanTimeShift( player ) )
- return
-
- player.s.isTimeTraveling = true
-
- // no idea why respawn did this, but removing it doesn't seem to break anything
- //entity player = GetPlayerArray()[0]
- //if ( !player )
- // return
-
- player.ClearTraverse()
-
- player.EndSignal( "OnDeath" )
-
- var skyCam
- vector playerPos = player.GetOrigin()
- vector newPlayerPos
- int timeOffset
-
- player.SetCloakReactEndTime( Time() )
-
-
- if ( timeZoneDestination == TIMEZONE_NIGHT )
- {
- //--------------------------
- // switch to night/overgrown
- //--------------------------
- SetGlobalNetBool( "PlayerInOvergrownTimeline", true )
- skyCam = GetEnt( "skybox_cam_night" )
-
- //level.timeZone = TIMEZONE_NIGHT
- player.s.timeline = TIMEZONE_NIGHT
-
- timeOffset = TIME_ZOFFSET * -1
-
- // make this not use global stuff
- //FreezeNpcs( TIMEZONE_DAY )
- if ( GetPlayersInTimeline( TIMEZONE_DAY ).len() == 0 )
- FreezeNpcs( TIMEZONE_DAY )
-
- player.Signal( "OnTimeFlippedTimezoneNight" )
- SetTimeshiftTimeOfDay_Night()
- if ( Flag( "PlayerPickedUpTimeshiftDevice" ) )
- SetTimeshiftArmDeviceSkin( 1 )
- if ( Flag( "HidePlayerWeaponsDuringShifts") )
- player.EnableWeapon()
- }
-
- else if ( timeZoneDestination == TIMEZONE_DAY )
- {
- //------------------------
- //switch to day/pristine
- //------------------------
- SetGlobalNetBool( "PlayerInOvergrownTimeline", false )
- skyCam = GetEnt( "skybox_cam_day" )
-
- //level.timeZone = TIMEZONE_DAY
- player.s.timeline = TIMEZONE_DAY
-
- timeOffset = TIME_ZOFFSET
- FreezeNpcs( TIMEZONE_NIGHT )
-
- // make this not use global stuff
- //FreezeNpcs( TIMEZONE_NIGHT )
- if ( GetPlayersInTimeline( TIMEZONE_NIGHT ).len() == 0 )
- FreezeNpcs( TIMEZONE_NIGHT )
-
- player.Signal( "OnTimeFlippedTimezoneDay" )
-
- SetTimeshiftTimeOfDay_Day()
- if ( Flag( "PlayerPickedUpTimeshiftDevice" ) )
- SetTimeshiftArmDeviceSkin( 0 )
- if ( Flag( "HidePlayerWeaponsDuringShifts") )
- player.DisableWeapon()
- }
- else
- SetGlobalNetBool( "PlayerInOvergrownTimeline", false )
-
-
- SatchelManagement( player, timeZoneDestination )
-
- if ( ( player.IsTitan() ) && ( !Flag( "PlayerHasTimeTraveledInsideBT" ) ) )
- {
- FlagSet( "PlayerHasTimeTraveledInsideBT" )
- }
-
- TimeshiftUntrackLockedTargets( player )
-
- vector positionOffset = Vector( 0, 0, timeOffset );
- newPlayerPos = playerPos + positionOffset;
-
- if ( PlayerPosInSolid( player, newPlayerPos ) )
- {
- if ( timeZoneDestination == TIMEZONE_DAY )
- {
- printt( "***WARNING: Destination TimeShiftPos " + newPlayerPos + " is in solid. Using file.lastGoodTimeshiftPosPristine instead" )
- //newPlayerPos = file.lastGoodTimeshiftPosPristine
- // use player script var instead
- // this won't compile if we don't manually do type safety stuff here
- var pos = player.s.lastGoodTimeshiftPosPristine
- newPlayerPos = expect vector( pos )
- }
- else if ( timeZoneDestination == TIMEZONE_NIGHT )
- {
- printt( "***WARNING: Destination TimeShiftPos " + newPlayerPos + " is in solid. Using file.lastGoodTimeshiftPosOvergrown instead" )
- //newPlayerPos = file.lastGoodTimeshiftPosOvergrown
- // use player script var instead
- // this won't compile if we don't manually do type safety stuff here
- var pos = player.s.lastGoodTimeshiftPosOvergrown
- newPlayerPos = expect vector( pos )
- }
- }
- else
- {
- //Not in solid, just use the offset
- newPlayerPos = Vector( playerPos.x, playerPos.y, playerPos.z + timeOffset )
- }
-
- thread SwapTimelineEffectsAndSound( player, timeZoneDestination )
-
- const float EFFECT_DURATION_TOTAL = 0.5
- const float EFFECT_DURATION_EASE_OUT = 0.5
- StatusEffect_AddTimed( player, eStatusEffect.timeshift_visual_effect, 1.0, EFFECT_DURATION_TOTAL, EFFECT_DURATION_EASE_OUT )
-
- Remote_CallFunction_NonReplay( player, "ServerCallback_TimeFlipped", player.s.timeline )
- player.SetSkyCamera( skyCam )
- if ( !IsAlive( player ) )
- return
- MakeInvincible( player )
- WaitEndFrame() //player will take damage from random hazard triggers otherwise
-
- if ( Flag( "DoingCinematicTimeshift" ) )
- player.SetAbsOrigin( newPlayerPos )
- else
- player.SetOrigin( newPlayerPos )
-
- EmitAISoundWithOwner( player, SOUND_PLAYER, 0, newPlayerPos, 150, 0.2 )
-
- SetRapidShiftOffset( -positionOffset );
- ClearInvincible( player )
-
- if ( timeZoneDestination == TIMEZONE_DAY )
- GruntChatter_TryEnemyTimeShifted( player )
-
- ObjectiveCompensate( player, file.currentObjectiveEntity )
- player.s.isTimeTraveling = false
-
- //thread SonarColorCorrection( player, 0.5, null )
-}
-
-
-
-void function TimeshiftUntrackLockedTargets( entity player )
-{
- if ( !IsValid( player ) )
- return
-
- entity trackingWeapon
- entity offhand
-
- if ( !player.IsTitan() )
- return
-
-
- offhand = player.GetOffhandWeapon( OFFHAND_RIGHT )
- if ( !IsValid( offhand ) )
- return
- if ( offhand.GetWeaponClassName() == "mp_titanweapon_tracker_rockets" )
- trackingWeapon = offhand
-
-
- if ( !IsValid( trackingWeapon ) )
- return
-
- trackingWeapon.SmartAmmo_Clear( true, true )
-
- /*
- var allTargets = trackingWeapon.SmartAmmo_GetTargets()
- foreach ( target in allTargets )
- {
- if ( !IsValid( target.ent ) )
- continue
- trackingWeapon.SmartAmmo_UntrackEntity( target.ent )
-
- }
- */
-
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function PlayerIndorsStatus()
-{
- while( GetPlayerArray().len() == 0 )
- wait 0.1
-
- entity player = GetPlayerArray()[ 0 ]
- Assert( IsValid( player ) )
- player.EndSignal( "OnDeath" )
-
-
- if ( GetMapName() == "sp_timeshift_spoke02" )
- {
- Remote_CallFunction_NonReplay( player, "ServerCallback_PlayerIndoorsChanged", 1 )
- return
- }
-
-
- Remote_CallFunction_NonReplay( player, "ServerCallback_PlayerIndoorsChanged", 0 )
-
- while( true )
- {
- wait 0.1
-
- FlagWait( "player_is_indoors" )
- Remote_CallFunction_NonReplay( player, "ServerCallback_PlayerIndoorsChanged", 1 )
-
- FlagWaitClear( "player_is_indoors" )
- Remote_CallFunction_NonReplay( player, "ServerCallback_PlayerIndoorsChanged", 0 )
-
- }
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function SatchelManagement( entity player, var timeZone )
-{
- if ( !IsValid( player ) )
- return
-
- array<entity> traps = GetScriptManagedEntArray( player.s.activeTrapArrayId )
- foreach ( index, satchel in traps )
- {
- if ( !IsValid( satchel ) )
- continue
- if ( GetEntityTimelinePosition( satchel ) == timeZone )
- DisableSatchel( satchel, false )
- else
- DisableSatchel( satchel, true )
- }
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DisableSatchel( entity satchel, bool isDisabled )
-{
- satchel.e.isDisabled = isDisabled
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool function CanTimeShift( entity player )
-{
- if ( Flag( "DoingCinematicTimeshift" ) )
- return true
-
- if ( player.GetParent() )
- {
- printl( "Can't teleport...parented")
- return false
- }
-
- /*
- if ( player.IsTraversing() )
- {
- printl( "Can't teleport...traversing")
- return false
- }
- */
- /*
- if ( ( player.IsTitan() ) && ( level.titanCanTimeTravel == false ) )
- {
- printl( "Can't teleport...Titan")
- return false
- }
- */
-
- if ( player.s.isTimeTraveling )
- return false
-
- return true
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
-function OnTimeShiftAbilityUsed( player )
-{
- if ( level.allowTimeTravel == false )
- {
- if ( Flag( "SwappedToFrozenWorld" ) )
- thread DeviceUsedInFrozenWorld( expect entity( player ) )
- return
-
- }
-
- //if ( level.timeZone == TIMEZONE_DAY )
- if ( player.s.timeline == TIMEZONE_DAY )
- SwapTimelines( expect entity( player ), TIMEZONE_NIGHT )
- else
- SwapTimelines( expect entity( player ), TIMEZONE_DAY )
-}
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
-function OnSatchelPlanted( player, collisionParams )
-{
- expect entity( player )
- if ( !IsValid( player ) )
- return
-
- expect table( collisionParams )
-
- vector plantAngles = VectorToAngles( collisionParams.normal )
- vector plantPosition = expect vector( collisionParams.pos )
-
- //thread SatchelHint( player )
-
- //----------------------------------------------------------------
- //create a duplicate satchel in the present if planted in the past
- //----------------------------------------------------------------
- if ( GetTimelinePosition( plantPosition ) == TIMEZONE_NIGHT )
- return
-
- if ( collisionParams.hitEnt != null ) //forget it if it's attached to an AI or anything moving
- return
-
- //TO DO - plant a dupe satchel here
- //bool result = PlantStickyEntity( weapon, collisionParams )
-
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-/*
-function SatchelHint( entity player )
-{
- player.EndSignal( "OnDeath" )
- player.Signal( "DisplayingSatchelHint" )
- player.EndSignal( "DisplayingSatchelHint" )
-
- array<entity> traps
- entity playerCurrentWeapon
- string playerCurrentWeaponClassname
- bool isDisplayingHint = false
-
- entity closestSatchel
- entity offHandOrdinance
- while ( true )
- {
- wait 1.5
-
- if ( isDisplayingHint == true )
- {
- isDisplayingHint = false
- ClearOnscreenHint( player )
- }
-
- offHandOrdinance = player.GetOffhandWeapon( 0 )
- if ( !offHandOrdinance )
- break
- if ( offHandOrdinance.GetWeaponClassName() != "mp_weapon_satchel" )
- break
-
- traps = GetScriptManagedEntArray( player.s.activeTrapArrayId )
- if ( traps.len() < 1 )
- break
-
- playerCurrentWeapon = player.GetActiveWeapon()
-
- // No current weapon selected
- if ( !IsValid( playerCurrentWeapon ) )
- continue
-
- playerCurrentWeaponClassname = playerCurrentWeapon.GetWeaponClassName()
-
- //Player is equipped with the clacker, clear message
- if ( playerCurrentWeaponClassname == "mp_weapon_satchel" )
- continue
-
- closestSatchel = GetClosest( traps, player.GetOrigin() )
- if ( !IsValid( closestSatchel ) )
- continue
-
- if ( DistanceSqr( player.GetOrigin(), closestSatchel.GetOrigin() ) > ( 1024 * 1024 ) )
- continue
-
-
- //player is not equipped with the clacker, display message
- else
- {
- if ( file.isDisplayingTimeshiftHint)
- continue
- if ( file.isDisplayingDamageText )
- continue
-
- DisplayOnscreenHint( player, "satchel_hint_tap_twice", 3.0 )
- isDisplayingHint = true
- continue
- }
-
- }
-
- ClearOnscreenHint( player )
-
-
-}
-
-*/
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool function PlayerHasSatchels( entity player )
-{
- if ( !IsValid( player ) )
- return false
-
- entity weapon = player.GetOffhandWeapon( 0 )
- if ( !IsValid( weapon ) )
- return false
-
- int satchelCount = player.GetWeaponAmmoMaxLoaded( weapon )
- if ( satchelCount == 0 )
- return false
-
- return true
-
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
-function FreezeNpcs( timeZone )
-{
- array<entity> npcsToFreeze
- array<entity> npcsToUnFreeze
- ArrayRemoveDead( file.npcsPresent )
- ArrayRemoveDead( file.npcsPast )
-
- if ( timeZone == TIMEZONE_NIGHT )
- {
- npcsToFreeze = file.npcsPresent
- npcsToUnFreeze = file.npcsPast
- }
-
-
- else if ( timeZone == TIMEZONE_DAY )
- {
- npcsToFreeze = file.npcsPast
- npcsToUnFreeze = file.npcsPresent
- }
-
-
- foreach( npc in npcsToFreeze )
- FreezeNPC( npc )
-
- foreach( npc in npcsToUnFreeze )
- UnFreezeNPC( npc )
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function FreezeNPC( entity npc )
-{
- if ( !IsValid( npc ) )
- return
-
- if ( IsFreezeProof( npc ) )
- return
-
- if ( IsFrozen( npc ) == true )
- return
-
- npc.Freeze()
- npc.Signal( "Frozen" )
-
- if ( !( "isFrozen" in npc.s ) )
- npc.s.isFrozen <- null
- npc.s.isFrozen = true
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function UnFreezeNPC( entity npc )
-{
- if ( !IsValid( npc ) )
- return
-
- if ( IsFrozen( npc ) == false )
- return
-
- npc.Unfreeze()
- npc.Signal( "UnFrozen" )
- if ( !( "isFrozen" in npc.s ) )
- npc.s.isFrozen <- null
- npc.s.isFrozen = false
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function IsFrozen( npc )
-{
- if ( !( "isFrozen" in npc.s ) )
- return false
-
- return npc.s.isFrozen
-}
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool function IsFreezeProof( entity npc )
-{
- if ( !IsValid( npc ) )
- return false
- if ( "dontAllowFreeze" in npc.s )
- return true
-
- return false
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DontAllowFreeze( entity npc, bool state )
-{
- if ( !IsValid( npc ) )
- return
-
- if ( state == true )
- {
- if ( !( "dontAllowFreeze" in npc.s ) )
- npc.s.dontAllowFreeze <- null
- npc.s.dontAllowFreeze = true
- }
- else
- {
- if ( "dontAllowFreeze" in npc.s )
- delete npc.s.dontAllowFreeze
- }
-}
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function OnSpawnedNPC( entity npc )
-{
- string classname = npc.GetClassName()
- string editorClassname = GetEditorClass( npc )
-
- if ( editorClassname == "npc_marvin_drone" )
- return
-
- var timeZone = GetEntityTimelinePosition( npc )
- expect int(timeZone)
-
- int difficulty = GetSpDifficulty()
-
-
- if ( timeZone == TIMEZONE_NIGHT )
- file.npcsPresent.append( npc )
- else if ( timeZone == TIMEZONE_DAY )
- file.npcsPast.append( npc )
- else
- {
- //Frozen world - do nothing
- }
-
- //If I just spawned in the opposite time zone as the player, freeze me
- //if ( ( level.timeZone != timeZone ) && ( timeZone != TIMEZONE_FROZEN ) )
- if ( GetPlayersInTimeline( timeZone ).len() == 0 && timeZone != TIMEZONE_FROZEN )
- FreezeNPC( npc )
-
- if ( timeZone == TIMEZONE_FROZEN )
- return
-
- //Do blue afterglow if we have the device now
- if ( level.allowTimeTravel )
- thread TimeshiftAfterglowThink( npc, timeZone )
-
-
-
-
- int maxHealth = npc.GetMaxHealth()
- switch( classname )
- {
- case "npc_marvin":
- if ( timeZone == TIMEZONE_NIGHT )
- {
- npc.SetModel( MARVIN_MODEL_OVERGROWN )
- npc.SetSkin( 1 ) //mossy
- }
- break
- case "npc_stalker":
- case "npc_stalker_zombie":
- case "npc_stalker_zombie_mossy":
- case "npc_stalker_crawling_mossy":
- thread StalkerThink( npc, classname )
-
- break
- case "npc_drone":
- break
- case "npc_turret_sentry":
- if ( difficulty < DIFFICULTY_MASTER )
- npc.kv.AccuracyMultiplier = 4
- else
- npc.kv.AccuracyMultiplier = 3
- break
- case "npc_titan":
- thread TitanEnemyThink( npc )
- break
- }
-
- string scriptName = npc.GetScriptName()
- //--------------------------
- // Civilians
- //--------------------------
- if ( scriptName.find( "civilian_walker_" ) != null )
- thread CivilianWalkerThink( npc )
- if ( scriptName.find( "civilian_actor_" ) != null )
- thread CivilianActorThink( npc )
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function TitanEnemyThink( entity npc )
-{
- if ( npc.GetTeam() != TEAM_IMC )
- return
-
- //npc.WaitSignal( "WeakTitanHealthInitialized" )
- //DeregisterBossTitan( npc )
- //npc.SetHealth( 100 )
-
- var timeZone = GetEntityTimelinePosition( npc )
-
- if ( timeZone == TIMEZONE_DAY )
- thread TitanEnemyThinkPristine( npc )
- else
- thread TitanEnemyThinkOvergrown( npc )
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function TitanEnemyThinkOvergrown( npc )
-{
- npc.WaitSignal( "WeakTitanHealthInitialized" )
- npc.TakeDamage( npc.GetMaxHealth()/2, null, null, { damageSourceId=damagedef_suicide } )
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function TitanEnemyThinkPristine( npc )
-{
- npc.WaitSignal( "WeakTitanHealthInitialized" )
- printt( "Titan health: ", npc.GetHealth() )
- npc.SetMaxHealth( 10000 )
- npc.SetHealth( 10000 )
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function StalkerThink( entity npc, string classname )
-{
- npc.SetSkin( 1 ) //mossy
- TakeAllWeapons( npc )
-
- if ( ( GetMapName() == "sp_hub_timeshift" ) && ( !Flag( "player_back_in_amenities_lobby") ) )
- return
-
- if ( ( GetMapName() == "sp_timeshift_spoke02" ) && ( !Flag( "StartAndersonHologram1" ) ) )
- return
-
- npc.GiveWeapon( "mp_weapon_mgl" )
-
- npc.EndSignal( "OnDeath" )
- while( true )
- {
- npc.kv.allowshoot = 0
- wait RandomFloatRange( 4, 6 )
- npc.kv.allowshoot = 1
- wait RandomFloatRange( 3, 5 )
- }
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function TimeshiftAfterglowThink( entity npc, var timeZone )
-{
-
- if( !IsValid( npc ) )
- return
-
- npc.EndSignal( "OnDestroy" )
- npc.EndSignal( "OnDeath" )
-
- //don't do glows for friendlies
- int team = npc.GetTeam()
- if ( team == TEAM_MILITIA )
- return
-
- if ( team == TEAM_UNASSIGNED )
- return
-
- //don't do glow for certain scripted things
- string scriptName = npc.GetScriptName()
- if ( ( IsValid( scriptName ) ) && ( scriptName == "lab_prowlers" ) )
- return
-
- if ( ( IsValid( scriptName ) ) && ( scriptName == "bio_pod_body" ) )
- return
-
-
-
- string classname = npc.GetClassName()
- string glowSound = "Timeshift_Scr_TimeResidue_Generic"
- int zOffset
- vector fxAfterglowAdditionalOffset
-
- switch( classname )
- {
- case "npc_marvin":
- return
- case "npc_soldier":
- glowSound = "Timeshift_Scr_TimeResidue_Grunt"
- fxAfterglowAdditionalOffset = Vector( 0, 0, 32 )
- break
- case "npc_spectre":
- case "npc_stalker_zombie":
- case "npc_stalker_zombie_mossy":
- case "npc_stalker_crawling_mossy":
- fxAfterglowAdditionalOffset = Vector( 0, 0, 32 )
- glowSound = "Timeshift_Scr_TimeResidue_ZombieStalker"
- break
- case "npc_stalker":
- glowSound = "Timeshift_Scr_TimeResidue_Stalker"
- fxAfterglowAdditionalOffset = Vector( 0, 0, 32 )
- break
- case "npc_prowler":
- glowSound = "Timeshift_Scr_TimeResidue_Prowler"
- fxAfterglowAdditionalOffset = Vector( 0, 0, 32 )
- break
- case "npc_drone":
- glowSound = "Timeshift_Scr_TimeResidue_Drone"
- fxAfterglowAdditionalOffset = Vector( 0, 0, 0 )
- break
- case "npc_titan":
- fxAfterglowAdditionalOffset = Vector( 0, 0, 80 )
- break
- case "npc_super_spectre":
- fxAfterglowAdditionalOffset = Vector( 0, 0, 64 )
- break
- case "npc_frag_drone":
- fxAfterglowAdditionalOffset = Vector( 0, 0, 32 )
- break
- case "npc_turret_sentry":
- fxAfterglowAdditionalOffset = Vector( 0, 0, 16 )
- break
- default:
- Assert( 0, "Unhandled npc: " + classname )
- break
- }
-
-
- if ( GetEditorClass( npc ) == "npc_specialist_imc" )
- glowSound = "Timeshift_Scr_TimeResidue_Generic"
-
- if ( timeZone == TIMEZONE_NIGHT )
- zOffset = TIME_ZOFFSET
- else
- zOffset = TIME_ZOFFSET * -1
-
- vector fxAfterglowPos
- vector fxAfterglowAng
-
- entity fx
- while( true )
- {
- npc.WaitSignal( "Frozen" )
- fxAfterglowPos = npc.GetOrigin()
- fxAfterglowPos = fxAfterglowPos + fxAfterglowAdditionalOffset
- fxAfterglowPos = Vector( fxAfterglowPos.x, fxAfterglowPos.y, fxAfterglowPos.z + zOffset )
- fxAfterglowAng = npc.GetAngles()
- fx = PlayFX( FX_TIMESHIFT_ENTITY_MARKER, fxAfterglowPos, fxAfterglowAng )
- if ( glowSound != "" )
- EmitSoundAtPosition( TEAM_UNASSIGNED, fxAfterglowPos, glowSound )
-
- OnThreadEnd(
- function() : ( fx, glowSound, fxAfterglowPos )
- {
- DestroyFxIfValid( fx )
- if ( glowSound != "" )
- StopSoundAtPosition( fxAfterglowPos, glowSound )
- }
- )
-
- npc.WaitSignal( "UnFrozen" )
- DestroyFxIfValid( fx )
- if ( glowSound != "" )
- StopSoundAtPosition( fxAfterglowPos, glowSound )
- }
-}
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DestroyFxIfValid( entity fx )
-{
- if ( !IsValid( fx) )
- return
- fx.Fire( "Stop" )
- fx.Fire( "DestroyImmediately" )
- fx.Destroy()
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function TS_OnDeathNPC( entity npc, var damageInfo )
-{
- thread TS_OnDeathNPCThread( npc, damageInfo )
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function TS_OnDeathNPCThread( entity npc, var damageInfo )
-{
- if ( !IsValid( npc ) )
- return
-
- string editorClassname = GetEditorClass( npc )
-
- if ( GetEntityTimelinePosition( npc ) == TIMEZONE_NIGHT )
- {
- if ( editorClassname == "npc_marvin" )
- npc.SetSkin( 1 ) //bug where Marvins revert to base skin when killed
-
- //TryTimeshiftGibDeath( npc, damageInfo )
-
- //get out of here because we don't care about npcs in the present
- return
- }
-
- int damageType = DamageInfo_GetCustomDamageType( damageInfo )
-
- if ( !damageType )
- return
-
- printt( "explosive: " + ( damageType & DF_EXPLOSION ) )
- printt( "bullet: " + ( damageType & DF_BULLET ) )
- printt( "gib: " + ( damageType & DF_GIB ) )
-
- if ( damageType & DF_GIB )
- {
- return
- }
-
- //if ( TryTimeshiftGibDeath( npc, damageInfo ) )
- //return
-
-
- //vector deathPos = npc.GetOrigin()
- vector deathPos = npc.GetOrigin() + Vector( 0, 0, ( TIME_ZOFFSET * -1 ) )
- //vector deathPos = npc.GetOrigin()
-
-
-
-
- asset deathModel
- entity corpseOrg
- bool usesSingleDeathModel = true
- int additionalZoffset = 0
- if ( editorClassname == "" )
- editorClassname = npc.GetClassName()
-
- switch( editorClassname )
- {
- case "npc_prowler":
- break
- case "npc_marvin":
- deathModel = MARVIN_MODEL_OVERGROWN
- break
- case "npc_stalker":
- corpseOrg = file.stalkerCorpseOrg
- usesSingleDeathModel = false
- additionalZoffset = 16
- break
- case "npc_titan_ogre_minigun":
- case "npc_titan":
- corpseOrg = file.titanCorpseOrg
- usesSingleDeathModel = false
- additionalZoffset = 64
- break
- case "npc_soldier_imc_shotgun":
- deathModel = IMC_CORPSE_MODEL_SHOTGUN
- break
- case "npc_soldier_imc_rifle":
- case "npc_soldier":
- deathModel = IMC_CORPSE_MODEL_RIFLE
- break
- case "npc_shield_captain_imc":
- deathModel = IMC_CORPSE_MODEL_HEAVY
- break
- case "npc_soldier_imc_smg":
- deathModel = IMC_CORPSE_MODEL_SMG
- break
- }
-
-
- /*
- int xAngle = 90
- if ( CoinFlip() )
- xAngle = -90
- vector deathAng = Vector( xAngle, RandomFloatRange( 0, 360 ), RandomFloatRange( 0, 360 ) )
- */
-
- //randomly spin the body/gib collection on it's y axis
- vector deathAng = Vector( 0, RandomFloatRange( 0, 360 ), 0 )
-
- if ( ( deathModel == $"" ) && ( usesSingleDeathModel ) )
- {
- printt( "Unhandled corpse type: '" + editorClassname + "'")
- return
- }
-
-
- array<entity> corpseModels
-
- if ( usesSingleDeathModel )
- {
- entity corpse = CreatePropDynamic( deathModel, deathPos + Vector( 0, 0, 5), deathAng, 6 ) // 0 = no collision, 2 = bounding box, 6 = use vPhysics, 8 = hitboxes only
- corpse.Hide()
- if ( deathModel == MARVIN_MODEL_OVERGROWN )
- corpse.SetSkin( 1 ) //mossy
- corpseModels.append( corpse )
- string anim = GetrandomDeathPose( deathModel )
- vector newOrg = HackGetDeltaToRef( corpse.GetOrigin(), corpse.GetAngles(), corpse, anim )
- thread PlayAnimTeleport( corpse, anim, newOrg, corpse.GetAngles() )
- }
- else
- {
-
- corpseOrg.SetOrigin( deathPos )
- corpseOrg.SetAngles( deathAng )
- array<entity> bodyPartArray = file.titanCorpsePieces
- if ( editorClassname == "npc_stalker" )
- bodyPartArray = file.stalkerCorpsePieces
-
- foreach( bodypart in bodyPartArray )
- {
- asset modelName = bodypart.GetModelName()
- vector angles = bodypart.GetAngles()
- vector origin = bodypart.GetOrigin()
- entity clonedModel = CreatePropPhysics( modelName, origin + Vector( 0, 0, 20 + additionalZoffset ), angles ) // 0 = no collision, 2 = bounding box, 6 = use vPhysics, 8 = hitboxes only
- clonedModel.Hide()
- corpseModels.append( clonedModel )
- }
-
-
- }
-
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_NIGHT )
-
- foreach( corpse in corpseModels )
- {
- corpse.Show()
-
- if ( usesSingleDeathModel )
- corpse.BecomeRagdoll( Vector( 0,0,0 ), false )
- }
-
-}
-
-/*
- array<string> idles = [ "pt_S2S_crew_A_idle",
- "pt_S2S_crew_B_idle",
- "pt_S2S_crew_C_idle",
- "pt_S2S_crew_D_idle" ]
-*/
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//HACK: need a better global way to spawn marvins using levelEd ents
-void function OnSpawnedMarvinSpawner( entity spawner )
-{
- SpawnMarvin( spawner )
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool function TryTimeshiftGibDeath( entity npc, var damageInfo )
-{
- if ( !IsValid( npc ) )
- return false
-
- int damageSourceId = DamageInfo_GetDamageSourceIdentifier( damageInfo )
- if ( !IsValid( damageSourceId ) )
- return false
- if ( damageSourceId != eDamageSourceId.mp_weapon_satchel )
- return false
-
-
- //string editorClassname = GetEditorClass( npc )
- string classname = npc.GetClassName()
-
- if ( !IsValidGibTarget( classname ) )
- return false
-
-
- vector npcOrigin = npc.GetOrigin()
- vector damageOrigin = DamageInfo_GetDamagePosition( damageInfo )
-
- if ( !IsValid( npcOrigin ) )
- return false
-
- if ( !IsValid( damageOrigin ) )
- return false
-
- float minDist = 100
- if ( Distance( npcOrigin, damageOrigin ) > minDist )
- return false
-
- EmitSoundAtPosition( TEAM_ANY, npcOrigin, "death.pinkmist" )
- npc.Dissolve( ENTITY_DISSOLVE_PINKMIST, Vector( 0, 0, 0 ), 500 )
-
- return true
-
-}
-
-bool function IsValidGibTarget( string classname )
-{
- if ( classname == "npc_prowler" )
- return true
-
- if ( classname == "npc_soldier" )
- return true
-
- return false
-
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//HACK: need a better global way to spawn marvins using levelEd ents
-function SpawnMarvin( spawner )
-{
- local origin = spawner.GetOrigin()
- local angles = spawner.GetAngles()
- entity npc_marvin = CreateEntity( "npc_marvin" )
- SetTargetName( npc_marvin, UniqueString( "mp_random_marvin") )
- npc_marvin.SetOrigin( origin )
- npc_marvin.SetAngles( angles )
- //npc_marvin.kv.rendercolor = "255 255 255"
- npc_marvin.kv.health = -1
- npc_marvin.kv.max_health = -1
- npc_marvin.kv.spawnflags = 516 // Fall to ground, Fade Corpse
- //npc_marvin.kv.FieldOfView = 0.5
- //npc_marvin.kv.FieldOfViewAlert = 0.2
- npc_marvin.kv.AccuracyMultiplier = 1.0
- npc_marvin.kv.physdamagescale = 1.0
- npc_marvin.kv.WeaponProficiency = eWeaponProficiency.GOOD
-
- npc_marvin.s.bodytype <- MARVIN_TYPE_WORKER
- npc_marvin.SetValueForModelKey( $"models/robots/marvin/marvin.mdl" )
-
- DispatchSpawn( npc_marvin )
-
- SetTeam( npc_marvin, TEAM_UNASSIGNED )
-
- return npc_marvin
-}
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool function PlayerInRange( vector pos1, vector pos2, float minRange )
-{
-
- if ( Distance( pos1 , pos2 ) > minRange )
- return false
-
- return true
-
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-entity function GetSpectreDoorSwitchByDummyName( string dummyName )
-{
- entity dummy = GetEntByScriptName( dummyName )
- entity doorSwitch = GetClosest( file.spectreDoorPanels, dummy.GetOrigin() )
-
- Assert( IsValid( doorSwitch ) )
- Assert( Distance( doorSwitch.GetOrigin(), dummy.GetOrigin() ) < 50, "No doorSwitch within 50 units of dummy: " + dummyName )
-
- return doorSwitch
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*
-void function TimeVortexThink( entity trigger )
-{
- trigger.EndSignal( "OnDestroy" )
-
- local result
- entity player
- entity fxEnt = trigger.GetLinkEnt()
- Assert( IsValid( fxEnt ), "Time vortex trig at " + trigger.GetOrigin() + " isn't linked to anything")
-
- var destinationTimeline = GetOppositeTimeline( GetEntityTimelinePosition( fxEnt ) )
-
- //----------------
- // Play looping fx
- //----------------
- entity FX = CreateEntity( "info_particle_system" )
- FX.SetValueForEffectNameKey( FX_TIME_PORTAL )
- FX.kv.VisibilityFlags = ENTITY_VISIBLE_TO_EVERYONE
- FX.kv.start_active = 1
- FX.SetOrigin( fxEnt.GetOrigin() )
- FX.SetAngles( fxEnt.GetAngles() + Vector( 90, 0, 0 ) )
- DispatchSpawn( FX )
- EmitSoundAtPosition( TEAM_UNASSIGNED, fxEnt.GetOrigin(), SOUND_TIME_PORTAL_LOOP )
-
-
- OnThreadEnd(
- function() : ( FX, fxEnt )
- {
- StopSoundAtPosition( fxEnt.GetOrigin(), SOUND_TIME_PORTAL_LOOP )
- DestroyFxIfValid( FX )
- fxEnt.Destroy()
- }
- )
-
-
- //----------------
- // Think...
- //----------------
- while( 1 )
- {
- player = null
- wait 0.1
- result = trigger.WaitSignal( "OnTrigger" )
-
- if ( !IsValid( result.activator ) )
- continue
- if ( result.activator.IsTitan() )
- continue
- if ( !result.activator.IsPlayer() )
- continue
-
- player = expect entity( result.activator )
- player.EndSignal( "OnDeath" )
- thread TimeVortexSoundThread( player )
-
-
- SwapTimelines( player, destinationTimeline )
-
- //thread TimeShiftSwapEffect( player )
- wait 4
-
- EmitSoundOnEntity( player, "Pilot_Time_Vortex_Deactivate" )
-
- wait 1
- float fadeTime = 0.3
- float holdTime = 0
- //(player, r, g, b, a, fadeTime, fadeHold, FFADE_ flags)
- wait 0.75
- ScreenFade( player, 255, 255, 255, 254, fadeTime, holdTime, FFADE_OUT | FFADE_PURGE )
- wait 0.25
-
- //HACK: can't time shift if player in the middle of hacking a panel
- while ( !CanTimeShift( player ) )
- wait 0.1
-
- StopSoundOnEntity( player, "Pilot_Time_Vortex_Loop" )
- SwapTimelines( player, GetOppositeTimeline( destinationTimeline ) )
- wait 1
- }
-
-}
-
-*/
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*
-void function TimeVortexSoundThread( player )
-{
- player.EndSignal( "OnDeath" )
-
- //need to delay 0.1 otherwise won't hear the sound when he is teleported
- wait 0.1
- EmitSoundOnEntity( player, "Pilot_Time_Vortex_Activate" )
- EmitSoundOnEntity( player, "Pilot_Time_Vortex_Loop" )
-
-}
-
-*/
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////
-void function SwapTimelineEffectsAndSound( entity player, timeZone )
-{
-
-
-
-
- //---------------------------------
- // Player has wrist mounted device
- //---------------------------------
- if ( Flag( "PlayerPickedUpTimeshiftDevice" ) )
- {
- //( amplitude frequency duration
- CreateAirShake( player.GetOrigin(), 10, 50, 0.2, 10000 )
-
- if ( player.IsTitan() )
- {
- float fadeTime = 0.1
- float holdTime = 0.03
- ScreenFade( player, 255, 255, 255, 254, fadeTime, holdTime, FFADE_IN | FFADE_PURGE )
- CreateAirShake( player.GetOrigin(), 10, 50, 1, 20000 )
- }
-
-
- if ( timeZone == TIMEZONE_NIGHT )
- {
- //--------------------------
- // switch to night/overgrown
- //--------------------------
- StopSoundOnEntity( player, "Timeshift_Scr_DeviceShift2Past" )
- EmitSoundOnEntity( player, "Timeshift_Scr_DeviceShift2Present" )
- }
- else
- {
- //--------------------------
- // switch to day/pristine
- //--------------------------
- StopSoundOnEntity( player, "Timeshift_Scr_DeviceShift2Present" )
- EmitSoundOnEntity( player, "Timeshift_Scr_DeviceShift2Past" )
-
- }
-
- }
- //---------------------------------
- // Scripted timeshift, no device
- //---------------------------------
- else
- {
- float fadeTime = 0.1
- float holdTime = 0.05
- ScreenFade( player, 255, 255, 255, 254, fadeTime, holdTime, FFADE_IN | FFADE_PURGE )
-
- //--------------
- // FX
- //--------------
- EmitSoundOnEntity( player, "Timeshift_Scr_InvoluntaryShift" )
- }
-
-
-
-
-
- //-----------------------------------
- // Impact table on ground
- //-----------------------------------
- TraceResults results = TraceLine( player.GetOrigin() + Vector( 0, 0, 32 ), player.GetOrigin() + Vector( 0, 0, -200 ), [ player ], TRACE_MASK_NPCSOLID_BRUSHONLY | TRACE_MASK_WATER, TRACE_COLLISION_GROUP_NONE )
- if ( !results.startSolid && !results.allSolid )
- PlayImpactFXTable( GetPosInOtherTimeline( results.endPos ), player, FX_IMPACT_TABLE_TIMESHIFT )
-
- //-----------------------------------
- // FX for viewmodel device
- //-----------------------------------
- if ( !Flag( "PlayerPickedUpTimeshiftDevice" ) )
- return
-
- entity timeShiftOffhand
-
-
-
- //-------------------------------------
- // Skin change for cinematic device equip only
- //---------------------------------------
- if ( !Flag( "DoingCinematicTimeshift" ) )
- return
-
- timeShiftOffhand = player.GetFirstPersonProxy()
-
- if ( !IsValid( timeShiftOffhand) )
- return
-
- if ( timeZone == TIMEZONE_DAY )
- {
- timeShiftOffhand.SetSkin( 0 ) //orange 0
- }
-
- else if ( timeZone == TIMEZONE_NIGHT )
- {
- timeShiftOffhand.SetSkin( 1 ) //blue 1
- }
-
-
- //{ "hero_mil_jack_gauntlet_timeshift_skn_01"} // present amber
- //{ "hero_mil_jack_gauntlet_timeshift_skn_01_v1"} // past blue
- //{ "hero_mil_jack_gauntlet_timeshift_skn_01_v2"} // error red
- //{ "hero_mil_jack_gauntlet_timeshift_skn_01_v3"} // off
-
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////
-var function GetOppositeTimeline( timeline )
-{
- var destinationTimeline
- if ( timeline == TIMEZONE_NIGHT )
- destinationTimeline = TIMEZONE_DAY
- else
- destinationTimeline = TIMEZONE_NIGHT
-
- return destinationTimeline
-
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////
-var function GetEntityTimelinePosition( ent )
-{
- //What time period does this ent live in?
- local z = ent.GetOrigin().z
- if ( z < -6000 )
- return TIMEZONE_FROZEN
- else if ( z < 5300 )
- return TIMEZONE_NIGHT
- else
- return TIMEZONE_DAY
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////
-var function GetTimelinePosition( vector pos )
-{
- //What time period does this pos live in?
- local z = pos.z
- if ( z < -6000 )
- return TIMEZONE_FROZEN
- else if ( z < 5300 )
- return TIMEZONE_NIGHT
- else
- return TIMEZONE_DAY
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DebugDrawOnEnt( ent )
-{
- expect entity( ent )
-
- while ( true )
- {
- DebugDrawSphere( ent.GetOrigin(), 16, 255, 255, 255, true, 0.22 )
- wait 0.2
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////
-void function WaitTillPlayerTouchesTrigger( trigger )
-{
- local result
- while ( 1 )
- {
- result = trigger.WaitSignal( "OnStartTouch" )
-
- if ( !IsValid( result.activator ) )
- continue
- if ( !result.activator.IsPlayer() )
- continue
- break
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function SetFlagWhenBreakablesDestroyed( string flagToSet, string scriptName, string instanceName )
-{
- array < entity > breakableFuncBrushes = GetEntArrayByScriptNameInInstance( scriptName, instanceName )
- foreach ( funcBrush in breakableFuncBrushes )
- {
- Assert( !( "flagToSetWhenDestroyed" in funcBrush.s ), "func brush '" + scriptName + "' instanceName '" + instanceName + "' has flag: " + flagToSet)
- funcBrush.s.flagToSetWhenDestroyed <- flagToSet
- }
-
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function OnDamagedFuncBrush( entity funcBrush, var damageInfo )
-{
-
- //----------------------
- // Return if not player
- //----------------------
- int damageSourceID = DamageInfo_GetDamageSourceIdentifier( damageInfo )
- entity attacker = DamageInfo_GetAttacker( damageInfo )
- float damageAmount = DamageInfo_GetDamage( damageInfo )
-
- if ( !damageSourceID )
- return
-
- if ( !damageAmount )
- return
-
- if ( !attacker )
- return
-
- if ( !attacker.IsPlayer() )
- return
-
- //-----------------------------------
- // Do damage if correct damage type
- //-----------------------------------
- var health = funcBrush.s.health
- var breakableType = funcBrush.s.breakableType
- switch( breakableType )
- {
- case BREAKABLE_TYPE_AQUARIUM:
- case BREAKABLE_TYPE_SATCHEL_DEBRIS_MEDIUM_WIDE:
- case BREAKABLE_TYPE_SATCHEL_DEBRIS_MEDIUM:
- DamageSatchelDebris( funcBrush, damageSourceID, damageAmount )
- break
- default:
- Assert( 0, "Unhandled breakableType ' " + breakableType + "' at " + funcBrush.GetOrigin() )
- }
-
-
- if ( funcBrush.s.health > 0 )
- return
-
- DestroyFuncBrushBreakable( funcBrush )
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DestroyFuncBrushBreakable( funcBrush )
-{
- expect entity( funcBrush )
-
- if ( !IsValid( funcBrush ) )
- return
-
- //----------------------
- // Debris blows up
- //----------------------
- Signal( funcBrush, "BreakableDestroyed" )
-
- entity hintTrigger
- if ( ( "hintTrigger" in funcBrush.s ) )
- hintTrigger = expect entity( funcBrush.s.hintTrigger )
-
- entity fxEnt = expect entity( funcBrush.s.fxEnt )
- asset explosionFx = expect asset( funcBrush.s.fxExplode )
- var explosionSound = funcBrush.s.soundExplode
- vector origin = fxEnt.GetOrigin()
- vector angles = fxEnt.GetAngles()
-
- PlayFX( explosionFx, origin, angles )
- EmitSoundAtPosition( TEAM_UNASSIGNED, origin, explosionSound )
-
- //--------------------------------------
- // Swap out damaged/intact if applicable
- //-------------------------------------
- if ( ( "brokenState" in funcBrush.s ) && ( funcBrush.s.brokenState != null ) )
- funcBrush.s.brokenState.Show()
-
- //--------------------------------------
- // Delete intact version
- //-------------------------------------
- funcBrush.Destroy()
-
- if ( "flagToSetWhenDestroyed" in funcBrush.s )
- {
- FlagSet( expect string( funcBrush.s.flagToSetWhenDestroyed ) )
- }
-
- //----------------------
- // Cleanup
- //----------------------
- if ( IsValid( hintTrigger ) )
- hintTrigger.Destroy()
- fxEnt.Destroy()
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DamageSatchelDebris( funcBrush, damageSourceID, damageAmount )
-{
- if ( damageSourceID != eDamageSourceId.mp_weapon_satchel )
- return
- funcBrush.s.health = funcBrush.s.health - damageAmount
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function TriggerHazardThink( entity trigger )
-{
- trigger.EndSignal( "OnDeath" )
- trigger.EndSignal( "OnDestroy" )
-
- int damageAmt
- float interval
- string scriptName = trigger.GetScriptName()
- asset fx
- var sound
- local scriptTypeMask = damageTypes.dissolve | DF_STOPS_TITAN_REGEN
-
- if ( scriptName.find( "fireSmall" ) != null )
- scriptName = "fireSmall"
-
- if ( scriptName.find( "fireHuge" ) != null )
- scriptName = "fireHuge"
-
- if ( scriptName.find( "fireMedium" ) != null )
- scriptName = "fireMedium"
-
- if ( scriptName.find( "radiation" ) != null )
- scriptName = "radiation"
-
- string soundDamage = ""
- int damageID = eDamageSourceId.burn
-
- switch( scriptName )
- {
- case "electricity":
- fx = FX_ELECTRICITY
- sound = SOUND_ELECTRICITY
- scriptTypeMask = damageTypes.dissolve | DF_STOPS_TITAN_REGEN
- damageAmt = 25
- interval = 0.75
- soundDamage = "flesh_electrical_damage_1p"
- damageID = eDamageSourceId.electric_conduit
- break
- case "fireMedium":
- fx = FX_FIRE_MEDIUM
- sound = SOUND_FIRE_MEDIUM
- scriptTypeMask = damageTypes.dissolve | DF_STOPS_TITAN_REGEN
- damageAmt = 25
- interval = 1
- soundDamage = "flesh_fire_damage_1p"
- damageID = eDamageSourceId.burn
- break
- case "fireSmall":
- fx = FX_FIRE_SMALL
- sound = SOUND_FIRE_MEDIUM
- scriptTypeMask = damageTypes.dissolve | DF_STOPS_TITAN_REGEN
- damageAmt = 25
- interval = 1
- soundDamage = "flesh_fire_damage_1p"
- damageID = eDamageSourceId.burn
- break
- case "fireHuge":
- fx = FX_FIRE_HUGE
- sound = SOUND_FIRE_HUGE
- scriptTypeMask = damageTypes.dissolve | DF_STOPS_TITAN_REGEN
- damageAmt = 25
- interval = 1
- soundDamage = "flesh_fire_damage_1p"
- damageID = eDamageSourceId.burn
- break
- case "radiation":
- case "trigger_concourse_radiation":
- fx = FX_RADIATION
- scriptTypeMask = damageTypes.dissolve | DF_STOPS_TITAN_REGEN
- damageAmt = 100
- interval = 1
- soundDamage = "flesh_fire_damage_1p"
- damageID = eDamageSourceId.burn
- break
- default:
- Assert( 0, "Unhandled hazard type ' " + scriptName + "' at " + trigger.GetOrigin() )
- }
-
- array< entity > linkedEnts = trigger.GetLinkEntArray()
- array< var > fxHandles
- //Assert( linkedEnts.len() > 0, "Hazard trigger at " + trigger.GetOrigin() + " has no linked ents to play fx on" )
-
- //-------------------
- // Hazard sound/FX
- //--------------------
- foreach( ent in linkedEnts )
- thread HackPlayLoopEffectOnEntity( fx, ent )
-
- if ( sound )
- thread EmitSoundAtPositionHack( TEAM_UNASSIGNED, trigger.GetOrigin(), sound )
-
- OnThreadEnd(
- function() : ( trigger, linkedEnts )
- {
- if ( IsValid( trigger ) )
- trigger.Destroy()
- foreach( ent in linkedEnts )
- {
- if ( IsValid( ent ) )
- ent.Destroy()
- }
- }
- )
- //-------------------
- // Damage player
- //--------------------
-
- var player
- local result
- vector origin
- while ( IsValid( trigger) )
- {
-
- wait 0.1
-
- player = null
- result = trigger.WaitSignal( "OnTrigger" )
-
- //if ( level.isTimeTraveling )
- // continue
-
- if ( !IsValid( result.activator ) )
- continue
- if ( result.activator.IsPlayer() )
- {
- player = result.activator
-
- if ( player.s.isTimeTraveling )
- continue
-
- while ( trigger.IsTouching( player ) )
- {
- player.TakeDamage( damageAmt, svGlobal.worldspawn, svGlobal.worldspawn, { origin = player.GetOrigin(), scriptType = scriptTypeMask, damageSourceId = damageID } )
- CreateShakeRumbleOnly( expect entity( player ).GetOrigin(), 10, 105, interval )
- if ( soundDamage != "" )
- EmitSoundOnEntity( player, soundDamage )
- printt( "Player taking damage: " + damageAmt )
- wait interval
- }
- }
- }
-
-}
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function EmitSoundAtPositionHack( int team, vector origin, var sound )
-{
- //Need to delay 0.2 before playing at level start, Baker/Barb know this is a big but said will fix next game
- wait 0.2
- EmitSoundAtPosition( team, origin, sound )
-
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// HACK - need better way to play fx on server
-void function HackPlayLoopEffectOnEntity( asset fxName, entity ent )
-{
- ent.EndSignal( "OnDeath" )
- ent.EndSignal( "OnDestroy" )
- entity fxHandle
- float waitTime
-
-
-
- fxHandle = CreateEntity( "info_particle_system" )
- fxHandle.SetValueForEffectNameKey( fxName )
- fxHandle.kv.VisibilityFlags = ENTITY_VISIBLE_TO_EVERYONE
- fxHandle.kv.start_active = 1
- fxHandle.SetOrigin( ent.GetOrigin() )
- fxHandle.SetAngles( ent.GetAngles() )
- DispatchSpawn( fxHandle )
-
-
- OnThreadEnd(
- function() : ( fxHandle )
- {
- DestroyFxIfValid( fxHandle )
- }
- )
-
-
- WaitForever()
-
-}
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DropHangingOgre( entity titan, entity player )
-{
- thread PlayAnim( titan.s.rack, "tr_AI_titanrack_bootup_heavy" )
- PlayAnimTeleport( titan, "ht_AI_titanrack_bootup_heavy", titan.s.rack )
- wait 0.5
- Embark_Allow( player )
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DropHangingOgreOnFlag( entity titan, string flagToDrop, entity player )
-{
- Assert( IsValid( titan ) )
- FlagWait( flagToDrop )
- thread DropHangingOgre( titan, player )
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function GenericSparks( entity ent )
-{
- vector origin = ent.GetOrigin()
- vector angles = ent.GetAngles()
-
- entity fxHandle
- wait ( RandomFloatRange( 0.1, 2.5 ) )
-
- while( IsValid( ent ) )
- {
- if ( GetBugReproNum() == 007 )
- {
- //fails silently to play fx/sound when it's an info_target
- fxHandle = PlayLoopFXOnEntity( FX_SPARKS, ent )
- EmitSoundOnEntity( ent, SOUND_SPARKS )
- }
- else
- {
- fxHandle = PlayFX( FX_SPARKS, origin, angles )
- EmitSoundAtPosition( TEAM_UNASSIGNED, origin, SOUND_SPARKS )
- }
-
- wait ( RandomFloatRange( 1.7, 5.2 ) )
-
- if ( IsValid( fxHandle ) )
- {
- DestroyFxIfValid( fxHandle )
- }
- wait ( RandomFloatRange( 0.1, 0.4 ) )
- }
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function ZombieSpectreSpawnAndDie( entity npc )
-{
- npc.EndSignal( "OnDeath" )
-
- wait ( RandomFloatRange( 0.2, 1.75 ) )
-
- npc.Die()
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function RackSpawnCallback( entity npc, entity activator )
-{
- string scriptName = npc.GetScriptName()
-
- if ( scriptName == "rusted_spectre" )
- thread ZombieSpectreSpawnAndDie( npc )
-
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DestroyArray( array entities )
-{
- foreach( ent in entities )
- {
- if( IsValid( ent ) )
- ent.Destroy()
- }
-}
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function MoveEntityToOppositeTimePeriod( entity ent )
-{
- int zOffset = TIME_ZOFFSET
- if ( GetEntityTimelinePosition( ent ) == TIMEZONE_DAY )
- zOffset = TIME_ZOFFSET * -1
-
- ent.SetOrigin( ent.GetOrigin() + Vector( 0, 0, TIME_ZOFFSET ) )
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DeleteFireHazards( string scriptName )
-{
-array< entity > fireTriggers = GetEntArrayByScriptName( scriptName )
- entity fxEnt
- foreach( trigger in fireTriggers )
- {
- fxEnt = trigger.GetLinkEnt()
- fxEnt.Destroy()
- trigger.Destroy()
- }
-
-}
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-/*
-void function SpawnWallSpectreGroupWhenInRange( entity player, array< entity > propSpawners, int maxToSpawn, string flagToAbort = "", string flagToSetWhenDone = "", float delayMin = 3, float delayMax = 5, string flagToSet = "", bool requireLookAt = false )
-{
- Assert( propSpawners.len() >= maxToSpawn, "Max to spawn( " + maxToSpawn + ") is greater than number of propSpawners (" + propSpawners.len() + ") " )
- int spectresSpawned = 0
- entity spawner
-
- var spawnerTimezone = GetEntityTimelinePosition( propSpawners[ 0 ] )
-
- while( spectresSpawned < maxToSpawn )
- {
- if ( ( flagToAbort != "") && ( Flag( flagToAbort ) ) )
- break
-
-
- // Don't spawn if player not in the same timezone
- if ( spawnerTimezone != GetEntityTimelinePosition( player ) )
- {
- wait 0.1
- continue
-
- }
-
- spawner = GetBestPropSpawnerFromGroup( propSpawners, player, requireLookAt )
- if ( !IsValid( spawner ) )
- {
- wait 0.1
- continue
- }
-
- spawner.Signal( "PropSpawnerActivate" )
- spectresSpawned++
-
- if ( ( flagToSet != "" ) && ( !Flag( flagToSet ) ) )
- FlagSet( flagToSet )
-
- propSpawners.fastremovebyvalue( spawner )
- if ( ( spectresSpawned == maxToSpawn ) && ( flagToSetWhenDone != "" ) )
- {
- FlagSet( flagToSetWhenDone )
- break
- }
-
- wait( RandomFloatRange( delayMin, delayMax ) )
- }
-}
-*/
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function SpawnShowcaseGroupWhenInRange( entity player, array< entity > propSpawners, int maxToSpawn, string flagToAbort = "", string flagToSetWhenDone = "", float delayMin = 3, float delayMax = 5, string flagToSet = "", bool requireLookAt = false )
-{
- Assert( propSpawners.len() >= maxToSpawn, "Max to spawn( " + maxToSpawn + ") is greater than number of propSpawners (" + propSpawners.len() + ") " )
- int dudesSpawned = 0
- entity spawnProp
-
- var spawnerTimezone = GetEntityTimelinePosition( propSpawners[ 0 ] )
-
- while( dudesSpawned < maxToSpawn )
- {
- if ( ( flagToAbort != "") && ( Flag( flagToAbort ) ) )
- break
-
-
- // Don't spawn if player not in the same timezone
- if ( spawnerTimezone != GetEntityTimelinePosition( player ) )
- {
- wait 0.1
- continue
-
- }
-
- spawnProp = GetBestPropSpawnerFromGroup( propSpawners, player, requireLookAt )
- if ( !IsValid( spawnProp ) )
- {
- wait 0.1
- continue
- }
-
- if ( IsSpectreRackDoorSpawner( spawnProp ) )
- spawnProp.Signal( "PropSpawnerActivate" )
- else
- thread ShowcaseSpawn( spawnProp )
-
- dudesSpawned++
-
- if ( ( flagToSet != "" ) && ( !Flag( flagToSet ) ) )
- FlagSet( flagToSet )
-
- propSpawners.fastremovebyvalue( spawnProp )
- if ( ( dudesSpawned == maxToSpawn ) && ( flagToSetWhenDone != "" ) )
- {
- FlagSet( flagToSetWhenDone )
- break
- }
-
- wait( RandomFloatRange( delayMin, delayMax ) )
- }
-
- if ( FlagExists( flagToSetWhenDone ) )
- FlagSet( flagToSetWhenDone )
-
-}
-
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-entity function GetBestPropSpawnerFromGroup( array< entity > propSpawners, entity player, bool requireLookAt = false )
-{
- entity bestSpawnerProp
-
- array< entity > propSpawnersOrderedClosest = ArrayClosest( propSpawners, player.GetOrigin() )
-
- float minDistSqr = 128 * 128
- bool doTrace = true
- float degrees = 90
-
- foreach( spawnerProp in propSpawnersOrderedClosest )
- {
- if ( DistanceSqr( player.GetOrigin(), spawnerProp.GetOrigin() ) < minDistSqr )
- continue
-
- if ( TS_WithinPlayerFOV( spawnerProp.GetOrigin() + Vector( 0, 0, 16) ) )
- {
- bestSpawnerProp = spawnerProp
- break
- }
- }
-
- if ( ( !IsValid( bestSpawnerProp ) ) && ( requireLookAt == false ) )
- bestSpawnerProp = GetClosest( propSpawners, player.GetOrigin() )
-
- return bestSpawnerProp
-}
-
-//////////////////////////////////////////////////////////////
-// HACK: Move to utility?
-bool function TS_WithinPlayerFOV( targetPos, MinDot = 0.8 )
-{
- expect vector( targetPos )
- entity player = GetPlayerArray()[0]
- if ( !player )
- return false
-
- float dot = VectorDot_PlayerToOrigin( player, targetPos )
- if ( dot < MinDot )
- return false
-
- return true
-}
-//////////////////////////////////////////////////////////////
-void function RemoveBlocker( string scriptName )
-{
- array <entity> blockers = GetEntArrayByScriptName( scriptName )
- Assert( blockers.len() > 0, "No blockers found with scriptName " + scriptName )
- foreach( blocker in blockers )
- {
- blocker.Hide() //Does this even do anything anymore?
- blocker.MakeInvisible()
- blocker.NotSolid()
- }
-
-}
-//////////////////////////////////////////////////////////////
-void function RestoreBlocker( string scriptName )
-{
- array <entity> blockers = GetEntArrayByScriptName( scriptName )
- Assert( blockers.len() > 0, "No blockers found with scriptName " + scriptName )
- foreach( blocker in blockers )
- {
- blocker.Show() //Does this even do anything anymore?
- blocker.MakeVisible()
- blocker.Solid()
- }
-}
-
-//////////////////////////////////////////////////////////////
-void function TempExplosion( vector origin )
-{
- CreateAirShake( origin, 10, 105, 1.25 )
- PlayFX( FX_BREAKABLE_SATCHEL_DEBRIS_MEDIUM, origin )
- EmitSoundAtPosition( TEAM_UNASSIGNED, origin, SOUND_BREAKABLE_SATCHEL_DEBRIS_MEDIUM )
-}
-//////////////////////////////////////////////////////////////
-void function DestroyEntByScriptName( string scriptName )
-{
- entity ent = GetEntByScriptName( scriptName )
- Assert( IsValid( ent ) )
- ent.Destroy()
-
-}
-
-//////////////////////////////////////////////////////////////
-void function DestroyInstancesByScriptInstanceName( string scriptName, string instanceName )
-{
- array< entity > ents = GetEntArrayByScriptNameInInstance( scriptName, instanceName )
- Assert( ents.len() > 0, "No entities with script_name/instance_name combo: " + scriptName + " / " + instanceName )
- foreach( ent in ents )
- ent.Destroy()
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function WaittillSomeDudesAreDead( string scriptName, int numberToWaitToBeDead, string flagToSet = "" )
-{
- array< entity > entities = GetEntArrayByScriptName( scriptName )
- Assert( entities.len() > 0 )
- array< entity > dudes
- foreach( ent in entities )
- {
- if ( ent.IsNPC() )
- dudes.append( ent )
- }
- if ( dudes.len() == 0 )
- {
- printt( "Warning: WaittillSomeDudesAreDead returning. No npcs exist for scriptName " + scriptName )
- return
- }
- Assert( dudes.len() >= numberToWaitToBeDead )
- int dudesThatHaveDied = 0
-
- while( dudesThatHaveDied < numberToWaitToBeDead )
- {
- wait 0.1
- foreach( dude in dudes )
- {
- if ( !IsAlive( dude ) )
- {
- dudesThatHaveDied++
- dudes.fastremovebyvalue( dude )
- }
- }
- }
-
- if ( flagToSet != "" )
- FlagSet( flagToSet )
-
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function WaittillPlayerSwitchesTimezone( var timeZoneToWaitFor )
-{
-
- if ( level.timeZone == timeZoneToWaitFor )
- return
-
- while( level.timeZone != timeZoneToWaitFor )
- wait 0.1
-
- wait 0.1
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function TimeshiftPlayerThink( entity player )
-{
- player.EndSignal( "OnDeath" )
-
- vector posInOtherTimeline
- vector playerOrigin
- var timeZoneCurrent
- float minDist = 32
- float minDistSqr = minDist * minDist
- vector idealPosInOvergrown
- vector idealPosInPristine
-
- wait 0.1
-
- while( true )
- {
- WaitFrame()
-
- playerOrigin = player.GetOrigin()
- timeZoneCurrent = GetTimelinePosition( playerOrigin )
- if ( timeZoneCurrent == TIMEZONE_FROZEN )
- return
-
- posInOtherTimeline = GetPosInOtherTimeline( playerOrigin )
-
- if ( timeZoneCurrent == TIMEZONE_NIGHT )
- {
- idealPosInOvergrown = playerOrigin
- idealPosInPristine = posInOtherTimeline
- }
- else if ( timeZoneCurrent == TIMEZONE_DAY )
- {
- idealPosInOvergrown = posInOtherTimeline
- idealPosInPristine = playerOrigin
- }
- else
- printl( "Player in frozen world, no need to run the TimeshiftPlayerThinkThread anymore" )
-
- //-------------------------------------------------------------
- // get last good pos in current timeline (player's pos, usually)
- //-------------------------------------------------------------
- if ( !PlayerPosInSolid( player, playerOrigin ) )
- {
- if ( timeZoneCurrent == TIMEZONE_NIGHT )
- //file.lastGoodTimeshiftPosOvergrown = playerOrigin
- player.s.lastGoodTimeshiftPosOvergrown = playerOrigin
- else if ( timeZoneCurrent == TIMEZONE_DAY )
- //file.lastGoodTimeshiftPosPristine = playerOrigin
- player.s.lastGoodTimeshiftPosPristine = playerOrigin
- else
- printl( "Player in frozen world, no need to run the TimeshiftPlayerThinkThread anymore" )
- }
- else
- {
- if ( GetBugReproNum() == 88 )
- printt( "Player is stuck in solid in home timeline: " + playerOrigin )
- }
-
- //--------------------------------------
- // get last good pos in other timeline
- //--------------------------------------
- if ( !PlayerPosInSolid( player, posInOtherTimeline ) )
- {
- if ( timeZoneCurrent == TIMEZONE_NIGHT )
- {
- //file.lastGoodTimeshiftPosPristine = posInOtherTimeline
- player.s.lastGoodTimeshiftPosPristine = posInOtherTimeline
-
- }
- else if ( timeZoneCurrent == TIMEZONE_DAY )
- {
- //file.lastGoodTimeshiftPosOvergrown = posInOtherTimeline
- player.s.lastGoodTimeshiftPosOvergrown = posInOtherTimeline
- }
- else
- printl( "Player in frozen world, no need to run the TimeshiftPlayerThinkThread anymore" )
- }
- else
- {
- if ( GetBugReproNum() == 88 )
- {
- printt( "******WARNING: player would be in solid in other timeline: " + posInOtherTimeline )
- thread DebugDrawBadCollisionBox( posInOtherTimeline )
- }
-
-
- }
-
- //-------------------------------------------
- // Assert if vectors are in the wrong timeline
- //-------------------------------------------
- //Assert ( GetTimelinePosition( file.lastGoodTimeshiftPosPristine ) == TIMEZONE_DAY, "lastGoodTimeshiftPosPristine ( " + file.lastGoodTimeshiftPosPristine + " ) is not in the proper timeZone" )
- //Assert ( GetTimelinePosition( file.lastGoodTimeshiftPosOvergrown ) == TIMEZONE_NIGHT, "lastGoodTimeshiftPosPristine ( " + file.lastGoodTimeshiftPosPristine + " ) is not in the proper timeZone" )
- Assert ( GetTimelinePosition( player.s.lastGoodTimeshiftPosPristine ) == TIMEZONE_DAY, "lastGoodTimeshiftPosPristine ( " + player.s.lastGoodTimeshiftPosPristine + " ) is not in the proper timeZone" )
- Assert ( GetTimelinePosition( player.s.lastGoodTimeshiftPosOvergrown ) == TIMEZONE_NIGHT, "lastGoodTimeshiftPosPristine ( " + player.s.lastGoodTimeshiftPosPristine + " ) is not in the proper timeZone" )
-
- //---------------------------------------------------------------
- // Check if disparity between ideal pos and proposed is too huge
- //----------------------------------------------------------------
- //if ( ( DistanceSqr( file.lastGoodTimeshiftPosOvergrown, idealPosInOvergrown ) > minDistSqr ) && ( GetBugReproNum() == 88 ) )
- if ( ( DistanceSqr( player.s.lastGoodTimeshiftPosOvergrown, idealPosInOvergrown ) > minDistSqr ) && ( GetBugReproNum() == 88 ) )
- {
- printl( "*****************WARNING:")
- //printt( "lastGoodTimeshiftPosOvergrown( " + file.lastGoodTimeshiftPosOvergrown + " > " + minDist + " from ( " + idealPosInOvergrown + ")" )
- printt( "lastGoodTimeshiftPosOvergrown( " + player.s.lastGoodTimeshiftPosOvergrown + " > " + minDist + " from ( " + idealPosInOvergrown + ")" )
- //thread DebugDrawBadTeleportBoxes( file.lastGoodTimeshiftPosOvergrown, idealPosInOvergrown )
- var pos = player.s.lastGoodTimeshiftPosOvergrown
- thread DebugDrawBadTeleportBoxes( expect vector( pos ), idealPosInOvergrown )
- }
- //if ( ( DistanceSqr( file.lastGoodTimeshiftPosPristine, idealPosInPristine ) > minDistSqr ) && ( GetBugReproNum() == 88 ) )
- if ( ( DistanceSqr( player.s.lastGoodTimeshiftPosPristine, idealPosInPristine ) > minDistSqr ) && ( GetBugReproNum() == 88 ) )
- {
- printl( "*****************WARNING:")
- //printt( "lastGoodTimeshiftPosPristine( " + file.lastGoodTimeshiftPosPristine + " > " + minDist + " from ( " + idealPosInPristine + ")" )
- printt( "lastGoodTimeshiftPosPristine( " + player.s.lastGoodTimeshiftPosPristine + " > " + minDist + " from ( " + idealPosInPristine + ")" )
- //thread DebugDrawBadTeleportBoxes( file.lastGoodTimeshiftPosPristine, idealPosInPristine )
- var pos = player.s.lastGoodTimeshiftPosPristine
- thread DebugDrawBadTeleportBoxes( expect vector( pos ), idealPosInPristine )
- }
- //Assert( DistanceSqr( file.lastGoodTimeshiftPosOvergrown, idealPosInOvergrown ) < minDistSqr, "lastGoodTimeshiftPosOvergrown( " + file.lastGoodTimeshiftPosOvergrown + " > " + minDist + " from ( " + idealPosInOvergrown + ")" )
- //Assert( DistanceSqr( file.lastGoodTimeshiftPosPristine, idealPosInPristine ) < minDistSqr, "lastGoodTimeshiftPosPristine( " + file.lastGoodTimeshiftPosPristine + " > " + minDist + " from ( " + idealPosInPristine + ")" )
-
- }
-}
-
-
-void function DebugDrawBadTeleportBoxes( vector badPos, vector goodPos )
-{
-
- vector boxSize1 = Vector(-16,-16,0)
- vector boxSize2 = Vector(16,16,72)
- vector zOffset = Vector( 0, 0, 36)
-
- while( true )
- {
- wait 0.15
- //r, g, b, a, drwTime
- DebugDrawBox( badPos, boxSize1, boxSize2, 255, 0, 0, 1, 0.15 )
- DebugDrawBox( goodPos, boxSize1, boxSize2, 0, 255, 0, 1, 0.15 )
- DebugDrawLine( badPos + zOffset, goodPos + zOffset, 255, 0, 0, true, 0.15 )
- DebugDrawText( badPos + zOffset, "Bad TimeTravel Teleports", true, 0.15 )
- }
-
-}
-
-
-void function DebugDrawAudioLogNumber( entity audioLogModel, string number )
-{
- audioLogModel.Signal( "AudioLogDebugDraw" )
- audioLogModel.EndSignal( "AudioLogDebugDraw" )
-
- vector pos = audioLogModel.GetOrigin()
- while( true )
- {
- wait 0.15
- DebugDrawText( pos, number, true, 0.15 )
- }
-
-
-}
-void function DebugDrawBadCollisionBox( vector badPos )
-{
-
- vector boxSize1 = Vector(-16,-16,0)
- vector boxSize2 = Vector(16,16,72)
- vector zOffset = Vector( 0, 0, 36)
-
- while( true )
- {
- wait 0.15
- //r, g, b, a, drwTime
- DebugDrawBox( badPos, boxSize1, boxSize2, 255, 255, 0, 1, 0.15 )
- DebugDrawText( badPos + zOffset, "Timeshift into solid", true, 0.15 )
- }
-
-}
-
-
-//////////////////////////////////////////////////////////////////////////////////////
-void function OnPlayerDamage_TimeShift( entity player, var damageInfo )
-{
- if ( level.allowTimeTravel == false )
- return
-
- int damageSourceID = DamageInfo_GetDamageSourceIdentifier( damageInfo )
- entity attacker = DamageInfo_GetAttacker( damageInfo )
- local damageAmount = DamageInfo_GetDamage( damageInfo )
-
- if ( !IsValid( attacker ) )
- return
-
- if ( !attacker.IsNPC() )
- return
-
- int playerHealth = player.GetHealth()
- int playerMaxHealth = player.GetMaxHealth()
-
- if ( !Flag( "DisplayTheDamageHint" ) )
- return
-
- //if ( playerHealth > ( playerMaxHealth - 50 ) )
- //return
-
- //Show damage hint if we are at 60% or lower
- printt( "Player health: ", playerHealth / playerMaxHealth.tofloat() )
- if ( playerHealth / playerMaxHealth.tofloat() <= 0.90 )
- thread DamageHintTillTimetravel( player )
-
-}
-
-//////////////////////////////////////////////////////////////////////////////////////
-function DamageHintTillTimetravel( entity player )
-{
-
- if ( file.isDisplayingDamageText )
- return
-
- file.isDisplayingDamageText = true
- file.isDisplayingTimeshiftHint = true
-
- player.EndSignal( "OnDeath" )
- player.Signal( "DisplayingDamageHint" )
- player.EndSignal( "DisplayingDamageHint" )
- EndSignal( player, "OnTimeFlippedTimezoneNight" )
- EndSignal( player, "OnTimeFlippedTimezoneDay" )
-
- OnThreadEnd(
- function() : ( player )
- {
- ClearOnscreenHint( player )
- file.isDisplayingDamageText = false
- file.isDisplayingTimeshiftHint = false
- }
- )
-
- thread DisplayOnscreenHint( player, "timeshift_hint_combat", 3.0 )
- wait 3
-
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-/*
-void function TriggerTimehintThink( entity trigger )
-{
- wait 1
-
- trigger.EndSignal( "OnDestroy" )
- string flagToAbort = trigger.GetTargetName()
- Assert( IsValid( flagToAbort ) )
- if ( Flag( flagToAbort ) )
- return
- FlagEnd( flagToAbort )
-
- var timeZoneToShowHint = GetEntityTimelinePosition( trigger )
-
-
- local result
- entity player
-
- while( true )
- {
- result = trigger.WaitSignal( "OnTrigger" )
-
- if ( !IsValid( result.activator ) )
- continue
- if ( !result.activator.IsPlayer() )
- continue
- if ( result.activator.IsTitan() )
- continue
-
- player = expect entity( result.activator )
-
- break
- }
-
- thread TimeshiftHint( player, timeZoneToShowHint, flagToAbort, "#BLANK_TEXT", trigger )
-
-}
-*/
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function TimeshiftHint( entity player, var timeZoneToShowHint, string flagToAbort, string message, entity trigger = null )
-{
- player.EndSignal( "OnDeath" )
- if( !IsValid( player ) )
- return
-
- if ( IsValid( trigger ) )
- trigger.EndSignal( "OnDestroy")
-
- Assert( FlagExists( flagToAbort ) )
- if ( Flag( flagToAbort ) )
- return
- FlagEnd( flagToAbort )
-
- //--------------------------------
- // Display in any timezone?
- //--------------------------------
- bool hintIsTimezoneSpecific = true
- if ( timeZoneToShowHint == TIMEZONE_ALL )
- hintIsTimezoneSpecific = false
-
- //--------------------------------`
- // Custom hint message or default?
- //--------------------------------
- string hintMessage
- if ( message != "" )
- hintMessage = message
- else
- {
- if ( timeZoneToShowHint == TIMEZONE_DAY )
- hintMessage = "timeshift_hint_present"
- else if ( timeZoneToShowHint == TIMEZONE_NIGHT )
- hintMessage = "timeshift_hint_past"
- else if ( timeZoneToShowHint == TIMEZONE_ALL )
- hintMessage = "timeshift_hint_default"
- }
-
- //-----------
- // Cleanup
- //-----------
- /*
- OnThreadEnd(
- function() : ( trigger )
- {
- ClearOnscreenHint( player )
- if ( IsValid( trigger ) )
- trigger.Destroy()
- }
- )
- */
-
- //----------------------------
- // Hint message display logic
- //----------------------------
-
- var hintTimezone = GetOppositeTimeline( timeZoneToShowHint )
-
- bool isDisplayingMsg = false
- file.isDisplayingTimeshiftHint = false
-
- float ticker = 0.0
- float displayTime = 5.0
- float increment = 0.25
-
- //---------------------------------------------
- // Don't be condescending, before displaying
- //------------------------------------------------
- wait 2
-
- while( true )
- {
- wait increment
-
- //----------------------------------------------------
- // No message if player not touching (optional) trigger
- //----------------------------------------------------
- if ( IsValid( trigger ) )
- {
- if ( !trigger.IsTouching( player ) )
- {
- ClearOnscreenHint( player )
- continue
- }
-
- }
-
- //----------------------------------------------------
- // No message if player has swapped to correct timeline
- //----------------------------------------------------
- if ( ( GetEntityTimelinePosition( player ) != timeZoneToShowHint ) && ( hintIsTimezoneSpecific ) )
- {
- ClearOnscreenHint( player )
- continue
- }
-
- //----------------------------------------------------
- // Clear msg and wait if we've displayed it long enough
- //----------------------------------------------------
- if ( ticker >= displayTime )
- {
- ClearOnscreenHint( player )
- isDisplayingMsg = false
- file.isDisplayingTimeshiftHint = false
- wait 5
- }
-
- //----------------------------------------------------
- // Increment ticker if we are already displaying message
- //----------------------------------------------------
- if ( isDisplayingMsg )
- {
- ticker = ticker + increment
- continue
- }
- //------------------------------------
- // Display the hint, reset the ticker
- //------------------------------------
- else
- {
- ticker = 0.0
- DisplayOnscreenHint( player, hintMessage, displayTime )
- isDisplayingMsg = true
- file.isDisplayingTimeshiftHint = true
- }
-
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-function HACK_DisableTurret( turret, shield = false )
-{
- //turret.EndSignal( "OnDestroy" )
-
-
- turret.EnableNPCFlag( NPC_IGNORE_ALL )
- turret.SetNoTarget( true )
- //turret.EnableNPCFlag( NPC_DISABLE_SENSING )
- turret.Anim_ScriptedPlay( "undeploy" )
- wait 1.0
- turret.DisableTurret()
- turret.UnsetUsable()
- turret.SetTitle( "" )
-
- if ( !shield )
- turret.Signal( "TurretShieldWallRelease" )
- //turret.Anim_Stop()
-}
-
-function HACK_EnableTurret( turret )
-{
- //turret.EndSignal( "OnDestroy" )
-
- turret.Anim_ScriptedPlay( "deploy" )
- wait 1.0
- turret.EnableTurret()
- turret.kv.AccuracyMultiplier = 100
-
- //wait 1.0
- //turret.Anim_Stop()
- turret.DisableNPCFlag( NPC_IGNORE_ALL )
- turret.SetNoTarget( false )
- //turret.DisableNPCFlag( NPC_DISABLE_SENSING )
-}
-
-void function OnSpawnedScriptedSwitch( entity button )
-{
- array< entity > linkedEnts = button.GetLinkEntArray()
- array< entity > turrets
-
- foreach( entity ent in linkedEnts )
- {
- if ( ent.GetClassName() == "npc_turret_sentry")
- turrets.append( ent )
- }
-
- if ( turrets.len() > 0 )
- thread TurretButtonThink( button, turrets )
-}
-//////////////////////////////////////////////////////////////////////////////////////////
-void function TurretButtonThink( entity button, array< entity > turrets )
-{
-
- foreach( turret in turrets )
- thread HACK_DisableTurret( turret )
-
- var player //hack: have to use "var" when waiting on a usable signal or trigger
-
- string flagRequired = expect string( button.kv.scr_flagRequired )
- if ( flagRequired != "" )
- FlagWait( flagRequired )
-
- button.SetUsePrompts( "#TIMESHIFT_HINT_TURRET_USE" , "#TIMESHIFT_HINT_TURRET_USE" )
-
- while( true )
- {
- button.WaitSignal( "OnActivate" )
- break
- }
-
- if ( !Flag( "AtLeastOneBunkerTurretRestored" ) )
- FlagSet( "AtLeastOneBunkerTurretRestored" )
-
-
- string scriptName = button.GetScriptName()
- if ( ( IsValid( scriptName ) ) && ( scriptName == "button_bunker_turrets_fence" ) )
- FlagSet( "TurretsNearBunkerFenceActivated" )
-
- foreach( turret in turrets )
- {
- thread HACK_EnableTurret( turret )
- }
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-entity function GetNpcByScriptName( string scriptName )
-{
-
- array< entity > ents = GetEntArrayByScriptName( scriptName )
- array< entity > npcs
- foreach( ent in ents )
- {
- if ( ent.IsNPC() )
- npcs.append( ent )
- }
-
- Assert( npcs.len() > 0, "No NPCs found with script name: " + scriptName )
- Assert( npcs.len() < 2, "Multiple NPCs ( " + npcs.len() + " ) found with scriptName: " + scriptName )
-
- return npcs[ 0 ]
-}
-
-
-entity function CreateLoudspeakerEnt( vector origin )
-{
- entity loudspeakerEnt = CreateEntity( "info_target" )
- loudspeakerEnt.kv.spawnflags = SF_INFOTARGET_ALWAYS_TRANSMIT_TO_CLIENT
- DispatchSpawn( loudspeakerEnt )
- loudspeakerEnt.SetOrigin( origin )
-
- return loudspeakerEnt
-}
-
-/*
-void function BatteryMoveSounds( entity leftBattery, entity rightBattery )
-{
- entity soundEnt = leftBattery
- EmitSoundOnEntity( soundEnt, "timeshift_battery_conduit_stop" )
- EmitSoundOnEntity( soundEnt, "timeshift_battery_conduit_move_loop" )
- wait 1.5
- StopSoundOnEntity( soundEnt, "timeshift_battery_conduit_move_loop" )
- soundEnt = rightBattery
- EmitSoundOnEntity( soundEnt, "timeshift_battery_conduit_stop" )
-}
-*/
-
-
-/*
-void function BrokenBatteryMoveSounds( entity leftBattery )
-{
- FlagEnd( "bunker_move_battery" )
-
- entity soundEnt = leftBattery
-
- while( !Flag( "bunker_move_battery" ) )
- {
-
-
- OnThreadEnd(
- function() : ( soundEnt )
- {
- StopSoundOnEntity( soundEnt, "timeshift_battery_conduit_move_loop" )
- }
- )
-
- FlagWait( "broken_battery_moved_to_node0" )
- StopSoundOnEntity( soundEnt, "timeshift_battery_conduit_move_loop" )
- EmitSoundOnEntity( soundEnt, "timeshift_battery_conduit_stop" )
- wait 1
- EmitSoundOnEntity( soundEnt, "timeshift_battery_conduit_move_loop" )
-
- FlagWait( "broken_battery_moved_to_node1" )
- EmitSoundOnEntity( soundEnt, "timeshift_battery_conduit_stop" )
-
- FlagWait( "broken_battery_moved_to_node2" )
- EmitSoundOnEntity( soundEnt, "timeshift_battery_conduit_stop" )
- StopSoundOnEntity( soundEnt, "timeshift_battery_conduit_move_loop" )
- wait 0.75
-
- EmitSoundOnEntity( soundEnt, "timeshift_battery_conduit_move_loop" )
- FlagWait( "broken_battery_moved_to_node3" )
- EmitSoundOnEntity( soundEnt, "timeshift_battery_conduit_stop" )
- StopSoundOnEntity( soundEnt, "timeshift_battery_conduit_move_loop" )
- wait 0.75
-
- EmitSoundOnEntity( soundEnt, "timeshift_battery_conduit_move_loop" )
-
- }
-}
-
-*/
-
-
-/*
-
-void function FuelPanelSounds( vector origin, string flagToStart, string flagToStop )
-{
- FlagWait( flagToStart )
- EmitSoundAtPosition( TEAM_UNASSIGNED, origin, "door_stop" )
-
-
- EmitSoundAtPosition( TEAM_UNASSIGNED, origin, "door_open_loop" )
-
- FlagWait( flagToStop )
- StopSoundAtPosition( origin, "door_open_loop")
- EmitSoundAtPosition( TEAM_UNASSIGNED, origin, "door_stop" )
-}
-
-*/
-
-
-void function DestroyIfValid( string scriptName )
-{
- array< entity > ents = GetEntArrayByScriptName( scriptName )
- foreach( ent in ents )
- {
- if ( IsValid( ent ) )
- ent.Destroy()
- }
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-function SkyboxStart()
-{
- wait 1.5
- local skyCam = GetEnt( "skybox_cam_night" )
- foreach ( player in GetPlayerArray() )
- {
- player.SetSkyCamera( skyCam )
- }
-}
-
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-void function SleepingSpectreFX( entity spectreModel, string signalToAbort )
-{
- spectreModel.EndSignal( "OnDestroy" )
- spectreModel.EndSignal( signalToAbort )
-
- entity fxEyeSparksLeft
- entity fxEyeSparksRight
-
- array< entity > fxArray
- fxArray.append( fxEyeSparksLeft )
- fxArray.append( fxEyeSparksRight )
-
- //fxFullBodyEffect = PlayFXOnEntity( <whatever>, spectreModel, "TAG" )
-
- while( true )
- {
-
- OnThreadEnd(
- function() : ( fxArray )
- {
- foreach( fx in fxArray )
- DestroyFxIfValid( fx )
- }
- )
-
-// ModelFX_EnableGroup( spectreModel, "friend_lights" )
-
- wait( RandomFloatRange( 2, 3.75 ) )
-
-// ModelFX_DisableGroup( spectreModel, "friend_lights" )
-
- fxEyeSparksLeft = PlayFXOnEntity( FX_SPARKS, spectreModel, "vent_left_out" )
- fxEyeSparksRight = PlayFXOnEntity( FX_SPARKS, spectreModel, "vent_right_out" )
- EmitSoundOnEntity( spectreModel, SOUND_SPARKS )
- wait( RandomFloatRange( 0.2, 0.25 ) )
- fxEyeSparksLeft.Fire( "Stop" )
- fxEyeSparksLeft.Fire( "DestroyImmediately" )
- fxEyeSparksLeft.Destroy()
- fxEyeSparksRight.Fire( "Stop" )
- fxEyeSparksRight.Fire( "DestroyImmediately" )
- fxEyeSparksRight.Destroy()
-
-
- fxEyeSparksLeft = PlayFXOnEntity( FX_SPARKS, spectreModel, "vent_left_out" )
- fxEyeSparksRight = PlayFXOnEntity( FX_SPARKS, spectreModel, "vent_right_out" )
- EmitSoundOnEntity( spectreModel, SOUND_SPARKS )
- wait( RandomFloatRange( 0.3, 0.5 ) )
- fxEyeSparksLeft.Fire( "Stop" )
- fxEyeSparksLeft.Fire( "DestroyImmediately" )
- fxEyeSparksLeft.Destroy()
- fxEyeSparksRight.Fire( "Stop" )
- fxEyeSparksRight.Fire( "DestroyImmediately" )
- fxEyeSparksRight.Destroy()
-
- wait( RandomFloatRange( 0.1, 0.25 ) )
-
-
- }
-}
-
-///////////////////////////////////////////////////////////////
-void function CleanupEnts( string scriptName )
-{
- array<entity> entArray = GetEntArrayByScriptName( scriptName )
- foreach( ent in entArray )
- {
- if( IsValid( ent ) )
- ent.Destroy()
- }
-
-}
-
-///////////////////////////////////////////////////////////////
-void function CleanupAI( entity player, string triggerScriptName = "", immediate = false )
-{
- if ( !IsValid( player ) )
- return
-
- array<entity> npcArray = GetNPCArray()
-
- if ( npcArray.len() == 0 )
- return
-
- //--------------------------------------------------
- // Optional trigger to specify which npcs to select
- //--------------------------------------------------
- if ( triggerScriptName != "" )
- {
-
- entity trigger = GetEntByScriptName( triggerScriptName )
- vector triggerMins = trigger.GetBoundingMins()
- vector triggerMaxs = trigger.GetBoundingMaxs()
- bool entIsInsideTrigger
-
- for ( int i = npcArray.len() - 1; i >= 0; i-- ) //loop backward through array since we are removing entries
- {
-
-
- //HACK: Titans and marvins aren't registering IsTouching
- if ( ( triggerScriptName == "trigger_ai_pristine" ) && ( GetEntityTimelinePosition( npcArray[ i ] ) == TIMEZONE_DAY ) )
- {
- if ( !trigger.IsTouching( npcArray[ i ] ) )
- {
- printl( "Ent " + ( npcArray[ i ] ).GetClassName() + " at " + npcArray[ i ].GetOrigin() + " is within trigger " + triggerScriptName + " but IsTouching returns false" )
- continue
- }
- }
-
- if ( !trigger.IsTouching( npcArray[ i ] ) )
- {
- //Remove the npc
- npcArray.fastremove( i )
- }
- }
- }
-
-
- if ( npcArray.len() == 0 )
- return
-
- if ( immediate )
- {
- foreach( npc in npcArray )
- {
- if ( ( IsAlive( npc ) ) && ( npc.GetTeam() != TEAM_MILITIA ) )
- npc.Destroy()
- }
-
- return
- }
-
- //--------------------------------------------------
- // Delete all NPCs when out of sight
- //--------------------------------------------------
- while ( npcArray.len() > 0 )
- {
- ArrayRemoveDead( npcArray )
- for ( int i = npcArray.len() - 1; i >= 0; i-- ) //loop backward through array since we are removing entries
- {
- if ( npcArray[ i ].GetTeam() != TEAM_IMC )
- {
- npcArray.fastremove( i )
- continue
- }
- thread DeleteNpcWhenOutOfSight( npcArray[ i ], player )
- npcArray.fastremove( i )
- }
- wait 0.1
- }
-}
-
-///////////////////////////////////////////////////////////////
-void function DeleteNpcWhenOutOfSight( entity npc, entity player )
-{
- if ( !IsValid( npc ) )
- return
-
- if ( !IsValid( player ) )
- return
-
- if ( !npc.IsNPC() )
- return
-
- npc.EndSignal( "OnDestroy" )
- player.EndSignal( "OnDeath" )
-
- //don't run this func twice on the same npc)
- if ( npc.l.npcMarkedForCleanup == true )
- return
-
- npc.l.npcMarkedForCleanup = true
-
- float minDistSqr = 1024 * 1024
- bool doTrace = true
- float degrees = 90
-
- while( IsAlive( npc ) )
- {
- WaitFrame()
-
- if ( DistanceSqr( player.GetOrigin(), npc.GetOrigin() ) < minDistSqr )
- continue
-
- if ( PlayerCanSee( player, npc, doTrace, degrees ) )
- continue
-
- npc.Destroy()
- break
- }
-
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*
-void function TimeFlux( entity player, string triggerNameToDoFlux, string flagToAbort = "", int maxSwaps = -1, float minFluxTime = 0.75, maxFluxTime = 2 )
-{
- if ( !IsValid( player ) )
- return
- if ( ( flagToAbort != "" ) && ( Flag( flagToAbort ) ) )
- return
-
- entity triggerToDoFluxIn = GetEntByScriptName( triggerNameToDoFlux )
- entity lookTarget = triggerToDoFluxIn.GetLinkEnt()
- var homeTimeZone = GetEntityTimelinePosition( triggerToDoFluxIn )
- var destTimeZone = GetOppositeTimeline( homeTimeZone )
- float fluxTime
- int swapCount = 0
-
- float fadeTime = 0.3
- float holdFadeTime = 0
-
-
- player.EndSignal( "OnDeath" )
-
- if ( flagToAbort != "" )
- FlagEnd( flagToAbort )
-
-
- OnThreadEnd(
- function() : ( player, homeTimeZone )
- {
- if ( !IsValid( player ) )
- return
- if ( GetEntityTimelinePosition( player ) != homeTimeZone )
- thread SwapTimelinesScripted( player, homeTimeZone )
- }
- )
-
-
-
- while( true )
- {
- wait RandomFloatRange( 0.2, 0.5 )
-
- //--------------------------------------------------
- // Player in home timezone with all requirements met
- //--------------------------------------------------
- if ( ( GetEntityTimelinePosition( player ) == homeTimeZone ) && ( TS_WithinPlayerFOV( lookTarget.GetOrigin(), 0.7 ) ) && ( triggerToDoFluxIn.IsTouching( player ) ) )
- {
- thread SwapTimelinesScripted( player, destTimeZone )
- fluxTime = RandomFloatRange( minFluxTime, maxFluxTime )
- wait fluxTime
-
- }
-
- //--------------------------------------------------
- // Player in dest timezone...swap back to home timezone
- //--------------------------------------------------
- if ( GetEntityTimelinePosition( player ) == destTimeZone )
- {
- thread SwapTimelinesScripted( player, homeTimeZone )
- fluxTime = RandomFloatRange( minFluxTime, maxFluxTime )
- wait fluxTime
- swapCount++
- }
-
- //---------------------------------------
- // Early out if we've done enough swaps
- //----------------------------------------
- if ( ( maxSwaps != -1 ) && ( swapCount >= maxSwaps ) )
- break
-
- }
-
-}
-
-*/
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////
-void function SwapTimelinesScripted( entity player, var timeZone )
-{
- Remote_CallFunction_NonReplay( player, "ServerCallback_ScriptedTimeshiftStart", timeZone )
-
- //-------------------
- // crescendo sound
- //-------------------
- if ( timeZone == TIMEZONE_DAY )
- EmitSoundOnEntity( player, "Timeshift_Scr_InvoluntaryShift2Past_Start" )
- else
- EmitSoundOnEntity( player, "Timeshift_Scr_InvoluntaryShift2Present_Start" )
-
- wait 0.55
- //-------------------
- // Scripted timeshift FX
- //-------------------
-
- //Mostly done on the client
-
- wait 0.8
- //( amplitude frequency duration
- CreateAirShake( player.GetOrigin(), 10, 50, 1.4, 20000 )
- wait 0.4
-
- //-------------------
- // Swap timelines
- //-------------------
- SwapTimelines( player, timeZone )
-
-
- //phaseshift_postfx_forceOn 1
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
-
-
-/*
-void function MakeSpectreOwnedByPlayer( entity spectre, entity player )
-{
- spectre.EnableNPCFlag( NPC_IGNORE_ALL )
- spectre.SetNoTarget( true )
- //spectre.SetOwner( player )
- //spectre.SetOwnerPlayer( player )
- //spectre.SetBossPlayer( player )
- SetTeam( spectre, TEAM_MILITIA )
-
- spectre.SetTitle( "" )
- SetTargetName( spectre, "" )
-
-
- int followBehavior = GetDefaultNPCFollowBehavior( spectre )
- spectre.InitFollowBehavior( player, followBehavior )
- spectre.DisableBehavior( "Assault" )
- spectre.DisableNPCFlag( NPC_ALLOW_PATROL | NPC_ALLOW_INVESTIGATE | NPC_USE_SHOOTING_COVER )
- spectre.EnableBehavior( "Follow" )
-
-}
-*/
-
-/////////////////////////////////////////////////////////////////////////////////////////
-entity function CreateBestLoudspeakerEnt( entity player, var timeZone, entity existingEnt = null )
-{
- entity soundEnt = existingEnt
- if ( existingEnt == null)
- soundEnt = CreateLoudspeakerEnt( player.GetOrigin() + Vector( 0, 0, 100 ) )
- if ( GetEntityTimelinePosition( soundEnt ) != timeZone )
- soundEnt.SetOrigin( GetPosInOtherTimeline( soundEnt.GetOrigin() ) )
-
- //randomize position
- vector baseOrigin = soundEnt.GetOrigin()
- soundEnt.SetOrigin( baseOrigin + Vector( RandomIntRange( 0, 150 ), RandomIntRange( 0, 150 ), 0 ) )
-
- return soundEnt
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function HideWeaponsAndAmmoTillFlag( string scriptName, string flagToRestore )
-{
- array <entity> weapons = GetWeaponArray( true )
- foreach ( weapon in weapons )
- {
- if ( ( weapon.HasKey( "script_name" ) ) && ( weapon.kv.script_name == scriptName ) )
- {
- weapon.Hide()
- weapon.MakeInvisible()
- weapon.UnsetUsable()
- thread ShowEntityOnFlag( weapon, flagToRestore )
- }
-
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-/*
-void function DeleteWaponsWithScriptname( string scriptName )
-{
- array <entity> weapons = GetWeaponArray( true )
- foreach ( weapon in weapons )
- {
- if ( ( weapon.HasKey( "script_name" ) ) && ( weapon.kv.script_name == scriptName ) )
- weapon.Destroy()
-
- }
-}
-*/
-/////////////////////////////////////////////////////////////////////////////////////
-void function ShowEntityOnFlag( entity weapon, string flagToRestore )
-{
- FlagWait( flagToRestore )
- weapon.Show()
- weapon.MakeVisible()
- weapon.SetUsable()
-}
-
-/////////////////////////////////////////////////////////////////////////////////////
-void function SetFlagWhenPlayerLookingAtEnt( entity player, string flagToSet, entity ent, entity trigger = null )
-{
- if ( Flag( flagToSet ) )
- return
- FlagEnd( flagToSet )
-
- //WaitTillLookingAt( entity player, entity ent, bool doTrace, float degrees, float minDist = 0, float timeOut = 0, entity trigger = null )
- waitthread WaitTillLookingAt( player, ent, true, 45, 0, 0 )
- FlagSet( flagToSet )
-}
-
-
-void function DoorOutOfOrderThink( entity propDynamic )
-{
- thread PlayAnim( propDynamic, "stutter01", propDynamic.GetOrigin(), propDynamic.GetAngles() )
-}
-
-
-
-entity function TSCreateScriptMoverLight( entity owner = null, origin = null, angles = null, solidType = 0 )
-{
- if ( owner == null )
- {
- entity script_mover = CreateEntity( "script_mover_lightweight" )
- script_mover.kv.solid = solidType
- script_mover.SetValueForModelKey( $"models/dev/empty_model.mdl" )
- script_mover.kv.SpawnAsPhysicsMover = 0
- if ( origin )
- script_mover.SetOrigin( origin)
- if ( angles )
- script_mover.SetAngles( angles )
-
- DispatchSpawn( script_mover )
- return script_mover
- }
-
- entity script_mover = CreateEntity( "script_mover_lightweight" )
- script_mover.kv.solid = solidType
- script_mover.SetValueForModelKey( $"models/dev/empty_model.mdl" )
- script_mover.kv.SpawnAsPhysicsMover = 0
- script_mover.SetOrigin( owner.GetOrigin() )
- script_mover.SetAngles( owner.GetAngles() )
- DispatchSpawn( script_mover )
- script_mover.Hide()
-
- script_mover.SetOwner( owner )
- return script_mover
-}
-
-void function GiveLowAmmo( entity player )
-{
- //give player one clip of ammo
- int clipBulletCapacity
- int currentAmmo
-
- entity weapon = player.GetMainWeapons()[ 0 ]
- clipBulletCapacity = player.GetWeaponAmmoMaxLoaded( weapon )
- currentAmmo = player.GetActiveWeaponPrimaryAmmoLoaded()
-
- //hack - just refill the current clips if ammo is picked up
- weapon.SetWeaponPrimaryClipCount( clipBulletCapacity )
- player.SetActiveWeaponPrimaryAmmoTotal( 1 )
-}
-
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////
-void function CivilianSkitThink( entity civilian, entity player, string flagToReact = "" )
-{
- /*
- //---------------------------------------------
- // Does civilian have props or escape nodes?
- //---------------------------------------------
- array< entity > linkedEnts = civilian.GetLinkEntArray()
- string classname
- entity escapeOrg
- entity animProp
- foreach( entity ent in linkedEnts )
- {
- classname = ent.GetClassName()
- if ( classname == "prop_dynamic" )
- animProp = ent
- if ( classname == "info_move_target" )
- escapeOrg = ent
- }
-
- */
-
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function CivilianWalkerThink( entity civilian )
-{
- if ( !civilian.HasKey( "script_noteworthy" ) )
- return
-
- string walkAnim = expect string( civilian.kv.script_noteworthy )
- Assert( IsValid( walkAnim ), "Ent at " + civilian.GetOrigin() + " needs a walk anim name in its script_noteworthy" )
-
- thread GivePropForAnim( civilian, walkAnim )
-
- /*
- entity spawner = civilian.spawner
- Assert( IsValid ( spawner ) )
- asset model = civilian.spawner.GetSpawnerModelName()
- */
-
- civilian.SetModel( GetRandomCivilianModel() )
- civilian.SetMoveAnim( walkAnim )
- MakeCivilian( civilian )
-
-
-
- array< entity > linkedEnts = civilian.GetLinkEntArray()
- string editorClassname
- entity destinationOrg
- foreach( entity ent in linkedEnts )
- {
- editorClassname = GetEditorClass( ent )
- if ( editorClassname == "info_move_target" )
- destinationOrg = ent
-
- }
- Assert( IsValid( destinationOrg ) )
- civilian.AssaultPoint( destinationOrg.GetOrigin() )
-}
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function CivilianActorThink( entity civilian )
-{
- civilian.SetModel( GetRandomCivilianModel() )
- MakeCivilian( civilian )
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function QuickSkit( entity player, entity skitNode, string failsafeFlagToStart = "", entity lookAtEnt = null, entity lookAtTrigger = null )
-{
- array< entity > linkedEnts = skitNode.GetLinkEntArray()
- Assert( linkedEnts.len() > 0, "skitNode at " + skitNode.GetOrigin() + " has no linked ents")
- vector origin = skitNode.GetOrigin()
- vector angles = skitNode.GetAngles()
- skitNode.Destroy()
- bool isLooping = false
- bool showIdle = false
- bool isSpawnSkit = false
- bool isDeleteSkit = false
-
-
- string scriptName
- if ( ( skitNode.HasKey( "script_noteworthy") ) && ( skitNode.kv.script_noteworthy == "looping" ) )
- isLooping = true
- if ( ( skitNode.HasKey( "script_noteworthy") ) && ( skitNode.kv.script_noteworthy == "show_idle" ) )
- showIdle = true
- if ( ( skitNode.HasKey( "script_noteworthy") ) && ( skitNode.kv.script_noteworthy == "delete" ) )
- isDeleteSkit = true
-
- entity actor
- array <entity> skitActors
- bool isDoorSkit = false
- asset modelName
-
- foreach( entity ent in linkedEnts )
- {
- modelName = ent.GetModelName()
- if ( modelName == $"models/door/door_imc_interior_03_128_animated.mdl" )
- isDoorSkit = true
-
- }
-
-
- foreach( entity ent in linkedEnts )
- {
-
- if( IsSpawner( ent ) )
- {
- actor = ent.SpawnEntity()
- actor.kv.spawnflags = SF_NPC_ALLOW_SPAWN_SOLID
- DispatchSpawn( actor )
- isSpawnSkit = true
- actor.EnableNPCFlag( NPC_DISABLE_SENSING )
- actor.kv.alwaysAlert = 0
- actor.EnableNPCFlag( NPC_IGNORE_ALL )
- actor.SetNoTarget( true )
- actor.EnableNPCFlag( NPC_NO_MOVING_PLATFORM_DEATH )
- }
- else
- actor = ent
-
-
- actor.EndSignal( "OnDestroy" )
- actor.EndSignal( "OnDeath" )
-
- actor.s.anim <- expect string( actor.kv.script_noteworthy )
- Assert( IsValid( actor.s.anim ), "Ent at " + actor.GetOrigin() + " needs an anim name in its script_noteworthy" )
- Assert( actor.s.anim != "", "Ent at " + actor.GetOrigin() + " needs an anim name in its script_noteworthy" )
-
- if ( isDoorSkit == true )
- DontAllowFreeze( actor, true )
-
-
- if ( ( actor.GetScriptName().find( "civilian_" ) != null ) && ( isSpawnSkit == true ) )
- {
- actor.SetMoveAnim( GetRandomCivilianRunAnim() )
- MakeCivilian( actor )
- isDeleteSkit = true
- }
-
- if ( !isLooping )
- {
- actor.s.animIdle <- actor.s.anim + "_idle"
- thread PlayAnimTeleport( actor, actor.s.animIdle, origin, angles )
- }
- else if ( ( isLooping ) && ( actor.IsNPC() ) )
- actor.EnableNPCFlag( NPC_DISABLE_SENSING )
-
- if ( !showIdle )
- actor.Hide()
-
- skitActors.append( actor )
- }
-
- if ( lookAtEnt )
- waitthread WaitTillLookingAt( player, lookAtEnt, true, 30, 0, 0, lookAtTrigger, failsafeFlagToStart )
- else if ( failsafeFlagToStart != "" )
- FlagWait( failsafeFlagToStart )
-
-
- float animLength
-
-
- foreach( entity actor in skitActors )
- {
-
-
- modelName = actor.GetModelName()
- if ( modelName == $"models/door/door_imc_interior_03_128_animated.mdl" )
- {
- //actor.NotSolid()
- //actor.kv.solid = 0
- // 0 = no collision, 2 = bounding box, 6 = use vPhysics, 8 = hitboxes only
-
- animLength = actor.GetSequenceDuration( actor.s.anim )
- delaythread ( animLength ) DisableNavmeshSeperatorTargetedByEnt( actor )
- //ToggleNPCPathsForEntity( actor, true )
- DisableNavmeshSeperatorTargetedByEnt( actor )
- }
-
- actor.Show()
- if ( ( isSpawnSkit ) && ( isDeleteSkit ) )
- thread PlayAnimThenDelete( actor, expect string( actor.s.anim ), origin, angles )
- else if ( isSpawnSkit )
- {
- thread PlayAnim( actor, expect string( actor.s.anim ), origin, angles )
- animLength = actor.GetSequenceDuration( actor.s.anim )
- if ( actor.IsNPC() )
- {
- actor.DisableNPCFlag( NPC_DISABLE_SENSING )
- actor.DisableNPCFlag( NPC_IGNORE_ALL )
- actor.SetNoTarget( false )
-
- }
-
- if ( isDoorSkit == true )
- thread AllowFreezeWhenAnimDone( actor, animLength )
- }
- else if ( isLooping )
- thread PlayAnim( actor, expect string( actor.s.anim ), origin, angles )
- else
- thread PlayAnimThenDelete( actor, expect string( actor.s.anim ), origin, angles )
- }
-
-}
-
-
-void function AllowFreezeWhenAnimDone( entity npc, float animLength )
-{
- if ( !IsValid( npc ) )
- return
- npc.EndSignal( "OnDeath" )
-
- wait animLength
-
- DontAllowFreeze( npc, false )
-
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////
-string function GetRandomCivilianRunAnim()
-{
- array<string> anims
- //anims.append( "pt_civ_walk_swagger" )
- anims.append( "pt_civ_fleeing_run_flail" )
- anims.append( "pt_civ_fleeing_run_hunched" )
- //anims.append( "pt_civ_fleeing_run_lookback" )
- //anims.append( "pt_civ_fleeing_run_pause" )
- //anims.append( "pt_civ_fleeing_run_spin" )
- anims.randomize()
- return anims[ 0 ]
-}
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void function MakeCivilian( entity npc )
-{
-
- TakeAllWeapons( npc )
- npc.EnableNPCFlag( NPC_DISABLE_SENSING )
- npc.kv.alwaysAlert = 0
- npc.EnableNPCFlag( NPC_IGNORE_ALL )
- npc.EnableNPCMoveFlag( NPCMF_DISABLE_MOVE_TRANSITIONS )
- SetTeam( npc, TEAM_UNASSIGNED )
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////
-asset function GetRandomCivilianModel()
-{
- array<asset> models
- models.append( MODEL_CIV01 )
- models.append( MODEL_CIV02 )
- models.append( MODEL_CIV03 )
- models.append( MODEL_CIV04 )
- models.randomize()
- return models[ 0 ]
-}
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function PlayAnimThenDelete( entity actor, string anim, origin, angles )
-{
- actor.EndSignal( "OnDeath" )
- actor.EndSignal( "OnDestroy" )
- entity node = actor.GetLinkEnt()
- if ( ( actor.IsNPC ) && ( IsValid( node ) ) )
- actor.AssaultPoint( node.GetOrigin() )
-
- float animLength = actor.GetSequenceDuration( anim )
- thread PlayAnimTeleport( actor, anim, origin, angles )
- wait animLength
-
- if ( ( actor.IsNPC ) && ( IsValid( node ) ) )
- actor.WaitSignal( "OnFinishedAssault" )
-
- if ( IsValid( actor ) )
- actor.Destroy()
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function TriggerShowcaseSpawnInit( entity trigger )
-{
- bool requiresLookAt = false
- if ( ( trigger.HasKey( "script_noteworthy") ) && ( trigger.kv.script_noteworthy == "lookat" ) )
- requiresLookAt = true
-
- array< entity > linkedEnts = trigger.GetLinkEntArray()
- Assert( linkedEnts.len() > 0, "Showcase spawn trigger at " + trigger.GetOrigin() + " has no linked ents" )
-
- foreach( ent in linkedEnts )
- {
- Assert( ent.GetClassName() == "prop_dynamic", "Showcase spawn trigger at " + trigger.GetOrigin() + " Should only link to prop_dynamics " + ( ent.GetClassName() ) )
- thread SpawnerShowcaseSpawnerThink( trigger, ent, requiresLookAt )
- }
-
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function SpawnerShowcaseSpawnerThink( entity trigger, entity spawnProp, bool requiresLookAt )
-{
- FlagWait( "PlayerDidSpawn" )
- entity player = GetPlayerArray()[ 0 ]
- if ( !IsValid( player ) )
- return
- player.EndSignal( "OnDeath" )
- trigger.EndSignal( "OnDestroy" )
-
- //---------------------------------------------
- // Get spawner and associated animated prop
- //---------------------------------------------
- entity spawner = spawnProp.GetLinkEnt()
- Assert( IsSpawner( spawner ), "Entity at " + spawner.GetOrigin() + " is not a spawner" )
- var spawnerKeyValues = spawner.GetSpawnEntityKeyValues()
- expect table( spawnerKeyValues )
- int spawnCount = 1
- float spawnDelayTime = 0.0
-
- if ( "script_delay" in spawnerKeyValues )
- spawnDelayTime = float( spawnerKeyValues.script_delay )
-
- if ( "spawn_count" in spawnerKeyValues ) //spawn_count not implemented yet, but will add later
- spawnCount = int( spawnerKeyValues.script_delay )
-
- string spawnModel = expect string( spawnerKeyValues.model )
-
- int npcsSpawned = 0
-
-
- //--------------------------
- // Wait for trigger to be hit
- //--------------------------
-
- entity npc
-
- while ( GetTriggerEnabled( trigger ) == false )
- wait 0.1
-
- while( true )
- {
- wait 0.1
- trigger.WaitSignal( "OnTrigger" )
-
- wait spawnDelayTime
-
- if ( requiresLookAt )
- {
- //player, entity, doTrace, degrees minDist, timeOut, trigger
- waitthread WaitTillLookingAt( player, spawnProp, true, 45, 0, 0, trigger )
- }
-
- thread ShowcaseSpawn( spawnProp )
-
- npcsSpawned++
- if ( npcsSpawned == spawnCount )
- break
-
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-void function ShowcaseSpawn( entity spawnProp )
-{
- vector origin = spawnProp.GetOrigin()
- vector angles = spawnProp.GetAngles()
- string spawnAnimNPC = ""
- string spawnAnimProp = ""
- entity spawner = spawnProp.GetLinkEnt()
- Assert( IsSpawner( spawner ), "Entity at " + spawner.GetOrigin() + " is not a spawner" )
- var spawnerKeyValues = spawner.GetSpawnEntityKeyValues()
- expect table( spawnerKeyValues )
- string spawnModel = expect string( spawnerKeyValues.model ).tolower()
-
- switch( spawnProp.GetModelName() )
- {
- //--------------------------
- // Floor panel prop
- //--------------------------
- case $"models/props/floor_panel_animated.mdl":
- case $"models/props/floor_vent_d_animated.mdl":
- if ( spawnModel == "models/creatures/prowler/r2_prowler.mdl" )
- {
- //spawnAnimProp = "floor_timeshift_prowler_spawn_01"
- //spawnAnimNPC = "pr_timeshift_floor_spawn_01"
- spawnAnimProp = "floor_timeshift_prowler_spawn_01_long"
- spawnAnimNPC = "pr_timeshift_floor_spawn_01_long"
-
- }
- else if ( spawnModel == "models/robots/stalker/robot_stalker_mossy.mdl" )
- {
- if ( CoinFlip() )
- {
- //spawnAnimProp = "floor_breakout_spawn_floorpanel"
- //spawnAnimNPC = "st_breakout_spawn_floorpanel"
- spawnAnimProp = "floor_breakout_spawn_floorpanel_long"
- spawnAnimNPC = "st_breakout_spawn_floorpanel_long"
- }
- else
- {
- //spawnAnimProp = "floor_breakout_spawn_floordeath"
- //spawnAnimNPC = "st_breakout_spawn_floordeath"
- spawnAnimProp = "floor_breakout_spawn_floordeath_long"
- spawnAnimNPC = "st_breakout_spawn_floordeath_long"
- }
- }
- else
- Assert( 0, "Unhandled spawn prop: " + spawnProp.GetModelName() )
- break
- //--------------------------
- // Wall panel prop
- //--------------------------
- case $"models/props/wall_vent_animated.mdl":
- if ( spawnModel == "models/creatures/prowler/r2_prowler.mdl" )
- {
- if ( ( spawnProp.HasKey( "script_noteworthy") ) && ( spawnProp.kv.script_noteworthy == "ground_vent" ) )
- {
- //spawnAnimProp = "vent_low_timeshift_prowler_spawn_01"
- //spawnAnimNPC = "pr_timeshift_vent_low_spawn_01"
- spawnAnimProp = "vent_low_timeshift_prowler_spawn_01_long"
- spawnAnimNPC = "pr_timeshift_vent_low_spawn_01_long"
- }
- else
- {
- //spawnAnimProp = "vent_timeshift_prowler_spawn_01"
- //spawnAnimNPC = "pr_timeshift_vent_spawn_01"
- spawnAnimProp = "vent_timeshift_prowler_spawn_01_long"
- spawnAnimNPC = "pr_timeshift_vent_spawn_01_long"
- }
-
- }
- else if ( spawnModel == "models/robots/stalker/robot_stalker_mossy.mdl" )
- {
- //spawnAnimProp = "vent_vent_spawn_core"
- //spawnAnimNPC = "st_vent_spawn_core"
- spawnAnimProp = "vent_vent_spawn_damaged_longintro"
- spawnAnimNPC = "st_vent_spawn_damaged_longintro"
- }
- else
- {
- Assert( 0, "Unhandled spawnModel: " + spawnModel )
- }
- break
- default:
- Assert( 0, "Unhandled spawn prop: " + spawnProp.GetModelName() )
-
- }
-
- //------------------
- //Spawn the npc
- //------------------
- entity npc = spawner.SpawnEntity()
- npc.Hide()
- npc.kv.spawnflags = SF_NPC_ALLOW_SPAWN_SOLID
- DispatchSpawn( npc )
-
- //----------------------------------
- // Animate the spawned npc and prop
- //----------------------------------
- thread PlayAnim( npc, spawnAnimNPC, origin, angles )
- npc.Show()
- thread PlayAnim( spawnProp, spawnAnimProp, origin, angles )
-
-}
-
-///////////////////////////////////////////////////////////////////
-
-bool function IsSpectreRackDoorSpawner( entity spawnProp )
-{
- array validModels = [
- $"models/timeshift/timeshift_column_panel_09_destroyed.mdl",
- $"models/timeshift/timeshift_column_panel_10_destroyed.mdl",
- $"models/timeshift/timeshift_column_panel_09.mdl",
- $"models/timeshift/timeshift_column_panel_10.mdl"
- ]
-
- if ( validModels.contains( spawnProp.GetModelName() ) )
- return true
-
- return false
-}
-
-///////////////////////////////////////////////////////////////////
-void function HideStuff( string scriptName )
-{
- array <entity> stuff = GetEntArrayByScriptName( scriptName )
- foreach( thing in stuff )
- {
- thing.Hide()
- thing.MakeInvisible()
- thing.NotSolid()
- }
-
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function ShowStuff( string scriptName )
-{
- array <entity> stuff = GetEntArrayByScriptName( scriptName )
- foreach( thing in stuff )
- {
- thing.Show()
- thing.Solid()
- thing.MakeVisible()
- }
-
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function AttackPlayer( entity npc )
-{
- if ( !IsValid( npc ) )
- return
-
- array<entity> players = GetPlayerArray()
- if ( players.len() <= 0 )
- return
-
- npc.SetEnemy( players[ 0 ] )
- printt( "Attacking player..." )
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-/*
-void function ChangeIMCCorpse( entity model, string corpseType )
-{
- //disable all bodygroups
- int stateIndex = 1 // 0 = show, 1 = hide
- model.SetBodygroup( model.FindBodyGroup( "imc_corpse_rifle" ), 1 )
- model.SetBodygroup( model.FindBodyGroup( "imc_corpse_shotgun" ), 1 )
- model.SetBodygroup( model.FindBodyGroup( "imc_corpse_smg" ), 1 )
- model.SetBodygroup( model.FindBodyGroup( "imc_corpse_lmg" ), 1 )
-
- //enable the right one
- int bodyGroupIndex = model.FindBodyGroup( corpseType )
- stateIndex = 0 // 0 = show, 1 = hide
- model.SetBodygroup( bodyGroupIndex, stateIndex )
-}
-*/
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DestroyNPCOnFlag( entity npc, string flagToDestroy )
-{
- npc.EndSignal( "OnDeath" )
- FlagEnd( flagToDestroy )
-
- OnThreadEnd(
- function() : ( npc )
- {
- if ( IsAlive( npc ) )
- npc.Destroy()
- }
- )
- WaitForever()
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-entity function GetClosestGrunt( entity player, var timeZone, string scriptName = "" )
-{
- if ( !IsValid( player ) )
- return
- player.EndSignal( "OnDeath" )
-
- vector playerOrigin = player.GetOrigin()
- if ( level.timeZone != timeZone )
- playerOrigin = GetPosInOtherTimeline( player.GetOrigin() )
-
- array <entity> npcs = GetNPCArray()
- array <entity> grunts
- string classname
- foreach( npc in npcs )
- {
- if ( !IsValid( npc ) )
- continue
- if ( !npc.IsNPC() )
- continue
- if ( !IsAlive( npc ) )
- continue
- if ( ( scriptName != "" ) && ( npc.GetScriptName() != scriptName ) )
- continue
- if ( !npc.IsHuman() )
- continue
-
- grunts.append( npc )
- }
-
- ArrayRemoveDead( grunts )
- if ( grunts.len() == 0 )
- return null
-
- entity closestDude = GetClosest( grunts, playerOrigin )
-
- if ( IsValid( closestDude ) )
- return closestDude
- else
- return null
-
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-entity function GetTimeshiftPlayer()
-{
- array<entity> players = GetPlayerArray()
- if ( players.len() <= 0 )
- return null
- entity player = players[ 0 ]
- return player
-}
-
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function GunshipSequence( string instanceName, entity player, string nodeName, string whichSequence, string flagToStart )
-{
-
- entity gunship = GetEntByScriptNameInInstance( "gunship_artifact_hauler", instanceName )
- entity artifact = GetEntByScriptNameInInstance( "artifact_cargo", instanceName )
- entity harness = GetEntByScriptNameInInstance( "artifact_cargo_containment", instanceName )
- array <entity> ropeLinks = GetEntArrayByScriptNameInInstance( "harness_rope_points", instanceName )
-
- foreach( ropeAttachEnt in ropeLinks )
- ropeAttachEnt.SetParent( harness )
-
- gunship.SetFadeDistance( 1000000 )
- artifact.SetFadeDistance( 1000000 )
- harness.SetFadeDistance( 1000000 )
-
- entity animEnt = GetEntByScriptName( nodeName )
-
-
- artifact.SetParent( gunship, "", true )
- harness.SetParent( gunship, "", true )
-
-
- string animIdle = ""
- string animLeave = ""
-
- if ( whichSequence == "rings" )
- {
- artifact.Destroy()
- animIdle = "gunship_timeshift_fly_from_rings_idle"
- animLeave = "gunship_timeshift_fly_from_rings"
-
- }
- else if ( whichSequence == "pad" )
- {
- animIdle = "st_AngelCity_IMC_Win_Idle"
- //EmitSoundOnEntity( gunship, "Timeshift_Scr_DropshipTowingCore_Hover" )
- //animLeave = "st_AngelCity_IMC_Win_Leave"
- }
- else
- Assert( 0, "Invalid sequence: " + whichSequence )
-
-
-
- entity gunshipAttachEnt = CreateScriptRef( gunship.GetOrigin(), gunship.GetAngles() )
- gunshipAttachEnt.SetParent( gunship )
- local subdivisions = 15 // 25
- local slack = 25 // 25
-
- wait 0.1
-
- if ( whichSequence == "pad" )
- animEnt.SetOrigin( animEnt.GetOrigin() + Vector( 0, 0, -400 ) )
-
- thread PlayAnimTeleport( gunship, animIdle, animEnt )
-
-
- wait 0.1
-
- if ( whichSequence == "pad" )
- {
- foreach( ropeAttachEnt in ropeLinks )
- {
-
- string startpointName = UniqueString( "rope_startpoint" )
- string endpointName = UniqueString( "rope_endpoint" )
-
- entity rope_start = CreateEntity( "move_rope" )
- SetTargetName( rope_start, startpointName )
- rope_start.kv.NextKey = endpointName
- rope_start.kv.MoveSpeed = 32
- rope_start.kv.Slack = slack
- rope_start.kv.Subdiv = subdivisions
- rope_start.kv.Width = "3"
- rope_start.kv.TextureScale = "1"
- rope_start.kv.RopeMaterial = "cable/cable.vmt"
- rope_start.kv.PositionInterpolator = 2
- rope_start.SetOrigin( gunshipAttachEnt.GetOrigin() )
-
- entity rope_end = CreateEntity( "keyframe_rope" )
- SetTargetName( rope_end, endpointName )
- rope_end.kv.MoveSpeed = 32
- rope_end.kv.Slack = slack
- rope_end.kv.Subdiv = subdivisions
- rope_end.kv.Width = "3"
- rope_end.kv.TextureScale = "1"
- rope_end.kv.RopeMaterial = "cable/cable.vmt"
- rope_end.SetOrigin( ropeAttachEnt.GetOrigin() )
-
-
- DispatchSpawn( rope_start )
- DispatchSpawn( rope_end )
-
- rope_start.SetParent( gunship )
- rope_end.SetParent( harness )
- }
- //
-
- }
- else
- {
- harness.Destroy()
-
- }
-
-
-
- wait 0.1
-
- FlagWait( flagToStart )
-
- if ( whichSequence == "rings" )
- {
- EmitSoundAtPosition( TEAM_UNASSIGNED, GetEntByScriptName( "lookent_rings" ).GetOrigin(), "timeshift_scr_dropshipcoreflyover_long_muffled" )
- waitthread PlayAnim( gunship, animLeave, animEnt )
-
- }
-
- else if ( whichSequence == "pad" )
- {
-
- int attachID = gunship.LookupAttachment( "REF" )
- vector attachOrg = gunship.GetAttachmentOrigin( attachID )
- vector attachAng = gunship.GetAttachmentAngles( attachID )
- entity mover = CreateScriptMover( attachOrg, attachAng )
- gunship.SetParent( mover, "", true )
- float duration = 30
- //StopSoundOnEntity( gunship, "Timeshift_Scr_DropshipTowingCore_Hover" )
- EmitSoundOnEntity( gunship, "Timeshift_Scr_DropshipTowingCore_Takeoff" )
-
- mover.NonPhysicsMoveTo( gunship.GetOrigin() + Vector( 0, 0, 3200 ), duration, 0, 0 ) //, duration*0.4, duration*0.4 )
- wait duration
- mover.Destroy()
- }
-
-
-}
-
-/////////////////////////////////////////////////////////////////////////////
-void function AndersonHologramSequence( entity player, string nodeName, string flagToStart )
-{
- //Double the geo, double the fun
- entity node = GetEntByScriptName( nodeName )
- entity node2 = CreateScriptRef( node.GetOrigin() + Vector( 0, 0, TIME_ZOFFSET ), node.GetAngles() )
- node2.kv.script_name = nodeName
-
- thread AndersonHologramSequenceThread( player, node, flagToStart )
- thread AndersonHologramSequenceThread( player, node2, flagToStart )
-}
-
-/////////////////////////////////////////////////////////////////////////////
-void function AndersonHologramSequenceThread( entity player, entity node, string flagToStart )
-{
- player.EndSignal( "OnDeath" )
- vector origin = node.GetOrigin()
- vector angles = node.GetAngles()
- entity anderson = CreatePropDynamic( ANDERSON_HOLOGRAM_MODEL, origin, angles, 0 ) // 0 = no collision
- anderson.kv.script_name = "anderson_holo"
- entity andersonWeapon = CreatePropDynamic( ANDERSON_PISTOL_MODEL, origin, angles, 0 ) // 0 = no collision
- andersonWeapon.SetSkin( 1 )
- anderson.SetSkin( 1 )
- string nodeName = node.GetScriptName()
- Assert( nodeName != "" )
-
- bool isOvergrownHolo = false
- if ( GetEntityTimelinePosition( node ) == TIMEZONE_NIGHT )
- isOvergrownHolo = true
-
- anderson.Hide()
- andersonWeapon.Hide()
-
- //string attachment = "PROPGUN"
- //int attachIndex = anderson.LookupAttachment( attachment )
- //vector attachOrigin = anderson.GetAttachmentOrigin( attachIndex )
- andersonWeapon.SetParent( anderson, "PROPGUN", false, 0.0 )
-
- string animAnderson
- string animAndersonIdle
- string animEnemy
- string animEnemyIdle
- entity andersonEnemy
- entity enemyKnife
- entity enemyGun
- string flagToSetWhenDone
- string flagToSetWhenPlaying
-
- switch( nodeName )
- {
- case "node_hologram_lab1":
- animAndersonIdle = "anderson_ghost_A_scene_idle"
- animAnderson = "anderson_ghost_A_scene"
- flagToSetWhenDone = "AndersonHologram1Finished"
- flagToSetWhenPlaying = "AndersonHologram1Playing"
- break
- case "node_hologram_lab2":
- animAndersonIdle = "anderson_ghost_B_scene_idle"
- animAnderson = "anderson_ghost_B_scene"
- flagToSetWhenDone = "AndersonHologram2Finished"
- flagToSetWhenPlaying = "AndersonHologram2Playing"
- break
- case "node_hologram_lab3":
- animAndersonIdle = "anderson_ghost_C_scene_idle"
- animAnderson = "anderson_ghost_C_scene"
- flagToSetWhenPlaying = "AndersonHologram3Playing"
- andersonEnemy = CreatePropDynamic( ENEMY_HOLOGRAM_MODEL, origin, angles, 0 ) // 0 = no collision
- andersonEnemy.SetSkin( 1 )
- enemyKnife = CreatePropDynamic( HOLOGRAM_KNIFE_MODEL, origin, angles, 0 ) // 0 = no collision
- enemyKnife.SetSkin( 1 )
- enemyGun = CreatePropDynamic( HOLOGRAM_ENEMY_GUN_MODEL, origin, angles, 0 ) // 0 = no collision
- enemyGun.SetSkin( 1 )
- enemyGun.SetParent( andersonEnemy, "PROPGUN", false, 0.0 )
- enemyKnife.SetParent( andersonEnemy, "KNIFE", false, 0.0 )
- andersonEnemy.Hide()
- andersonEnemy.MakeInvisible()
- enemyKnife.Hide()
- enemyKnife.MakeInvisible()
- animEnemy = "pt_ghost_C_scene"
- animEnemyIdle = "pt_ghost_C_scene_idle"
- flagToSetWhenDone = "AndersonHologram3Finished"
- thread AndersonHologram3Think( anderson, andersonWeapon )
- thread AndersonEnemyHologram3Think( andersonEnemy, enemyKnife, enemyGun )
- break
- default:
- Assert( 0, "Unhandled nodeName: " + nodeName )
- }
-
- if ( IsValid( andersonEnemy) )
- {
- Assert( animEnemyIdle != "" )
- thread PlayAnimTeleport( andersonEnemy, animEnemyIdle, node )
- }
- Assert( animAndersonIdle != "" )
- thread PlayAnimTeleport( anderson, animAndersonIdle, node )
-
-
- FlagWait( flagToStart )
-
-
-
-
-
-
-
-
- //only display HUD stuff once
- if ( isOvergrownHolo )
- thread DecodingLogsScreenPrint( player )
-
- anderson.Show()
- //spawn effects
- int attachIndex = anderson.LookupAttachment( "CHESTFOCUS" )
- StartParticleEffectOnEntity( anderson, GetParticleSystemIndex( FX_HOLOGRAM_FLASH_EFFECT ), FX_PATTACH_POINT_FOLLOW, attachIndex )
- StartParticleEffectOnEntity( anderson, GetParticleSystemIndex( FX_HOLOGRAM_HEX_EFFECT ), FX_PATTACH_POINT_FOLLOW, attachIndex )
-
- /*
- int scanEffectIndex = GetParticleSystemIndex( FX_HOLO_SCAN_ENVIRONMENT )
- int particleIndex = StartParticleEffectInWorldWithHandle( scanEffectIndex, anderson.GetOrigin(), <0,0,0> )
- EffectSetControlPointVector( particleIndex, 1, <2.5,50,0> )
- */
-
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Show()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Show()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Show()
- StartParticleEffectOnEntity( anderson, GetParticleSystemIndex( FX_HOLOGRAM_FLASH_EFFECT ), FX_PATTACH_POINT_FOLLOW, attachIndex )
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.25
-
- anderson.Show()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.5
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.25
-
- anderson.Show()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.01
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.25
-
- anderson.Show()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.03
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.2
-
-
- anderson.Show()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.3
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.2
-
- anderson.Show()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.05
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.5
-
- anderson.Show()
- StartParticleEffectOnEntity( anderson, GetParticleSystemIndex( FX_HOLOGRAM_FLASH_EFFECT ), FX_PATTACH_POINT_FOLLOW, attachIndex )
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.2
-
- anderson.Show()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.2
-
- anderson.Show()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Show()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Show()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Show()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Show()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
- anderson.Hide()
- EmitSoundOnEntity( anderson, SOUND_HOLOGRAM_FLICKER )
- wait 0.1
-
-
- FlagSet( flagToSetWhenPlaying )
-
- EmitSoundOnEntity( anderson, "PathHologram_Materialized_3P" )
- //EmitSoundOnEntity( anderson, "PathHologram_Sustain_Loop_3P" )
-
- if ( IsValid( andersonEnemy) )
- {
- Assert( animEnemy != "" )
- thread PlayAnim( andersonEnemy, animEnemy, node )
- int attachIndexEnemy = andersonEnemy.LookupAttachment( "CHESTFOCUS" )
- StartParticleEffectOnEntity( andersonEnemy, GetParticleSystemIndex( FX_HOLOGRAM_HEX_EFFECT ), FX_PATTACH_POINT_FOLLOW, attachIndexEnemy )
- }
- anderson.Show()
- andersonWeapon.Show()
- Assert( animAnderson != "" )
- StartParticleEffectOnEntity( anderson, GetParticleSystemIndex( FX_HOLOGRAM_FLASH_EFFECT ), FX_PATTACH_POINT_FOLLOW, attachIndex )
- waitthread PlayAnim( anderson, animAnderson, node )
-
- vector andersonEndPos = anderson.GetAttachmentOrigin( attachIndex )
-
- //hologram 3 we need to manually deal with Anderson disappearing at the end...all others he can just blink out
- if ( nodeName != "node_hologram_lab3" )
- {
- EmitSoundAtPosition( TEAM_UNASSIGNED, andersonEndPos, "AndersonHologram_Deactivate" )
- PlayFX( FX_HOLOGRAM_FLASH_EFFECT, andersonEndPos )
- }
-
- FlagSet( flagToSetWhenDone )
- anderson.Destroy()
- if ( IsValid( andersonEnemy) )
- {
- int attachIndexEnemy = andersonEnemy.LookupAttachment( "CHESTFOCUS" )
- vector andersonEnemyEndPos = andersonEnemy.GetAttachmentOrigin( attachIndexEnemy )
- PlayFX( FX_HOLOGRAM_FLASH_EFFECT, andersonEnemyEndPos )
- andersonEnemy.Destroy()
- }
-
-
-
- if ( isOvergrownHolo )
- Remote_CallFunction_NonReplay( player, "ServerCallback_ClearScanningHudElem" )
-
-
-}
-//////////////////////////////////////////////////////////////////
-void function AndersonHologram3Think( entity anderson, entity andersonGun )
-{
- anderson.EndSignal( "OnDestroy" )
-
- anderson.WaitSignal( "AndersonHideGun" )
- andersonGun.Destroy()
-
- anderson.WaitSignal( "AndersonTimeshifts" )
-
- anderson.Dissolve( ENTITY_DISSOLVE_CHAR, Vector( 0, 0, 0 ), 0 )
-
-}
-//////////////////////////////////////////////////////////////////
-void function AndersonEnemyHologram3Think( entity andersonEnemy, entity knife, entity andersonEnemyGun )
-{
- andersonEnemy.EndSignal( "OnDestroy" )
-
- andersonEnemy.WaitSignal( "AndersonEnemyShow" )
- andersonEnemy.Show()
- andersonEnemy.MakeVisible()
-
- andersonEnemy.WaitSignal( "AndersonEnemyShowKnife" )
- knife.Show()
- knife.MakeVisible()
-}
-
-
-/*
-//////////////////////////////////////////////////////////////////
-void function TitanTimeshiftLoadoutOLD( entity player )
-{
- wait 1
- Assert( IsValid( player ) )
- entity bt = player.GetPetTitan()
- Assert( IsValid( bt ) )
- //TitanLoadoutDef loadout = bt.ai.titanSpawnLoadout
- //loadout.special = "mp_titanability_timeshift"
- entity weapon = bt.GetOffhandWeapon( OFFHAND_SPECIAL )
- bt.TakeWeapon( weapon.GetWeaponClassName() )
- //entity offhand2weapon = bt.GetOffhandWeapon( OFFHAND_ANTIRODEO )
- //bt.TakeWeapon( offhand2weapon.GetWeaponClassName() )
- bt.GiveOffhandWeapon( "mp_titanability_timeshift", OFFHAND_SPECIAL, [] )
- LockOffhandSlot( player, OFFHAND_SPECIAL )
-}
-
-*/
-
-
-
-//////////////////////////////////////////////////////////////////
-void function TitanTimeshiftLoadout( entity player )
-{
- entity weapon = player.GetOffhandWeapon( OFFHAND_SPECIAL )
- if ( IsValid( weapon ) )
- {
- string weaponName = weapon.GetWeaponClassName()
- if ( weaponName == "mp_titanability_timeshift" )
- return
-
- player.TakeWeapon( weaponName )
- }
-
- player.GiveOffhandWeapon( "mp_titanability_timeshift", OFFHAND_SPECIAL, [] )
-// LockOffhandSlot( player, OFFHAND_SPECIAL )
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function KillMyInterdimensionalBrother( entity baseNpc, entity brotherNpc = null )
-{
- if ( !IsValid( baseNpc ) )
- return
-
- if ( baseNpc.IsTitan() )
- baseNpc.WaitSignal( "OnDeath" ) //may change to Doomed if not weak
- else
- baseNpc.WaitSignal( "OnDeath" )
-
- entity brother = brotherNpc
-
- if ( !IsValid( brother ) )
- return
- if ( !IsAlive( brother ) )
- return
- if ( !brother.IsNPC() )
- return
-
- vector origin = brother.GetOrigin()
-
- TakeAllWeapons( brother )
- UnFreezeNPC( brother )
-
-
- if( level.timeZone == TIMEZONE_NIGHT )
- brother.TakeDamage( brother.GetMaxHealth() + 1, null, null, { damageSourceId=damagedef_suicide } ) //Kill npc manually if player can see him
- else
- brother.Destroy() //otherwise delete as if he never existed
-
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function SpawnPristineStalkersWithDopplegangers( string scriptName )
-{
- array <entity> spawners = GetEntArrayByScriptName( scriptName )
- Assert( spawners.len() > 0 )
-
-
- foreach( spawner in spawners )
- {
- Assert( IsSpawner( spawner ) )
- entity baseStalker = spawner.SpawnEntity()
- DispatchSpawn( baseStalker )
- baseStalker.kv.alwaysAlert = 1
-
-
- entity doppleganger = CreateZombieStalkerMossy( TEAM_IMC, baseStalker.GetOrigin() + Vector( 0, 0, ( TIME_ZOFFSET * -1 ) ), baseStalker.GetAngles() )
- DispatchSpawn( doppleganger )
- SetSquad( doppleganger, "bridge_room_overgrown" )
- doppleganger.kv.alwaysAlert = 1
- thread KillMyInterdimensionalBrother( baseStalker, doppleganger )
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function SpawnAutoSecurityGroup( string scriptName )
-{
- array <entity> spawners = GetEntArrayByScriptName( scriptName )
- Assert( spawners.len() > 0 )
- array <entity> pristineRobots
- array <entity> overgrownRobots
-
- foreach( spawner in spawners )
- {
- Assert( IsSpawner( spawner ) )
- entity npc = spawner.SpawnEntity()
- DispatchSpawn( npc )
- if ( GetEntityTimelinePosition( npc ) == TIMEZONE_DAY )
- pristineRobots.append( npc )
- else
- overgrownRobots.append( npc )
-
- }
-
- Assert( overgrownRobots.len() == pristineRobots.len(), "Arrays of pristine and overgrown robots are not equal: " + scriptName )
-
- int i = 0
- foreach( robot in pristineRobots )
- {
- thread KillMyInterdimensionalBrother( robot, overgrownRobots[ i ] )
- i++
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function TitanRackSpawnersThink( string scriptName )
-{
- array <entity> spawners = GetEntArrayByScriptName( scriptName )
- Assert( spawners.len() > 0 )
- entity pristineTitan
- entity overgrownTitan
-
- foreach( spawner in spawners )
- {
- Assert( IsSpawner( spawner ) )
-
- array <entity> linkedEnts = spawner.GetLinkEntArray()
- entity rack
- foreach( ent in linkedEnts )
- {
- if ( ent.GetClassName() == "info_target" )
- rack = ent
- }
- Assert( IsValid( rack ) )
- entity npc = spawner.SpawnEntity()
- npc.kv.spawnflags = SF_NPC_ALLOW_SPAWN_SOLID
- DispatchSpawn( npc )
- npc.EnableNPCFlag( NPC_IGNORE_ALL )
- npc.SetNoTarget( true )
- npc.SetTitle( "" )
- npc.SetValidHealthBarTarget( false )
- DisableTitanRodeo( npc )
- HideName( npc )
- //thread PlayAnimTeleport( npc, "bt_TDay_drop_titan1", rack )
- thread PlayAnimTeleport( npc, "at_titanrack_bootup_idle", rack ) //bt_TDay_drop_titan1
- //thread PlayAnim( rack, "tr_titanrack_bootup_idle" )
-
- npc.s.rack <- rack
-
- if ( GetEntityTimelinePosition( npc ) == TIMEZONE_DAY )
- {
- pristineTitan = npc
- thread TitanRackHealthThink( pristineTitan, TIMEZONE_DAY )
- }
- else
- {
- overgrownTitan = npc
- thread TitanRackHealthThink( overgrownTitan, TIMEZONE_DAY )
- }
- }
-
- thread KillMyInterdimensionalBrother( pristineTitan, overgrownTitan )
-}
-
-
-void function TitanRackHealthThink( entity titan, var timeZone )
-{
- titan.EndSignal( "OnDeath" )
- if ( timeZone == TIMEZONE_DAY )
- FlagWait( "player_inside_bridge_room_pristine" )
- else
- FlagWait( "player_inside_bridge_room_overgrown" )
-
- titan.SetMaxHealth( 1000 )
- titan.SetHealth( 1000 )
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void function TitanRackDeploy( string scriptName, var timeZone )
-{
- array <entity> ents = GetEntArrayByScriptName( scriptName )
- foreach( ent in ents )
- {
- if ( !IsValid( ent ) )
- continue
- if ( ent.IsNPC() )
- thread TitanRackDeployThread( ent, timeZone )
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function TitanRackDeployThread( entity titan, var timeZone )
-{
- if( !IsValid( titan ) )
- return
- if( !IsAlive( titan ) )
- return
-
- titan.EndSignal( "OnDeath" )
- titan.EndSignal( "OnDestroy" )
-
- if ( ( GetEntityTimelinePosition( titan ) == TIMEZONE_DAY ) && ( timeZone == TIMEZONE_NIGHT ) )
- return
- if ( ( GetEntityTimelinePosition( titan ) == TIMEZONE_NIGHT ) && ( timeZone == TIMEZONE_DAY ) )
- return
-
- float animLength = titan.GetSequenceDuration( "at_titanrack_bootup" )
- entity rack = titan.GetLinkEnt()
- Assert( IsValid( rack ) )
- thread PlayAnim( titan, "at_titanrack_bootup", rack )
- thread PlayAnim( rack, "tr_titanrack_bootup" )
- titan.SetNoTarget( false )
-
- wait animLength
-
- titan.DisableNPCFlag( NPC_IGNORE_ALL )
-}
-
-
-void function HideCritTimeshift( entity ent )
-{
- int bodyGroupIndex = ent.FindBodyGroup( "hitpoints" )
-
- if ( bodyGroupIndex == -1 )
- {
- return
- }
-
- ent.SetBodygroup( bodyGroupIndex, 1 )
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function RingsThink()
-{
- entity rings = GetEntByScriptName( "rings_pristine" )
- if ( !IsValid( rings ) )
- return
-
- rings.EndSignal( "OnDestroy" )
- thread PlayAnim( rings, "idle" )
-
- FlagWait( "RingsShouldBeSpinning" )
-
- string spinAnim = "animated_slow"
- if ( Flag( "player_back_in_amenities_lobby" ) )
- spinAnim = "animated"
-
- //rings.Anim_Stop()
- thread PlayAnim( rings, spinAnim )
-
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function PlayerConversationStopOnFlagImmediate( string name, entity player, string flagToAbort )
-{
- Assert( flagToAbort != "" )
- waitthread PlayerConversationStopOnFlag( name, player, flagToAbort, true )
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function PlayerConversationStopOnFlag( string name, entity player, string flagToAbort = "", bool immediate = false )
-{
- if ( flagToAbort != "" )
- {
- if ( Flag( flagToAbort ) )
- return
-
- FlagEnd( flagToAbort )
- }
-
- OnThreadEnd(
- function() : ( player, immediate, flagToAbort )
- {
- if ( flagToAbort == "" )
- return
- if ( !IsValid( player ) )
- return
- if ( immediate == false )
- StopConversation( player )
- else if ( immediate == true )
- StopConversationNow( player )
- }
- )
-
- thread PlayerConversation( name, player )
- WaitSignal( player, "ConversationEnded" )
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function FlagSetDelayed( string flagToSet, float delay )
-{
- thread FlagSetDelayedThread( flagToSet, delay )
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function FlagSetDelayedThread( string flagToSet, float delay )
-{
- wait delay
- FlagSet( flagToSet )
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function FlagClearDelayed( string flagToClear, float delay )
-{
- thread FlagClearDelayedThread( flagToClear, delay )
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function FlagClearDelayedThread( string flagToClear, float delay )
-{
- wait delay
- FlagClear( flagToClear )
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function DecodingLogsScreenPrint( entity player )
-{
- Remote_CallFunction_NonReplay( player, "ServerCallback_ShowHoloDecoding" )
-
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void function AudioLogModelThink( entity audioLogModel )
-{
- wait 0.25
-
- file.audioLogModels.append( audioLogModel )
- audioLogModel.SetFadeDistance( 2048 )
- EmitSoundAtPosition( TEAM_UNASSIGNED, audioLogModel.GetOrigin(), "LSTAR_Reloading_Beep_low" )
- audioLogModel.Highlight_ShowInside( 1.0 )
- audioLogModel.Highlight_ShowOutline( 1.0 )
-
- string instanceName = audioLogModel.GetInstanceName()
- string audioLogAlias
- int logIndex
- bool isTempAudioLog = false
- bool isBoyleAudioLog = false
- int boyleAudioLogNumber = 0
- int boyleLogInstanceNumber = 0
-
- Assert( instanceName != "", "Audio log has no instance name: " + audioLogModel.GetOrigin() )
-
- if ( instanceName == "audiolog_lobby_overgrown" )
- {
- // Audio Log - Scientist 2 The trial-run of the Sculptor Core will continue as planned, but you have to get security to evacuate all Tier 1 personnel.
- // General Marder and his key team members are transferring to remote observation.
- audioLogAlias = "diag_sp_anderson_TS171_02_01_imc_scientist2"
- logIndex = 1
- }
- else if ( instanceName == "audiolog_security_overgrown" )
- {
- // Dr. Alexander Darren log fourteen point six. The intruder has some kind of advanced tech and is slaughtering our response teams.
- //Tyler in Wildlife Research said 2 teams were taken out at the elevator banks in a matter of seconds...by one guy!
- audioLogAlias = "diag_sp_anderson_TS171_01_01_imc_scientist1"
- logIndex = 2
- }
- else if ( instanceName == "audiolog_lecture_overgrown" )
- {
-
- bool doLongSpeechAtLectern = false
-
- if ( doLongSpeechAtLectern == true )
- {
- // Full ted talk, 1-28
- instanceName = "audiolog_ted_talk"
- audioLogAlias = "tedTalk01"
- logIndex = 9
- }
- else
- {
- //General Marder
- //But lest we lose sight of the bigger picture - remember those losses are ultimately
- //replaceable by the inexorable march of human civilization.
- audioLogAlias = "lectureLogA"
- logIndex = 3
- }
-
- }
- else if ( instanceName == "audiolog_upper_hub1_overgrown" )
- {
-
- //Audio log 4 This is Dr. Colby Marvin. I don't know how to explain it, but a Vanguard-Class Titan just appeared out of nowhere. The test is still underway. It will be completed.
- audioLogAlias = "diag_sp_ambScience_TS551_09_01_imc_sci"
- logIndex = 4
-
- }
- else if ( instanceName == "audiolog_upper_hub2_overgrown" )
- {
- //Audio log 5 Dr. Altamirano log seven point six. General Marder is gone. He's making us stay to complete the test. I don't trust this thing. The Ark is unstable.
- audioLogAlias = "diag_sp_ambScience_TS551_10_01_imc_sci"
- logIndex = 5
-
- }
- else if ( IsAudioLogBoyle( instanceName ) )
- {
- isBoyleAudioLog = true
- logIndex = 6
- boyleLogInstanceNumber = GetBoyleLogInstanceNumber( instanceName )
-
- if ( file.debugAudioLogs )
- thread DebugDrawAudioLogNumber( audioLogModel, file.boyleAudioLogNumberAssignments[ boyleLogInstanceNumber ].tostring() )
- }
-
- else if ( instanceName == "audiolog_humanroom" )
- {
-
- //Marders Log 21b - Human specimen 3 point 4. The experiments on the IMS Odyssey's colonists are underway.
- //Soon we will discover the long lasting effects the Ark has on organic matter and brain function.
- audioLogAlias = "diag_sp_audioLog_TS132_01_01_imc_genMarder"
- logIndex = 7
-
- }
- else if ( instanceName == "audiolog_humanroom_tower" )
- {
- //Audio log 7 Dr. Ehrenberg log eleven point four. Further research still leaves questions about the Fold Weapon and its intended purpose.
- //I don't think we're using it right and that may cause a problem. Marder thinks it's worth it. Well I'm going on record - this is a bad idea.
- audioLogAlias = "diag_sp_ambScience_TS551_12_01_imc_sci"
- logIndex = 8
- }
-
- else if ( instanceName == "audiolog_ted_talk" )
- {
- // Full ted talk, 1-28
- audioLogAlias = "tedTalk01"
- logIndex = 9
- }
-
-
- else
- Assert( 0, "Unhandled audio log instance name: " + instanceName )
-
-
- audioLogModel.SetUsable()
- audioLogModel.SetUsableByGroup( "pilot" )
- audioLogModel.SetUsePrompts( "#TIMESHIFT_HINT_AUDIO_LOG" , "#TIMESHIFT_HINT_AUDIO_LOG_PC" )
- local playerActivator
- while( true )
- {
- playerActivator = audioLogModel.WaitSignal( "OnPlayerUse" ).player
- if ( IsValid( playerActivator ) && playerActivator.IsPlayer() )
- break
- }
-
- FlagSet( "AudioLogPlaying" )
-
- EmitSoundAtPosition( TEAM_UNASSIGNED, audioLogModel.GetOrigin(), "LSTAR_Reloading_Beep_low" )
- audioLogModel.UnsetUsable()
- audioLogModel.Highlight_HideInside( 0 )
- audioLogModel.Highlight_HideOutline( 0 )
-
- wait 0.5
-
- entity player = GetPlayerArray()[ 0 ]
- if ( !IsValid( player ) )
- return
-
- player.EndSignal( "OnDeath" )
-
-
- //Remote_CallFunction_NonReplay( player, "ServerCallback_ShowHoloDecoding", logIndex )
-
- //wait 2
-
- thread StopAudioLogWhenPlayerFarAway( audioLogModel )
-
- audioLogModel.EndSignal( "StopAudioLog" )
-
- OnThreadEnd(
- function() : ( player, audioLogModel )
- {
- Remote_CallFunction_NonReplay( player, "ServerCallback_ClearScanningHudElem" )
- FlagClear( "AudioLogPlaying" )
- if ( IsValid( audioLogModel ) )
- {
- audioLogModel.Signal( "StopAudioLog" )
- EmitSoundAtPosition( TEAM_UNASSIGNED, audioLogModel.GetOrigin(), "LSTAR_Reloading_Beep_low" )
- delaythread( 2 ) AudioLogModelThink( audioLogModel )
- }
-
-
- }
- )
-
-
- if ( isBoyleAudioLog )
- {
- boyleAudioLogNumber = GetBoyleLogNumber( boyleLogInstanceNumber, audioLogModel )
- file.boyleAudioLogNumberAssignments[ boyleLogInstanceNumber ] = boyleAudioLogNumber
- }
- else
- waitthread PlayTimeShiftDialogue( player, audioLogModel, audioLogAlias )
-
-
-
-
- //------------------------------------------------
- // If this is the lecture hall, play the tail lines
- //-------------------------------------------------
- if ( instanceName == "audiolog_lecture_overgrown" )
- {
- if ( !Flag( "PlayerInterruptedLecture") )
- {
-
- //General Marder By decisively neutralizing the Militia forces,
- //we will in fact, safeguard the existence of the human race, extending its reach and power towards a prosperous, and bright future.
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "lectureLogB" )
- }
- else
- {
- entity soundDummy = CreateLoudspeakerEnt( audioLogModel.GetOrigin() )
-
- //General Marder By decisively neutralizing the Militia forces,
- //we will in fact, safeguard the existence of the human race, extending its reach and power towards a prosperous, and bright future.
- thread PlayTimeShiftDialogue( player, soundDummy, "lectureLogB" )
- wait file.lectureHallTimeBeforePlayerInterrupts
-
- //General Marder Yes, test Pilot? May I help you?
- soundDummy.Destroy()
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "lectureLogC" )
-
- }
- }
-
- //------------------------------------------------
- // If this is a Boyle log, play all the aliases for the log number
- //-------------------------------------------------
- else if ( isBoyleAudioLog )
- {
- array <string> aliases
- if ( boyleAudioLogNumber == 1 )
- {
- //---------------------------------------
- // Boyle audio logs: 1
- //---------------------------------------
- //Dr. Jefferson Boyle - Log one. Looks like they went forward with the Ark test despite my warnings to postpone, but what Marder wants - Marder gets.
- aliases.append( "diag_sp_BoyleLog1_TS701_01_01_imc_boyle" )
-
- //I don’t know how I survived, but I did...for now. I don’t know how I survived, but I did...for now.
- aliases.append( "diag_sp_BoyleLog1_TS701_02_01_imc_boyle" )
-
- //I’ve tried all exits but I’m trapped; damn place is locked down good. All I have is Hope. That’s what I get for picking a lab underground... What can say? I like archaeology.
- aliases.append( "diag_sp_BoyleLog1_TS701_03_01_imc_boyle" )
- }
- else if ( boyleAudioLogNumber == 2 )
- {
-
- //---------------------------------------
- // Boyle audio logs: 2
- //---------------------------------------
- //Dr. Jefferson Boyle Log 2 Dr. Jefferson Boyle - Log two. I found myself a standard IMC survival kit, which provides me with enough flavorless rations to keep me alive for a few days. Dr. Jefferson Boyle. Log two. I found myself a standard IMC survival kit, which provides me with enough flavorless rations to keep me alive for a few days.
- aliases.append( "diag_sp_BoyleLog2_TS701_04_01_imc_boyle" )
-
- //Dr. Jefferson Boyle Log 2 I’m hoping that’s all I need otherwise I’m going to have to get creative. I hate getting creative... I’m hoping that’s all I need otherwise I’m going to have to get creative. I hate getting creative...
- aliases.append( "diag_sp_BoyleLog2_TS701_05_01_imc_boyle" )
-
- //Dr. Jefferson Boyle Log 2 I hate getting creative...
- //aliases.append( "diag_sp_BoyleLog2_TS701_06_01_imc_boyle" )
-
- }
- else if ( boyleAudioLogNumber == 3 )
- {
-
- //---------------------------------------
- // Boyle audio logs: 3
- //---------------------------------------
- //Dr. Jefferson Boyle Log 3 Dr. Jefferson Boyle - Log three. I had to get creative. Failed experiments on Typhon’s indigenous wildlife are unfortunately next door...in other words, I cooked a prowler. Dr. Jefferson Boyle. Log three. I had to get creative. Failed experiments on Typhon’s indigenous wildlife are unfortunately next door...in other words, I cooked a prowler.
- aliases.append( "diag_sp_BoyleLog3_TS701_07_01_imc_boyle" )
-
- //Dr. Jefferson Boyle Log 3 It tasted like chicken if chicken was a weird dinosaur-like creature injected with IMC meds and steroids. It tasted like chicken if chicken was a weird dinosaur-like creature injected with IMC meds and steroids.
- aliases.append( "diag_sp_BoyleLog3_TS701_08_01_imc_boyle" )
-
- //Dr. Jefferson Boyle Log 3 On a lighter note, I think I found a way to upload these logs to what's left of the IMC network here. Maybe someone's monitoring...here's to Hope. On a lighter note, I think I found a way to upload these logs to what's left of the IMC network here. Maybe someone's monitoring...here's to Hope.
- aliases.append( "diag_sp_BoyleLog3_TS701_09_01_imc_boyle" )
-
- }
- else if ( boyleAudioLogNumber == 4 )
- {
- //---------------------------------------
- // Boyle audio logs: 4
- //---------------------------------------
- //Dr. Jefferson Boyle Log 4 Dr. Jefferson Boyle - Log four. All right, my logs are on the network but unfortunately, I am out of Prowler so I'm pretty disappointed. Dr. Jefferson Boyle. Log four. All right, my logs are on the network but unfortunately, I am out of Prowler so I'm pretty disappointed.
- aliases.append( "diag_sp_BoyleLog4_TS701_10_01_imc_boyle" )
-
- //Dr. Jefferson Boyle Log 4 I’ve moved on to the vines and plants growing throughout this facility. I’ve moved on to the vines and plants growing throughout this facility.
- aliases.append( "diag_sp_BoyleLog4_TS701_11_01_imc_boyle" )
-
- //Dr. Jefferson Boyle Log 4 It’s raining non-stop so I have water, at least I think it’s water. It’s raining non-stop so I have water, at least I think it’s water.
- aliases.append( "diag_sp_BoyleLog4_TS701_12_01_imc_boyle" )
-
- //Dr. Jefferson Boyle Log 4 Yeah, it's water. It's definitely water....I think. Um, I gotta go run some tests... Yeah, it's water. It's definitely water...I think. Um, I got to go run some tests...
- aliases.append( "diag_sp_BoyleLog4_TS701_13_01_imc_boyle" )
-
- }
- else if ( boyleAudioLogNumber == 5 )
- {
- //---------------------------------------
- // Boyle audio logs: 5
- //---------------------------------------
-
- //Dr. Jefferson Boyle Log 5 Dr. Jefferson Boyle - Log five. Okay, good news, tests came back negative...it is water. Bad news... Literally everything else. Nothing's good. Dr. Jefferson Boyle. Log five. Okay, good news, tests came back negative...it is water. Bad news... Literally everything else. Nothing's good.
- aliases.append( "diag_sp_BoyleLog5_TS701_14_01_imc_boyle" )
-
- //Dr. Jefferson Boyle Log 5 I think it's time I get out of this place. I've managed to breach a hole in the wall, it leads up to the main campus. I think it's time I get out of this place. I've managed to breach a hole in the wall, it leads up to the main campus.
- aliases.append( "diag_sp_BoyleLog5_TS701_15_01_imc_boyle" )
-
- //Dr. Jefferson Boyle Log 5 I'm about 100 meters underground. I have no idea how long it'll take me to get to the top because I'm horrible at math, but I am an archaeologist; I've done some climbing before. I'm about 100 meters underground. I have no idea how long it'll take me to get to the top because I'm horrible at math, but I am an archaeologist; I've done some climbing before.
- aliases.append( "diag_sp_BoyleLog5_TS701_16_01_imc_boyle" )
-
- //Dr. Jefferson Boyle Log 5 I just don't know what I'll find when I get up there but I have no choice. Okay, I have a choice but right now, it's not to die. I just don't know what I'll find when I get up there but I have no choice. Okay, I have a choice but right now, it's not to die.
- aliases.append( "diag_sp_BoyleLog5_TS701_17_01_imc_boyle" )
-
- //Dr. Jefferson Boyle Log 5 So, that's it. This is my final entry. Wish me luck. So, that's it. This is my final entry. Wish me luck.
- aliases.append( "diag_sp_BoyleLog5_TS701_18_01_imc_boyle" )
-
- //Dr. Jefferson Boyle Log 5 See you soon, Hope. See you soon, Hope.
- aliases.append( "diag_sp_BoyleLog5_TS701_19_01_imc_boyle" )
-
- //Dr. Jefferson Boyle Log 5 Dr. Jefferson Boyle - Signing Off. Err.. over and out. Is that how you say it? Whatever... bye. Dr. Jefferson Boyle. Signing Off. Err.. over and out. Is that how you say it? Whatever... bye.
- aliases.append( "diag_sp_BoyleLog5_TS701_20_01_imc_boyle" )
-
- }
- else
- Assert( 0, "Invalid Boyle audio log number " + boyleAudioLogNumber )
-
- foreach( alias in aliases )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, alias )
- }
-
-
-
-
- //-------------------------------------------------------------
- // If this is the full ted talk, play the whole damn thing
- //--------------------------------------------------------------
- else if ( instanceName == "audiolog_ted_talk" )
- {
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk02" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk03" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk04" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk05" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk06" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk07" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk08" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk09" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk10" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk11" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk12" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk13" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk14" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk15" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk16" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk17" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk18" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk19" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk20" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk21" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk22" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk23" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk24" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk25" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk26" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk27" )
- waitthread PlayTimeShiftDialogue( player, audioLogModel, "tedTalk28" )
- }
-}
-
-///////////////////////////////////////////////////////////////////////////
-void function StopAudioLogWhenPlayerFarAway( entity audioLogModel )
-{
- if ( !IsValid( audioLogModel ) )
- return
-
- audioLogModel.EndSignal( "StopAudioLog" )
-
- array<entity> players = GetPlayerArray()
- if ( players.len() == 0 )
- return
-
- entity player = players[ 0 ]
- if ( !IsValid( player ) )
- return
-
- var timeZoneAudioLog = GetEntityTimelinePosition( audioLogModel )
- player.EndSignal( "OnDeath" )
-
- while( true )
- {
- wait 0.25
- if ( timeZoneAudioLog != level.timeZone ) //don't do distance check if we are in other timezone
- continue
- if ( !PlayerInRange( player.GetOrigin(), audioLogModel.GetOrigin(), DIST_TO_NOT_CARE_ABOUT_AUDIOLOGS ) )
- break
- }
-
-
- audioLogModel.Signal( "StopAudioLog" )
-}
-///////////////////////////////////////////////////////////////////////////
-bool function IsAudioLogBoyle( string instanceName )
-{
- if ( instanceName.find( "audiolog_boyle" ) == null )
- return false
- return true
-
-}
-///////////////////////////////////////////////////////////////////////////
-int function GetBoyleLogInstanceNumber( string instanceName )
-{
- int instanceNumber = -1
-
- if ( instanceName == "audiolog_boyle_0" )
- instanceNumber = 0
- else if ( instanceName == "audiolog_boyle_1" )
- instanceNumber = 1
- else if ( instanceName == "audiolog_boyle_2" )
- instanceNumber = 2
- else if ( instanceName == "audiolog_boyle_3" )
- instanceNumber = 3
- else if ( instanceName == "audiolog_boyle_4" )
- instanceNumber = 4
- else
- Assert( 0, "Unhandled instance name " + instanceName )
-
- Assert( instanceNumber > -1 )
-
- return instanceNumber
-}
-///////////////////////////////////////////////////////////////////////////
-int function GetBoyleLogNumber( int instanceNumber, entity audioLogModel )
-{
- int logNumber = file.boyleAudioLogNumberAssignments[ instanceNumber ]
- if ( logNumber == 0 )
- logNumber = GetNextBoyleLogNumber( audioLogModel )
-
- return logNumber
-
-}
-
-///////////////////////////////////////////////////////////////////////////
-int function GetNextBoyleLogNumber( entity audioLogModel )
-{
- int logNumber = file.boyleAudioLogsCollected + 1
- Assert( logNumber > 0 && logNumber < 6, "Boyle log at " + audioLogModel.GetOrigin() + " is trying to get assigned a number greater than 5: " + logNumber )
- file.boyleAudioLogsCollected++
-
- return logNumber
-}
-///////////////////////////////////////////////////////////////////////////
-void function TempAudioLogDevMsg( entity player )
-{
- Dev_PrintMessage( player, "#BLANK_TEXT", "#AUDIOLLOG_TEMPTEXT_TIMESHIFT", 3.0 )
-}
-
-////////////////////////////////////////////////////////////////////////////
-void function InitBoyleAudioLogs()
-{
- LevelTransitionStruct ornull trans = GetLevelTransitionStruct()
- if ( trans == null )
- return
-
- expect LevelTransitionStruct( trans )
- file.boyleAudioLogsCollected = trans.boyleAudioLogsCollected
-
- for ( int i = 0 ; i < file.boyleAudioLogNumberAssignments.len(); i++ )
- {
- file.boyleAudioLogNumberAssignments[ i ] = trans.boyleAudioLogNumberAssignments[ i ]
- }
-}
-
-////////////////////////////////////////////////////////////////////////////
-LevelTransitionStruct function SaveBoyleAudioLogs()
-{
- LevelTransitionStruct trans
- trans.boyleAudioLogsCollected = file.boyleAudioLogsCollected
-
- for ( int i = 0 ; i < trans.boyleAudioLogNumberAssignments.len(); i++ )
- {
- trans.boyleAudioLogNumberAssignments[ i ] = file.boyleAudioLogNumberAssignments[ i ]
- }
-
- return trans
-}
-
-
-///////////////////////////////////////////////////////////////////////////
-void function SetLectureHallLineDuration( float duration )
-{
- file. lectureHallTimeBeforePlayerInterrupts = duration
-}
-///////////////////////////////////////////////////////////////////////////
-
-void function ProwlersAmbientThink( entity npc )
-{
- npc.EnableNPCFlag( NPC_IGNORE_ALL )
- npc.SetNoTarget( true )
-}
-///////////////////////////////////////////////////////////////////////////
-
-void function LightFlickerThink( entity lightModelOff )
-{
- entity lightModelOn = lightModelOff.GetLinkEnt()
- Assert( IsValid( lightModelOn ), "Light model at " + lightModelOff.GetOrigin() + " needs to target a lit version of the same model" )
-
- lightModelOn.Hide()
- entity fx
-
- while( true )
- {
-
- wait RandomFloatRange( 0.5, 0.6 )
- lightModelOn.Show()
- lightModelOff.Hide()
- fx = PlayFXOnEntity( FX_DLIGHT_LIGHT_FLICKER, lightModelOn )
- EmitSoundOnEntity( lightModelOn, SOUND_LIGHT_FLICKER )
-
- wait RandomFloatRange( 0.3, 0.4 )
- lightModelOff.Show()
- lightModelOn.Hide()
- EntFireByHandle( fx, "Stop", "", 0, null, null )
-
- wait RandomFloatRange( 0.5, 0.6 )
- lightModelOn.Show()
- lightModelOff.Hide()
- fx = PlayFXOnEntity( FX_DLIGHT_LIGHT_FLICKER, lightModelOn )
-
- wait RandomFloatRange( 0.5, 0.6 )
- lightModelOff.Show()
- lightModelOn.Hide()
- EntFireByHandle( fx, "Stop", "", 0, null, null )
-
- wait RandomFloatRange( 0.5, 0.6 )
- lightModelOn.Show()
- lightModelOff.Hide()
- fx = PlayFXOnEntity( FX_DLIGHT_LIGHT_FLICKER, lightModelOn )
-
-
- wait RandomFloatRange( 0.01, 0.02 )
- lightModelOff.Show()
- lightModelOn.Hide()
- EntFireByHandle( fx, "Stop", "", 0, null, null )
-
- wait RandomFloatRange( 0.01, 0.02 )
- lightModelOn.Show()
- lightModelOff.Hide()
- fx = PlayFXOnEntity( FX_DLIGHT_LIGHT_FLICKER, lightModelOn )
- EmitSoundOnEntity( lightModelOn, SOUND_LIGHT_FLICKER )
-
- wait RandomFloatRange( 0.02, 0.03 )
- lightModelOff.Show()
- lightModelOn.Hide()
- EntFireByHandle( fx, "Stop", "", 0, null, null )
-
- wait RandomFloatRange( 1, 1.1 )
- lightModelOn.Show()
- lightModelOff.Hide()
- fx = PlayFXOnEntity( FX_DLIGHT_LIGHT_FLICKER, lightModelOn )
-
-
- wait RandomFloatRange( 0.2, 0.3 )
- lightModelOff.Show()
- lightModelOn.Hide()
- EntFireByHandle( fx, "Stop", "", 0, null, null )
-
- wait RandomFloatRange( 1, 1.1 )
- lightModelOn.Show()
- lightModelOff.Hide()
- fx = PlayFXOnEntity( FX_DLIGHT_LIGHT_FLICKER, lightModelOn )
- EmitSoundOnEntity( lightModelOn, SOUND_LIGHT_FLICKER )
-
- wait RandomFloatRange( 0.2, 0.3 )
- lightModelOff.Show()
- lightModelOn.Hide()
- EntFireByHandle( fx, "Stop", "", 0, null, null )
-
- wait RandomFloatRange( 0.2, 0.3 )
- lightModelOn.Show()
- lightModelOff.Hide()
- fx = PlayFXOnEntity( FX_DLIGHT_LIGHT_FLICKER, lightModelOn )
-
-
-
- wait RandomFloatRange( 0.01, 0.02 )
- lightModelOff.Show()
- lightModelOn.Hide()
- EntFireByHandle( fx, "Stop", "", 0, null, null )
-
- wait RandomFloatRange( 0.01, 0.02 )
- lightModelOn.Show()
- lightModelOff.Hide()
- fx = PlayFXOnEntity( FX_DLIGHT_LIGHT_FLICKER, lightModelOn )
- EmitSoundOnEntity( lightModelOn, SOUND_LIGHT_FLICKER )
-
- wait RandomFloatRange( 0.01, 0.02 )
- lightModelOff.Show()
- lightModelOn.Hide()
- EntFireByHandle( fx, "Stop", "", 0, null, null )
-
- wait RandomFloatRange( 0.01, 0.02 )
- lightModelOn.Show()
- lightModelOff.Hide()
- fx = PlayFXOnEntity( FX_DLIGHT_LIGHT_FLICKER, lightModelOn )
-
-
- wait RandomFloatRange( 0.02, 0.03 )
- lightModelOff.Show()
- lightModelOn.Hide()
- EntFireByHandle( fx, "Stop", "", 0, null, null )
-
-
- }
-
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////
-void function PlayerDropLand( entity player, entity node, bool doBlur = false )
-{
- entity moverNode = CreateScriptMover( node.GetOrigin(), node.GetAngles() )
-
- float targetZpos = node.GetOrigin().z + 16
-
- while( player.GetOrigin().z > targetZpos )
- WaitFrame()
-
- player.UnfreezeControlsOnServer()
- player.ClearInvulnerable()
-
- string anim3rd= "pt_timeshift_fall_land"
- string animPOV = "ptpov_timeshift_fall_land"
-
- player.SetAnimNearZ( 3 )
-
- if ( doBlur )
- Remote_CallFunction_Replay( player, "ServerCallback_FanDropBlur" )
-
- //PlayFPSAnimTeleportShowProxy( player, anim3rd, anim1st ref = null optionalTag, animView = null, float initialTime = 0.0 )
- waitthread PlayFPSAnimTeleportShowProxy( player, anim3rd, animPOV, moverNode, "REF", ViewConeTight )
- //wait 2
- player.ClearAnimNearZ()
- player.ClearParent()
- moverNode.Destroy()
- player.UnforceStand()
- player.Anim_Stop()
- ClearPlayerAnimViewEntity( player )
- player.ClearParent()
- player.EnableWeaponWithSlowDeploy()
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function RingsLocalExplosionNormal( entity rings )
-{
- if ( level.timeZone == TIMEZONE_NIGHT )
- return
- vector origin = rings.GetOrigin()
- //CreateShake( org, amplitude = 16, frequency = 150, duration = 1.5, radius = 2048 )
- thread CreateAirShake( origin, 4, 10, 1, 32000 )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function RingsLocalExplosionBig( entity rings )
-{
- if ( level.timeZone == TIMEZONE_NIGHT )
- return
-
- vector origin = rings.GetOrigin()
- //CreateShake( vector org, float amplitude = 16, float frequency = 150, float duration = 1.5, float radius = 2048 )
- thread CreateAirShake( origin, 4, 10, 1, 32000 )
-}
-
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-void function CreateShakeTimeshift( float amplitude, float frequency, float duration )
-{
- array<entity> players = GetPlayerArray()
- if ( players.len() == 0 )
- return
-
- entity player = players[ 0 ]
- if ( !IsValid( player ) )
- return
-
- CreateAirShake( player.GetOrigin(), amplitude, frequency, duration )
- //Remote_CallFunction_Replay( player, "ServerCallback_ScreenShake", amplitude, frequency, duration )
-}
-/////////////////////////////////////////////////////////////////////////////////////////
-void function CreateShakeWhileFlagSet( float amplitude, float frequency, float duration, string flagToShake, string flagToAbort )
-{
- array<entity> players = GetPlayerArray()
- if ( players.len() == 0 )
- return
-
- entity player = players[ 0 ]
- if ( !IsValid( player ) )
- return
-
- player.EndSignal( "OnDeath" )
- FlagEnd( flagToAbort )
-
- while ( true )
- {
- wait 0.1
- if ( Flag( flagToShake ) )
- {
- CreateAirShake( player.GetOrigin(), amplitude, frequency, duration )
- //Remote_CallFunction_Replay( player, "ServerCallback_ScreenShake", amplitude, frequency, duration )
- wait duration / 4
- }
- }
-
-}
-
-void function TitanTimeshiftHint( entity player )
-{
- Remote_CallFunction_Replay( player, "ServerCallback_ShowTitanTimeshiftHint" )
-}
-
-/////////////////////////////////////////////////////////////////////////////
-string function GetrandomDeathPose( asset deathModel )
-{
- if ( deathModel == MARVIN_MODEL_OVERGROWN )
- return "mv_timeshift_death_pose_01"
-
- array <string> deathPosesLocal = file.deathPoses
- deathPosesLocal.randomize()
- return deathPosesLocal[ 0 ]
-}
-
-/////////////////////////////////////////////////////////////////////////////
-void function FlyerAmbientThink( entity flyer )
-{
- if ( GetMapName() == "sp_hub_timeshift" )
- return
-
- flyer.EndSignal( "OnDeath" )
- flyer.EndSignal( "OnDestroy" )
-
- FlagWait( "ForceFlyerTakeoff" )
- flyer.Signal( "FlyerStopThink" )
- //flyer.WaitSignal( "FlyerTakeoffOverride" )
- wait RandomFloatRange( 0, 6 )
- thread FlyerTakeOff( flyer )
-}
-
-void function DropshipSpawnAndRepeat( entity dropship )
-{
- dropship.EndSignal( "OnDeath" )
- dropship.EndSignal( "OnDestroy" )
- dropship.EndSignal( "OnAnimationInterrupted" )
- entity animNode = dropship.GetLinkEnt()
- Assert( IsValid( animNode ) )
- string anim = expect string( animNode.kv.leveled_animation )
- float animLength = dropship.GetSequenceDuration( anim )
- Assert( IsValid( anim ) )
-
- bool repeat = true
- if ( dropship.GetScriptName() == "dropships_skybridge" )
- repeat = false
-
- OnThreadEnd(
- function() : ( dropship )
- {
- if ( IsValid( dropship ) )
- dropship.Destroy()
- }
- )
-
- while( true )
- {
-
- wait animLength
-
- if ( repeat == false )
- break
-
- }
-
-}
-
-
-void function DisableNavmeshSeperatorTargetedByEnt( entity doorModel )
-{
- array <entity> linkedEnts = doorModel.GetLinkEntArray()
- Assert( linkedEnts.len() > 0 )
- string classname
- entity navmeshBrush
-
- foreach( entity ent in linkedEnts )
- {
- classname = GetEditorClass( ent )
- if ( classname == "func_brush_navmesh_separator" )
- {
- navmeshBrush = ent
- break
- }
- }
-
- Assert( IsValid( navmeshBrush ), "Entity at " + doorModel.GetOrigin() + " isn't targeting a func_brush_navmesh_separator" )
-
- //navmeshBrush.Hide()
- navmeshBrush.NotSolid()
- ToggleNPCPathsForEntity( navmeshBrush, true )
-
-
-}
-
-
-
-
-void function ElectricalScreenEffects( entity player, string enabledFlag = "" )
-{
- EndSignal( player, "OnDeath" )
- EndSignal( player, "StopCoreEffects" )
- OnThreadEnd(
- function() : ( player )
- {
- if ( IsValid ( player ) )
- StopSoundOnEntity( player, EMP_IMPARED_SOUND )
- }
- )
-
- if ( enabledFlag != "" )
- {
- if ( !Flag( enabledFlag ) )
- FlagWait( enabledFlag )
- }
-
- array<entity> ents = GetEntArrayByScriptName( "BeaconScreenEffect" )
- array<vector> start
- array<vector> end
- array<float> radius
- foreach( entity ent in ents )
- {
- start.append( ent.GetOrigin() )
- end.append( ent.GetLinkEnt().GetOrigin() )
- radius.append( float( ent.kv.radius ) )
- }
-
- bool soundPlaying
- float maxAmount
- vector p
- while( true )
- {
- maxAmount = 0
- p = player.GetOrigin()
- for ( int i = 0 ; i < ents.len() ; i++ )
- {
- float d = GetDistanceFromLineSegment( start[i], end[i], p )
- float amount = GraphCapped( d, 0.0, radius[i], 1.0, 0.0 )
- maxAmount = max( amount, maxAmount )
- }
-
- if ( maxAmount > 0 )
- {
- StatusEffect_AddTimed( player, eStatusEffect.emp, maxAmount, 0.25, 0.05 )
- if ( !soundPlaying )
- {
- EmitSoundOnEntity( player, EMP_IMPARED_SOUND )
- soundPlaying = true
- }
- }
- else if ( soundPlaying )
- {
- StopSoundOnEntity( player, EMP_IMPARED_SOUND )
- soundPlaying = false
- }
-
- wait 0.1
- }
-}
-
-
-void function GivePropForAnim( entity npc, string anim )
-{
- if ( !IsValid( npc ) )
- return
-
- string tagName
- asset model
-
- if ( anim == "pt_lecture_student_1_idle" )
- {
- tagName = "L_HAND"
- model = MODEL_IPAD
- }
-
- else if ( anim == "pt_lecture_student_2_idle" )
- {
- tagName = "R_HAND"
- model = MODEL_COFFEE
- }
-
- else if ( anim == "pt_lecture_student_5_idle" )
- {
- tagName = "L_HAND"
- model = MODEL_IPAD
- }
- else if ( anim == "pt_civ_walk_tablet" )
- {
- tagName = "R_HAND"
- model = MODEL_IPAD
- }
-
- else if ( anim == "pt_civ_walk_tablet_reading" )
- {
- tagName = "R_HAND"
- model = MODEL_IPAD
- }
-
- else if ( anim == "pt_civ_walk_drink" )
- {
- tagName = "R_HAND"
- model = MODEL_COFFEE
- }
-
- else
- return
-
- entity prop = CreatePropDynamic( model )
- prop.SetParent( npc, tagName, false )
-}
-
-
-
-void function LoudspeakerThread( entity player )
-{
-
- //if ( GetBugReproNum() != 202020 )
- //return
-
- if ( !IsValid( player ) )
- return
-
- if ( file.loudspeakerThreadRunning )
- return
-
- FlagSet( "ShouldPlayGlobalLoudspeker" )
-
- file.loudspeakerThreadRunning = true
-
- player.EndSignal( "OnDeath" )
-
- wait 3
-
- array <string> arrayLoudspeakerLines
- arrayLoudspeakerLines.append( "diag_sp_ambScience_TS551_01_01_imc_sci" )
- arrayLoudspeakerLines.append( "diag_sp_ambScience_TS551_02_01_imc_sci" )
- arrayLoudspeakerLines.append( "diag_sp_ambScience_TS551_03_01_imc_sci" )
- arrayLoudspeakerLines.append( "diag_sp_ambScience_TS551_04_01_imc_sci" )
- arrayLoudspeakerLines.append( "diag_sp_ambScience_TS551_05_01_imc_sci" )
- arrayLoudspeakerLines.append( "diag_sp_ambScience_TS551_06_01_imc_sci" )
- arrayLoudspeakerLines.append( "diag_sp_ambScience_TS551_07_01_imc_sci" )
- arrayLoudspeakerLines.append( "diag_sp_ambScience_TS551_08_01_imc_sci" )
-
- int numberOfLoudspeakerLines = arrayLoudspeakerLines.len() -1
-
- entity loudspeakerEnt = CreateBestLoudspeakerEnt( player, TIMEZONE_DAY )
- int loudspeakerLineCount = 0
- //bool playSpectreLine = false
-
-
- while( true )
- {
- waitthread WaittillPlayerSwitchesTimezone( TIMEZONE_DAY )
-
- if ( !Flag( "ShouldPlayGlobalLoudspeker" ) )
- {
- FlagWait( "ShouldPlayGlobalLoudspeker" )
- continue
- }
-
- loudspeakerEnt = CreateBestLoudspeakerEnt( player, TIMEZONE_DAY, loudspeakerEnt )
-
- waitthread PlayTimeShiftDialogue( player, loudspeakerEnt, "Timeshift_Scr_AnnouncementChime" )
-
- //if ( playSpectreLine )
- //waitthread PlayTimeShiftDialogue( player, loudspeakerEnt, "Timeshift_Scr_SpectreAnnouncement" )
-
- waitthread PlayTimeShiftDialogue( player, loudspeakerEnt, arrayLoudspeakerLines[ loudspeakerLineCount ] )
- loudspeakerLineCount++
- if ( loudspeakerLineCount > numberOfLoudspeakerLines )
- loudspeakerLineCount = 0
-
-
- wait RandomFloatRange( 60, 70 )
-
- /*
- if ( playSpectreLine == false )
- playSpectreLine = true
- else if ( playSpectreLine == true )
- playSpectreLine = false
- */
- }
-}
-
-
-void function ButtonOvergrownThink( entity propDynamic, string whichButton )
-{
- asset swapModelName
- entity swapModel
-
- if ( whichButton == "small" )
- swapModelName = MODEL_BUTTON
- else
- swapModelName = MODEL_BUTTON_LARGE
-
- swapModel = CreatePropDynamic( swapModelName, propDynamic.GetOrigin(), propDynamic.GetAngles() )
-
- while( true )
- {
- swapModel.Hide()
- propDynamic.Show()
-
- wait RandomFloatRange( 2, 3 )
-
- swapModel.Show()
- propDynamic.Hide()
-
- wait 0.2
-
- swapModel.Hide()
- propDynamic.Show()
-
- wait 0.1
-
- swapModel.Show()
- propDynamic.Hide()
-
- wait 0.2
-
- swapModel.Hide()
- propDynamic.Show()
-
- wait 0.05
-
- swapModel.Show()
- propDynamic.Hide()
-
- wait 0.05
-
- swapModel.Hide()
- propDynamic.Show()
-
- wait 0.05
-
- swapModel.Show()
- propDynamic.Hide()
-
- wait 0.4
-
- swapModel.Hide()
- propDynamic.Show()
-
- wait 0.1
-
- swapModel.Show()
- propDynamic.Hide()
-
- wait 0.2
-
- swapModel.Hide()
- propDynamic.Show()
-
- wait 0.05
-
- swapModel.Show()
- propDynamic.Hide()
-
- }
-}
-
-
-entity function CreateTimeshiftCinematicFlyer( entity flyerModel, entity victim = null )
-{
- entity newFlyer = CreateServerFlyer( flyerModel.GetOrigin(), flyerModel.GetAngles(), 100 )
- flyerModel.Destroy()
- return newFlyer
-
-}
-
-///////////////////////////////////////////////////////////////////
-void function ObjectiveRemindUntilFlag( string flagToAbort )
-{
- Assert( IsNewThread(), "Must be threaded off" )
-
- if ( Flag( flagToAbort ) )
- return
- FlagEnd( flagToAbort )
-
- while( true )
- {
- wait RandomFloatRange( 45, 50 )
- if ( Flag( flagToAbort ) )
- break
- Objective_Remind()
-
- }
-
-
-}
-///////////////////////////////////////////////////////////////////
-void function SetFlagWhenPlayerWithinRangeOfEnt( entity player, entity ent, float minDist, string flagToSet )
-{
- if ( Flag( flagToSet ) )
- return
-
- if ( !IsValid( ent ) )
- return
-
- if ( !IsValid( player ) )
- return
-
- FlagEnd( flagToSet )
- ent.EndSignal( "OnDestroy" )
- ent.EndSignal( "OnDeath" )
- player.EndSignal( "OnDeath" )
-
- while( true )
- {
- wait 0.25
- if ( Distance( player.GetOrigin(), ent.GetOrigin() ) < minDist )
- {
- FlagSet( flagToSet )
- break
- }
-
- }
-
-}
-///////////////////////////////////////////////////////////////////
-
-bool function IsAudioLogPlaying( entity player )
-{
- if ( !IsValid( player ) )
- return false
-
- if ( !Flag( "AudioLogPlaying" ) )
- return false
-
- if ( !PlayerInRangeOfAnyLaptopWhatsoever( player ) )
- return false
-
- return true
-}
-///////////////////////////////////////////////////////////////////
-bool function PlayerInRangeOfAnyLaptopWhatsoever( entity player )
-{
- //even if an audio log is "playing", we don't care if player is more than X units away from any laptop
- foreach( model in file.audioLogModels )
- {
- if ( PlayerInRange( player.GetOrigin(), model.GetOrigin(), DIST_TO_NOT_CARE_ABOUT_AUDIOLOGS ) )
- return true
- }
-
- return false
-} \ No newline at end of file
diff --git a/Northstar.Coop/scripts/vscripts/sp/sh_coop_sp_utils.gnut b/Northstar.Coop/scripts/vscripts/sp/sh_coop_sp_utils.gnut
deleted file mode 100644
index 62f603e9..00000000
--- a/Northstar.Coop/scripts/vscripts/sp/sh_coop_sp_utils.gnut
+++ /dev/null
@@ -1,34 +0,0 @@
-untyped
-
-global function ClCoopSpUtils_Init
-global function AreAllPlayersDead
-
-global function IsPlayingTimeshiftLevel
-
-void function ClCoopSpUtils_Init()
-{
-
-}
-
-bool function AreAllPlayersDead()
-{
- foreach ( entity player in GetPlayerArray() )
- if ( IsAlive( player ) )
- return false
-
- return true
-}
-
-// TIMESHIFT STUFF
-
-bool function IsPlayingTimeshiftLevel()
-{
- bool allowed = false
- try
- {
- allowed = expect bool( level.allowTimeTravel )
- }
- catch ( exception ) {}
-
- return GetMapName().find( "timeshift" ) != null || allowed
-}
diff --git a/Northstar.Coop/scripts/vscripts/sp/sh_sp_objective.gnut b/Northstar.Coop/scripts/vscripts/sp/sh_sp_objective.gnut
deleted file mode 100644
index d98d4a6e..00000000
--- a/Northstar.Coop/scripts/vscripts/sp/sh_sp_objective.gnut
+++ /dev/null
@@ -1,537 +0,0 @@
-global function SPObjectiveInit
-
-const OBJECTIVE_DISPLAY_TIME = 8.0
-const FADE_IN_TIME = 0.2
-const FADE_OUT_TIME = 0.5
-const OBJECTIVE_DISPLAY_TOTAL_TIME = FADE_IN_TIME + OBJECTIVE_DISPLAY_TIME + FADE_OUT_TIME
-
-#if SERVER
- global function Objective_Set
- global function Objective_SetSilent
- global function Objective_Set_WithAltHighlight
- global function Objective_SetSilent_WithAltHighlight
- global function Objective_AddHighlightEntity
- global function Objective_Clear
- global function Objective_Hide
- global function Objective_Update
- global function Objective_InitEntity
- global function Objective_Remind
- global function Objective_AddKilometers
- global function Objective_StaticModelHighlightOverrideEntity // if set it will highlight this entity instead, and also hide/show the entity when highlighting. This helps us get around not being able to do model highlight on a static model
- global function Objective_StaticModelHighlightOverrideEntityArray
- global function Objective_GetMarkerEntity // Dont use this if you're not working on S2S
- global function Objective_SetFastball// Don't use this unless you grab the marker ent and clear it's parent after you're done
- global function Objective_WayPointEneable
- global function Objective_LastShownTime
- global function Objective_SuppressCloseMenuShowsObjective
-
- struct
- {
- array<entity> objectiveEntities
- entity objectiveMarkerEnt
- array<entity> objectiveHighlightEntArray
- array<entity> objectiveAltHighlightEntArray
- bool showingObjective
- float objectiveLastShownTime
- bool suppressCloseMenuShowsObjective
- bool objectiveAltHighlight = false
- } file
-#endif
-
-#if CLIENT
- global function ShowObjectiveLineChanged
- global function ObjectiveStringChanged
- global function ShowObjectiveChanged
-
- const OBJECTIVE_MARKER_MODEL = $"models/dev/editor_ref.mdl"
- const BLING_DURATION = 0.2
-
- struct
- {
- bool onTimeshiftLevel
- var objectiveRUI
- } file
-#endif
-
-void function SPObjectiveInit()
-{
- #if SERVER
- RegisterSignal( "ShowingObjective" )
- RegisterSignal( "HidingObjective" )
- AddClientCommandCallback( "ToggleObjective", ClientCommandToggleObjective )
- AddClientCommandCallback( "ShowObjective", ClientCommandShowObjective )
- #endif
-
- #if CLIENT
- PrecacheModel( OBJECTIVE_MARKER_MODEL )
- RegisterSignal( "ShowingObjectiveRUI" )
-
- file.onTimeshiftLevel = GetMapName().find( "sp_timeshift" ) == 0
- if ( file.onTimeshiftLevel )
- thread TimeshiftClientMarkerPositionThink()
- #endif
-}
-
-#if SERVER
- void function Objective_Remind()
- {
- foreach( entity player in GetPlayerArray() )
- ClientCommand( player, "ShowObjective" )
- }
-
- void function Objective_InitEntity( entity ent )
- {
- if ( ent.GetClassName() == "func_brush" )
- return
-
- // Add the entity to a valid list of highlightable objective entities
- // (allows highlighting to be enabled without errors before everyone updates their script to call this function)
- file.objectiveEntities.append( ent )
-
- // Make the entity always render so the highlighting wont stop working
- ent.DisableHibernation()
- ent.EnableRenderAlways()
- ent.kv.fadedist = 99999
-
- // Highlight and unhighlight to precache the highlight ability on this entity (required by code)
- Highlight_SetNeutralHighlight( ent, OBJECTIVE_HIGHLIGHT )
- Highlight_ClearNeutralHighlight( ent )
- }
-
- void function Objective_Set_WithAltHighlight( string objective, vector position = < 0, 0, 0 >, entity ent = null )
- {
- file.objectiveAltHighlight = true
- _ObjectiveSet( objective, position, ent, false )
- }
-
- void function Objective_SetSilent_WithAltHighlight( string objective, vector position = < 0, 0, 0 >, entity ent = null )
- {
- file.objectiveAltHighlight = true
- _ObjectiveSet( objective, position, ent, true )
- }
-
- void function Objective_Set( string objective, vector position = < 0, 0, 0 >, entity ent = null )
- {
- file.objectiveAltHighlight = false
- _ObjectiveSet( objective, position, ent, false )
- }
-
- void function Objective_SetSilent( string objective, vector position = < 0, 0, 0 >, entity ent = null )
- {
- file.objectiveAltHighlight = false
- _ObjectiveSet( objective, position, ent, true )
- }
-
- void function _ObjectiveSet( string objective, vector position, entity ent, bool silent )
- {
- UpdateMarkerEnt( position, ent )
- SetGlobalNetInt( "objectiveStringIndex", GetObjectiveStringID( objective ) )
-
- ClearObjectiveHighlight()
- file.objectiveHighlightEntArray = [ ent ]
- file.objectiveAltHighlightEntArray = []
- SetGlobalNetBool( "hilightingObjective", IsValid( ent ) )
- SetGlobalNetFloat( "additionalKilometers", 0.0 )
-
- if ( !silent )
- thread ShowNewObjective()
-
- int stringIndex = GetGlobalNetInt( "objectiveStringIndex" )
- foreach( entity player in GetPlayerArray() )
- Remote_CallFunction_UI( player, "ServerCallback_UI_ObjectiveUpdated", stringIndex )
- }
-
- void function ShowNewObjective()
- {
- wait 0.1 // give time to sent position and entity to client
- foreach( entity player in GetPlayerArray() )
- thread ShowObjectiveForDuration( player, OBJECTIVE_DISPLAY_TOTAL_TIME )
- }
-
- void function Objective_AddKilometers( float kilometers )
- {
- Assert( kilometers >= 0.0 && kilometers <= 128.0 )
- SetGlobalNetFloat( "additionalKilometers", kilometers )
- }
-
- void function Objective_AddHighlightEntity( entity ent )
- {
- file.objectiveHighlightEntArray.append( ent )
- }
-
- void function Objective_StaticModelHighlightOverrideEntity( entity ent )
- {
- ent.kv.rendermode = 3
- ent.kv.renderamt = 1
- ent.Hide()
- file.objectiveAltHighlightEntArray.append( ent )
- }
-
- void function Objective_StaticModelHighlightOverrideEntityArray( array<entity> ents )
- {
- foreach ( ent in ents )
- Objective_StaticModelHighlightOverrideEntity( ent )
- }
-
- void function Objective_Clear()
- {
- file.objectiveAltHighlight = false
- ClearObjectiveHighlight()
- file.objectiveHighlightEntArray = []
- file.objectiveAltHighlightEntArray = []
- SetGlobalNetBool( "hilightingObjective", false )
- SetGlobalNetInt( "objectiveStringIndex", 0 )
- SetGlobalNetFloat( "additionalKilometers", 0.0 )
-
- foreach( entity player in GetPlayerArray() )
- {
- Objective_Hide( player )
- Remote_CallFunction_UI( player, "ServerCallback_UI_ObjectiveUpdated", -1 ) //-1 is no objective
- }
- }
-
- void function Objective_Update( vector position, entity ent = null )
- {
- UpdateMarkerEnt( position, ent )
- ClearObjectiveHighlight()
- file.objectiveHighlightEntArray = [ ent ]
- file.objectiveAltHighlightEntArray = []
- SetGlobalNetBool( "hilightingObjective", IsValid( ent ) )
- }
-
- void function UpdateMarkerEnt( vector position, entity ent )
- {
- vector newPos = position
- bool showLine = IsValid( ent ) || (position != <0,0,0>)
-
- SetGlobalNetBool( "showObjectiveLine", showLine )
-
- if ( IsValid( ent ) )
- {
- newPos = ent.GetOrigin() + position
- }
-
- // Create marker ent every time
- RefreshMarkerEnt( newPos )
-
- if ( IsValid( ent ) )
- {
- if ( ent.GetClassName() != "info_target" )
- file.objectiveMarkerEnt.SetParent( ent, "", true )
- else
- CodeWarning( "Tried to set objective entity to an info_target. This isn't supported because they aren't sent to the client. Try using a script_mover_lightweight or prop_dynamic." )
- }
- }
-
- void function RefreshMarkerEnt( vector position )
- {
- if ( !IsValid( file.objectiveMarkerEnt ) )
- {
- file.objectiveMarkerEnt = CreateEntity( "info_target" )
- file.objectiveMarkerEnt.kv.spawnflags = SF_INFOTARGET_ALWAYS_TRANSMIT_TO_CLIENT
- DispatchSpawn( file.objectiveMarkerEnt )
-
- SetGlobalNetEnt( "objectiveMarkerEntity", file.objectiveMarkerEnt )
- }
-
- file.objectiveMarkerEnt.ClearParent()
- file.objectiveMarkerEnt.SetOrigin( position )
- }
-
- void function ShowObjectiveForDuration( entity player, float duration )
- {
- EndSignal( player, "OnDeath" )
- EndSignal( player, "OnDestroy" )
-
- // Make sure thread only runs once
- Signal( player, "ShowingObjective" )
- EndSignal( player, "ShowingObjective" )
- EndSignal( player, "HidingObjective" )
-
- player.SetPlayerNetBool( "showObjective", true )
- SetObjectiveHighlight()
- file.objectiveLastShownTime = Time()
-
- wait duration
- Objective_Hide( player )
- }
-
- void function Objective_Hide( entity player )
- {
- player.SetPlayerNetBool( "showObjective", false )
- ClearObjectiveHighlight()
- Signal( player, "HidingObjective" )
- }
-
- float function Objective_LastShownTime()
- {
- return file.objectiveLastShownTime
- }
-
- bool function ClientCommandToggleObjective( entity player, array<string> args )
- {
- bool isShowing = player.GetPlayerNetBool( "showObjective" )
-
- if ( isShowing )
- thread Objective_Hide( player )
- else
- thread ShowObjectiveForDuration( player, OBJECTIVE_DISPLAY_TOTAL_TIME )
-
- return true
- }
-
- bool function ClientCommandShowObjective( entity player, array<string> args )
- {
- if ( args.len() > 0 )
- {
- if ( args[0] == "closedSPMenu" && file.suppressCloseMenuShowsObjective )
- return true
- }
-
- if ( IsAlive( player ) )
- thread ShowObjectiveForDuration( player, OBJECTIVE_DISPLAY_TOTAL_TIME )
- return true
- }
-
- void function Objective_SuppressCloseMenuShowsObjective( bool enabled )
- {
- file.suppressCloseMenuShowsObjective = enabled
- }
-
- void function SetObjectiveHighlight()
- {
- // Alt highlight ent?
- if ( file.objectiveAltHighlightEntArray.len() )
- {
- foreach ( ent in file.objectiveAltHighlightEntArray )
- {
- if ( !IsValid( ent ) )
- continue
- Assert( file.objectiveEntities.contains( ent ), "Tried to use Objective_StaticModelHighlightOverrideEntity on entity that didn't call Objective_InitEntity" )
- ent.Show()
- Highlight_SetNeutralHighlight( ent, OBJECTIVE_HIGHLIGHT )
- }
- }
- else if ( file.objectiveHighlightEntArray.len() )
- {
- foreach ( ent in file.objectiveHighlightEntArray )
- {
- if ( !IsValid( ent ) )
- continue
-
- if ( file.objectiveEntities.contains( ent ) )
- Highlight_SetNeutralHighlight( ent, OBJECTIVE_HIGHLIGHT )
- }
- }
- }
-
- void function ClearObjectiveHighlight()
- {
- // Alt highlight ent?
- if ( file.objectiveAltHighlightEntArray.len() )
- {
- foreach ( ent in file.objectiveAltHighlightEntArray )
- {
- if ( !IsValid( ent ) )
- continue
- Assert( file.objectiveEntities.contains( ent ), "Tried to use Objective_StaticModelHighlightOverrideEntity on entity that didn't call Objective_InitEntity" )
- ClearObjectiveHighlight_Internal( ent )
- ent.Hide()
- }
- }
- else if ( file.objectiveHighlightEntArray.len() )
- {
- foreach ( ent in file.objectiveHighlightEntArray )
- {
- if ( !IsValid( ent ) )
- continue
- if ( file.objectiveEntities.contains( ent ) )
- ClearObjectiveHighlight_Internal( ent )
- }
- }
- }
-
- void function ClearObjectiveHighlight_Internal( entity ent )
- {
- if ( !file.objectiveAltHighlight )
- Highlight_ClearNeutralHighlight( ent )
- else
- Highlight_SetNeutralHighlight( ent, OBJECTIVE_HIGHLIGHT_ALT )
- }
-
- entity function Objective_GetMarkerEntity()
- {
- return file.objectiveMarkerEnt
- }
-
- entity function Objective_WayPointEneable( bool enable )
- {
- SetGlobalNetBool( "objectiveMarkerIsWayPoint", enable )
- }
-
- // Don't use this unless you grab the marker ent and clear it's parent after you're done
- void function Objective_SetFastball( entity bt )
- {
- entity marker = Objective_GetMarkerEntity()
- string tag = "HAND_R"
- int attachID = bt.LookupAttachment( tag )
- vector angles = bt.GetAttachmentAngles( attachID )
- vector offset = AnglesToRight( angles ) * 20
- marker.SetOrigin( bt.GetAttachmentOrigin( attachID ) + offset )
- marker.SetParent( bt, tag, true, 0 )
- }
-
-
-#endif
-
-
-
-
-
-
-
-
-
-
-#if CLIENT
- void function ObjectiveStringChanged( entity player, int oldString, int newString, bool actuallyChanged )
- {
- if ( file.objectiveRUI == null )
- return
-
- if ( newString == 0 )
- return
-
- string objectiveText = GetObjectiveStringFromID( newString )
- RuiSetString( file.objectiveRUI, "objectiveText", objectiveText )
- }
-
- void function ShowObjectiveLineChanged( entity player, bool old, bool new, bool actuallyChanged )
- {
- if ( file.objectiveRUI == null )
- return
-
- if ( !new )
- RuiSetBool( file.objectiveRUI, "showLine", false )
- else
- RuiSetBool( file.objectiveRUI, "showLine", true )
-
- if ( GetGlobalNetBool( "hilightingObjective" ) == true || !new )
- RuiSetBool( file.objectiveRUI, "showMarker", false )
- else
- RuiSetBool( file.objectiveRUI, "showMarker", true )
- }
-
- void function ShowObjectiveChanged( entity player, bool wasShowing, bool isShowing, bool actuallyChanged )
- {
- if ( !actuallyChanged )
- return
-
- if ( isShowing )
- thread ShowObjective( true )
- else
- HideObjective()
- }
-
- void function ShowObjective( bool newObjective )
- {
- // Make sure only one RUI is displayed at a time
- Signal( clGlobal.levelEnt, "ShowingObjectiveRUI" )
- EndSignal( clGlobal.levelEnt, "ShowingObjectiveRUI" )
-
- entity marker = GetGlobalNetEnt( "objectiveMarkerEntity" )
- if ( !IsValid( marker ) )
- return
-
- OnThreadEnd(
- function() : ( )
- {
- HideObjective()
- }
- )
-
- int stringIndex = GetGlobalNetInt( "objectiveStringIndex" )
- if ( stringIndex == 0 )
- return
-
- string titleText = newObjective ? "#OBJECTIVE_UPDATED" : "#OBJECTIVE_REMIND"
- bool isWayPoint = GetGlobalNetBool( "objectiveMarkerIsWayPoint" )
- if( isWayPoint )
- titleText = "#OBJECTIVE_WAYPOINT"
-
- string objectiveText = GetObjectiveStringFromID( stringIndex )
- float additionalKilometers = GetGlobalNetFloat( "additionalKilometers" )
-
- HideObjective()
- file.objectiveRUI = CreatePermanentCockpitRui( $"ui/sp_objective.rpak", 0 )
-
- RuiSetGameTime( file.objectiveRUI, "startTime", Time() )
- RuiSetGameTime( file.objectiveRUI, "endTime", Time() + OBJECTIVE_DISPLAY_TIME )
- RuiSetFloat( file.objectiveRUI, "fadeInDuration", FADE_IN_TIME )
- RuiSetFloat( file.objectiveRUI, "fadeOutDuration", FADE_OUT_TIME )
- RuiSetFloat( file.objectiveRUI, "blingDuration", newObjective ? BLING_DURATION : 0.0 )
- RuiSetString( file.objectiveRUI, "objectiveTitleText", titleText )
- RuiSetString( file.objectiveRUI, "objectiveText", objectiveText )
- RuiSetBool( file.objectiveRUI, "showButtonHint", newObjective )
-
- // handle objective position in code on timeshift levels
- if ( !file.onTimeshiftLevel )
- RuiTrackFloat3( file.objectiveRUI, "pos", marker, RUI_TRACK_ABSORIGIN_FOLLOW )
-
- RuiSetFloat( file.objectiveRUI, "additionalKilometers", additionalKilometers )
-
- if ( !GetGlobalNetBool( "showObjectiveLine" ) )
- RuiSetBool( file.objectiveRUI, "showLine", false )
-
- if ( GetGlobalNetBool( "hilightingObjective" ) == true || !GetGlobalNetBool( "showObjectiveLine" ) )
- RuiSetBool( file.objectiveRUI, "showMarker", false )
-
- EmitSoundOnEntity( GetLocalClientPlayer(), "ui_holotutorial_analyzingfinish" )
-
- wait OBJECTIVE_DISPLAY_TOTAL_TIME
- }
-
- void function HideObjective()
- {
- if ( file.objectiveRUI != null )
- {
- RuiDestroyIfAlive( file.objectiveRUI )
- file.objectiveRUI = null
- }
- }
-
- void function TimeshiftClientMarkerPositionThink()
- {
- while ( true )
- {
- WaitFrame()
-
- if ( IsValid( file.objectiveRUI ) )
- {
- // marker is how the server tells us the objective pos
- entity marker = GetGlobalNetEnt( "objectiveMarkerEntity" )
- if ( !IsValid( marker ) )
- continue // unsure if this can even ever be hit
-
- // get our current timeline and get zoffset for it
- int zOffset = 0
- if ( marker.GetOrigin().z < -6000 ) // frozen time
- {
- RuiTrackFloat3( file.objectiveRUI, "pos", marker, RUI_TRACK_ABSORIGIN_FOLLOW )
- break // once we hit frozen time, all objectives from now will be on the same timeline as players so we can use normal objective pos logic
- }
- else if ( marker.GetOrigin().z < 5300 && GetLocalClientPlayer().GetOrigin().z > 5300 ) // marker in night, player in day
- zOffset = TIME_ZOFFSET
- else if ( marker.GetOrigin().z > 5300 && GetLocalClientPlayer().GetOrigin().z < 5300 ) // marker in day, player in night
- zOffset = TIME_ZOFFSET * -1
-
- // set objective pos
- vector pos = marker.GetOrigin() + Vector( 0, 0, zOffset )
- //RuiSetString( file.objectiveRUI, "objectiveTitleText", "marker: " + marker.GetOrigin() + ", player: " + GetLocalClientPlayer().GetOrigin() + ", offset: " + zOffset )
- RuiSetFloat3( file.objectiveRUI, "pos", pos )
- }
- }
- }
-
-#endif
-
diff --git a/Northstar.Coop/scripts/vscripts/sp/sp_training.nut b/Northstar.Coop/scripts/vscripts/sp/sp_training.nut
deleted file mode 100644
index 21a67a40..00000000
--- a/Northstar.Coop/scripts/vscripts/sp/sp_training.nut
+++ /dev/null
@@ -1,7554 +0,0 @@
-global function CodeCallback_MapInit
-
-#if DEV
-global function skyboxchange
-global function GetOGPilot
-global function wallruntest
-global function Record_ZenGarden_Wallrun
-global function Record_ZenGarden_Slide
-global function Record_ZenGarden_DoubleJump
-global function shutdownscreentest
-global function SendTrainingGauntletStats
-global function FancyTeleport_EffectsAndSound
-global function Training_WeaponRacks_SetSolidity
-global function setfakeinstalldone
-
-global function Training_EnvArtColorCorrection_SetEnabled
-global function SimpleScreenShake
-global function GetSkitGuyInfo_ByName
-global function NudgeSkitGuy
-#endif
-
-const MARVIN_MODEL = $"models/robots/marvin/marvin.mdl"
-const asset FX_POD_LASER = $"P_pod_scan_laser_FP"
-const asset FX_POD_GLOWLIGHT = $"P_pod_door_glow_FP"
-const asset FX_POD_SCREEN_IN = $"P_pod_screen_lasers_IN"
-const asset FX_POD_SCREEN_OUT = $"P_pod_screen_lasers_OUT"
-const asset FX_POD_DLIGHT_CONSOLE1 = $"P_pod_Dlight_console1"
-const asset FX_POD_DLIGHT_CONSOLE2 = $"P_pod_Dlight_console2"
-//const asset FX_POD_DLIGHT_BACKLIGHT_SIDE = $"P_pod_Dlight_backlight_side"
-//const asset FX_POD_DLIGHT_BACKLIGHT_TOP = $"P_pod_Dlight_backlight_top"
-const asset FX_FANCY_TELEPORT_ENV_PULSE = $"P_ar_holopulse_CP"
-const asset FX_COCKPIT_LIGHT = $"xo_cockpit_dlight"
-const asset OG_PILOT_HELMET_MODEL = $"models/Humans/heroes/mlt_hero_anderson_helmet.mdl"
-const asset ANDERSON_PILOT_MODEL = $"models/humans/heroes/mlt_hero_anderson.mdl"
-const asset PILOT_MODEL_BAY1 = $"models/humans/pilots/sp_medium_geist_f.mdl"
-const asset PILOT_MODEL_BAY2 = $"models/humans/pilots/sp_medium_reaper_m.mdl"
-const asset BUDDY_MODEL_POSED_NO_ANIMS = $"models/Titans/buddy/BT_posed.mdl"
-const asset SAFETY_BATON_MODEL = $"models/industrial/safety_baton.mdl"
-
-const asset OG_PILOT_MODEL = $"models/humans/heroes/mlt_hero_lastimosa.mdl"
-const int OG_PILOT_MODEL_HEAD_IDX_BARE = 0
-const int OG_PILOT_MODEL_HEAD_IDX_HELMET = 2
-const int OG_PILOT_MODEL_DECAL_IDX = 0
-const int OG_PILOT_MODEL_DECAL_IDX_BARE = 1
-
-const string OG_WEAPON = "mp_weapon_rspn101"
-
-const string ANIM_OG_STANDING_IDLE = "OG_stand_upright_idle"
-const string ANIM_OG_STANDING_TALK = "OG_stand_upright_talk"
-const string ANIM_OG_SITTING_IDLE = "OG_sit_high_idle"
-const string ANIM_OG_SITTING_TALK = "OG_sit_high_talk"
-const string ANIM_OG_LEANING_IDLE = "OG_stand_lean_idle"
-const string ANIM_OG_LEANING_TALK = "OG_stand_lean_talk"
-
-const int SCRIPTED_PATH_WALK = 0
-const int SCRIPTED_PATH_RUN = 1
-
-const int MAX_RECREATED_OLD_WEAPONS = 16
-
-const float TITANFALL_NAG_DURATION = 3.0 // extra time compensation for nag line playing when titanfall started
-
-const string TRAINING_PLAYER_SETTINGS = "pilot_solo_training"
-
-struct TrainingPod_dLightMapping
-{
- string scriptAlias
- asset fxName
- string attachName
- entity fxHandle
-}
-
-struct TrainingPod_LaserEmitter
-{
- entity ent
- string attachName
- vector ogAng
- bool sweepDone = false
- entity fxHandle
-}
-
-struct TrainingPod_GlowLightRow
-{
- array<string> fxSpotsL
- array<string> fxSpotsR
-}
-
-struct LoudspeakerVO_Info
-{
- string scriptAlias
- string soundAlias
- float duration
-}
-
-struct FiringRangeTarget
-{
- entity ent
- entity angleRefEnt
- entity mover
- bool wasDamaged
- vector ogAngles
-}
-
-struct SkitGuyInfo
-{
- int id
- string name
- string skitAnim
- entity guy
- entity skitRef
-}
-
-struct HangarTitanGroup
-{
- entity ref
-
- entity titan
- entity rack
- entity marvin
- entity pilot
-
- int titanSkin = -1
-
- string titanAnim
- string rackAnim
- string marvinAnim
- string pilotAnim
-
- asset pilotModel
-
- vector rack_ogPos
- vector rack_ogAng
-
- float sequenceDuration
- float animInitialTime = 0.0
-
- bool isInited = false
-}
-
-struct TrainingGauntletStats
-{
- bool didBeatRequiredTime = false
- int numRunsBeforeBeatRequiredTime = 0
- int numChallengeRuns = 0
- int numRestarts = 0
- float bestTime = -1.0
- int recommendedDifficulty = 0
-}
-
-struct
-{
- #if DEV
- bool fakeInstallDone = false
- #endif
-
- bool gauntletMode = false
-
- entity player
- int playerInputType
-
- entity ogPilot
- entity ogTwin
- entity anderson
- entity titanTwin
- entity ogHelmet
- entity playerAnimWeapon
-
- entity ogPathMover
-
- entity animref_hangar
- entity animref_leaveGauntlet
-
- entity trainingPod
- array<TrainingPod_GlowLightRow> trainingPodGlowLightRows
- array<entity> trainingPodGlowLightFXHandles
- array<TrainingPod_dLightMapping> trainingPodDLightMappings
- array<TrainingPod_LaserEmitter> trainingPodLaserEmitters
-
- float postWallrunVOEndTime = -1
-
- float titanfallNagStartTime = -1
- vector playerTitanCallInPos
-
- entity envArt_colorCorrectionEnt
- entity skycam_default
- entity skycam_glitch
-
- table<string,LoudspeakerVO_Info> loudspeakerVO = {}
- entity loudspeaker
-
- array<FiringRangeTarget> firingRangeTargets = []
-
- //table<string,SkitGuyInfo> skitguys = {}
- array<SkitGuyInfo> skitguys = []
-
- TrainingGauntletStats trainingGauntletStats
-
- array<entity> scriptCreatedWeaponPickups = []
- bool weaponPickupsHaveAmmo = false
-
- bool displayWeaponHUD = true
-} file
-
-void function CodeCallback_MapInit()
-{
- FlagSet( "FlightPath_TitanDrop" )
-
- PrecacheParticleSystem( FX_POD_LASER )
- PrecacheParticleSystem( FX_POD_GLOWLIGHT )
- PrecacheParticleSystem( FX_POD_SCREEN_IN )
- PrecacheParticleSystem( FX_POD_SCREEN_OUT )
- PrecacheParticleSystem( FX_POD_DLIGHT_CONSOLE1 )
- PrecacheParticleSystem( FX_POD_DLIGHT_CONSOLE2 )
- //PrecacheParticleSystem( FX_POD_DLIGHT_BACKLIGHT_SIDE )
- //PrecacheParticleSystem( FX_POD_DLIGHT_BACKLIGHT_TOP )
- PrecacheParticleSystem( FX_FANCY_TELEPORT_ENV_PULSE )
- PrecacheParticleSystem( FX_COCKPIT_LIGHT )
-
- PrecacheModel( OG_PILOT_HELMET_MODEL )
- PrecacheModel( OG_PILOT_MODEL )
- PrecacheModel( ANDERSON_PILOT_MODEL )
- PrecacheModel( PILOT_MODEL_BAY1 )
- PrecacheModel( PILOT_MODEL_BAY2 )
- PrecacheModel( BUDDY_MODEL_POSED_NO_ANIMS )
- PrecacheModel( SAFETY_BATON_MODEL )
- PrecacheModel( MARVIN_MODEL )
- PrecacheModel( DATA_KNIFE_MODEL )
-
- LoudspeakerVO_Setup()
- Training_SharedInit()
-
- RegisterSignal( "ButtonPressedJump" )
- RegisterSignal( "ButtonPressedAttack" )
- RegisterSignal( "PodIntro_OG_StartPodAnim" )
- RegisterSignal( "PodInteriorSequenceDone" )
- RegisterSignal( "FancyTeleportStart" )
- RegisterSignal( "TargetRotate" )
- RegisterSignal( "TargetDamaged" )
- RegisterSignal( "Target_WaitForDamage_Start" )
- RegisterSignal( "StopRepeatingGhostRecorder" )
- RegisterSignal( "FiringRange_StopResettingTargets" )
- RegisterSignal( "Gauntlet_StopTeleportingPlayerAtFinishLine" )
- RegisterSignal( "FirstRun_OG_Creates_Ghost" )
- RegisterSignal( "GauntletChallenge_FirstGhostAppear" )
- RegisterSignal( "PlayerMadeSelection" )
- RegisterSignal( "TrainingPod_BeginInteriorShutdown" )
- RegisterSignal( "NPC_NewCommand" )
- RegisterSignal( "LoudspeakerVO_Stop" )
- RegisterSignal( "glitch_start" )
-
- FlagInit( "PlayerPressedUse" )
- FlagInit( "PlayerReloaded" )
- FlagInit( "PodIntro_PodDoorsClosed" )
- FlagInit( "PlayerLookedAtTopTarget" )
- FlagInit( "PlayerLookedAtBottomTarget" )
- FlagInit( "PodIntro_InteriorBootSequence_Starting" )
- FlagInit( "OG_WhyWeFight_VO_Done" )
- FlagInit( "FiringRange_Approach_OG_Sequence_Done" )
- FlagInit( "ReloadTraining_PlayerPressedReload" )
- FlagInit( "PlayerSprinted" )
- FlagInit( "PlayerADSed" )
- FlagInit( "FiringRangeWeaponSwapped" )
- FlagInit( "FiringRange_AllTargetsKilled" )
- FlagInit( "OG_MovedTo_GauntletEntrance" )
- FlagInit( "Gauntlet_FirstRun_All_VO_Finished" )
- FlagInit( "Gauntlet_FirstRun_Done" )
- FlagInit( "ChallengeIntro_VO_Done" )
- FlagInit( "Gauntlet_PlayingFeedbackVO" )
- FlagInit( "PlayerUsedConversationInterface" )
- FlagInit( "GauntletExitConvo_FinishedResponse" )
- FlagInit( "TitanfallIntroConvo_FinishedResponse" )
- FlagInit( "PlayerConfirmedGauntletExit" )
- FlagInit( "PlayerLeavingGauntlet" )
- FlagInit( "PlayerStartedTitanfall" )
- FlagInit( "Titanfall_OG_FallingIn_VO_Start" )
- FlagInit( "TitanfallGlitchStart" )
- FlagInit( "PlayerWorldChangeThread" )
- FlagInit( "Glitch_WorldChanging_Zen" )
- FlagInit( "Glitch_WorldChanging_NonZen" )
- FlagInit( "PodOutroStarted" )
- FlagInit( "SimPodShutdown_LoudspeakerVO_Done" )
- FlagInit( "MeetOG_StartScene" )
- FlagInit( "CadillacMoment_MeetOG_Done" )
- FlagInit( "CadillacMoment_MeetOG_StartFadeOut" )
- FlagInit( "MeetOG_VO_Done" )
-
- FlagClear( "AutomaticCheckpointsEnabled" )
-
- AddClientCommandCallback( "Training_SetInputType", ClientCommand_Training_SetInputType )
- AddClientCommandCallback( "Training_PlayerPressedUse", ClientCommand_Training_PlayerPressedUse )
- AddClientCommandCallback( "Training_PlayerReloaded", ClientCommand_Training_PlayerReloaded )
- AddClientCommandCallback( "topTarget", ClientCommand_LookTarget_Top )
- AddClientCommandCallback( "bottomTarget", ClientCommand_LookTarget_Bottom )
-
- AddCallback_EntitiesDidLoad( EntitiesDidLoad )
- AddPlayerDidLoad( Training_PlayerDidLoad )
- AddCallback_OnLoadSaveGame( Training_OnLoadSaveGame )
-
- AddDamageCallback( "func_brush", Training_FuncBrush_OnDamaged )
-
- TimerInit( "firingRangeNag", 15.0 )
- TimerInit( "installWaitComment", 60.0 )
-
- AddStartPoint( "Pod Intro", Training_PodIntro, null, Training_Skipped_PodIntro )
- AddStartPoint( "Basic Movement", Training_BasicMovement, Training_Setup_BasicMovement, Training_Skipped_BasicMovement )
- AddStartPoint( "Zen Garden", Training_ZenGarden, Training_Setup_ZenGarden, Training_Skipped_ZenGarden )
- AddStartPoint( "Firing Range", Training_FiringRange, Training_Setup_FiringRange, Training_Skipped_FiringRange )
- AddStartPoint( "Gauntlet", Training_Gauntlet, Training_Setup_Gauntlet, Training_Skipped_Gauntlet )
- AddStartPoint( "Gauntlet Challenge", Training_GauntletChallenge, Training_Setup_GauntletChallenge, Training_Skipped_GauntletChallenge )
- AddStartPoint( "Titanfall", Training_Titanfall, Training_Setup_Titanfall, Training_Skipped_Titanfall )
- AddStartPoint( "Pod Outro", Training_PodOutro, Training_Setup_PodOutro, Training_Skipped_PodOutro )
- AddStartPoint( "Meet OG", Training_MeetOG, Training_Setup_MeetOG, Training_Skipped_MeetOG )
- AddStartPoint( "Gauntlet Mode", Training_GauntletModeStart, Training_Setup_GauntletMode, null )
-
- #if DEV
- AddStartPoint( "DEV_GHOSTREC_GAUNTLET_FIRSTRUN", TrainingGauntlet_RecordGhostStart_FirstRun, null, null )
- AddStartPoint( "DEV_GHOSTREC_GAUNTLET_CHAL_WIP", TrainingGauntlet_RecordGhostStart_Challenge_WIP, null, null )
- AddStartPoint( "DEV_GHOSTREC_GAUNTLET_CHAL_01", TrainingGauntlet_RecordGhostStart_Challenge_01, null, null )
- AddStartPoint( "DEV_GHOSTREC_GAUNTLET_CHAL_02", TrainingGauntlet_RecordGhostStart_Challenge_02, null, null )
- AddStartPoint( "DEV_GHOSTREC_GAUNTLET_CHAL_03", TrainingGauntlet_RecordGhostStart_Challenge_03, null, null )
- AddStartPoint( "DEV_GHOSTREC_GAUNTLET_CHAL_04", TrainingGauntlet_RecordGhostStart_Challenge_04, null, null )
- AddStartPoint( "DEV_GHOSTREC_GAUNTLET_CHAL_05", TrainingGauntlet_RecordGhostStart_Challenge_05, null, null )
- AddStartPoint( "DEV_GHOSTREC_GAUNTLET_CHAL_06", TrainingGauntlet_RecordGhostStart_Challenge_06, null, null )
- AddStartPoint( "DEV_GHOSTREC_GAUNTLET_CHAL_07", TrainingGauntlet_RecordGhostStart_Challenge_07, null, null )
- AddStartPoint( "DEV_GHOSTREC_GAUNTLET_CHAL_08", TrainingGauntlet_RecordGhostStart_Challenge_08, null, null )
- AddStartPoint( "DEV_GHOSTREC_GAUNTLET_CHAL_09", TrainingGauntlet_RecordGhostStart_Challenge_09, null, null )
-
- AddStartPoint( "Pod Intro DEV", DEV_PodIntro, null, null )
- AddStartPoint( "Pod Outro DEV", DEV_PodOutro, null, null )
- #endif
-}
-
-
-void function EntitiesDidLoad()
-{
- QuickDeathTrigger_SetIsPunitive( false )
-
- SetupTrainingPod()
- TrainingPod_GlowLightsArraySetup()
-
- FiringRangeTargets_Init()
-
- file.animref_hangar = GetEntByScriptName( "animref_hangar" )
- file.animref_hangar.DisableHibernation()
-
- file.skycam_default = GetEnt( "skybox_cam_level" )
- file.skycam_glitch = GetEnt( "skybox_cam_glitch" )
-}
-
-
-void function Training_PlayerDidLoad( entity player )
-{
- player.SetNoTarget( true )
- SetGlobalForcedDialogueOnly( true )
-
- AddButtonPressedPlayerInputCallback( player, IN_JUMP, Training_ButtonPressedJump )
- AddButtonPressedPlayerInputCallback( player, IN_ATTACK, Training_ButtonPressedAttack )
-
- file.envArt_colorCorrectionEnt = GetEnt( "color_correction_1" )
-
- file.player = player
-
- EnableDemigod( player )
-
- player.ForceMPAimassist() // TODO doublecheck this
-
- player.SetSkyCamera( file.skycam_default )
-
- Training_WeaponPickups_Init( player )
- player.PreventWeaponDestroyNoAmmo() // makes it so when player swaps empty weapon for another pickup, doesn't destroy empty weapon
-
- thread Training_PlayerQuickdeathSFX( player )
-
- DisableFriendlyHighlight()
-}
-
-
-void function Training_OnLoadSaveGame( entity player )
-{
- thread Training_OnLoadSaveGame_Think( player )
-}
-
-void function Training_OnLoadSaveGame_Think( entity player )
-{
- EndSignal( player, "OnDestroy" )
-
- wait 0.5 // HACK have to wait otherwise it doesn't work
- SetWeaponHUDEnabled( player, file.displayWeaponHUD )
-}
-
-
-void function Training_ButtonPressedJump( entity player )
-{
- player.Signal( "ButtonPressedJump" )
-}
-
-void function Training_ButtonPressedAttack( entity player )
-{
- player.Signal( "ButtonPressedAttack" )
-}
-
-void function Training_FuncBrush_OnDamaged( entity ent, var damageInfo )
-{
- if( !IsValid( ent ) )
- return
-
- entity attacker = DamageInfo_GetAttacker( damageInfo )
-
- if ( ent.GetScriptName() == "firingrange_target" )
- {
- if ( IsValid( attacker ) && attacker.IsPlayer() )
- {
- table<string,vector> resultTable = {}
- resultTable["damagePos"] <- DamageInfo_GetDamagePosition( damageInfo )
- ent.Signal( "TargetDamaged", resultTable )
- }
- }
-}
-
-
-// ==============================
-// ========= POD INTRO ==========
-// ==============================
-void function Training_Skipped_PodIntro( entity player )
-{
- player.SetExtraWeaponMods( [ "low_ammo_disable" ] )
- SetWeaponHUDEnabled( player, false )
-}
-
-#if DEV
-// bare bones start in pod
-void function DEV_PodIntro( entity player )
-{
- player.EndSignal( "OnDestroy" )
-
- TakeAllWeapons( player )
-
- player.SetExtraWeaponMods( [ "low_ammo_disable" ] )
- SetWeaponHUDEnabled( player, false )
-
- Training_EnvArtColorCorrection_SetEnabled( false )
- SetDoF_Hangar( player )
-
- thread PodIntro_BackgroundSkits( player )
-
- entity pod = file.trainingPod
-
- TrainingPod_PlayerSequence_DoorsOpenIdle( player, false )
-
- // anim starts at a slightly different spot
- player.SetOrigin( < 10564, -10235, -6056.9 > )
- player.SetAngles( < -6, 90, 0 > )
-
- WaitForever()
-}
-#endif //DEV
-
-
-void function Training_PodIntro( entity player )
-{
- player.EndSignal( "OnDestroy" )
-
- player.SetExtraWeaponMods( [ "low_ammo_disable" ] )
- SetWeaponHUDEnabled( player, false )
-
- Training_EnvArtColorCorrection_SetEnabled( false )
-
- entity pod = file.trainingPod
-
- OnThreadEnd(
- function() : ( player, pod )
- {
- if ( IsValid( player ) )
- {
- player.Anim_Stop()
- ClearPlayerAnimViewEntity( player )
- player.ClearParent()
- player.UnforceStand()
-
- Training_EnvArtColorCorrection_SetEnabled( true )
- }
-
- if ( IsValid ( pod ) )
- {
- pod.Anim_Stop()
-
- thread TrainingPod_ResetLaserEmitterRotation( pod )
- thread TrainingPod_KillLasers( pod )
- thread TrainingPod_KillGlowFX( pod )
- TrainingPod_KillInteriorDLights()
- }
- }
- )
-
- // NORMAL LEVEL START
- SetDoF_Hangar( player )
-
- ShowIntroScreen( player )
-
- thread PodIntro_MeetOG( player )
-
- TrainingPod_PlayerSequence_DoorsOpenIdle( player )
-
- FlagWait( "IntroScreenFading" )
- wait 1.2
- Remote_CallFunction_Replay( player, "ScriptCallback_LevelIntroText" )
- wait 4.2 // matches fade time in sp_introscreen data
-
- thread PodIntro_BackgroundSkits( player )
-
-
- player.Signal( "PodIntro_OG_StartPodAnim" )
-
- // time for OG to animate before starting viewmodel anim
- wait 11.8
-
- FirstPersonSequenceStruct playerSequence
- playerSequence.blendTime = 0.25
- playerSequence.attachment = "REF"
- playerSequence.firstPersonAnim = "ptpov_trainingpod_doors_close"
- playerSequence.firstPersonAnimIdle = "ptpov_trainingpod_idle"
- playerSequence.thirdPersonAnim = "pt_trainingpod_doors_close"
- playerSequence.thirdPersonAnimIdle = "pt_trainingpod_idle"
- playerSequence.viewConeFunction = TrainingPod_ViewConeLock_SemiStrict
- playerSequence.renderWithViewModels = true
-
- FirstPersonSequenceStruct podSequence
- podSequence.blendTime = 0.25
- podSequence.thirdPersonAnim = "trainingpod_doors_close"
- podSequence.thirdPersonAnimIdle = "trainingpod_doors_close_idle"
- podSequence.renderWithViewModels = true
-
- entity viewmodel = player.GetFirstPersonProxy()
-
- if ( !HasAnimEvent( viewmodel, "PlaySound_SimPod_DoorShut" ) )
- AddAnimEvent( viewmodel, "PlaySound_SimPod_DoorShut", PlaySound_SimPod_DoorShut )
-
- // HACK this should be based on an anim event
- thread TrainingPod_KillInteriorDLights_Delayed( player, 2.65 )
-
- thread FirstPersonSequence( podSequence, pod )
- waitthread FirstPersonSequence( playerSequence, player, pod )
-
- FlagSet( "PodIntro_PodDoorsClosed" )
-
- TrainingPod_ViewConeLock_PodClosed( player )
-
- waitthread LookTraining( player )
-
- // "Let's see how much you remember from last time."
- waitthread PlayDialogue( "og_how_much_you_remember", player )
-
- // "Setting the neural link."
- waitthread PlayDialogue( "og_neural_link", player )
-
- // "Not quite the same as a Titan link, but it's similar."
- waitthread PlayDialogue( "og_neural_link_2", player )
-
- thread TrainingPod_Interior_BootSequence( player )
-
- // "To learn new skills, we need to be in the right state of mind."
- thread PlayDialogue( "og_simulation_starting", player, 2.5 )
-
- player.WaitSignal( "PodInteriorSequenceDone" )
- printt( "POD SEQUENCE DONE" )
-
- wait 2.0 // timed to match the screen effect white screen flash
-
- SetDoF_Default( player )
-}
-
-void function PlaySound_SimPod_DoorShut( entity playerFirstPersonProxy ) //Hack, needed for wargames but has unfortunate side effect for Training.
-{
- entity player = playerFirstPersonProxy.GetOwner()
- if ( !IsValid( player ) )
- return
-
- EmitSoundOnEntityOnlyToPlayer( player, player, "NPE_Scr_SimPod_DoorShut" )
-
-}
-
-void function PodIntro_MeetOG( entity player )
-{
- entity animref = file.animref_hangar
- vector animrefOrigin = animref.GetOrigin()
- vector animrefAngles = animref.GetAngles()
- vector btSpawnOrg = <0,0,0> // to avoid red text errors about BT spawning in solid
-
- entity animEnt = CreateScriptMover( animrefOrigin, animrefAngles )
-
- // Spawn scene actors
- entity og = Training_SpawnOGPilot( animref )
- Training_OGPilot_SetHelmetOn( og, false )
- AddAnimEvent( file.ogPilot, "pod_slap", PodIntro_OG_Slaps_Pod )
-
- TitanLoadoutDef loadout = GetTitanLoadoutForCurrentMap()
- entity bt = CreateAutoTitanForPlayer_FromTitanLoadout( player, loadout, btSpawnOrg, animrefAngles )
- SetSpawnOption_AISettings( bt, "npc_titan_buddy" )
- bt.kv.spawnflags = SF_NPC_ALLOW_SPAWN_SOLID
- DispatchSpawn( bt )
- FreeAutoTitan( bt ) // HACK this disables the worldspace BT locator icon
- TakeAllWeapons( bt )
-
- array<entity> actors = [ bt, og ]
-
- asset btWeaponModel = GetWeaponInfoFileKeyFieldAsset_Global( "mp_titanweapon_xo16_shorty", "playermodel" )
- Assert( btWeaponModel != $"" )
- entity btWeapon = CreatePropDynamic( btWeaponModel )
- btWeapon.SetParent( bt, "PROPGUN" )
-
- asset ogWeaponModel = GetWeaponInfoFileKeyFieldAsset_Global( OG_WEAPON, "playermodel" )
- Assert( ogWeaponModel != $"" )
- entity ogWeapon = CreatePropDynamic( ogWeaponModel )
- ogWeapon.SetParent( og, "PROPGUN" )
-
- entity ogHelmet = CreatePropDynamic( OG_PILOT_HELMET_MODEL )
- ogHelmet.DisableHibernation()
-
- array<entity> props = [ btWeapon, ogWeapon, ogHelmet ]
-
- OnThreadEnd(
- function() : ( actors, props, animEnt )
- {
- if ( IsValid( file.ogPilot ) )
- DeleteAnimEvent( file.ogPilot, "pod_slap" )
-
- foreach ( weapon in props )
- {
- if ( IsValid( weapon ) )
- {
- weapon.ClearParent()
- weapon.Destroy()
- }
- }
-
- foreach ( actor in actors )
- {
- if ( !IsValid( actor ) )
- continue
-
- actor.ClearParent()
-
- if ( IsInvincible( actor ) )
- ClearInvincible( actor )
-
- if ( !actor.IsPlayer() )
- actor.Destroy()
- }
-
- if ( IsValid( animEnt ) )
- animEnt.Destroy()
- }
- )
-
- foreach ( guy in actors )
- {
- MakeInvincible( guy )
- guy.SetEfficientMode( true )
- Highlight_ClearFriendlyHighlight( guy )
- }
-
- string anim_og_idle = "pt_OG_training_rail_sit_idle"
- string anim_og_helmet_idle = "helmet_intro_scene_OG_idle"
- string anim_bt_idle = "BT_intro_scene_OG_idle"
-
- string anim_og = "pt_pod_setup_OG"
- string anim_bt = "BT_pod_setup_OG"
-
- thread PlayAnimTeleport( og, anim_og_idle, animEnt )
- thread PlayAnimTeleport( ogHelmet, anim_og_helmet_idle, animEnt )
- thread PlayAnimTeleport( bt, anim_bt_idle, animEnt )
-
- player.WaitSignal( "PodIntro_OG_StartPodAnim" )
-
- if ( !IsValid( og ) )
- return
-
- og.Anim_Stop()
- thread PlayAnim( og, anim_og, animEnt )
-
- bt.Anim_Stop()
- thread PlayAnim( bt, anim_bt, animEnt )
-
- float animDuration = og.GetSequenceDuration( anim_og )
- wait animDuration - 0.1
-
- if ( !IsValid( og ) )
- return
-
- og.Anim_Stop()
- thread PlayAnimTeleport( og, anim_og_idle, animEnt )
-
- bt.Anim_Stop()
- thread PlayAnimTeleport( bt, anim_bt_idle, animEnt )
-
- // wait for look training to get started before killing the scene
- FlagWaitAny( "PlayerLookedAtTopTarget", "PlayerLookedAtBottomTarget" )
-}
-
-void function PodIntro_OG_Slaps_Pod( entity ogPilot )
-{
- array<entity> players = GetPlayerArray()
- if ( !players.len() )
- return
-
- entity player = players[0]
- if ( !IsValid( player ) )
- return
-
- float shakeDuration = 0.45
- float shakeAmplitude = 0.14
- float screenBlurFrac = 0
- SimpleScreenShake( player, shakeDuration, shakeAmplitude, screenBlurFrac )
-}
-
-void function LookTraining( entity player )
-{
- thread LookTraining_StartNag( player, "PlayerLookedAtTopTarget", "PlayerLookedAtBottomTarget" )
-
- Remote_CallFunction_Replay( player, "ScriptCallback_ShowInvertCrosshair", true )
-
- // LOOKAT SECTION
- Remote_CallFunction_Replay( player, "ScriptCallback_SetupLookTargets" )
- wait 0.5
- Remote_CallFunction_Replay( player, "ScriptCallback_LookTargets_WaitForLookat" )
-
- DialogueGroup invertConfirmVO = GetDialogueGroup( "ogInvertConfirm" )
-
- int numInverts = 0
- int maxInverts = 2
- //while ( numInverts < maxInverts )
- while ( 1 )
- {
- Remote_CallFunction_Replay( player, "ScriptCallback_SetupLookTargets" )
- wait 0.5
- Remote_CallFunction_Replay( player, "ScriptCallback_LookTargets_WaitForLookat" )
-
- string hintAlias = "invert_look_at_lights"
- if ( numInverts > 0 )
- hintAlias = "invert_look_at_lights_again"
-
- // only play this VO once
- if ( numInverts == 1 )
- {
- // "You sure?"
- thread PlayDialogue( "og_invert_confirm_3", player )
- }
-
- DisplayOnscreenHint( player, hintAlias )
-
- printt( "Waiting for player to look at either target" )
-
- FlagWaitAny( "PlayerLookedAtTopTarget", "PlayerLookedAtBottomTarget" )
-
- printt( "Player looked at one of the targets" )
-
- hintAlias = "invert_look_at_lights_1_left"
- if ( numInverts > 0 )
- hintAlias = "invert_look_at_lights_again_1_left"
-
- DisplayOnscreenHint( player, hintAlias )
-
- FlagWait( "PlayerLookedAtTopTarget" )
- FlagWait( "PlayerLookedAtBottomTarget" )
-
- printt( "Player looked at both targets" )
-
- hintAlias = "invert_look_at_lights_0_left"
- if ( numInverts > 0 )
- hintAlias = "invert_look_at_lights_again_0_left"
-
- DisplayOnscreenHint( player, hintAlias )
-
- printt( "invert waiting for OG dialogue" )
-
- // "Does that feel right to you?"
- // "How about now? Feel alright?"
- string askAlias = DialogueGroup_GetNextLine( invertConfirmVO )
- waitthread PlayDialogue( askAlias, player )
-
- printt( "invert OG dialogue done" )
-
- ClearOnscreenHint( player )
-
- string invertConvar = file.playerInputType == 0 ? INVERT_CONVAR_GAMEPAD : INVERT_CONVAR_MOUSE
- printt( "invertConvar:", invertConvar )
- bool invertSettingBeforeMenu = GetConVarBool( invertConvar )
-
- printt( "Opening invert look dialog" )
-
- // THIS PAUSES THE GAME UNTIL MENU IS CLOSED
- Remote_CallFunction_UI( player, "ScriptCallback_OpenInvertLookDialog" )
- wait 0.5 // let the game come back after menu is closed
-
- // if player didn't change setting, don't repeat
- invertConvar = file.playerInputType == 0 ? INVERT_CONVAR_GAMEPAD : INVERT_CONVAR_MOUSE
- printt( "invertConvar:", invertConvar )
- if ( GetConVarBool( invertConvar ) == invertSettingBeforeMenu )
- {
- printt( "player didn't change setting, not repeating" )
- break
- }
-
- printt( "invert- player changed setting, repeating to confirm" )
-
- numInverts++
-
- // kill lights and reset flags
- Remote_CallFunction_Replay( player, "ScriptCallback_LookTargets_KillLights" )
-
- FlagClear( "PlayerLookedAtTopTarget" )
- FlagClear( "PlayerLookedAtBottomTarget" )
- }
-
- ClearOnscreenHint( player )
- Remote_CallFunction_Replay( player, "ScriptCallback_ShowInvertCrosshair", false )
-
- // "Alright, we're good to go."
- waitthread PlayDialogue( "og_invert_complete", player )
-
- TrainingPod_ViewConeLock_PodClosed( player )
-
- TrainingPod_ViewConeLock_SemiStrict( player ) // recenter player view
- Remote_CallFunction_Replay( player, "ScriptCallback_LookTargets_KillLights" )
-}
-
-void function LookTraining_StartNag( entity player, string flag1, string flag2 )
-{
- EndSignal( player, "OnDestroy" )
-
- if ( Flag( flag1 ) || Flag( flag2 ) )
- return
-
- FlagEnd( flag1 )
- FlagEnd( flag2 )
-
- float nagInterval = 15.0
- float nextNagTime = Time() + nagInterval
-
- while( 1 )
- {
- wait 1
-
- if ( Time() < nextNagTime )
- continue
-
- // "We have to calibrate the pod. It won't boot up until you look at both of those lights."
- waitthread PlayDialogue( "og_pod_calibrate", player )
-
- nextNagTime = Time() + nagInterval
- }
-}
-
-void function TrainingPod_PlayerSequence_DoorsOpenIdle( entity player, bool doPlayerAnim = true )
-{
- entity pod = file.trainingPod
-
- // Have to do this first so the anim starts centered on the ref attachment angles
- string podAttach = "REF"
- int attachID = pod.LookupAttachment( podAttach )
- vector podRefOrg = pod.GetAttachmentOrigin( attachID )
- vector podRefAng = pod.GetAttachmentAngles( attachID )
- player.SetOrigin( podRefOrg )
- player.SetAngles( podRefAng )
- player.ForceStand()
-
- player.DisableWeapon()
-
- // default start anim starts open
- void functionref( entity ) viewConeFunction_start = TrainingPod_ViewConeLock_PodOpen
- string podAnim_start = "trainingpod_doors_open_idle"
-
- // start open idle
- FirstPersonSequenceStruct playerSequence
- playerSequence.blendTime = 0.0
- playerSequence.attachment = podAttach
- playerSequence.firstPersonAnimIdle = "ptpov_trainingpod_idle"
- playerSequence.thirdPersonAnimIdle = "pt_trainingpod_idle"
- playerSequence.viewConeFunction = viewConeFunction_start
- playerSequence.renderWithViewModels = true
-
- FirstPersonSequenceStruct podSequence
- podSequence.blendTime = 0.0
- podSequence.thirdPersonAnimIdle = podAnim_start
- podSequence.renderWithViewModels = true
-
- thread FirstPersonSequence( podSequence, pod )
-
- if ( doPlayerAnim )
- thread FirstPersonSequence( playerSequence, player, pod )
-
- TrainingPod_TurnOnInteriorDLight( "console1" )
- TrainingPod_TurnOnInteriorDLight( "console2" )
- //TrainingPod_TurnOnInteriorDLight( "backlight_side_L" )
- //TrainingPod_TurnOnInteriorDLight( "backlight_side_R" )
-}
-
-
-
-// ------ POD INTRO BACKGROUND SKITS ------
-void function PodIntro_BackgroundSkits( entity player )
-{
- string endFlag = "PodIntro_PodDoorsClosed"
- FlagEnd( endFlag )
-
- thread PodIntro_LoudspeakerVO( player, "PodIntro_InteriorBootSequence_Starting" )
-
- thread PodIntro_TitanRacks( endFlag )
-
- thread PodIntro_Background_WalkingGuys()
-
- // ---- ANIMATING SKIT GUYS ---
- // script NudgeSkitGuy( "back_console_supervisor", 0, 5, 0 )
-
- // guy sitting at console in back center of room
- SkitGuyInfo backConsoleGuy1 = SpawnSkitGuy( "back_console_sitting", "pt_console_idle", < 10521.1, -9679.33, -6044.1 >, < 0, 88.3541, 0 >, TEAM_MILITIA, "npc_soldier" )
- SkitGuy_PlayAnim( backConsoleGuy1 )
- SkitGuyInfo backConsoleGuy2 = SpawnSkitGuy( "back_console_supervisor", "pt_bored_interface_leanback", < 10527.6, -9656.36, -6043.97 >, < 0, -26.564, 0 >, TEAM_MILITIA, "npc_soldier_specialist_militia", "mp_weapon_g2" )
- SkitGuy_PlayAnim( backConsoleGuy2 )
-
- // extra marvins working on titans 1 and 2
- SkitGuyInfo titanBay1_marvin = SpawnSkitGuy( "bay1_marvin", "mv_idle_weld", < 10711.2, -9781.04, -6080.65 >, < 0, 153.715, 0 > )
- SkitGuy_PlayAnim( titanBay1_marvin, 3.0 ) // don't play same anim at same time
- SkitGuyInfo titanBay2_marvin = SpawnSkitGuy( "bay2_marvin", "mv_idle_weld", < 10316.2, -9730.23, -6079.97 >, < 0, -69.965, 0 > )
- SkitGuy_PlayAnim( titanBay2_marvin )
-
- // guys looking at console in back left
- SkitGuyInfo leftConsoleGuy1 = SpawnSkitGuy( "console_lean", "pt_bored_interface_leanin", < 10257.6, -9846.63, -6079.97 >, < 0, 34.5175, 0 >, TEAM_MILITIA, "npc_soldier" )
- SkitGuy_PlayAnim( leftConsoleGuy1 )
- SkitGuyInfo leftConsoleGuy2 = SpawnSkitGuy( "console_supervisor", "pt_bored_interface_leanback", < 10260.5, -9874.78, -6079.97 >, < 0, -42.534, 0 >, TEAM_MILITIA, "npc_soldier", "mp_weapon_mastiff" )
- SkitGuy_PlayAnim( leftConsoleGuy2 )
-
- OnThreadEnd(
- function() : ()
- {
- DeleteAllSkitGuys()
- }
- )
-
- WaitForever()
-}
-
-void function PodIntro_LoudspeakerVO( entity player, string endFlag )
-{
- EndSignal( player, "OnDestroy" )
-
- array<string> aliases
- // "Inbound to Planet Typhon. Subspace rendezvous in approximately 20 minutes."
- aliases.append( "intro_0" )
- // "Reminder to dock personnel: Titan ordnance is a Type 3 Hazardous Material."
- aliases.append( "intro_2" )
- // "Running Lifeboat diagnostic test two point one. All Mark Eight lifeboats are in the green."
- aliases.append( "intro_4" )
- // "3rd Militia Grenadiers - prep dropship MacAllan 17."
- aliases.append( "intro_5" )
- // "Captain Cole to communications."
- aliases.append( "intro_3" )
- // "Major Anderson, please report to the briefing room."
- aliases.append( "intro_1" )
-
- thread LoopLoudspeakerVO( aliases, endFlag, 1.0, 2.0 )
-}
-
-void function PodIntro_Background_WalkingGuys()
-{
- // group of guys walking left to right
- array<Point> path1 = []
- ScriptedPath_AddPoint( path1, < 10327.9, -10000.28, -6079.97 >, < 0, 0.918, 0 > )
- ScriptedPath_AddPoint( path1, < 10373.5, -9987.14, -6079.97 >, < 0, 0.093, 0 > )
- ScriptedPath_AddPoint( path1, < 10688.3, -9973.76, -6079.97 >, < 0, 0, 0 > )
- ScriptedPath_AddPoint( path1, < 10856.4, -9973.58, -6079.97 >, < 0, 0, 0 > )
- SkitGuyInfo walkerInfo_1 = SpawnSkitGuy( "walker_1", "", path1[0].origin, path1[0].angles, TEAM_MILITIA, "npc_soldier_specialist_militia", "mp_weapon_hemlok_smg" )
- thread ScriptedPath_Walk( walkerInfo_1, path1, 0.75 )
-
- array<Point> path2 = []
- ScriptedPath_AddPoint( path2, < 10248.6, -9925.06, -6079.97 >, < 0, 6.36392, 0 > )
- ScriptedPath_AddPoint( path2, < 10373.5, -9939.14, -6079.97 >, < 0, 0.093, 0 > )
- ScriptedPath_AddPoint( path2, < 10688.3, -9973.76, -6079.97 >, < 0, 0, 0 > )
- ScriptedPath_AddPoint( path2, < 10856.4, -9973.58, -6079.97 >, < 0, 0, 0 > )
- SkitGuyInfo walkerInfo_2 = SpawnSkitGuy( "walker_2", "", path2[0].origin, path2[0].angles, TEAM_MILITIA, "npc_soldier", "mp_weapon_hemlok" )
- thread ScriptedPath_Walk( walkerInfo_2, path2, 0.85 )
-}
-
-void function PodIntro_TitanRacks( string endFlag )
-{
- FlagEnd( endFlag )
-
- array<HangarTitanGroup> titanGroups
-
- HangarTitanGroup bay1
- bay1.ref = GetEntByScriptName( "animref_drop_hangar_titan_1" )
- bay1.titan = GetEntByScriptName( "hangar_titan_1" )
- bay1.rack = GetEntByScriptName( "hangar_titan_rack_1" )
- bay1.titanAnim = "bt_TDay_drop_titan4"
- bay1.rackAnim = "rack_TDay_drop_rack4"
- bay1.marvinAnim = "mv_TDay_drop_marvin4"
- HangarTitanGroup_Init( bay1 )
- titanGroups.append( bay1 )
-
- // --- BAY 2 ---
- HangarTitanGroup bay2
- bay2.ref = GetEntByScriptName( "animref_drop_hangar_titan_2" )
- bay2.titan = GetEntByScriptName( "hangar_titan_2" )
- bay2.rack = GetEntByScriptName( "hangar_titan_rack_2" )
- bay2.titanAnim = "bt_TDay_drop_titan3"
- bay2.rackAnim = "rack_TDay_drop_rack3"
- bay2.marvinAnim = "mv_TDay_drop_marvin3"
- HangarTitanGroup_Init( bay2 )
- titanGroups.append( bay2 )
-
- float wait_earlyEnd = 27.0
- thread HangarTitanGroup_Animate( bay1, endFlag, wait_earlyEnd )
- thread HangarTitanGroup_Animate( bay2, endFlag, wait_earlyEnd )
-
- wait wait_earlyEnd
- thread PodIntro_TitanRacks( endFlag )
-}
-
-
-
-// ===================================
-// ========= BASIC MOVEMENT ==========
-// ===================================
-void function Training_Setup_BasicMovement( entity player )
-{
- player.DisableWeapon()
-}
-
-void function Training_Skipped_BasicMovement( entity player )
-{
- player.SetPlayerSettingsWithMods( TRAINING_PLAYER_SETTINGS, [ "disable_doublejump", "disable_wallrun" ] )
-
- Objective_SetSilent( "#TRAINING_OBJ_DEFAULT" )
-}
-
-void function Training_BasicMovement( entity player )
-{
- entity standNearJumpRef = GetEntByScriptName( "basic_movement_og_stand_near_jump" )
- standNearJumpRef.SetOrigin( OriginToGround( standNearJumpRef.GetOrigin() + <0,0,0.5> ) ) // HACK HACK the ref node is a tiny bit in the geo which causes OG to dip when blending between anims
- entity ogStart = GetEntByScriptName( "basic_movement_og_start" )
- entity og = Training_SpawnOGPilot( ogStart )
-
- player.SetPlayerSettingsWithMods( TRAINING_PLAYER_SETTINGS, [ "disable_doublejump", "disable_wallrun" ] )
- player.ForceAutoSprintOff()
-
- entity playerStart = GetEntByScriptName( "startpoint_basic_movement" )
- waitthread PlayerAndOGTeleport_Fancy( player, playerStart.GetOrigin(), "basic_movement_og_start", playerStart.GetAngles() )
- Training_OG_Idles_Sitting( ogStart, "OG_base_move_A_idle" )
-
- thread BasicMovement_DelayedWeaponDeploy( player, 1.5 )
- Objective_SetSilent( "#TRAINING_OBJ_DEFAULT" )
-
- // "Ah. Much better."
- waitthread Training_OG_ScriptedAnim( ogStart, "OG_base_move_A" )
- thread Training_OG_Idles_Sitting( ogStart, "OG_base_move_B_idle" )
-
- CheckPoint_Silent()
-
- thread OnscreenHint_DisplayUntilFlag( player, "move_hint", "BasicMovement_PlayerMovedForward", 10.0 )
-
- FlagWait( "BasicMovement_PlayerMovedForward" )
-
- if ( !Flag( "BasicMovement_PlayerJumped" ) )
- {
- // "Technically, I'm not supposed to be training you. But in you, I see potential.
- waitthread Training_OG_ScriptedAnim( ogStart, "OG_base_move_B1")
- }
-
- if ( !Flag( "BasicMovement_PlayerJumped" ) )
- {
- // "Besides, we're at war. Who's got time for classes, eh?"
- waitthread Training_OG_ScriptedAnim( ogStart, "OG_base_move_B2")
- thread Training_OG_Idles_Sitting( ogStart )
- }
-
- if ( !Flag( "BasicMovement_PlayerJumped" ) && player.IsOnGround() )
- {
- DisplayOnscreenHint( player, "jump_hint" )
-
- // "Here you go, up and over."
- waitthread Training_OG_ScriptedAnim( ogStart, "OG_base_move_C" )
- waitthread Training_OG_Moves( standNearJumpRef )
- }
-
- if ( !Flag( "BasicMovement_PlayerJumped" ) )
- {
- // "Cmon, schedule's tight today."
- // "Here you go, up and over."
- array<string> jumpNags = [ "og_jump_nag_2", "og_jump_nag" ]
-
- thread Training_OG_NagPlayerUntilFlag( player, jumpNags, 20.0, standNearJumpRef, "BasicMovement_PlayerJumped" )
- }
-
- FlagWait( "BasicMovement_PlayerJumped" )
-
- ClearOnscreenHint( player )
-
- waitthread BasicMovement_Sprint( player )
-}
-
-void function BasicMovement_Sprint( entity player )
-{
- thread BasicMovement_Sprint_OG_Moves( player )
-
- //player.ForceAutoSprintOn()
-
- FlagClear( "PlayerSprinted" )
- thread BasicMovement_PlayerSprintDetection( player )
-
- // "Let's pick up the pace. Enabling jumpkit assist."
- float endVOTime = Time() + 3.5
- thread PlayDialogue( "og_autosprint_on", file.ogPilot )
-
- wait 2.5 // let the VO play a bit before showing the hint
-
- player.UnforceAutoSprint()
- thread BasicMovement_SprintHint_Think( player )
-
- wait endVOTime - Time()
-
- // HACK- Create a fake VO speaker where OG will eventually move to/from so the lines emit in worldspace for audio
- entity ref = GetEntByScriptName( "basic_movement_og_mid_hallway" )
- entity tempSpeaker = CreateScriptMover( ref.GetOrigin(), <0,0,0> )
- thread HACK_MoveTempSpeaker_WithOGPathMover( player, tempSpeaker )
-
- // "Jumpkits operate on the principle of relaxed stability."
- EmitSoundOnEntity( tempSpeaker, "diag_sp_addtional_TR411_53_mcor_og" ) // do this instead of PlayDialogue because it will follow the ent around
- wait 3.4 // HACK
-
- // "Once your jumpkit calibrates to your movement style, enhanced mobility becomes second nature."
- EmitSoundOnEntity( tempSpeaker, "diag_sp_movement_TR121_08_01_mcor_og" )
- wait 6.0 // HACK
-
- tempSpeaker.Destroy()
-}
-
-void function HACK_MoveTempSpeaker_WithOGPathMover( entity player, entity tempSpeaker )
-{
- EndSignal( player, "OnDestroy" )
- EndSignal( tempSpeaker, "OnDestroy" )
-
- vector prevOrg = < -1,-1,-1 >
-
- while ( 1 )
- {
- WaitFrame()
-
- vector newOrg = < -1,-1,-1 >
-
- // if we are doing a path move, use the pathMover origin- otherwise use OG's origin
- if ( IsValid( file.ogPathMover ) )
- newOrg = file.ogPathMover.GetOrigin()
- else if ( IsValid( file.ogPilot ) )
- file.ogPilot.GetOrigin()
-
- if ( newOrg != < -1,-1,-1 > && newOrg != prevOrg )
- {
- tempSpeaker.SetOrigin( newOrg )
- prevOrg = newOrg
- }
- }
-}
-
-void function BasicMovement_SprintHint_Think( entity player )
-{
- EndSignal( player, "OnDestroy" )
-
- float autosprintHintTime = 10.0
-
- // player with autosprint on will already be sprinting
- if ( GetAutosprintEnabled() )
- {
- thread DisplayOnscreenHint( player, "autosprint_hint", autosprintHintTime )
- return
- }
-
- // Below this point assume that autosprint is NOT enabled
- if ( !Flag( "PlayerSprinted" ) )
- {
- thread OnscreenHint_DisplayUntilFlag( player, "sprint_button_hint", "PlayerSprinted", 0.0, true )
- FlagWait( "PlayerSprinted" )
-
- wait 1.0
- }
-
- DisplayOnscreenHint( player, "autosprint_available", autosprintHintTime )
-}
-
-void function BasicMovement_Sprint_OG_Moves( entity player )
-{
- EndSignal( player, "OnDestroy" )
-
- entity ogMidHallwayRef = GetEntByScriptName( "basic_movement_og_mid_hallway" )
- waitthread Training_OG_Moves_ToSitting( ogMidHallwayRef, "", 0.8 )
-
- FlagWait( "BasicMovement_PlayerReachedMidHallway" )
-
- entity og_zenGarden_start = GetEntByScriptName( "basic_movement_og_zen_start" )
- thread Training_OG_Moves( og_zenGarden_start, "OG_Beautiful_idle" )
-}
-
-void function BasicMovement_PlayerSprintDetection( entity player )
-{
- EndSignal( player, "OnDestroy" )
- FlagEnd( "BasicMovement_PlayerReachedOpenArea" )
-
- while ( 1 )
- {
- WaitFrame()
-
- if ( player.IsSprinting() )
- break
- }
-
- FlagSet( "PlayerSprinted" )
-}
-
-void function BasicMovement_DelayedWeaponDeploy( entity player, float delay )
-{
- player.EndSignal( "OnDestroy" )
-
- wait delay
- player.EnableWeaponWithSlowDeploy()
- thread TakeAmmoFromPlayerASAP( player )
-}
-
-
-// =================================================
-// ========= BASIC MOVEMENT 2: ZEN GARDEN ==========
-// =================================================
-void function Training_Setup_ZenGarden( entity player )
-{
- entity ogStart = GetEntByScriptName( "basic_movement_og_zen_start" )
- entity og = Training_SpawnOGPilot( ogStart )
- Training_OG_Idles( ogStart, "OG_Beautiful_idle" )
-
- thread TakeAmmoFromPlayerASAP( player )
-
- TeleportPlayerAndBT( "startpoint_zen_garden" )
-}
-
-void function Training_Skipped_ZenGarden( entity player )
-{
- player.SetPlayerSettingsWithMods( TRAINING_PLAYER_SETTINGS, [] )
-
- OpenZenGardenExitDoor()
-}
-
-void function Training_ZenGarden( entity player )
-{
- entity og = GetOGPilot()
- Assert( IsValid( og ) )
-
- entity ref_hillclimbFinish = GetEntByScriptName( "zengarden_hillclimb_finish_idle" )
- entity ref_exitSpot = GetEntByScriptName( "zengarden_og_exit_ref" )
-
- OpenZenGardenExitDoor()
-
- FlagWait( "BasicMovement_PlayerReachedOpenArea" )
-
- player.SetPlayerSettingsWithMods( TRAINING_PLAYER_SETTINGS, ["disable_doublejump"] )
-
- CheckPoint_Silent()
-
- thread ZenGarden_WhyWeFight_VO( player, og )
-
- waitthread Training_ZenGarden_Wallrun( player )
-
- waitthread Training_ZenGarden_Crouch( player )
-
- player.SetPlayerSettingsWithMods( TRAINING_PLAYER_SETTINGS, [] )
-
- CheckPoint_Silent()
-
- waitthread Training_ZenGarden_DoubleJump( player )
-
- waitthread Training_ZenGarden_HillClimb( player, ref_hillclimbFinish, ref_exitSpot )
-
- if ( IsValid( level ) )
- Signal( level, "StopRepeatingGhostRecorder" )
-}
-
-// ZEN GARDEN SHARED BETWEEN PATHS
-void function ZenGarden_WhyWeFight_VO( entity player, entity og )
-{
- entity ogStart = GetEntByScriptName( "basic_movement_og_zen_start" )
- entity firstRockRef = GetEntByScriptName( "zengarden_og_rock1_ref" )
- entity pathRef = GetEntByScriptName( "zengarden_og_path_ref" )
- entity treeRef = GetEntByScriptName( "zengarden_og_tree_ref" )
-
- string stopFlag = "ZenGarden_PlayerReachedWallrunStart"
- string setFlag = "OG_WhyWeFight_VO_Done"
-
- if ( !Flag( stopFlag ) )
- {
- // "Beautiful, isn't it?"
- waitthread Training_OG_ScriptedAnim( ogStart, "OG_Beautiful" )
- }
-
- if ( !Flag( stopFlag ) )
- {
- waitthread Training_OG_Moves( firstRockRef, "", 0.25 )
- }
-
- if ( !Flag( stopFlag ) )
- {
- // "It's inspired by my home planet of Harmony."
- waitthread Training_OG_ScriptedAnim( firstRockRef, "OG_harmony_A" )
- }
-
- if ( !Flag( stopFlag ) )
- {
- // "This is where I grew up."
- waitthread Training_OG_ScriptedAnim( firstRockRef, "OG_harmony_B" )
- }
-
- if ( !Flag( stopFlag ) && !Flag( "ZenGarden_PlayerReachedFirstRock" ) )
- {
- waitthread Training_OG_Moves( pathRef )
- }
-
- FlagWaitAny( stopFlag, "ZenGarden_PlayerReachedFirstRock" )
-
- if ( !Flag( stopFlag ) )
- {
- waitthread Training_OG_Moves_ToSitting( treeRef, "", 0.5 )
- }
-
- if ( !Flag( stopFlag ) )
- {
- // "This is what we're fighting for, Cooper."
- waitthread Training_OG_ScriptedAnim( treeRef, "OG_freedom_A" )
- }
-
- if ( !Flag( stopFlag ) )
- {
- // "A world that's not metal and smoke."
- waitthread Training_OG_ScriptedAnim( treeRef, "OG_freedom_B" )
- }
-
- if ( !Flag( stopFlag ) )
- {
- // "The freedom to live in peace and prosperity."
- waitthread Training_OG_ScriptedAnim( treeRef, "OG_freedom_C" )
- }
-
- FlagSet( setFlag )
-}
-
-void function Training_ZenGarden_Wallrun( entity player )
-{
- entity wallrunRef = GetEntByScriptName( "basic_movement_og_zen_wallrun_idle" )
- entity recorderRef = GetEntByScriptName( "basic_movement_wallrun_start_ref" )
-
- FlagWaitAny( "ZenGarden_PlayerReachedWallrunStart", "OG_WhyWeFight_VO_Done" )
-
- FlagWait( "OG_WhyWeFight_VO_Done" )
-
- waitthread Training_OG_Moves_ToSitting( wallrunRef, "OG_primed_idle", 0.5 )
-
- FlagWait( "ZenGarden_PlayerReachedWallrunStart" )
-
- thread GhostRecorder_RepeatUntilFlag( player, "ZenGarden_PlayerFinishedWallrun", recorderRef, $"anim_recording/training_record_zengarden_wallrun.rpak" )
-
- if ( !Flag( "ZenGarden_PlayerFinishedWallrun" ) )
- thread OnscreenHint_DisplayUntilFlag( player, "wallrun_hint", "ZenGarden_PlayerFinishedWallrun" )
-
- wait 1.0 // wait to see if player starts wallrunning right away
-
- if ( !Flag( "ZenGarden_PlayerFinishedWallrun" ) && !Flag( "ZenGarden_PlayerTouchingWallrunPanel" ) )
- {
- // "Let's make sure your jump kit is primed. Basic wallrun here, give it a try."
- waitthread Training_OG_ScriptedAnim( wallrunRef, "OG_primed" )
- thread Training_OG_Idles_Sitting( wallrunRef, "OG_primed_idle" )
- }
-
- if ( !Flag( "ZenGarden_PlayerFinishedWallrun" ) && !Flag( "ZenGarden_PlayerTouchingWallrunPanel" ) )
- wait 1.0
-
- if ( !Flag( "ZenGarden_PlayerFinishedWallrun" ) && !Flag( "ZenGarden_PlayerTouchingWallrunPanel" ) )
- {
- // "Same routine as last time- watch the ghost pilot, and try to follow along."
- thread PlayDialogue( "og_wallrun_follow_ghost", file.ogPilot )
- waitthread Training_OG_ScriptedAnim( wallrunRef, "OG_primed_generic" )
- thread Training_OG_Idles_Sitting( wallrunRef, "OG_primed_idle" )
- }
-
- FlagWait( "ZenGarden_PlayerFinishedWallrun" )
-
- if ( !Flag( "ZenGarden_PlayerReachedCrouchArea" ) )
- {
- // "Good! Now you're moving."
- file.postWallrunVOEndTime = Time() + 3.0
- thread PlayDialogue( "og_wallrun_done", player )
- wait 0.3 // min wait after
- }
-}
-
-void function Training_ZenGarden_Crouch( entity player )
-{
- entity ogIdle_crouchSpot = GetEntByScriptName( "zengarden_og_slide_idle")
- entity ref_slideStart = GetEntByScriptName( "zengarden_slide_ref" )
-
- if ( Flag( "ZenGarden_PlayerCrouched" ) )
- return
-
- waitthread Training_OG_Moves_ToSitting( ogIdle_crouchSpot, "OG_low_idle", 0.8 )
- thread GhostRecorder_RepeatUntilFlag( player, "ZenGarden_PlayerCrouched", ref_slideStart, $"anim_recording/training_record_zengarden_slide.rpak", 1.0 )
-
- FlagWait( "ZenGarden_PlayerReachedCrouchArea" )
-
- DisplayOnscreenHint( player, "crouch_hint", 5.0 )
-
- while ( file.postWallrunVOEndTime > 0 && file.postWallrunVOEndTime - Time() > 0 )
- wait 0.1
-
- if ( Flag( "ZenGarden_PlayerCrouched" ) )
- return
-
- // "Under here. Stay low."
- waitthread Training_OG_ScriptedAnim( ogIdle_crouchSpot, "OG_low" )
- thread Training_OG_Idles_Sitting( ogIdle_crouchSpot, "OG_low_idle", true )
-
- thread Training_ZenGarden_CrouchHint_WithNags( player, 10.0, ogIdle_crouchSpot, "OG_low_idle" )
-
- FlagWait( "ZenGarden_PlayerCrouched" )
-
- ClearOnscreenHint( player )
-}
-
-void function Training_ZenGarden_CrouchHint_WithNags( entity player, float nagInterval, entity idleRef, string ogIdleAnim )
-{
- player.EndSignal( "OnDestroy" )
-
- string endFlag = "ZenGarden_PlayerCrouched"
- string activeFlag = "ZenGarden_PlayerAtCrouchStart"
-
- // "Crouch underneath, and we'll keep moving."
- // "You need to get low here."
- array<string> nags = [ "og_crouch_nag_1", "og_crouch_nag_2" ]
-
- int nagIdx = 0
- float nextNagTime = Time() + nagInterval
-
- bool showingHint = false
-
- while ( !Flag( endFlag ) )
- {
- FlagWait( activeFlag )
-
- while ( Flag( activeFlag ) )
- {
- wait 0.1
-
- if ( player.IsCrouched() )
- {
- if ( showingHint )
- {
- showingHint = false
- ClearOnscreenHint( player )
- }
-
- continue
- }
-
- if ( !showingHint )
- {
- DisplayOnscreenHint( player, "crouch_hint" )
- showingHint = true
- }
-
- if ( Time() - nextNagTime >= nagInterval )
- {
- thread Training_OG_Talks_Sitting( nags[nagIdx], idleRef, "", ogIdleAnim )
- nextNagTime = Time() + nagInterval
-
- nagIdx++
- if ( nagIdx >= nags.len() )
- nagIdx = 0
- }
- }
-
- if ( showingHint )
- {
- showingHint = false
- ClearOnscreenHint( player )
- }
- }
-}
-
-void function Training_ZenGarden_DoubleJump( entity player )
-{
- entity pathRef = GetEntByScriptName( "zengarden_og_postslide_idle" )
- entity ogIdleRef = GetEntByScriptName( "zengarden_og_doublejump_idle" )
- entity recordedAnimRef = GetEntByScriptName( "zengarden_doublejump_ref" )
-
- waitthread Training_OG_Moves( pathRef, "", 0.5 )
-
- // "Simple double jump. Follow the ghost."
- waitthread Training_OG_Talks( "og_doublejump_hint", pathRef )
-
- thread GhostRecorder_RepeatUntilFlag( player, "ZenGarden_PlayerDoubleJumped", recordedAnimRef, $"anim_recording/training_record_zengarden_doublejump.rpak", 1.0 )
-
- waitthread Training_OG_Moves_ToSitting( ogIdleRef, "OG_doublejump_idle", 0.5 )
-
- // "We've retaken over a quarter of Frontier space since the Battle of Demeter. The Militia's better organized now. More people join everyday to fight the IMC. People like you."
- waitthread Training_OG_ScriptedAnim( ogIdleRef, "OG_doublejump_A" )
- Training_OG_Idles( ogIdleRef, "OG_doublejump_B_idle" )
-
- FlagWait( "ZenGarden_PlayerReachedDoubleJumpArea" )
-
- if ( !Flag( "ZenGarden_PlayerDoubleJumped" ) )
- {
- DisplayOnscreenHint( player, "doublejump_hint", 5.0 )
- thread OnscreenHint_NagUntilFlag( player, "doublejump_hint", "ZenGarden_PlayerDoubleJumped", 10.0, 5.0 )
-
- wait 0.8
- }
-
- FlagWait( "ZenGarden_PlayerDoubleJumped" )
-}
-
-void function Training_ZenGarden_HillClimb( entity player, entity ref_hillclimbFinish, entity ref_exitSpot )
-{
- // "We used to just run and hide from them. But now we chase them."
- string nextAnim = "OG_doublejump_B"
-
- if ( !Flag( "ZenGarden_PlayerClimbedHill" ) )
- {
- waitthread Training_OG_Moves( ref_hillclimbFinish, "", 0.25 )
- //waitthread Training_OG_Talks( nextLine, ref_hillclimbFinish )
- waitthread Training_OG_ScriptedAnim( ref_hillclimbFinish, nextAnim )
- FlagWait( "ZenGarden_PlayerClimbedHill" )
- waitthread Training_OG_Moves( ref_exitSpot, ANIM_OG_LEANING_IDLE, 0.5 )
- }
- else if ( !Flag( "ZenGarden_PlayerReachedExitArea" ) )
- {
- waitthread Training_OG_Moves( ref_exitSpot, ANIM_OG_LEANING_IDLE, 0.5 )
-
- if ( !Flag( "ZenGarden_PlayerReachedExitArea" ) )
- waitthread Training_OG_ScriptedAnim( ref_exitSpot, nextAnim )
-
- if ( !Flag( "ZenGarden_PlayerReachedExitArea" ) )
- waitthread Training_OG_Moves( ref_exitSpot, ANIM_OG_LEANING_IDLE, 0.5 )
- }
-
- FlagWait( "ZenGarden_PlayerReachedExitArea" )
-}
-
-
-// =================================
-// ========= FIRING RANGE ==========
-// =================================
-void function Training_Setup_FiringRange( entity player )
-{
- entity ogStart = GetEntByScriptName( "firingrange_og_needguns_start_sitting" )
- entity og = Training_SpawnOGPilot( ogStart )
- Training_OG_Idles_Sitting( ogStart )
-
- thread TakeAmmoFromPlayerASAP( player )
-
- TeleportPlayerAndBT( "startpoint_firing_range" )
-}
-
-void function Training_Skipped_FiringRange( entity player )
-{
- CloseZenGardenExitDoor()
- OpenGauntletDoor()
-
- FlagSet( "ineedguns" )
- Training_WeaponRacks_SetSolidity( true )
-
- player.SetExtraWeaponMods( [ "" ] ) // turns off low_ammo_disable
- SetWeaponHUDEnabled( player, true )
-
- Training_SetWeaponPickupsFullAmmo()
-}
-
-void function Training_FiringRange( entity player )
-{
- entity ref_og_needGunsStart = GetEntByScriptName( "firingrange_og_needguns_start_sitting" )
- entity ref_og_firingRangeSpot = GetEntByScriptName( "firingrange_og_spot" )
- entity ref_og_firingRangeAttractSpot = GetEntByScriptName( "firingrange_og_attract_spot" )
-
- float ogMoveTime = -1
-
- Training_WeaponRacks_SetSolidity( false )
- Training_SetWeaponPickupsEmptyAmmo()
-
- thread FiringRange_CloseZenGardenDoor_WhenPlayerReachesRange( player )
-
- waitthread Training_OG_Moves_ToSitting( ref_og_needGunsStart, "OG_Weapons_idle", ogMoveTime )
-
- FlagWait( "PlayerApproachingFiringRange" )
-
- thread FiringRange_DetectWeaponSwitch( player )
-
- waitthread FiringRange_ApproachAndEntry( player, ref_og_needGunsStart, ref_og_firingRangeAttractSpot, ref_og_firingRangeSpot )
-
- waitthread FiringRange_TrainReload( player, ref_og_firingRangeSpot )
-
- Training_WeaponRacks_SetSolidity( true )
- thread FiringRange_InfiniteAmmo_WhenNearRange( player, "PodOutroStarted" )
- thread FiringRange_ResetTargets_Think( player )
-
- thread Training_OG_Idles( ref_og_firingRangeSpot, "OG_firingrange_idle" )
-
- waitthread FiringRange_TrainADS( player, ref_og_firingRangeSpot )
-
- waitthread FiringRange_PlayerMustDamageAllTargets( player, ref_og_firingRangeSpot, true, false )
-
- Training_SetWeaponPickupsFullAmmo()
-
- if ( !Flag( "FiringRangeWeaponSwapped" ) )
- {
- waitthread FiringRange_TrainWeaponSwap( player, ref_og_firingRangeSpot )
-
- FlagWait( "PlayerNearFiringRange" ) // if player moved away to get a weapon, wait for them to come back
- wait 0.25 // extra wait for player to see the targets reset
-
- waitthread FiringRange_PlayerMustDamageAllTargets( player, ref_og_firingRangeSpot, false )
- }
-
- OpenGauntletDoor()
-
- CheckPoint_Silent()
-
- // "Good. Practice more if you want, then head to the Gauntlet."
- waitthread Training_OG_ScriptedAnim( ref_og_firingRangeSpot, "OG_firingrange_ending" )
-
- array<string> moveToGauntletNags = [ "og_moving_to_gauntlet_nag_1", "og_moving_to_gauntlet_nag_2", "og_moving_to_gauntlet_nag_3" ]
-
- if ( Flag( "PlayerNearFiringRange" ) )
- {
- entity ref_og_midway2Gauntlet = GetEntByScriptName( "og_between_firingrange_and_gauntlet" )
- thread Training_OG_NagPlayerUntilFlag_Sitting( player, moveToGauntletNags, 45.0, ref_og_midway2Gauntlet, "OG_MovedTo_GauntletEntrance" )
-
- waitthread Training_OG_Moves_ToSitting( ref_og_midway2Gauntlet )
-
- FlagWaitClear( "PlayerNearFiringRange" )
- }
-
- FlagSet( "OG_MovedTo_GauntletEntrance" )
-
- entity ref_og_gauntletEntrance = GetEntByScriptName( "og_gauntlet_entrance_attract_spot" )
- thread Training_OG_NagPlayerUntilFlag( player, moveToGauntletNags, 45.0, ref_og_gauntletEntrance, "PlayerInGauntletEntryway" )
-
- waitthread Training_OG_Moves( ref_og_gauntletEntrance )
-}
-
-void function FiringRange_CloseZenGardenDoor_WhenPlayerReachesRange( entity player )
-{
- EndSignal( player, "OnDestroy" )
-
- vector doorFarEdge = < -6368, -952, 48 > // HACK this is the bottom edge of the door farthest from the firing range
-
- while ( 1 )
- {
- WaitFrame()
-
- if ( !Flag( "PlayerNearFiringRange" ) )
- continue
-
- if ( PlayerCanSeePos( player, doorFarEdge, true, 90 ) )
- continue
-
- break
- }
-
- CloseZenGardenExitDoor()
-}
-
-void function FiringRange_ApproachAndEntry( entity player, entity ref_og_needGunsStart, entity ref_og_firingRangeAttractSpot, entity ref_og_firingRangeSpot )
-{
- thread FiringRange_Approach_OG_Sequence( player, ref_og_needGunsStart )
-
- FlagWait( "FiringRange_Approach_OG_Sequence_Done" )
-
- if ( !Flag( "PlayerNearFiringRange" ) )
- {
- // "Time to hit the range."
- waitthread Training_OG_ScriptedAnim( ref_og_needGunsStart, "OG_Weapons_D" )
- }
-
- if ( !Flag( "PlayerNearFiringRange" ) )
- {
- // "I'm over here at the range, Cooper."
- thread Training_OG_NagPlayerUntilFlag( player, [ "og_firingrange_attract_nag" ], 40.0, ref_og_firingRangeAttractSpot, "PlayerNearFiringRange" )
-
- waitthread Training_OG_Moves( ref_og_firingRangeAttractSpot )
- }
-
- FlagWait( "PlayerNearFiringRange" )
-
- waitthread Training_OG_Moves( ref_og_firingRangeSpot, "OG_firingrange_idle" )
-}
-
-void function FiringRange_Approach_OG_Sequence( entity player, entity ref_og_needGunsStart )
-{
- EndSignal( player, "OnDestroy" )
-
- if ( !Flag( "PlayerNearFiringRange" ) )
- Training_OG_Idles_Sitting( ref_og_needGunsStart )
-
- if ( Flag( "PlayerNearFiringRange" ) )
- {
- // player is rushing forward
- FlagSet( "ineedguns" )
- thread FiringRange_INeedGuns_SFX( player, 0.0 )
- }
- else
- {
- FlagSetDelayed( "ineedguns", 2.0 )
- thread FiringRange_INeedGuns_SFX( player, 2.0 )
- }
-
- if ( !Flag( "PlayerNearFiringRange" ) )
- {
- // "In combat, things never go as you expect."
- waitthread Training_OG_ScriptedAnim( ref_og_needGunsStart, "OG_Weapons_A" )
- }
-
- if ( !Flag( "PlayerNearFiringRange" ) )
- {
- // "You must be ready to use any weapon you can find on the field."
- waitthread Training_OG_ScriptedAnim( ref_og_needGunsStart, "OG_Weapons_B" )
- }
-
- if ( !Flag( "PlayerNearFiringRange" ) )
- {
- // "These are just a few of the weapons I've come across out there."
- waitthread Training_OG_ScriptedAnim( ref_og_needGunsStart, "OG_Weapons_C" )
- }
-
- FlagSet( "FiringRange_Approach_OG_Sequence_Done" )
-}
-
-void function FiringRange_INeedGuns_SFX( entity player, float delayTime )
-{
- EndSignal( player, "OnDestroy" )
-
-
- entity centerEmitter = GetEntByScriptName( "ref_firingrange_rack_sfx_center" )
- entity backCenterEmitter = GetEntByScriptName( "ref_firingrange_rack_sfx_backcenter" )
- entity leftEmitter = GetEntByScriptName( "ref_firingrange_rack_sfx_left" )
- entity rightEmitter = GetEntByScriptName( "ref_firingrange_rack_sfx_right" )
-
- entity moverCenter = CreateScriptMover( centerEmitter.GetOrigin(), centerEmitter.GetAngles() )
- entity moverBackCenter = CreateScriptMover( backCenterEmitter.GetOrigin(), backCenterEmitter.GetAngles() )
- entity moverLeft = CreateScriptMover( leftEmitter.GetOrigin(), leftEmitter.GetAngles() )
- entity moverRight = CreateScriptMover( rightEmitter.GetOrigin(), rightEmitter.GetAngles() )
- array<entity> movers = [ moverCenter, moverBackCenter, moverLeft, moverRight ]
-
- OnThreadEnd(
- function() : ( movers )
- {
- foreach ( mover in movers )
- {
- if( !IsValid( mover ) )
- continue
-
- mover.Destroy()
- }
- }
- )
-
- if ( delayTime > 0.0 )
- wait delayTime
-
- EmitSoundOnEntity( moverCenter, "training_scr_center_racks" )
- EmitSoundOnEntity( moverBackCenter, "training_scr_back_racks" )
- EmitSoundOnEntity( moverLeft, "training_scr_left_racks" )
- EmitSoundOnEntity( moverRight, "training_scr_right_racks" )
-
- wait 15.0 // wait before cleaning up movers
-}
-
-void function FiringRange_DetectWeaponSwitch( entity player )
-{
- player.EndSignal( "OnDestroy" )
-
- entity ogWeapon = WaitForPlayerActiveWeapon( player )
- string ogWeaponName = ogWeapon.GetWeaponClassName()
-
- while ( 1 )
- {
- entity weapon = WaitForPlayerActiveWeapon( player )
- string weaponName = weapon.GetWeaponClassName()
-
- if ( weaponName != "" && weaponName != ogWeaponName )
- {
- FlagSet( "FiringRangeWeaponSwapped" )
- break
- }
-
- wait 0.5
- }
-}
-
-void function FiringRange_TrainReload( entity player, entity ogIdleSpot )
-{
- FlagClear( "PlayerReloaded" )
-
- SetWeaponHUDEnabled( player, true )
-
- player.SetExtraWeaponMods( [ "" ] ) // turns off low_ammo_disable
- thread TakeAmmoFromPlayerASAP( player )
-
- thread TrainReload_GivePlayerAmmoAfterButtonPressed( player )
-
- // "Load your weapon."
- // "Swap in a fresh mag."
- array<string> reloadNags = [ "og_reload_hint", "og_reload_nag" ]
-
- wait 1.1 // let pro players reload before prompting
-
- int nagIdx = 0
-
- if ( !Flag( "PlayerReloaded" ) )
- {
- thread OnscreenHint_DisplayUntilFlag( player, "reload_hint", "PlayerReloaded" )
-
- float nagInterval = 15
- float lastNagTime = -100
-
- while ( !Flag( "PlayerReloaded" ) )
- {
- wait 0.1
-
- if ( Time() - lastNagTime >= nagInterval )
- {
- waitthread Training_OG_Talks( reloadNags[nagIdx], ogIdleSpot, "OG_firingrange_talk", "OG_firingrange_idle", true )
- lastNagTime = Time()
-
- nagIdx++
- if ( nagIdx >= reloadNags.len() )
- nagIdx = 0
- }
- }
- }
-}
-
-void function TrainReload_GivePlayerAmmoAfterButtonPressed( entity player )
-{
- player.EndSignal( "OnDestroy" )
-
- FlagWait( "PlayerReloaded" )
-
- FlagSet( "ReloadTraining_PlayerPressedReload" )
-
- player.SetActiveWeaponPrimaryAmmoTotal( 50 )
-}
-
-void function FiringRange_InfiniteAmmo_WhenNearRange( entity player, string endFlag )
-{
- player.EndSignal( "OnDestroy" )
- FlagEnd( endFlag )
-
- while ( 1 )
- {
- wait 0.5
-
- if ( !Flag( "PlayerNearFiringRange" ) )
- continue
-
- entity weapon = player.GetActiveWeapon()
-
- if ( weapon == null )
- continue
-
- int currAmmo = player.GetWeaponAmmoStockpile( weapon )
- int magSize = weapon.GetWeaponSettingInt( eWeaponVar.ammo_clip_size )
- int maxAmmo = weapon.GetWeaponSettingInt( eWeaponVar.ammo_stockpile_max )
-
- // let player reload before restocking
- if ( currAmmo > (maxAmmo-magSize + 1) )
- continue
-
- printt( "firing range restock ammo" )
-
- RestockPlayerAmmo_Silent( player )
- }
-}
-
-void function FiringRange_TrainADS( entity player, entity ref_og_firingRangeSpot )
-{
- thread FlagSetWhenPlayerADS( player, "PlayerADSed" )
-
- FlagWaitWithTimeout( "PlayerADSed", 2.5 ) // give player time to ADS before hinting
-
- if ( !Flag( "PlayerADSed" ) )
- {
- // "Aim down the sights when engaging more distant targets."
- // "You can focus more tightly on your targets if you aim down the sights."
- array<string> adsNags = [ "og_ads_nag_1", "og_ads_nag_2" ]
- thread Training_OG_NagPlayerUntilFlag( player, adsNags, 10.0, ref_og_firingRangeSpot, "PlayerADSed", "OG_firingrange_talk", "OG_firingrange_idle" )
-
- thread OnscreenHint_DisplayUntilFlag( player, "ads_hint", "PlayerADSed" )
-
- // "To get more precision, aim down the sights of your weapon."
- waitthread Training_OG_Talks( "og_ads_hint", ref_og_firingRangeSpot, "OG_firingrange_talk", "OG_firingrange_idle", true )
- }
-
- FlagWait( "PlayerADSed" )
-}
-
-void function FiringRange_TrainWeaponSwap( entity player, entity ref_og_firingRangeSpot )
-{
- Signal( player, "FiringRange_StopResettingTargets" )
-
- if ( !Flag( "FiringRangeWeaponSwapped" ) )
- {
- DisplayOnscreenHint( player, "weapon_pickup_hint", 5.0 )
- thread OnscreenHint_NagUntilFlag( player, "weapon_pickup_hint", "FiringRangeWeaponSwapped", 10.0, 5.0 )
-
- // "Use a different weapon this time. Grab another one off the rack."
- thread Training_OG_Talks( "og_weaponswap_hint", ref_og_firingRangeSpot, "OG_firingrange_talk", "OG_firingrange_idle", true )
-
- // "Switch to a different weapon."
- array<string> weaponSwapNags = [ "og_weaponswap_nag" ]
- waitthread Training_OG_NagPlayerUntilFlag( player, weaponSwapNags, 10.0, ref_og_firingRangeSpot, "FiringRangeWeaponSwapped", "OG_firingrange_talk", "OG_firingrange_idle" )
- }
-}
-
-void function FiringRange_PlayerMustDamageAllTargets( entity player, entity ref_og_firingRangeSpot, bool firstTime, bool resetTargetsAtStart = true )
-{
- EndSignal( player, "OnDestroy" )
-
- FlagClear( "FiringRange_AllTargetsKilled" )
- thread FiringRange_ResetTargets_Think( player, resetTargetsAtStart )
-
- thread OnscreenHint_DisplayUntilFlag( player, "firingrange_dmg_targets_hint", "FiringRange_AllTargetsKilled" )
-
- wait 2.0
-
- // "Gotta take 'em all out before we can move on."
- // "Just aim, take a breath, and squeeze the trigger."
- // "In the real world, the targets don't just stand still. They shoot back."
- DialogueGroup nags = GetDialogueGroup( "shootTargetsNag" )
-
- int numTargetsKilled = FiringRange_GetNumDamagedTargets()
-
- while ( !Flag( "FiringRange_AllTargetsKilled" ) )
- {
- wait 1.0
-
- // don't nag player if they recently damaged a target
- if ( FiringRange_GetNumDamagedTargets() > numTargetsKilled )
- {
- numTargetsKilled = FiringRange_GetNumDamagedTargets()
- TimerReset( "firingRangeNag" )
-
- continue
- }
-
- if ( !TimerCheck( "firingRangeNag" ) )
- continue
-
- string nagLine = DialogueGroup_GetNextLine( nags )
- waitthread Training_OG_Talks( nagLine, ref_og_firingRangeSpot, "OG_firingrange_talk", "OG_firingrange_idle", true )
-
- TimerReset( "firingRangeNag" )
- }
-}
-
-void function FiringRangeTargets_Init()
-{
- string targetScriptName = "firingrange_target"
- array<entity> targetEnts = GetEntArrayByScriptName( targetScriptName )
- Assert( targetEnts.len(), "Couldn't get firing range targets with script_name " + targetScriptName )
-
- foreach ( ent in targetEnts )
- {
- ent.SetTakeDamageType( DAMAGE_EVENTS_ONLY )
- ent.SetDamageNotifications( true )
-
- entity angleRefEnt = ent.GetLinkEnt()
- Assert( IsValid( angleRefEnt ), "Firing range target needs an angle reference entity linked" )
- angleRefEnt.SetParent( ent )
-
- FiringRangeTarget target
- target.ent = ent
- target.angleRefEnt = angleRefEnt
- target.ogAngles = ent.GetAngles()
- target.mover = CreateScriptMover( ent.GetOrigin(), ent.GetAngles() )
- ent.SetParent( target.mover )
-
- file.firingRangeTargets.append( target )
- }
-}
-
-int function FiringRange_GetNumDamagedTargets()
-{
- int numDamaged = 0
-
- foreach ( target in file.firingRangeTargets )
- if ( target.wasDamaged )
- numDamaged++
-
- return numDamaged
-}
-
-void function FiringRange_ResetAllTargets()
-{
- foreach ( target in file.firingRangeTargets )
- FiringRangeTarget_Reset( target )
-}
-
-void function FiringRangeTarget_Reset( FiringRangeTarget target )
-{
- if ( !IsValid( target.ent ) )
- return
-
- target.wasDamaged = false
-
- thread FiringRangeTarget_RotateBack( target )
-}
-
-void function FiringRange_ResetTargets_Think( entity player, bool resetTargetsAtStart = true )
-{
- Signal( player, "FiringRange_StopResettingTargets" )
- EndSignal( player, "FiringRange_StopResettingTargets" )
- EndSignal( player, "OnDestroy" )
-
- FlagEnd( "PodOutroStarted" )
-
- array<FiringRangeTarget> firingRangeTargets = file.firingRangeTargets
-
- bool firstLoop = true
- float targetResetWait = 1.75
-
- while ( 1 )
- {
- bool resetTargets = true
- if ( firstLoop && !resetTargetsAtStart )
- resetTargets = false
-
- if ( resetTargets )
- FiringRange_ResetAllTargets()
-
- foreach ( target in firingRangeTargets )
- thread FiringRangeTarget_WaitForDamage( target )
-
- // wait for all targets to take damage
- while ( 1 )
- {
- wait 0.2
-
- bool allDamaged = true
- foreach ( target in firingRangeTargets )
- {
- if ( !target.wasDamaged )
- {
- allDamaged = false
- break
- }
- }
-
- if ( allDamaged )
- break
- }
-
- FlagSet( "FiringRange_AllTargetsKilled" )
-
- wait targetResetWait
-
- if ( firstLoop )
- firstLoop = false
- }
-}
-
-void function FiringRangeTarget_WaitForDamage( FiringRangeTarget target )
-{
- Signal( target.ent, "Target_WaitForDamage_Start" )
- EndSignal( target.ent, "Target_WaitForDamage_Start" )
- EndSignal( target.ent, "OnDestroy" )
-
- bool first = true
- while ( 1 )
- {
- table result = WaitSignal( target.ent, "TargetDamaged" )
- vector damagePos = expect vector( result.damagePos )
-
- if ( first )
- {
- thread FiringRangeTarget_FirstDamage( target, damagePos )
- first = false
- }
- }
-
- return
-}
-
-string function FiringRangeTarget_GetDamageSide( FiringRangeTarget target, vector damagePos )
-{
- vector upEntPos = target.angleRefEnt.GetOrigin()
- vector upEntAngles = target.angleRefEnt.GetAngles()
-
- vector facingVec = AnglesToForward( upEntAngles )
- vector vecToDamage = Normalize( damagePos - upEntPos )
- float dot2Damage = DotProduct( vecToDamage, facingVec )
- printt( "damage dot product:", dot2Damage )
-
- #if DEV
- //float debugDrawTime = 3.0
- //DebugDrawAngles( damagePos, upEntAngles, debugDrawTime )
- //DebugDrawLine( upEntPos, upEntPos + (facingVec * 200), 200, 200, 0, true, debugDrawTime )
- #endif
-
- vector frontFacingVec = AnglesToRight( upEntAngles )
- bool isOnLeft = IsPointInFrontofLine( damagePos, upEntPos, frontFacingVec )
-
- string returnStr = "left"
- if ( isOnLeft )
- {
- printt( "LEFT SIDE" )
- }
- else
- {
- printt( "RIGHT SIDE" )
- returnStr = "right"
- }
-
- return returnStr
-}
-
-void function FiringRangeTarget_FirstDamage( FiringRangeTarget target, vector damagePos )
-{
- //Assert( !target.wasDamaged, "Target not expected to be damaged yet" )
- if ( target.wasDamaged )
- return
-
- target.wasDamaged = true
-
- if ( IsAlive( file.player ) )
- EmitSoundOnEntity( file.player, "training_scr_hit_target" )
-
- // rotate left by default
- float rotateAngY = 179.9
- if ( FiringRangeTarget_GetDamageSide( target, damagePos ) == "right" )
- rotateAngY *= -1
-
- vector newAngles = target.ogAngles + Vector( 0, rotateAngY, 0 )
- thread FiringRangeTarget_Rotate( target, newAngles )
-}
-
-void function FiringRangeTarget_Rotate( FiringRangeTarget target, vector targetAngles )
-{
- Signal( target.mover, "TargetRotate" )
- EndSignal( target.mover, "TargetRotate" )
- EndSignal( target.mover, "OnDestroy" )
-
- float rotateTime = 0.14
- float accelTime = 0
- float decelTime = 0.1
- target.mover.NonPhysicsRotateTo( targetAngles, rotateTime, accelTime, decelTime )
-
- wait rotateTime
-}
-
-void function FiringRangeTarget_RotateBack( FiringRangeTarget target )
-{
- if ( target.ent.GetAngles() == target.ogAngles )
- return
-
- EmitSoundAtPosition( TEAM_UNASSIGNED, target.ent.GetOrigin(), "training_scr_range_target_spin" )
-
- waitthread FiringRangeTarget_Rotate( target, target.ogAngles )
-}
-
-
-void function FlagSetWhenPlayerADS( entity player, string setFlag )
-{
- player.EndSignal( "OnDestroy" )
-
- while ( player.GetZoomFrac() < 0.9 )
- wait 0.1
-
- FlagSet( setFlag )
-}
-
-
-
-// =============================
-// ========= GAUNTLET ==========
-// =============================
-void function Training_Setup_Gauntlet( entity player )
-{
- entity ogStart = GetEntByScriptName( "og_gauntlet_entrance_attract_spot" )
- entity og = Training_SpawnOGPilot( ogStart )
- Training_OG_Idles( ogStart )
-
- TeleportPlayerAndBT( "startpoint_gauntlet_entrance" )
-}
-
-void function Training_Skipped_Gauntlet( entity player )
-{
- FlagSet( "Gauntlet_FirstRun_Done" )
- thread TrainingGauntlet_RemindPlayerAboutMobility( player )
- thread TrainingGauntlet_CrouchHint( player )
- thread TrainingGauntlet_SetsDifficulty( player )
-}
-
-void function Training_Gauntlet( entity player )
-{
- entity og = GetOGPilot()
-
- entity ref_og_gauntletStartPos = GetEntByScriptName( "og_near_gauntlet_start_pos" )
- GauntletInfo trainingGauntlet = GetTrainingGauntlet()
-
- // HACK
- vector resultsBoardCenterPos = < -4899.15, 666.269, 107.187 >
-
- if ( !Flag( "PlayerInGauntletEntryway" ) && !trainingGauntlet.isActive && !PlayerCanSeePos( player, resultsBoardCenterPos, true, 90 ) )
- DisableGauntlet( trainingGauntlet ) // let a rushing player start the gauntlet
-
- if ( !trainingGauntlet.isActive )
- FlagWait( "PlayerInGauntletEntryway" )
-
- if ( !trainingGauntlet.isActive )
- CheckPoint_Silent()
-
- waitthread Training_OG_Moves( ref_og_gauntletStartPos, ANIM_OG_LEANING_IDLE )
-
- thread Training_Gauntlet_FirstRunDialogue( player, trainingGauntlet, ref_og_gauntletStartPos )
- wait 1.0
-
- EnableGauntlet( trainingGauntlet )
- thread Training_Gauntlet_FirstRunGhostPlaybackStart( player, trainingGauntlet )
- thread TrainingGauntlet_TeleportPlayerAtFinishLine( player )
- thread TrainingGauntlet_RemindPlayerAboutMobility( player, "Gauntlet_FirstRun_All_VO_Finished" )
- thread TrainingGauntlet_CrouchHint( player )
- thread TrainingGauntlet_SetsDifficulty( player )
-
- thread Training_Gauntlet_WaitForRequiredTime( player, ref_og_gauntletStartPos )
- FlagWait( "Gauntlet_FirstRun_Done" )
-
- if ( !trainingGauntlet.isActive )
- CheckPoint_Silent()
-
- Gauntlet_StopGhostPlayback( trainingGauntlet )
-
- waitthread Training_Gauntlet_PostFirstRunDialogue( player, trainingGauntlet )
-}
-
-
-void function Training_Gauntlet_FirstRunDialogue( entity player, GauntletInfo gauntlet, entity ogIdleSpot )
-{
- player.EndSignal( "OnDestroy" )
-
- if ( !gauntlet.isActive )
- {
- // "Alright. Got a new gauntlet for you to run today."
- waitthread Training_OG_ScriptedAnim( ogIdleSpot, "OG_gauntlet_start_A" )
- }
-
- if ( !gauntlet.isActive )
- {
- // "Par time is a minute-forty-five."
- waitthread Training_OG_ScriptedAnim( ogIdleSpot, "OG_gauntlet_start_B" )
- }
-
- if ( !gauntlet.isActive )
- {
- // "Gotta do better than that to continue."
- waitthread Training_OG_ScriptedAnim( ogIdleSpot, "OG_gauntlet_start_C" )
- }
-
- Objective_Set( "#TRAINING_OBJ_GAUNTLET_FIRSTRUN" )
-
- //if ( gauntlet.isActive )
- // Training_Gauntlet_OG_Creates_FirstRun_Ghost( file.ogPilot )
-
- AddAnimEvent( file.ogPilot, "create_ghost", Training_Gauntlet_OG_Creates_FirstRun_Ghost )
-
- // "Follow the ghost, or find your own path."
- waitthread Training_OG_ScriptedAnim( ogIdleSpot, "OG_gauntlet_start_D" )
- thread Training_OG_Idles( ogIdleSpot, "OG_gauntlet_start_endidle" )
-
- DeleteAnimEvent( file.ogPilot, "create_ghost" )
-
- float minDelayEnd = 5.0 + Time()
- DialogueGroup firstRunGauntletLore = GetDialogueGroup( "firstRunGauntletLore" )
- while ( !Flag( "Gauntlet_FirstRun_Done" ) && !firstRunGauntletLore.allPlayed )
- {
- wait 1
-
- if ( !gauntlet.isActive )
- continue
-
- if ( Time() < minDelayEnd )
- continue
-
- string line = DialogueGroup_GetNextLine( firstRunGauntletLore )
- PlayDialogue( line, player )
- }
-
- FlagSet( "Gauntlet_FirstRun_All_VO_Finished" )
-}
-
-void function Training_Gauntlet_OG_Creates_FirstRun_Ghost( entity og )
-{
- entity player = file.player
- if ( !IsValid( player ) )
- return
-
- player.Signal( "FirstRun_OG_Creates_Ghost" )
-}
-
-void function TrainingGauntlet_RemindPlayerAboutMobility( entity player, string waitFlag = "" )
-{
- EndSignal( player, "OnDestroy" )
- FlagEnd( "PlayerLeavingGauntlet" )
-
- GauntletInfo trainingGauntlet = GetTrainingGauntlet()
-
- //if ( waitFlag != "" && !Flag( waitFlag ) )
- // FlagWait( waitFlag )
-
- float nagInterval = 300 // 5 minutes
- float nextNagTime = -1
-
- float minSampleTime = 15.0
- float lowWallrunningFrac = 0.05
-
- bool hasSprinted = false
-
- FlagWait( "Gauntlet_FirstRun_All_VO_Finished" )
-
- while ( !Flag( "PlayerLeavingGauntlet" ) )
- {
- if ( !trainingGauntlet.isActive )
- WaitSignal( player, "Gauntlet_RunStarted" )
-
- float startTime = Time()
- float samplePoints = 0
- float samplesWallrunning = 0
-
- while ( trainingGauntlet.isActive )
- {
- wait 0.1
-
- if ( player.IsSprinting() && !hasSprinted )
- hasSprinted = true
-
- samplePoints++
- if ( player.IsWallRunning() )
- samplesWallrunning++
-
- if ( (Time() - startTime) < minSampleTime )
- continue
-
- float wallrunningFrac = samplesWallrunning / samplePoints
- printt( "wallrunningFrac:", wallrunningFrac )
-
- // Has player done all the stuff we would want to remind them about?
- if ( wallrunningFrac >= lowWallrunningFrac && hasSprinted )
- break
-
- if ( Time() >= nextNagTime )
- {
- if ( !hasSprinted )
- thread TrainingGauntlet_SprintNag( player )
- else if ( wallrunningFrac < lowWallrunningFrac )
- thread TrainingGauntlet_WallrunNag( player, trainingGauntlet )
-
- nextNagTime = Time() + nagInterval
- }
-
- break
- }
-
- if ( trainingGauntlet.isActive )
- WaitSignal( player, "Gauntlet_RunStopped" )
- }
-}
-
-void function TrainingGauntlet_SprintNag( entity player )
-{
- EndSignal( player, "OnDestroy" )
-
- float hintDuration = 10.0
- float hintEndTime = Time() + hintDuration
- DisplayOnscreenHint( player, "sprint_button_hint", hintDuration )
-
- EndSignal( player, "DisplayingOnscreenHint" )
-
- while ( Time() < hintEndTime && !player.IsSprinting() )
- WaitFrame()
-
- ClearOnscreenHint( player )
-}
-
-void function TrainingGauntlet_WallrunNag( entity player, GauntletInfo trainingGauntlet )
-{
- EndSignal( player, "OnDestroy" )
-
- //printt( "playing mobility nag" )
-
- DisplayOnscreenHint( player, "gauntlet_wallrun_hint", 8.0 )
-
- DialogueGroup gauntletHints_wallrun = GetDialogueGroup( "gauntletHints_wallrun" )
- string line = DialogueGroup_GetNextLine( gauntletHints_wallrun )
- waitthread PlayDialogue( line, player )
-
- if ( !trainingGauntlet.isActive )
- return
-
- waitthread PlayDialogue( "og_gauntlet_hint_wallrun_capper", player )
-}
-
-void function TrainingGauntlet_CrouchHint( entity player )
-{
- EndSignal( player, "OnDestroy" )
-
- string checkFlag = "Gauntlet_PlayerInCrouchHintZone"
- string nagTimer = "gauntlet_crouchHint"
-
- TimerInit( nagTimer, 2.5 )
-
- float waitTime = 1.0
- bool hintShowing = false
-
- while ( 1 )
- {
- wait waitTime
-
- if ( !Flag( checkFlag ) )
- continue
-
- TimerReset( nagTimer )
-
- while ( Flag( checkFlag ) )
- {
- wait waitTime
-
- if ( !TimerCheck( "gauntlet_crouchHint" ) )
- continue
-
- if ( !hintShowing )
- {
- DisplayOnscreenHint( player, "crouch_hint" )
- hintShowing = true
- }
- }
-
- if ( hintShowing )
- {
- ClearOnscreenHint( player )
- hintShowing = false
- }
- }
-}
-
-void function Training_Gauntlet_PostFirstRunDialogue( entity player, GauntletInfo gauntlet )
-{
- player.EndSignal( "OnDestroy" )
- player.EndSignal( "Gauntlet_RunStarted" )
-
- entity ref_og_gauntletResults = GetEntByScriptName( "og_ref_gauntlet_results_display" )
-
- Objective_SetSilent( "#TRAINING_OBJ_DEFAULT" )
-
- waitthread Training_OG_Moves( ref_og_gauntletResults, "", 1.0 )
-
- AddAnimEvent( file.ogPilot, "highlight_results_board_tip", Gauntlet_PostFirstRun_SetRandomTip )
-
- // "Nice run! See the results board on the wall? You set a new Best Time."
- // "Everyone has different strengths and weaknesses, so be sure to run this a few times with different weapons."
- // "Look at the results board for more tips on how to improve."
- waitthread Training_OG_ScriptedAnim( ref_og_gauntletResults, "OG_Gauntlet_return" )
-
- DeleteAnimEvent( file.ogPilot, "highlight_results_board_tip" )
-}
-
-// update tip while OG is talking about the tips
-void function Gauntlet_PostFirstRun_SetRandomTip( entity og )
-{
- entity player = file.player
- if ( !IsValid( player ) )
- return
-
- GauntletInfo gauntlet = GetTrainingGauntlet()
- Remote_CallFunction_Replay( player, "ScriptCallback_GauntletResultsDisplay_SetRandomTip", gauntlet.id )
-}
-
-void function Training_Gauntlet_FirstRunGhostPlaybackStart( entity player, GauntletInfo gauntlet )
-{
- if ( !gauntlet.isActive )
- WaitSignal( player, "Gauntlet_RunStarted", "FirstRun_OG_Creates_Ghost" )
-
- thread Gauntlet_StartGhostPlayback( gauntlet, GHOST_NAME_FIRSTRUN, "#GAUNTLET_GHOST_NAME_FIRSTRUN" )
-}
-
-void function Training_Gauntlet_WaitForRequiredTime( entity player, entity ogIdleSpot )
-{
- player.EndSignal( "OnDestroy" )
-
- GauntletInfo gauntlet = GetTrainingGauntlet()
-
- // "The first run of the day is always the toughest."
- // "Too slow! I know you can do better. Give it another try."
- DialogueGroup firstRunFailedGroup = GetDialogueGroup( "firstRunFailed" )
-
- int failCount = 0
- while ( 1 )
- {
- // keep setting this here because by default the gauntlet updates its random tip after each finished run
- Remote_CallFunction_Replay( player, "ScriptCallback_TrainingGauntlet_ResultsDisplay_SetTip", gauntlet.id, 0 )
-
- player.WaitSignal( "Gauntlet_RunStopped" )
-
- wait 0.1 // HACK let the gauntlet struct get updated before checking it
-
- TrainingGauntletStats_PostRunUpdate( player, gauntlet, 0 )
-
- if ( !gauntlet.runFinished )
- continue
-
- failCount++
-
- if ( gauntlet.bestTime <= TRAINING_GAUNTLET_MAX_TIME_TO_PROGRESS || failCount == NUM_GAUNTLET_FAILS_BEFORE_FORCED_PROGRESS )
- {
- if ( gauntlet.bestTime <= TRAINING_GAUNTLET_MAX_TIME_TO_PROGRESS )
- printt( "Gauntlet moving on: beat required time" )
- else if ( failCount == NUM_GAUNTLET_FAILS_BEFORE_FORCED_PROGRESS )
- printt( "Gauntlet moving on: forced progress after", NUM_GAUNTLET_FAILS_BEFORE_FORCED_PROGRESS, "failures" )
-
- break
- }
-
- wait 0.5 // let player get settled before VO starts
-
- EmitSoundOnEntityOnlyToPlayer( player, player, "training_scr_gaunlet_fail_01" )
-
- string firstRunFailedLine = DialogueGroup_GetNextLine( firstRunFailedGroup )
- thread Training_OG_Talks_Leaning( firstRunFailedLine, ogIdleSpot, "", "", true )
-
- Objective_Remind()
- //DisplayOnscreenHint( player, "gauntlet_first_run_progression_hint", 9.0 )
-
- if ( failCount == 2 )
- thread DoSprintEnableDialogForGauntletIfNeeded_Thread( player, 3.5 )
- }
-
- TrainingGauntletPostRun_TryAchievements( player, gauntlet )
-
- FlagSet( "Gauntlet_FirstRun_Done" )
-}
-
-void function DoSprintEnableDialogForGauntletIfNeeded_Thread( entity player, float waitTime )
-{
- EndSignal( player, "OnDestroy" )
- wait waitTime
-
- if ( GetAutosprintEnabled() )
- return
-
- Remote_CallFunction_UI( player, "ScriptCallback_OpenAutosprintDialogForGauntlet" )
-}
-
-void function TrainingGauntlet_TeleportPlayerAtFinishLine( entity player )
-{
- Signal( player, "Gauntlet_StopTeleportingPlayerAtFinishLine" )
- EndSignal( player, "Gauntlet_StopTeleportingPlayerAtFinishLine" )
- EndSignal( player, "OnDestroy" )
-
- entity startEnt = GetEntByScriptName( "results_room_teleport_refA" )
- entity endEnt = GetEntByScriptName( "results_room_teleport_refB" )
- vector startPos = startEnt.GetOrigin()
- vector endPos = endEnt.GetOrigin()
-
- while ( 1 )
- {
- player.WaitSignal( "Gauntlet_PlayerHitFinishTrig" )
-
- vector currentPos = player.GetOrigin()
- float offsetX = currentPos.x - startPos.x
- float offsetY = currentPos.y - startPos.y
- float offsetZ = currentPos.z - startPos.z
-
- float newPosX = endPos.x + offsetX
- float newPosY = endPos.y + offsetY
- float newPosZ = endPos.z + offsetZ
-
- vector newPos = < newPosX, newPosY, newPosZ >
-
- player.SetOrigin( newPos )
- }
-}
-
-
-void function TrainingGauntlet_SetsDifficulty( entity player )
-{
- if ( Flag( "PlayerLeavingGauntlet" ) )
- return
-
- FlagEnd( "PlayerLeavingGauntlet" )
-
- player.EndSignal( "OnDestroy" )
-
- GauntletInfo gauntlet = GetTrainingGauntlet()
-
- bool diffSetOnce = false
-
- while ( 1 )
- {
- WaitSignal( player, "Gauntlet_RunStopped" )
-
- if ( file.gauntletMode )
- return
-
- wait 0.2 // HACK let the gauntlet struct and file variables get set up after the run
-
- // extra wait for player to finish seeing their time, etc.
- wait 2.0
-
- if ( !gauntlet.runFinished )
- continue
-
- if ( !gauntlet.lastRunBestTime )
- continue
-
- int prevDiff = -1
- if ( diffSetOnce )
- prevDiff = GetConVarInt( "sp_difficulty" )
-
- Training_SetDifficultyForGauntletTime( gauntlet.bestTime )
- if ( GetConVarInt( "sp_difficulty" ) > prevDiff )
- Training_AnnounceDifficultyForGauntletTime( player, 8.0 )
-
- if ( !diffSetOnce )
- diffSetOnce = true
- }
-}
-
-void function Training_SetDifficultyForGauntletTime( float time )
-{
- float time = file.trainingGauntletStats.bestTime
- if ( time == -1 )
- time = TRAINING_GAUNTLET_MAX_TIME_TO_PROGRESS
-
- int difficulty = DIFFICULTY_EASY
- //if ( time <= REC_DIFF_GAUNTLET_TIME_MASTER )
- // difficulty = DIFFICULTY_MASTER
- // else if
- if ( time <= REC_DIFF_GAUNTLET_TIME_HARD )
- difficulty = DIFFICULTY_HARD
- else if ( time <= REC_DIFF_GAUNTLET_TIME_NORMAL )
- difficulty = DIFFICULTY_NORMAL
-
- printt( "GetDifficultyForGauntletTime: diff", difficulty, "for time", time )
-
- file.trainingGauntletStats.recommendedDifficulty = difficulty
-
- SetConVarInt( "sp_difficulty", difficulty )
-}
-
-void function Training_AnnounceDifficultyForGauntletTime( entity player, float displayTime = 5.0 )
-{
- string hintAlias = "hint_diff_"
- hintAlias += file.trainingGauntletStats.recommendedDifficulty.tostring()
- DisplayOnscreenHint( player, hintAlias, displayTime )
-}
-
-
-// ======================================================
-// ========= GAUNTLET CHALLENGE (post 1st run) ==========
-// ======================================================
-void function Training_Setup_GauntletChallenge( entity player )
-{
- entity ogStart = GetEntByScriptName( "og_ref_gauntlet_results_display" )
- entity og = Training_SpawnOGPilot( ogStart )
- Training_OG_Idles( ogStart )
-
- TeleportPlayerAndBT( "playerstart_gauntlet_challenge" )
-}
-
-void function Training_Skipped_GauntletChallenge( entity player )
-{
-}
-
-void function Training_GauntletChallenge( entity player )
-{
- GauntletInfo gauntlet = GetTrainingGauntlet()
-
- thread TrainingGauntlet_TeleportPlayerAtFinishLine( player )
-
- entity ref_og_gauntletLeaderboardPos = GetEntByScriptName( "og_near_leaderboard" )
-
- // in gauntlet mode OG spawns here before player fade finishes, no need to move him
- if ( !file.gauntletMode )
- waitthread Training_OG_Moves( ref_og_gauntletLeaderboardPos, "" )
-
- Gauntlet_ShowLeaderboard( gauntlet )
-
- thread GauntletChallenge_GhostsThink( player, gauntlet, "GauntletChallenge_FirstGhostAppear", "PlayerLeavingGauntlet" )
- thread GauntletChallenge_IntroDialogue( player, gauntlet, ref_og_gauntletLeaderboardPos )
- thread GauntletChallege_RestartGauntletHint( player, gauntlet )
-
- FlagWait( "ChallengeIntro_VO_Done" )
-
- bool installRuiStarted = false
- if ( !Training_IsGameFullyInstalled() )
- Remote_CallFunction_Replay( player, "ScriptCallback_ShowInstallProgress", true )
-
- entity ref_og_gauntletExitPos = GetEntByScriptName( "og_gauntlet_exit_pos" )
- thread Training_GauntletChallenge_DialogueThink( player, gauntlet, ref_og_gauntletExitPos )
- thread Training_OG_Moves( ref_og_gauntletExitPos, "OG_all_done_idle" )
-
- wait 1.0
- thread Training_LeaveGauntletThink( player, ref_og_gauntletExitPos )
-
- FlagWait( "PlayerConfirmedGauntletExit" )
-
- Remote_CallFunction_Replay( player, "ScriptCallback_ShowInstallProgress", false )
-
- Objective_SetSilent( "#TRAINING_OBJ_DEFAULT" )
-
- DisableGauntlet( gauntlet )
-
- FlagWait( "PlayerLeavingGauntlet" )
-
- Signal( player, "Gauntlet_StopTeleportingPlayerAtFinishLine" )
-
- if ( file.gauntletMode )
- {
- thread Training_PodOutro( player )
- WaitForever() // stall normal progression
- }
- else
- {
- thread DisableWeaponDelayed( player, 0.3 ) // disable weapon so crosshairs aren't visible during white screen
-
- entity destEnt = GetEntByScriptName( "startpoint_titanfall" )
- waitthread PlayerAndOGTeleport_Fancy( player, destEnt.GetOrigin(), "og_titanfall_start_pos", destEnt.GetAngles() )
-
- CheckPoint_Silent()
- }
-}
-
-void function DisableWeaponDelayed( entity player, float delay )
-{
- EndSignal( player, "OnDestroy" )
-
- if ( delay > 0 )
- wait delay
-
- player.DisableWeapon()
-}
-
-void function GauntletChallege_RestartGauntletHint( entity player, GauntletInfo gauntlet )
-{
- EndSignal( player, "OnDestroy" )
-
- float displayTime = 5.0
- float delayTime = 2.5
-
- const int RUNS_BETWEEN_REMINDERS = 3
- int runsSinceLastReminder = 3 // do reminder on first run
-
- while ( 1 )
- {
- if ( !gauntlet.isActive )
- WaitSignal( player, "Gauntlet_RunStarted" )
-
- float displayEndTime = -1
-
- // check if we should remind after run starts
- if ( runsSinceLastReminder >= RUNS_BETWEEN_REMINDERS )
- {
- thread OnscreenHint_DisplayAfterDelay( player, "gauntlet_restart_hint", displayTime, delayTime )
- displayEndTime = Time() + displayTime + delayTime
- }
-
- // wait for run to stop
- table result = WaitSignal( player, "Gauntlet_RunStopped", "Gauntlet_ForceRestart" )
- string signal = expect string( result.signal )
-
- // clear initial hint if player cancelled the run before it would auto clear
- if ( displayEndTime != -1 && Time() < displayEndTime )
- ClearOnscreenHint( player )
-
- // player went back through the starting gate?
- if ( signal == "Gauntlet_RunStopped" && !gauntlet.runFinished )
- {
- // Don't care about how many runs between reminders here- if player does this it means they don't really get it yet
- thread DisplayOnscreenHint( player, "gauntlet_restart_hint", displayTime )
- runsSinceLastReminder = 0
- }
- // player used menu to restart?
- else if ( signal == "Gauntlet_ForceRestart" )
- {
- runsSinceLastReminder = 0 // reset the counter when force restarted
- }
-
- if ( runsSinceLastReminder >= RUNS_BETWEEN_REMINDERS )
- runsSinceLastReminder = 0
- if ( gauntlet.runFinished ) // player restarted from menu or went back through the gate
- runsSinceLastReminder++
- }
-}
-
-void function GauntletChallenge_IntroDialogue( entity player, GauntletInfo gauntlet, entity ogRef )
-{
- if ( file.gauntletMode )
- {
- thread GauntletChallengeModeOnly_IntroDialogue( player, gauntlet, ogRef )
- return
- }
-
- player.EndSignal( "OnDestroy" )
-
- if ( !gauntlet.isActive )
- {
- // "Now that you're warmed up: if you want a REAL challenge, you can race against other Pilot ghosts."
- waitthread Training_OG_ScriptedAnim( ogRef, "OG_Leaderboard_A" )
- }
-
- player.Signal( "GauntletChallenge_FirstGhostAppear" )
-
- if ( !gauntlet.isActive )
- {
- // "Word of warning, though- the Pilots who recorded these ghosts are the best in the SRS.
- waitthread Training_OG_ScriptedAnim( ogRef, "OG_Leaderboard_B" )
- }
-
- if ( !gauntlet.isActive )
- {
- // "If you can beat them, you'll be halfway to being a real Pilot."
- waitthread Training_OG_ScriptedAnim( ogRef, "OG_Leaderboard_C" )
- }
-
- if ( !gauntlet.isActive )
- {
- // "Go ahead and run the Gauntlet as much as you want."
- waitthread Training_OG_ScriptedAnim( ogRef, "OG_Leaderboard_D" )
- }
-
- // "When you're done, I've got something special to show you."
- waitthread Training_OG_ScriptedAnim( ogRef, "OG_Leaderboard_E" )
-
- if ( !Training_IsGameFullyInstalled() )
- {
- Objective_Set( "#TRAINING_OBJ_GAUNTLET_CHALLENGE_INSTALLING" )
- thread ChangeGauntletObjective_OnInstallComplete( player )
- }
- else
- {
- Objective_Set( "#TRAINING_OBJ_GAUNTLET_CHALLENGE" )
- }
-
- FlagSet( "ChallengeIntro_VO_Done" )
-}
-
-void function GauntletChallengeModeOnly_IntroDialogue( entity player, GauntletInfo gauntlet, entity ogRef )
-{
- player.EndSignal( "OnDestroy" )
-
- SetSignalDelayed( player, "GauntletChallenge_FirstGhostAppear", 0.25 )
-
- wait 1.5 // let player teleport and fade in before starting to talk
-
- if ( !gauntlet.isActive )
- {
- // "Go ahead and run the Gauntlet as much as you want."
- waitthread Training_OG_ScriptedAnim( ogRef, "OG_Leaderboard_D", true )
- }
-
- // "When you're done, I've got something special to show you."
- //waitthread Training_OG_ScriptedAnim( ogRef, "OG_Leaderboard_E" )
-
- Objective_Set( "#TRAINING_OBJ_GAUNTLET_CHALLENGE" )
-
- FlagSet( "ChallengeIntro_VO_Done" )
-}
-
-void function ChangeGauntletObjective_OnInstallComplete( entity player )
-{
- EndSignal( player, "OnDestroy" )
-
- while ( !Training_IsGameFullyInstalled() )
- wait 1.0
-
- Objective_Set( "#TRAINING_OBJ_GAUNTLET_CHALLENGE" )
-}
-
-void function GauntletChallenge_GhostsThink( entity player, GauntletInfo gauntlet, string signalWait, string endFlag )
-{
- if ( Flag( endFlag ) )
- return
-
- player.EndSignal( "OnDestroy" )
- gauntlet.signalEnt.EndSignal( "OnDestroy" )
-
- FlagEnd( endFlag )
-
- if ( !gauntlet.isActive )
- WaitSignal( player, "Gauntlet_RunStarted", signalWait )
-
- thread Gauntlet_ChallengeLeaderboardGhosts( player, gauntlet, "PlayerLeavingGauntlet" )
-}
-
-void function Training_GauntletChallenge_DialogueThink( entity player, GauntletInfo gauntlet, entity ogSpot )
-{
- player.EndSignal( "OnDestroy" )
-
- FlagWait( "ChallengeIntro_VO_Done" )
-
- DialogueGroup clearedLeaderboard = GetDialogueGroup( "clearedLeaderboard" )
- DialogueGroup defeatedGhost = GetDialogueGroup( "defeatedGhost" )
- DialogueGroup notBestTime = GetDialogueGroup( "notBestTime" )
- DialogueGroup newBestTime = GetDialogueGroup( "newBestTime" )
-
- while ( 1 )
- {
- FlagClear( "Gauntlet_PlayingFeedbackVO" )
-
- WaitSignal( player, "Gauntlet_RunStopped" )
-
- wait 0.1 // HACK let the gauntlet struct get updated before checking
-
- TrainingGauntletStats_PostRunUpdate( player, gauntlet, 1 )
-
- if ( !gauntlet.runFinished )
- continue
-
- TrainingGauntletPostRun_TryAchievements( player, gauntlet )
-
- FlagSet( "Gauntlet_PlayingFeedbackVO" )
-
- string feedbackLine = ""
-
- // SPECIAL- defeated a Hero Ghost
- if ( gauntlet.lastRunDefeatedGhost && !gauntlet.allGhostsDefeated )
- {
- array<GauntletGhost> leaderboard = Gauntlet_GetLeaderboard( gauntlet )
- GauntletGhost playerGhost = Gauntlet_GetPlayerGhost( gauntlet )
-
- array<string> heroFileNames = [ GHOST_NAME_ALIAS_LASTIMOSA, GHOST_NAME_ALIAS_ANDERSON, GHOST_NAME_ALIAS_BRIGGS ]
-
- GauntletGhost loserGhost
- foreach ( ghost in leaderboard )
- {
- if ( playerGhost.duration <= ghost.duration && heroFileNames.contains( ghost.fileName ) )
- {
- loserGhost = ghost
- break
- }
- }
-
- switch ( loserGhost.fileName )
- {
- case GHOST_NAME_ALIAS_LASTIMOSA:
- // "Hey - that was my best time! I must be getting slow."
- feedbackLine = "og_gauntlet_unlocked_leaderboard_entry_og"
- break
-
- case GHOST_NAME_ALIAS_ANDERSON:
- // "Heh. Can't wait to tell Anderson about that. Son of a bitch..."
- feedbackLine = "og_gauntlet_unlocked_leaderboard_entry_anderson"
- break
-
- case GHOST_NAME_ALIAS_BRIGGS:
- // "You just beat Commander Briggs. Might not stay that way for long though, she's very competitive."
- feedbackLine = "og_gauntlet_unlocked_leaderboard_entry_briggs"
- break
- }
-
- if ( feedbackLine != "" )
- waitthread Training_OG_Talks( feedbackLine, ogSpot, "OG_all_done_talk", "OG_all_done_idle", true )
- }
-
- // SPECIAL - cleared leaderboard
- if ( gauntlet.allGhostsDefeated && !clearedLeaderboard.allPlayed )
- {
- while ( !clearedLeaderboard.allPlayed && !gauntlet.isActive )
- {
- feedbackLine = DialogueGroup_GetNextLine( clearedLeaderboard )
- waitthread Training_OG_Talks( feedbackLine, ogSpot, "OG_all_done_talk", "OG_all_done_idle", true )
- }
- }
-
- // If we played a line by now, it was Special, so we don't want the generic ones below.
- if ( feedbackLine != "" )
- continue
-
- // LAST RUN: DEFEATED GHOST (GENERIC)
- if ( gauntlet.lastRunDefeatedGhost && !gauntlet.allGhostsDefeated )
- {
- feedbackLine = DialogueGroup_GetNextLine( defeatedGhost )
- }
- // LAST RUN: BEAT BEST TIME
- else if ( gauntlet.lastRunBestTime )
- {
- feedbackLine = DialogueGroup_GetNextLine( newBestTime )
- }
- // LAST RUN: FAILED TO BEAT BEST TIME
- else
- {
- feedbackLine = DialogueGroup_GetNextLine( notBestTime )
- }
-
- Assert( feedbackLine != "" )
- waitthread Training_OG_Talks( feedbackLine, ogSpot, "OG_all_done_talk", "OG_all_done_idle", true )
- }
-}
-
-void function TrainingGauntletPostRun_TryAchievements( entity player, GauntletInfo gauntlet )
-{
- Assert( gauntlet.runFinished )
-
- GauntletGhost andersonGhost = Gauntlet_GetGhostByFileName( gauntlet, GHOST_NAME_ALIAS_ANDERSON )
- if ( gauntlet.lastRunTime < andersonGhost.duration )
- {
- // Achievement - Beat Pilot Anderson's gauntlet ghost recorder time
- UnlockAchievement( player, achievements.GAUNTLET_BEAT_ANDERSON )
- }
-
- GauntletGhost playerGhost = Gauntlet_GetPlayerGhost( gauntlet )
- int playerLeaderboardPos = Gauntlet_GetLeaderboardPosition_ForGhostID( gauntlet, playerGhost.id )
- if ( playerLeaderboardPos <= 2 )
- {
- // Achievement - Get a top-3 spot on the Gauntlet scoreboard
- UnlockAchievement( player, achievements.GAUNTLET_TOPTHREE )
- }
-}
-
-void function Training_LeaveGauntletThink( entity player, entity ogSpot )
-{
- string gauntletExitConversation = "Gauntlet_Exit"
- if ( file.gauntletMode )
- gauntletExitConversation = "Gauntlet_Exit_TechTest"
-
- GauntletInfo trainingGauntlet = GetTrainingGauntlet()
-
- // NOTE conversation callbacks need this defined
- file.animref_leaveGauntlet = ogSpot
- AddConversationCallback( gauntletExitConversation, ConvoCallback_TrainingExit )
- AddConversationCallback( "Titanfall_Intro", ConvoCallback_TitanfallIntro)
-
- int numTimesInitiated = 0
-
- while ( !Flag( "PlayerConfirmedGauntletExit" ) )
- {
- FlagWait( "Gauntlet_PlayerInExitZone" )
-
- FlagWaitClear( "Gauntlet_PlayingFeedbackVO" )
-
- if ( !Flag( "Gauntlet_PlayerInExitZone" ) )
- continue
-
- if ( !Training_IsGameFullyInstalled() )
- {
- waitthread Gauntlet_GameNotFullyInstalled_Response( player, ogSpot )
- wait 0.1 // HACK make sure we always wait before continuing
- continue
- }
-
- numTimesInitiated++
-
- // All done with the gauntlet?
- waitthread Training_OG_ScriptedAnim( ogSpot, "OG_all_done", true )
- Training_OG_Idles( ogSpot, "OG_all_done_idle", true )
-
- // if player rushed to the gauntlet during the anim, don't wait for conversation
- if ( trainingGauntlet.isActive )
- continue
-
- // hint if player can't figure out how to conversate
- bool displayedOnscreenHint = false
- if ( numTimesInitiated > 1 && !Flag( "PlayerUsedConversationInterface" ) )
- {
- thread OnscreenHint_DisplayAfterDelay( player, "conversation_hint", 5.0, 1.5 )
- displayedOnscreenHint = true
- }
-
- // interactive dialogue: Gauntlet Exit
- FlagClear( "GauntletExitConvo_FinishedResponse" )
- thread PlayerConversation( gauntletExitConversation, player, file.ogPilot )
-
- table result = WaitSignal( player, "ConversationEnded", "PlayerMadeSelection", "Gauntlet_RunStarted" )
- string sig = expect string( result.signal )
-
- // bug 202299: Also check flag for player confirmed gauntlet exit
- // - player can confirm exit, but if player starts a gauntlet run just before the response line ends, convo can "cancel" causing a prog break here
- if ( sig == "Gauntlet_RunStarted" )
- {
- // HACK- wait a bit to make sure player didn't confirm exit before the conversation ended due to gauntlet run starting
- wait 0.5
-
- if ( !Flag( "PlayerConfirmedGauntletExit" ) )
- {
- StopConversationNow( player )
- continue
- }
- }
-
- /*
- #if DEV
- if ( sig == "Gauntlet_RunStarted" && Flag( "PlayerConfirmedGauntletExit" ) )
- printt( "BUG CONDITION DEFEATED" )
- #endif
- */
-
- if ( sig == "PlayerMadeSelection" )
- FlagSet( "PlayerUsedConversationInterface" )
-
- if ( displayedOnscreenHint )
- ClearOnscreenHint( player )
-
- // wait for callback function to finish doing its thing
- FlagWait( "GauntletExitConvo_FinishedResponse" )
-
- if ( Flag( "PlayerConfirmedGauntletExit" ) )
- break
-
- FlagWaitClear( "Gauntlet_PlayerInExitZone" )
-
- StopConversationNow( player )
- }
-
- if ( file.gauntletMode )
- {
- GauntletMode_Finished( player )
- }
- else
- {
- // interactive dialogue: Titanfall Intro
- FlagClear( "TitanfallIntroConvo_FinishedResponse" )
- waitthread PlayerConversation( "Titanfall_Intro", player, file.ogPilot )
-
- FlagWait( "TitanfallIntroConvo_FinishedResponse" )
- }
-
- wait 0.2
-
- FlagSet( "PlayerLeavingGauntlet" )
-}
-
-void function Gauntlet_GameNotFullyInstalled_Response( entity player, entity ogRef )
-{
- EndSignal( player, "OnDestroy" )
-
- float progress = GetGameFullyInstalledProgress()
- printt( "Game is not fully installed- cannot continue past Gauntlet. Progress:", progress, "/ 1.0" )
-
- DisplayOnscreenHint( player, "gauntlet_install_hint" )
-
- OnThreadEnd(
- function() : ( player )
- {
- if ( IsValid( player ) )
- ClearOnscreenHint( player )
- }
- )
-
- if ( TimerCheck( "installWaitComment" ) )
- {
- DialogueGroup installWait = GetDialogueGroup( "installWait" )
- string line = DialogueGroup_GetNextLine( installWait )
- waitthread Training_OG_Talks( line, ogRef, "OG_all_done_talk", "OG_all_done_idle", true )
-
- TimerReset( "installWaitComment" )
- }
-
- while ( Flag( "Gauntlet_PlayerInExitZone" ) && !Training_IsGameFullyInstalled() )
- {
- wait 0.25
- }
-}
-
-void function ConvoCallback_TrainingExit( int choice )
-{
- EndSignal( file.player, "OnDestroy" )
-
- OnThreadEnd(
- function() : ( )
- {
- if ( IsValid( file.player ) )
- FlagSet( "GauntletExitConvo_FinishedResponse" )
- }
- )
-
- printt( "TRAINING EXIT CALLBACK: player chose", choice )
- Assert( choice >= 0 && choice <= 2, "Nothing set up for Training Exit convo choice " + choice )
-
- // prompt timed out
- if ( choice == 0 )
- return
-
- Signal( file.player, "PlayerMadeSelection" )
-
- // player chooses to stay
- if ( choice == 2 )
- {
- waitthread Training_OG_ScriptedAnim( file.animref_leaveGauntlet, "OG_all_done_respond", true )
- Training_OG_Idles( file.animref_leaveGauntlet, "OG_all_done_idle", true )
- return
- }
-
- // player chooses to leave
- FlagSet( "PlayerConfirmedGauntletExit" )
- printt( "PLAYER CONFIRMED GAUNTLET EXIT" )
-
- // Good. You're gonna like this.
- // It's time you learned the other half of being a Pilot: the Titan. Let's go call one in.
- string anim = "OG_gonna_like_this"
- if ( file.gauntletMode )
- {
- // Good. You're gonna like this.
- // Let's get back to the real world.
- anim = "OG_gonna_like_this_tech_test_end"
- }
-
- waitthread Training_OG_ScriptedAnim( file.animref_leaveGauntlet, anim, true )
- Training_OG_Idles( file.animref_leaveGauntlet, "OG_gonna_like_this_endidle", true )
-}
-
-void function ConvoCallback_TitanfallIntro( int choice )
-{
- EndSignal( file.player, "OnDestroy" )
-
- OnThreadEnd(
- function() : ( )
- {
- if ( IsValid( file.player ) )
- FlagSet( "TitanfallIntroConvo_FinishedResponse" )
- }
- )
-
- printt( "TITANFALL INTRO CALLBACK: player chose", choice )
- Assert( choice >= 0 && choice <= 2, "Nothing set up for Titanfall Intro convo choice " + choice )
-
- // It's only a simulation, Cooper. It's not the real thing.
- // But first- We're gonna need a little more space
- string responseAnim = "OG_gonna_like_this_respond_A"
- if ( choice == 2 )
- {
- // That's the spirit.
- // But first- We're gonna need a little more space
- responseAnim = "OG_gonna_like_this_respond_B"
- }
-
- thread Training_OG_ScriptedAnim( file.animref_leaveGauntlet, responseAnim, true )
- float duration = GetOGPilot().GetSequenceDuration( responseAnim )
- wait duration - 1.0
-
- //Training_OG_Idles( file.animref_leaveGauntlet, "OG_gonna_like_this_endidle", true )
-}
-
-
-// runType: 0 = before beating required time; 1 = in challenge mode
-void function TrainingGauntletStats_PostRunUpdate( entity player, GauntletInfo gauntlet, int runType )
-{
- Assert( !gauntlet.isActive, "Can't update gauntlet stats reliably while gauntlet is active." )
-
- // restarted gauntlet from menu
- if ( !gauntlet.runFinished )
- {
- file.trainingGauntletStats.numRestarts++
- printt( "training gauntlet stats updated: numRestarts", file.trainingGauntletStats.numRestarts )
-
- SendTrainingGauntletStats( player )
- return
- }
-
- if ( gauntlet.lastRunBestTime )
- {
- file.trainingGauntletStats.bestTime = gauntlet.bestTime
- printt( "training gauntlet stats updated: bestTime", file.trainingGauntletStats.bestTime )
- }
-
- if ( runType == 0 )
- {
- file.trainingGauntletStats.numRunsBeforeBeatRequiredTime++
- printt( "training gauntlet stats updated: numRunsBeforeBeatRequiredTime", file.trainingGauntletStats.numRunsBeforeBeatRequiredTime )
-
- if ( gauntlet.bestTime > TRAINING_GAUNTLET_MAX_TIME_TO_PROGRESS )
- {
- // failed to get required time
- SendTrainingGauntletStats( player )
- return
- }
- else
- {
- file.trainingGauntletStats.didBeatRequiredTime = true
- printt( "training gauntlet stats updated: didBeatRequiredTime", file.trainingGauntletStats.didBeatRequiredTime )
- }
- }
- else if ( runType == 1 )
- {
- file.trainingGauntletStats.numChallengeRuns++
- printt( "training gauntlet stats updated: numChallengeRuns", file.trainingGauntletStats.numChallengeRuns )
- }
-
- SendTrainingGauntletStats( player )
-}
-
-
-void function SendTrainingGauntletStats( entity player )
-{
- printt("======== TRAINING GAUNTLET STATS =========" )
- printt( "numRestarts:", file.trainingGauntletStats.numRestarts )
- printt( "numRunsBeforeBeatRequiredTime:", file.trainingGauntletStats.numRunsBeforeBeatRequiredTime )
- printt( "didBeatRequiredTime:", file.trainingGauntletStats.didBeatRequiredTime )
- printt( "numChallengeRuns:", file.trainingGauntletStats.numChallengeRuns )
- printt( "bestTime:", file.trainingGauntletStats.bestTime )
- printt("========= END TRAINING GAUNTLET STATS ==========" )
- SendTrainingGauntletStatsToBackend(
- player,
- file.trainingGauntletStats.didBeatRequiredTime ? file.trainingGauntletStats.numRunsBeforeBeatRequiredTime : 0,
- file.trainingGauntletStats.numChallengeRuns,
- file.trainingGauntletStats.bestTime
- )
-}
-
-
-bool function Training_IsGameFullyInstalled()
-{
- #if DEV
- if ( INSTALL_DELAY_TEST )
- return file.fakeInstallDone
- #endif
-
- return IsGameFullyInstalled()
-}
-
-#if DEV
-void function setfakeinstalldone( bool isDone )
-{
- file.fakeInstallDone = isDone
-}
-#endif
-
-
-// ===================================
-// ============ TITANFALL ============
-// ===================================
-void function Training_Setup_Titanfall( entity player )
-{
- entity ogRef_titanfall = GetEntByScriptName( "og_titanfall_start_pos" )
- entity og = Training_SpawnOGPilot( ogRef_titanfall )
- Training_OG_Idles_Sitting( ogRef_titanfall, "OG_first_titan_idle" )
-
- player.DisableWeapon() // player weapon is disabled before teleport to Titanfall area starts
-
- TeleportPlayerAndBT( "startpoint_titanfall" )
-}
-
-void function Training_Skipped_Titanfall( entity player )
-{
- player.SetExtraWeaponMods( ["training_low_ammo_disable"] )
- SetWeaponHUDEnabled( player, false )
-}
-
-void function Training_Titanfall( entity player )
-{
- thread Titanfall_EnableWeaponDelayed( player, 0.9 )
-
- thread TakeAmmoFromPlayerASAP( player )
- thread Titanfall_SpecialWeaponRemove( player )
-
- entity og = GetOGPilot()
- entity ogRef_titanfall = GetEntByScriptName( "og_titanfall_start_pos" )
- Training_OG_Idles_Sitting( ogRef_titanfall, "OG_first_titan_idle" )
-
- vector twinRefSpawnOrg = TitanfallGlitch_WorldChange_GetOtherWorldPos( ogRef_titanfall.GetOrigin(), true )
- entity ogRef_titanfall_twin = CreateScriptMover( twinRefSpawnOrg, ogRef_titanfall.GetAngles() )
- entity ogTwin = Training_SpawnOGTwin( ogRef_titanfall_twin )
- Training_NPC_Idles_Sitting( ogTwin, ogRef_titanfall_twin, "OG_first_titan_idle" )
-
- OnThreadEnd(
- function() : ( player, ogTwin, ogRef_titanfall_twin )
- {
- if ( IsValid( player ) )
- player.UnfreezeControlsOnServer()
-
- if ( IsValid( ogTwin ) )
- ogTwin.Destroy()
-
- if ( IsValid( ogRef_titanfall_twin ) )
- ogRef_titanfall_twin.Destroy()
- }
- )
-
- //testglitch()
- //wait 1000000
-
- thread Titanfall_BT_Think( player, 6.5 )
-
- wait 2.0
-
- // "That's my partner, BT. He's a Vanguard-class."
- // "Homegrown Militia technology."
- // "The first Titan chassis we designed ourselves. One we didn't have to steal from the IMC."
- waitthread Training_OG_ScriptedAnim( ogRef_titanfall, "OG_Partner_BT", true )
- Training_OG_Idles_Sitting( ogRef_titanfall, "OG_first_titan_idle", true )
-
- wait 1.1 // take a breath between lines
-
- thread Training_EnableTitanfallAndNag( player, ogRef_titanfall, 25.0 )
-
- // "Go ahead Rifleman, call in your first Titan."
- Titanfall_ResetHintVOTimer() // in case player calls in Titan during this line
- waitthread Training_OG_ScriptedAnim( ogRef_titanfall, "OG_First_Titan", true )
- Training_OG_Idles_Sitting( ogRef_titanfall, "OG_first_titan_idle", true )
-
- FlagWait( "PlayerStartedTitanfall" )
- // Don't start OG's next line until the nag is done, to avoid overlap
- wait Titanfall_GetHintVORemainingDuration()
-
- // "Look up, to the sky- there he is."
- waitthread Training_OG_ScriptedAnim( ogRef_titanfall, "OG_Look_Up", true )
- Training_OG_Idles_Sitting( ogRef_titanfall, "OG_first_titan_idle", true )
-
- thread Titanfall_QuickdeathCustomResetPlayerPos( player, file.playerTitanCallInPos, "PodOutroStarted" )
-
- // wait for titan to appear
- while ( !GetPlayerTitanInMap( player ) )
- wait 0.1
-
- entity titan = GetPlayerTitanInMap( player )
-
- // "glitch" interrupts titan drop
- FlagWait( "TitanfallGlitchStart" )
-
- PlayMusic( "music_training_01_glitch" )
-
- // Glitch ends when this function ends
- float totalGlitchTime = 2.9
- float glitchEndTime = Time() + totalGlitchTime
-
- wait 1.0
- player.FreezeControlsOnServer()
-
- thread Training_OG_ScriptedAnim( ogRef_titanfall, "OG_Pulling_You_Out", true )
-
- wait glitchEndTime - Time()
-
- if ( IsValid( titan ) )
- titan.Destroy()
-
- if ( IsValid( file.titanTwin ) )
- file.titanTwin.Destroy()
-}
-
-void function Titanfall_EnableWeaponDelayed( entity player, float delay )
-{
- EndSignal( player, "OnDestroy" )
-
- if ( delay > 0 )
- wait delay
-
- player.EnableWeapon()
- player.SetExtraWeaponMods( ["training_low_ammo_disable"] )
- SetWeaponHUDEnabled( player, false )
-}
-
-void function Titanfall_SpecialWeaponRemove( entity player )
-{
- array<entity> weapons = player.GetMainWeapons()
- int numWeaponsStart = weapons.len()
-
- foreach ( equippedWeapon in weapons )
- {
- string equippedWeaponClassName = equippedWeapon.GetWeaponClassName()
- if ( equippedWeaponClassName == "mp_weapon_lstar" ) // LSTAR display blinks annoyingly if ammo is gone
- {
- // give player a weapon if we are going to take their only weapon
- if ( numWeaponsStart <= 1 )
- player.GiveWeapon( "mp_weapon_semipistol" )
-
- player.TakeWeapon( equippedWeaponClassName )
-
- break
- }
- }
-}
-
-void function Titanfall_BT_Think( entity player, float getUpDelay = 0.0 )
-{
- EndSignal( player, "OnDestroy" )
-
- entity spawnRef = GetEntByScriptName( "titanfall_bt_spawn_ref" )
- vector spawnOrg = spawnRef.GetOrigin()
- vector spawnAng = spawnRef.GetAngles()
-
- // create BT
- TitanLoadoutDef loadout = GetTitanLoadoutForPlayer( player )
- entity bt = CreateNPCTitan( loadout.setFile, player.GetTeam(), spawnOrg, spawnAng, loadout.setFileMods )
- bt.ai.titanSpawnLoadout = loadout
- bt.kv.spawnflags = SF_NPC_ALLOW_SPAWN_SOLID
- DispatchSpawn( bt )
-
- entity animref = CreateScriptMover( spawnOrg, spawnAng )
-
- OnThreadEnd(
- function() : ( bt, animref )
- {
- if ( IsValid( bt ) )
- bt.Destroy()
-
- if ( IsValid( animref ) )
- animref.Destroy()
- }
- )
-
- bt.EnableNPCFlag( NPC_IGNORE_FRIENDLY_SOUND )
- bt.SetEfficientMode( true )
- bt.SetTouchTriggers( false )
- bt.SetNoTarget( true )
- bt.UnsetUsable()
- bt.SetInvulnerable()
- bt.EnableRenderAlways()
-
- bt.SetTitle( "#NPC_BT_NAME" )
- ShowName( bt )
-
- DisableTitanfallForLifetimeOfEntityNearOrigin( bt, bt.GetOrigin(), TITANHOTDROP_DISABLE_ENEMY_TITANFALL_RADIUS )
-
- // HACK this anim pops if it's played off of the animref,
- // but looks good if played off BT before using the animref for the rest
- thread PlayAnim( bt, "bt_training_scripted_kneel_idle", bt )
-
- if ( getUpDelay > 0 )
- wait getUpDelay
-
- waitthread PlayAnim( bt, "bt_training_scripted_kneel2stand", animref )
- thread PlayAnim( bt, "bt_training_scripted_stand_idle", animref )
-
- FlagWait( "PodOutroStarted" )
-}
-
-void function Titanfall_QuickdeathCustomResetPlayerPos( entity player, vector titanCallInPos, string endFlag )
-{
- FlagEnd( endFlag )
-
- entity resetEnt = GetEntByScriptName( "ref_titanfall_quickdeath_reset" )
- vector resetPos = resetEnt.GetOrigin()
-
- while ( 1 )
- {
- WaitSignal( player, "QuickDeath" )
-
- vector angToCallInPos = VectorToAngles( titanCallInPos - resetPos )
- float viewTiltUpAngX = -10.0 // goose the view up a little
- vector viewAng = <viewTiltUpAngX, angToCallInPos.y, 0>
-
- player.p.quickDeathOrigin = resetPos
- player.p.quickDeathAngles = viewAng
- }
-}
-
-void function Training_EnableTitanfallAndNag( entity player, entity ogRef, float nagDelay )
-{
- EndSignal( player, "OnDestroy" )
-
- SetGlobalNetBool( "trainingTitanfallEnabled", true )
- AddClientCommandCallback( "ClientCommand_TrainingRequestedTitanfall", Training_RequestTitanfall )
-
- float onscreenHintDisplayTime = nagDelay * 0.5
- thread OnscreenHint_DisplayAfterDelay( player, "titanfall_hint", onscreenHintDisplayTime, 3.5 ) // extra delay on first screen prompt so pros can call it in
-
- Objective_SetSilent( "#TRAINING_OBJ_CALL_TITAN" )
-
- // "Titan's ready. Call it in."
- // "Titan's ready to drop. On your mark."
- array<string> titanfallNags = [ "og_titanfall_nag_1", "og_titanfall_nag_2" ]
-
- DialogueGroup callInTitan = GetDialogueGroup( "callInTitan" )
- while ( !Flag( "PlayerStartedTitanfall" ) )
- {
- FlagWaitWithTimeout( "PlayerStartedTitanfall", nagDelay )
- if ( Flag( "PlayerStartedTitanfall" ) )
- break
-
- thread OnscreenHint_DisplayAfterDelay( player, "titanfall_hint", onscreenHintDisplayTime, 2.5 )
-
- string line = DialogueGroup_GetNextLine( callInTitan )
- Titanfall_ResetHintVOTimer()
- waitthread Training_OG_Talks_Sitting( line, ogRef, "OG_first_titan_talk", "OG_first_titan_idle" )
- }
-
- Objective_SetSilent( "#TRAINING_OBJ_DEFAULT" )
- ClearOnscreenHint( player )
-}
-
-
-// CUSTOM HOTDROP
-bool function Training_RequestTitanfall( entity player, array<string> args )
-{
- Training_ReplacementTitan( player ) //Separate function because other functions will call ReplacementTitan
- return true
-}
-
-bool function Training_ReplacementTitan( entity player )
-{
- Assert( IsAlive( player ) )
-
- Assert ( !GetPlayerTitanInMap( player ) )
-
- Point spawnPoint = GetTitanReplacementPoint( player, false )
- vector origin = spawnPoint.origin
- vector angles = spawnPoint.angles
-
- file.playerTitanCallInPos = origin
-
- FlagSet( "PlayerStartedTitanfall" )
- SetGlobalNetBool( "trainingTitanfallEnabled", false )
-
- thread Training_CreateTitanForPlayerAndHotdrop( player, origin, angles )
-
- return true
-}
-
-#if DEV
-void function testglitch()
-{
- thread Training_CreateTitanForPlayerAndHotdrop( GetPlayerArray()[0], <2048, -2852, -349>, <0,0,0> )
-}
-#endif
-
-void function Training_CreateTitanForPlayerAndHotdrop( entity player, vector spawnOrg, vector spawnAng )
-{
- Assert( IsValid( player ) )
- OnThreadEnd(
- function() : ( player )
- {
- if ( !IsValid( player ) )
- return
-
- player.ClearHotDropImpactTime()
- }
- )
-
- player.EndSignal( "OnDestroy" )
-
- vector origin = spawnOrg
- vector angles
- if ( spawnAng != < 0.0, 0.0, 0.0 > )
- angles = spawnAng
- else
- angles = VectorToAngles( FlattenVector( player.GetViewVector() ) * -1 ) // face the player
-
- printt( "Dropping replacement titan at " + origin + " with angles " + angles )
-
- player.Signal( "CalledInReplacementTitan" )
-
- int playerTeam = player.GetTeam()
-
- // spawn the Titan that will drop
- TitanLoadoutDef loadout = GetTitanLoadoutForPlayer( player )
- entity titan = CreateAutoTitanForPlayer_FromTitanLoadout( player, loadout, origin, angles )
- DispatchSpawn( titan )
- titan.EndSignal( "OnDeath" )
-
- titan.SetSkin( 2 ) // "Sarah Briggs" Vanguard skin
- titan.SetTitle( "#NPC_BT_SPARE_NAME" )
- HideName( titan )
- TakeAllWeapons( titan )
- titan.SetEfficientMode( true )
- titan.SetTouchTriggers( false )
- titan.SetNoTarget( true )
- titan.UnsetUsable() // Disable titan embark
-
- titan.Hide()
-
- OnThreadEnd(
- function() : ( titan )
- {
- if ( !IsValid( titan ) )
- return
-
- // removed so that model highlight always works for you autotitan
- // titan.DisableRenderAlways()
- }
- )
-
- // based on "at_hotdrop_drop_2knee_turbo"
- string animation = "bt_hotdrop_glitch_descent"
- string postButtonPressSFX = "training_scr_titan_glitch_button_press"
- string hotdropToGlitchSFX = "training_anim_glitch_scene"
-
- EmitSoundOnEntity( player, postButtonPressSFX )
-
- float hotDropAnimDuration = titan.GetSequenceDuration( animation )
-
- float extraSpawnDelay = 1.5 // bit of extra padding time for "Look up, to the sky" VO to sink in
- extraSpawnDelay += Titanfall_GetHintVORemainingDuration()
-
- // Glitched hotdrop anim created by trimming the end from normal hotdrop anim (glitch starts just before the Titan hits the ground)
- // - add this little bit back so the timer looks "correct" (longer than actual anim duration)
- float arrivalTimerDuration = 0.7
- arrivalTimerDuration += (hotDropAnimDuration + extraSpawnDelay) // now add the rest of the normal delays before arrival
- thread Training_DrawReplacementTitanLocation( player, origin, arrivalTimerDuration )
-
- wait extraSpawnDelay
-
- titan.Show()
- ShowName( titan )
-
- Attachment result = titan.Anim_GetAttachmentAtTime( animation, "OFFSET", (hotDropAnimDuration - 0.1) )
- vector maxs = titan.GetBoundingMaxs()
- vector mins = titan.GetBoundingMins()
- int mask = titan.GetPhysicsSolidMask()
- origin = ModifyOriginForDrop( origin, mins, maxs, result.position, mask )
-
- titan.SetInvulnerable() //Make Titan invulnerable until bubble shield is up. Cleared in OnTitanHotdropImpact
- titan.EnableRenderAlways()
-
- int teamNum = TEAM_UNASSIGNED
- if ( IsValid( player ) )
- teamNum = player.GetTeam()
-
- vector fwdToPlayer = player.GetOrigin() - origin
- vector facingAngles = VectorToAngles( fwdToPlayer )
- vector facingAngles2D = <facingAngles.x, facingAngles.y, 0>
- angles = facingAngles2D
-
- //FadeOutSoundOnEntity( player, postButtonPressSFX, 1.0 )
- EmitSoundOnEntity( player, hotdropToGlitchSFX )
-
- thread PlayAnimTeleport( titan, animation, origin, angles )
- wait hotDropAnimDuration - 0.1
-
- titan.SetTouchTriggers( true )
-
- thread TitanfallGlitch( player, titan, origin, angles )
-}
-
-void function Titanfall_ResetHintVOTimer()
-{
- file.titanfallNagStartTime = Time()
-}
-
-float function Titanfall_GetHintVORemainingDuration()
-{
- if ( file.titanfallNagStartTime == -1 )
- return 0
-
- float duration = TITANFALL_NAG_DURATION - (Time() - file.titanfallNagStartTime)
- if ( duration < 0 )
- duration = 0
-
- return duration
-}
-
-bool function Titanfall_IsHintVOStillPlaying()
-{
- return Titanfall_GetHintVORemainingDuration() >= 0
-}
-
-void function TitanfallGlitch( entity player, entity titan, vector origin, vector angles )
-{
- if ( Flag( "PodOutroStarted" ) )
- return
- FlagEnd( "PodOutroStarted" )
-
- player.EndSignal( "OnDestroy" )
- titan.EndSignal( "OnDestroy" )
-
- titan.Signal( "glitch_start" )
- FlagSet( "TitanfallGlitchStart" )
-
- if ( IsValid( file.titanTwin ) )
- file.titanTwin.Destroy()
-
- entity titanTwin = CreatePropScript( BUDDY_MODEL, titan.GetOrigin(), titan.GetAngles() )
- file.titanTwin = titanTwin
- vector twinOrigin = TitanfallGlitch_WorldChange_GetOtherWorldPos( origin, true )
-
- array<entity> sceneTitans = [ titan, titanTwin ]
-
- // idle on last frame of descent anim
- titanTwin.Anim_Stop()
- titan.Anim_Stop()
- string endIdleAnim = GetDefaultTitanfallGlitchAnim()
- thread PlayAnimTeleport( titanTwin, endIdleAnim, twinOrigin, angles )
- thread PlayAnimTeleport( titan, endIdleAnim, origin, angles )
-
- // DEPRECATED no more glitchy anims
- // do this on the hotdropping titan to blend out of the hotdrop better (but makes the proxy on the client out of sync)
- // - in the future, need to play all the hotdrop anims on the proxy as well, to let it blend the same
- //thread PlayAnim( titan, endIdleAnim, origin, angles, 0.1 )
-
- // START GLITCH SEQUENCE
-
- // setup for client extra flicker
- titan.Hide()
- titanTwin.Hide()
- int eHandle_titan = titan.GetEncodedEHandle()
- int eHandle_twin = titanTwin.GetEncodedEHandle()
- Remote_CallFunction_Replay( player, "ScriptCallback_TitanfallGlitch_ExtraFlicker", eHandle_titan )
- Remote_CallFunction_Replay( player, "ScriptCallback_TitanfallGlitch_ExtraFlicker", eHandle_twin, true )
- SetGlobalNetBool( "titanGlitch_extraFlicker", true ) // makes him flicker until the world starts changing
-
- // DEPRECATED Not doing the huge anim moves might work better for the glitch moment, trying it out
- //thread TitanfallGlitch_CycleTitanGlitchAnims_OnWorldChange( player, titan, titanTwin, origin, twinOrigin, angles )
-
- float screenFXTime = 4.5
- float screenFXStartDelay = 0.1
- thread StartGlitchScreenFX_Delayed( player, screenFXTime, screenFXStartDelay )
-
- // FIRST IMPACT
- float firstShakeDuration = 3.0
-
- float shakeAmplitude = 14.0
- float screenBlurFrac = 0.25
- SimpleScreenShake( player, firstShakeDuration, shakeAmplitude, screenBlurFrac )
-
- // juice it with extra rumble
- // note- this is not juicing it as much as I would expect... even cranking the amplitude doesn't really work that well
- float rumbleAmplitude = 50.0
- float rumbleFrequency = 170
- float rumbleDuration = 4.5
- CreateShakeRumbleOnly( player.GetOrigin(), rumbleAmplitude, rumbleFrequency, rumbleDuration )
-
- // let the titan idle for a moment
- float postDescentIdleTime = 1.0
- wait postDescentIdleTime
-
- float firstShakeDuration_remaining = firstShakeDuration - postDescentIdleTime
- // DEPRECATED trying without world changes
- //thread TitanfallGlitch_PlayerWorldChange( player, firstShakeDuration_remaining * 0.9, 0.0 )
-
- wait firstShakeDuration_remaining
-
- /* DEPRECATED don't need smaller shakes now that the scene only lasts a short time
- printt( "FIRST IMPACT DONE")
-
- // LOOPING SMALLER IMPACTS
- float shakeDuration_min = 2.5
- float shakeDuration_max = 3.0
- shakeAmplitude = 5.5
- screenBlurFrac = 0.6
- while ( 1 )
- {
- float shakeDuration = RandomFloatRange( shakeDuration_min, shakeDuration_max )
-
- SimpleScreenShake( player, shakeDuration, shakeAmplitude, screenBlurFrac )
- thread TitanfallGlitch_PlayerWorldChange( player, shakeDuration * 0.85, shakeDuration * 0.1 )
-
- wait shakeDuration
- }
- */
-}
-
-void function StartGlitchScreenFX_Delayed( entity player, float screenFXTime, float delay )
-{
- if ( Flag( "PodOutroStarted" ) )
- return
- FlagEnd( "PodOutroStarted" )
-
- EndSignal( player, "OnDestroy" )
-
- if ( delay > 0 )
- wait delay
-
- Remote_CallFunction_Replay( player, "ScriptCallback_PodGlitch_PlayerScreenFX", screenFXTime )
-}
-
-const float GLITCH_WORLD_CHANGE_WAIT_MIN = 0.1
-const float GLITCH_WORLD_CHANGE_WAIT_MAX = 0.35
-const float GLITCH_WORLD_CHANGE_MINWAIT_FOR_EXTRA_FLICKER = 0.25
-
-void function TitanfallGlitch_CycleTitanGlitchAnims_OnWorldChange( entity player, entity mainTitan, entity titanTwin, vector origin, vector twinOrigin, vector angles, float delay = 0.0 )
-{
- player.EndSignal( "OnDestroy" )
- mainTitan.EndSignal( "OnDestroy" )
- titanTwin.EndSignal( "OnDestroy" )
-
- array<entity> sceneTitans = [ mainTitan, titanTwin ]
-
- OnThreadEnd(
- function() : ( player, sceneTitans )
- {
- if ( IsValid( player ) )
- {
- FlagClear( "PlayerWorldChangeThread" )
- SetGlobalNetBool( "titanGlitch_extraFlicker", false )
- }
-
- foreach ( titan in sceneTitans )
- if ( IsValid( titan ) )
- titan.Show()
- }
- )
-
- if ( delay > 0 )
- wait delay
-
- array<string> titanAnims = GetTitanfallGlitchAnims()
- array<string> twinAnims = GetTitanfallGlitchTwinAnims()
- Assert( titanAnims.len() == twinAnims.len() )
- int animIdx = GetGlobalNetInt( "titanfallGlitchAnimIdx" )
-
- while ( 1 )
- {
- table result = WaitSignal( player, "Glitch_WorldChanging_Zen", "Glitch_WorldChanging_NonZen" )
- string signal = expect string( result.signal )
-
- float worldChangeDuration = expect float( result.postChangeWait )
-
- //printt( "titan anim:", titanAnims[animIdx] )
-
- mainTitan.Anim_Stop()
- titanTwin.Anim_Stop()
- thread PlayAnimTeleport( mainTitan, titanAnims[animIdx], origin, angles )
- thread PlayAnimTeleport( titanTwin, twinAnims[animIdx], twinOrigin, angles )
-
- animIdx++
- if ( animIdx >= titanAnims.len() )
- animIdx = 0
-
- SetGlobalNetInt( "titanfallGlitchAnimIdx", animIdx )
-
- // update flicker settings & show/hide server versions of the titans
- if ( signal == "Glitch_WorldChanging_Zen" )
- {
- // only do extra flicker if a longer world change pause is happening
- if ( worldChangeDuration >= GLITCH_WORLD_CHANGE_MINWAIT_FOR_EXTRA_FLICKER )
- {
- SetGlobalNetBool( "titanGlitch_extraFlicker", true )
-
- foreach ( titan in sceneTitans )
- titan.Hide()
- }
- }
- else if ( signal == "Glitch_WorldChanging_NonZen" )
- {
- SetGlobalNetBool( "titanGlitch_extraFlicker", false )
-
- foreach ( titan in sceneTitans )
- titan.Show()
- }
- else
- {
- Assert( false, "Couldn't find signal: " + signal )
- }
- }
-}
-
-
-void function TitanfallGlitch_PlayerWorldChange( entity player, float duration, float delay = 0.0 )
-{
- if ( Flag( "PodOutroStarted" ) )
- return
- FlagEnd( "PodOutroStarted" )
-
- EndSignal( player, "OnDestroy" )
-
- if ( delay > 0 )
- wait delay
-
- FlagWaitClear( "PlayerWorldChangeThread" )
- FlagSet( "PlayerWorldChangeThread" )
-
- OnThreadEnd(
- function() : ( player )
- {
- if ( IsValid( player ) )
- FlagClear( "PlayerWorldChangeThread" )
- }
- )
-
- bool isInZenWorld = true
-
- float endTime = Time() + duration
-
- float minWait = GLITCH_WORLD_CHANGE_WAIT_MIN
- float maxWait = GLITCH_WORLD_CHANGE_WAIT_MAX
-
- while ( 1 )
- {
- // at end time, make sure player pos resets back to zen world before breaking
- if ( Time() >= endTime && isInZenWorld )
- break
-
- vector newpos = TitanfallGlitch_WorldChange_GetOtherWorldPos( player.GetOrigin(), isInZenWorld )
-
- float postChangeWait
- string changeSignal
- entity newSkyCam
-
- if ( isInZenWorld )
- {
- // Switch to non zen world
- changeSignal = "Glitch_WorldChanging_NonZen"
- postChangeWait = minWait // always wait min time in non zen world
-
- newSkyCam = file.skycam_glitch
- isInZenWorld = false
- }
- else
- {
- // Switch back to zen world
- postChangeWait = RandomFloatRange( minWait, maxWait )
- changeSignal = "Glitch_WorldChanging_Zen"
-
- newSkyCam = file.skycam_default
- isInZenWorld = true
- }
-
- table<string,float> extraInfo = {}
- extraInfo["postChangeWait"] <- postChangeWait
- Signal( player, changeSignal, extraInfo )
-
- player.SetSkyCamera( newSkyCam )
- player.SetOrigin( newpos )
-
- wait postChangeWait
- }
-}
-
-
-vector function TitanfallGlitch_WorldChange_GetOtherWorldPos( vector currentPos, bool startInZenWorld )
-{
- entity zenEnt = GetEntByScriptName( "titan_glitch_swap_ref1" )
- entity nonZenEnt = GetEntByScriptName( "titan_glitch_swap_ref2" )
- Assert( zenEnt && nonZenEnt )
- vector zenPos = zenEnt.GetOrigin()
- vector nonZenPos = nonZenEnt.GetOrigin()
-
- float offsetX
- float offsetY
- float offsetZ
- float newPosX
- float newPosY
- float newPosZ
-
- if ( startInZenWorld )
- {
- offsetX = currentPos.x - zenPos.x
- offsetY = currentPos.y - zenPos.y
- offsetZ = currentPos.z - zenPos.z
-
- newPosX = nonZenPos.x + offsetX
- newPosY = nonZenPos.y + offsetY
- newPosZ = nonZenPos.z + offsetZ
- }
- else
- {
- offsetX = currentPos.x - nonZenPos.x
- offsetY = currentPos.y - nonZenPos.y
- offsetZ = currentPos.z - nonZenPos.z
-
- newPosX = zenPos.x + offsetX
- newPosY = zenPos.y + offsetY
- newPosZ = zenPos.z + offsetZ
- }
-
- vector newPos = < newPosX, newPosY, newPosZ >
- return newPos
-}
-
-
-void function Training_DrawReplacementTitanLocation( entity player, vector origin, float delay )
-{
- float endTime = Time() + delay
-
- player.SetHotDropImpactDelay( endTime )
- Remote_CallFunction_Replay( player, "ServerCallback_ReplacementTitanSpawnpoint", origin.x, origin.y, origin.z, endTime )
- player.WaitSignal( "OnDeath" )
-}
-
-
-// ===================================
-// ============ POD OUTRO ============
-// ===================================
-void function Training_Setup_PodOutro( entity player )
-{
-}
-
-void function Training_Skipped_PodOutro( entity player )
-{
- Training_EnvArtColorCorrection_SetEnabled( false )
- SetDoF_Hangar( player )
-
- Objective_Clear()
-
- FlagSet( "PodOutroStarted" )
- FlagSet( "SimPodShutdown_LoudspeakerVO_Done" )
-}
-
-#if DEV
-// bare bones start in pod
-void function DEV_PodOutro( entity player )
-{
- player.EndSignal( "OnDestroy" )
-
- TakeAllWeapons( player )
-
- player.SetExtraWeaponMods( [ "low_ammo_disable" ] )
- SetWeaponHUDEnabled( player, false )
-
- Training_EnvArtColorCorrection_SetEnabled( false )
- SetDoF_Hangar( player )
-
- thread MeetOG_BackgroundSkits( player )
-
- entity pod = file.trainingPod
-
- TrainingPod_PlayerSequence_DoorsOpenIdle( player, false )
-
- // anim starts at a slightly different spot
- player.SetOrigin( < 10564, -10235, -6056.9 > )
- player.SetAngles( < -6, 90, 0 > )
-
- WaitForever()
-}
-#endif //DEV
-
-void function Training_PodOutro( entity player )
-{
- player.EndSignal( "OnDestroy" )
-
- Objective_Clear()
- CheckPoint_Silent()
-
- entity pod = file.trainingPod
-
- FlagSet( "PodOutroStarted" )
-
- OnThreadEnd(
- function() : ( player, pod )
- {
- if ( IsValid( player ) )
- {
- //StopSoundOnEntity( player, "NPE_Scr_SimPod_End" )
-
- // Not sure if we need any of this
- //player.Anim_Stop()
- //ClearAnimViewEntity( player )
- //player.ClearParent()
- //player.UnforceStand()
- }
-
- if ( IsValid ( pod ) )
- {
- // Not sure if we need any of this
- //pod.Anim_Stop()
- //thread TrainingPod_ResetLaserEmitterRotation( pod )
- //thread TrainingPod_KillLasers( pod )
- //thread TrainingPod_KillGlowFX( pod )
- //TrainingPod_KillInteriorDLights()
- }
- }
- )
-
- // Have to do this first so the anim starts centered on the ref attachment angles
- string podAttach = "REF"
- int attachID = pod.LookupAttachment( podAttach )
- vector podRefOrg = pod.GetAttachmentOrigin( attachID )
- vector podRefAng = pod.GetAttachmentAngles( attachID )
- player.SetOrigin( podRefOrg )
- player.SetAngles( podRefAng )
-
- player.ForceStand()
-
- TakeAllWeapons( player )
-
- // start closed idle
- FirstPersonSequenceStruct playerSequence
- playerSequence.blendTime = 0.0
- playerSequence.attachment = podAttach
- playerSequence.firstPersonAnimIdle = "ptpov_trainingpod_idle"
- playerSequence.thirdPersonAnimIdle = "pt_trainingpod_idle"
- playerSequence.viewConeFunction = TrainingPod_ViewConeLock_Strict // so player can't move camera under the pod shutdown screen
- playerSequence.renderWithViewModels = true
-
- FirstPersonSequenceStruct podSequence
- podSequence.blendTime = 0.0
- podSequence.thirdPersonAnimIdle = "trainingpod_doors_close_idle"
- podSequence.renderWithViewModels = true
-
- thread FirstPersonSequence( playerSequence, player, pod )
- thread FirstPersonSequence( podSequence, pod )
-
- thread CadillacMoment_MeetOG( player )
-
- //thread PodOutro_ScreenShake( player )
-
- Training_EnvArtColorCorrection_SetEnabled( false )
- SetDoF_Hangar( player )
-
- // show the "pod shutdown screen"
- float shutdownScreenWait = 7.0
- float screenFadeWait = 7.0
- ScreenFade( player, 0, 0, 0, 255, 0, screenFadeWait, FFADE_OUT | FFADE_STAYOUT )
- Remote_CallFunction_Replay( player, "ScriptCallback_SimPodShutdownScreen", shutdownScreenWait )
-
- thread SimPodShutdown_Dialogue( player )
-
- // HACK, need to wait a bit so player moves into pod before initing shutdown sequence
- // - otherwise, interior emitter angle setup math vs player eye position will crash the game
- float waitForPlayerToBeMoved = 1.0
- wait waitForPlayerToBeMoved
-
- float shutdownSequence_waitBeforeAnimStart = 10.0
- thread TrainingPod_Interior_ShutdownSequence( player, shutdownSequence_waitBeforeAnimStart )
-
- wait screenFadeWait - waitForPlayerToBeMoved
-
- // HACK reparent the emitters so they look correct, I didn't expect to have to do this
- TrainingPod_SnapLaserEmittersToAttachPoints()
-
- // Transition screen FX
- thread PlayFXOnEntity( FX_POD_SCREEN_OUT, player )
-
- float fadeInFromShutdownScreenTime = 0.2
- ScreenFade( player, 0, 0, 0, 255, fadeInFromShutdownScreenTime, 1, FFADE_IN | FFADE_PURGE )
- wait fadeInFromShutdownScreenTime
-
- TrainingPod_ViewConeLock_PodClosed( player )
-
- // start shutdown sequence
- // HACK- eventually one sound will cover the whole sequence
- thread HACK_DelayedShutdownSequenceSFX( player, 3.0 )
-
- player.Signal( "TrainingPod_BeginInteriorShutdown" )
- wait shutdownSequence_waitBeforeAnimStart
-
- FirstPersonSequenceStruct playerSequence_podOpens
- playerSequence_podOpens.blendTime = 0.25
- playerSequence_podOpens.attachment = podAttach
- playerSequence_podOpens.firstPersonAnim = "ptpov_trainingpod_doors_open"
- playerSequence_podOpens.firstPersonAnimIdle = "ptpov_trainingpod_idle"
- playerSequence_podOpens.thirdPersonAnim = "pt_trainingpod_doors_open"
- playerSequence_podOpens.thirdPersonAnimIdle = "pt_trainingpod_idle"
- playerSequence_podOpens.viewConeFunction = TrainingPod_ViewConeLock_SemiStrict
- playerSequence_podOpens.renderWithViewModels = true
-
- FirstPersonSequenceStruct podSequence_podOpens
- podSequence_podOpens.blendTime = 0.25
- podSequence_podOpens.thirdPersonAnim = "trainingpod_doors_open"
- podSequence_podOpens.thirdPersonAnimIdle = "trainingpod_doors_open_idle"
- podSequence_podOpens.renderWithViewModels = true
-
- thread TrainingPod_TurnOnInteriorDLights_Delayed( player, 1.5 )
-
- thread FirstPersonSequence( podSequence_podOpens, pod )
- thread FirstPersonSequence( playerSequence_podOpens, player, pod )
-
- wait 2.1 // wait until scene starts animating for Meet OG
-}
-
-void function HACK_DelayedShutdownSequenceSFX( entity player, float delayTime )
-{
- EndSignal( player, "OnDestroy" )
-
- wait delayTime
- EmitSoundOnEntityOnlyToPlayerWithSeek( player, player, "NPE_Scr_SimPod_End", 0.7 )
-}
-
-void function PodOutro_ScreenShake( entity player )
-{
- if ( Flag( "MeetOG_StartScene" ) )
- return
- FlagEnd( "MeetOG_StartScene" )
-
- player.EndSignal( "OnDestroy" )
-
- float shakeDuration = 2.0
- float shakeAmplitude = 0.2
- float screenBlurFrac = 0.0
- float shakeDelayMin = 1.75
- float shakeDelayMax = 2.25
- while ( 1 )
- {
- SimpleScreenShake( player, shakeDuration, shakeAmplitude, screenBlurFrac )
- wait shakeDuration - (shakeDuration * 0.25) // HACK shake dies down
- wait RandomFloatRange( shakeDelayMin, shakeDelayMax )
- }
-}
-
-void function SimPodShutdown_LoudspeakerVO( entity player )
-{
- player.EndSignal( "OnDestroy" )
-
- wait 4.0 // wait for "I'm pulling you out"
-
- // "Powering down all non-essential systems."
- waitthread PlayLoudspeakerVO( "outro_01_1" )
-
- // "Prepare for Typhon atmospheric entry in less than three minutes."
- //waitthread PlayLoudspeakerVO( "outro_01" )
-
- wait 7.0
-
- // "All personnel to battle stations."
- waitthread PlayLoudspeakerVO( "outro_01_2" )
-
- // "This is not a drill."
- waitthread PlayLoudspeakerVO( "outro_01_3" )
-
- FlagSet( "SimPodShutdown_LoudspeakerVO_Done" )
-}
-
-void function SimPodShutdown_Dialogue( entity player )
-{
- player.EndSignal( "OnDestroy" )
-
- thread SimPodShutdown_LoudspeakerVO( player )
-
- Assert( IsValid( file.ogPilot ), "Can't find scene entity ogPilot" )
-
- // "Alright Rifleman, sounds like it's about to hit the fan."
- waitthread PlayDialogue( "og_hit_the_fan", file.ogPilot )
-
- // "I'm pulling you out."
- waitthread PlayDialogue( "og_pulling_you_out", file.ogPilot )
-
- wait 2.0
-
- // "Cooper! Ready up!"
- waitthread PlayDialogue( "grunt_closed_pod_yell_at_player", file.ogPilot ) // HACK play it off OG until the animation idle is legit
-
- // "Easy Cole, he just left VR. Needs a minute to decompress. He'll be ready to go... trust me."
- waitthread PlayDialogue( "og_closed_pod_respond_to_grunt", file.ogPilot )
-
- // "Yes sir."
- waitthread PlayDialogue( "grunt_yes_sir", file.ogPilot )
-}
-
-#if DEV
-void function shutdownscreentest( float duration = 5.0 )
-{
- entity player = file.player
- EndSignal( player, "OnDestroy" )
-
- float fadeTime = 0.2
-
- ScreenFade( player, 0, 0, 0, 255, fadeTime, duration, FFADE_OUT | FFADE_STAYOUT )
- Remote_CallFunction_Replay( player, "ScriptCallback_SimPodShutdownScreen", duration )
- wait duration
- ScreenFade( player, 0,0,0, 255, fadeTime, fadeTime, FFADE_IN | FFADE_PURGE )
-}
-#endif
-
-
-
-// =================================
-// ============ MEET OG ============
-// =================================
-void function Training_Setup_MeetOG( entity player )
-{
- TakeAllWeapons( player )
-
- thread CadillacMoment_MeetOG( player )
- TrainingPod_PlayerSequence_DoorsOpenIdle( player )
-
- wait 0.2
-}
-
-void function Training_Skipped_MeetOG( entity player )
-{
- // settings for checkpoints after the normal level progression
- SetDoF_Default( player )
- player.SetExtraWeaponMods( [] ) // turn off low_ammo_disable
- SetWeaponHUDEnabled( player, true )
-}
-
-void function Training_MeetOG( entity player )
-{
- thread MeetOG_BackgroundSkits( player )
-
- FlagSet( "MeetOG_StartScene" )
-
- thread MeetOG_ControllerRumble( player )
-
- FlagWait( "CadillacMoment_MeetOG_StartFadeOut" )
-
- UnlockAchievement( player, achievements.COMPLETE_TRAINING )
-
- // Free SP trial? Load Beacon next.
- if( Script_IsRunningTrialVersion() )
- {
- thread FreeTrial_OutroPopup( player, 2.5 )
- PickStartPoint( "sp_beacon", "Level Start" )
- }
- else
- {
- thread OutroDifficultyPopup( player, 2.5 )
-
- // load next level
- // NOTE this does a screen fade already
- PickStartPoint( "sp_crashsite", "LevelStart" )
- }
-
- // don't ever progress from here to the dev functions beyond
- WaitForever()
-}
-
-void function FreeTrial_OutroPopup( entity player, float delay )
-{
- EndSignal( player, "OnDestroy" )
- wait delay
-
- Remote_CallFunction_UI( player, "ScriptCallback_Training_FreeTrialMessage" )
-}
-
-void function OutroDifficultyPopup( entity player, float delay )
-{
- EndSignal( player, "OnDestroy" )
- wait delay
-
- Remote_CallFunction_UI( player, "ScriptCallback_Training_SelectSPDifficulty" )
-}
-
-// can't do screen shake for this part because it looks bad (not connected) when player view is 1P animating while parented to the pod
-void function MeetOG_ControllerRumble( entity player )
-{
- player.EndSignal( "OnDestroy" )
- FlagEnd( "CadillacMoment_MeetOG_StartFadeOut" )
-
- float shakeDuration = 2.8
- float shakeAmplitudeMin = 13.5
- float shakeAmplitudeMax = 14.5
- float frequency = 155
- float shakeDelayMin = 4.0
- float shakeDelayMax = 7.0
- while ( 1 )
- {
- float amplitude = RandomFloatRange( shakeAmplitudeMin, shakeAmplitudeMax )
-
- //vector org, float amplitude = 16, float frequency = 150, float duration = 1.5, float radius = 2048
- CreateAirShakeRumbleOnly( player.GetOrigin(), amplitude, frequency, shakeDuration )
- printt( "Shake Rumble:", amplitude )
- wait shakeDuration * 0.75 // HACK shake dies down pretty early
-
- wait RandomFloatRange( shakeDelayMin, shakeDelayMax )
- }
-}
-
-void function CadillacMoment_MeetOG( entity player )
-{
- thread MeetOG_LoudspeakerVO( player )
-
- int friendlyTeam = player.GetTeam()
-
- entity animref = file.animref_hangar
- vector animrefOrigin = animref.GetOrigin()
- vector animrefAngles = animref.GetAngles()
- vector btSpawnOrg = <0,0,0> // to avoid red text errors about BT spawning in solid
-
- entity animEnt = CreateScriptMover( animrefOrigin, animrefAngles )
-
- // Spawn scene actors
- entity og = Training_SpawnOGPilot( animref )
- Training_OGPilot_SetHelmetOn( og, false )
- SetTeam( og, TEAM_SPECTATOR ) // turn off his glowy bits so they're accentuated when helmet turns on later
-
- entity anderson = CreateSoldier( friendlyTeam, animrefOrigin, animrefAngles )
- DispatchSpawn( anderson )
- anderson.SetModel( ANDERSON_PILOT_MODEL )
- anderson.SetTitle( "#TRAINING_ANDERSON_NAME" )
- //ShowName( anderson )
- HideName( anderson )
-
- entity redshirt = CreateSoldier( friendlyTeam, animrefOrigin, animrefAngles )
- DispatchSpawn( redshirt )
- redshirt.SetModel( TEAM_MIL_GRUNT_MODEL_LMG )
- redshirt.SetTitle( "#CPT_COLE" )
- //ShowName( redshirt )
- HideName( redshirt )
-
- TitanLoadoutDef loadout = GetTitanLoadoutForCurrentMap()
- entity bt = CreateAutoTitanForPlayer_FromTitanLoadout( player, loadout, btSpawnOrg, animrefAngles )
- SetSpawnOption_AISettings( bt, "npc_titan_buddy" )
- bt.kv.spawnflags = SF_NPC_ALLOW_SPAWN_SOLID
- DispatchSpawn( bt )
- FreeAutoTitan( bt ) // HACK this disables the worldspace BT locator icon
- TakeAllWeapons( bt )
-
- array<entity> actors = [ player, bt, og, anderson, redshirt ]
-
- // Setup scene props
-
- entity ogHelmet = CreatePropDynamic( OG_PILOT_HELMET_MODEL )
- ogHelmet.DisableHibernation()
- file.ogHelmet = ogHelmet
-
- string knifeTag = "KNIFE"
- int knifeTagID = og.LookupAttachment( knifeTag )
- entity dataKnife = CreatePropScript( DATA_KNIFE_MODEL, og.GetAttachmentOrigin( knifeTagID ), og.GetAttachmentAngles( knifeTagID ) )
- dataKnife.DisableHibernation()
- dataKnife.SetParent( og, knifeTag, false, 0.0 )
-
- asset btWeaponModel = GetWeaponInfoFileKeyFieldAsset_Global( "mp_titanweapon_xo16_shorty", "playermodel" )
- Assert( btWeaponModel != $"" )
- entity btWeapon = CreatePropDynamic( btWeaponModel )
- btWeapon.SetParent( bt, "PROPGUN" )
-
- string gruntRifleName = "mp_weapon_rspn101"
- string andersonWeaponName = "mp_weapon_car"
- asset gruntRifleModel = GetWeaponInfoFileKeyFieldAsset_Global( gruntRifleName, "playermodel" )
- asset andersonWeaponModel = GetWeaponInfoFileKeyFieldAsset_Global( andersonWeaponName, "playermodel" )
- asset ogWeaponModel = GetWeaponInfoFileKeyFieldAsset_Global( OG_WEAPON, "playermodel" )
- Assert( gruntRifleModel != $"" )
- Assert( andersonWeaponModel != $"" )
- Assert( ogWeaponModel != $"" )
-
- entity ogWeapon = CreatePropDynamic( ogWeaponModel )
- ogWeapon.DisableHibernation()
- ogWeapon.SetParent( og, "PROPGUN" )
-
- entity andersonWeapon = CreatePropDynamic( andersonWeaponModel )
- andersonWeapon.DisableHibernation()
- andersonWeapon.SetParent( anderson, "PROPGUN" )
-
- entity redshirtWeapon = CreatePropDynamic( gruntRifleModel )
- redshirtWeapon.DisableHibernation()
- redshirtWeapon.SetParent( redshirt, "PROPGUN" )
-
- array<entity> props = [ btWeapon, redshirtWeapon, andersonWeapon, ogWeapon, ogHelmet, dataKnife ]
-
- OnThreadEnd(
- function() : ( actors, props, animEnt )
- {
- foreach ( weapon in props )
- {
- if ( IsValid( weapon ) )
- {
- weapon.ClearParent()
- weapon.Destroy()
- }
- }
-
- foreach ( actor in actors )
- {
- if ( IsValid( actor ) )
- actor.ClearParent()
-
- if ( IsInvincible( actor ) )
- ClearInvincible( actor )
-
- if ( !actor.IsPlayer() )
- actor.Destroy()
- }
-
- if ( IsValid( animEnt ) )
- animEnt.Destroy()
- }
- )
-
- foreach ( guy in actors )
- {
- if ( guy.IsPlayer() )
- continue
-
- MakeInvincible( guy )
- guy.SetEfficientMode( true )
- Highlight_ClearFriendlyHighlight( guy )
- }
-
- string anim_og = "pt_intro_scene_OG"
- string anim_og_helmet = "helmet_intro_scene_OG"
- string anim_bt = "BT_intro_scene_OG"
- string anim_anderson = "pt_intro_scene_Anderson"
- string anim_redshirt = "pt_intro_scene_grunt"
-
- string anim_og_idle = "pt_intro_scene_OG_idle"
- string anim_og_helmet_idle = "helmet_intro_scene_OG_idle"
- string anim_bt_idle = "BT_intro_scene_OG_idle"
- string anim_anderson_idle = "pt_intro_scene_Anderson_idle"
- string anim_redshirt_idle = "pt_intro_scene_grunt_idle"
-
- thread PlayAnimTeleport( og, anim_og_idle, animEnt )
- thread PlayAnimTeleport( ogHelmet, anim_og_helmet_idle, animEnt )
- thread PlayAnimTeleport( bt, anim_bt_idle, animEnt )
- thread PlayAnimTeleport( anderson, anim_anderson_idle, animEnt )
- thread PlayAnimTeleport( redshirt, anim_redshirt_idle, animEnt )
-
- FlagWait( "MeetOG_StartScene" )
- printt( "STARTING ANIMS: MEET OG" )
-
- foreach ( guy in actors )
- guy.Anim_Stop()
-
- AddAnimEvent( og, "helmet_on", AnimEventCallback_MeetOG_HelmetTurnsOn )
-
- thread PlayAnimTeleport( og, anim_og, animEnt )
- thread PlayAnimTeleport( ogHelmet, anim_og_helmet, animEnt )
- thread PlayAnimTeleport( bt, anim_bt, animEnt )
- thread PlayAnimTeleport( anderson, anim_anderson, animEnt )
- thread PlayAnimTeleport( redshirt, anim_redshirt, animEnt )
-
- player.Anim_Stop()
-
- // give player weapon for the toss moment
- entity fpProxy = player.GetFirstPersonProxy()
- int attachID = fpProxy.LookupAttachment( "PROPGUN" )
- asset playerWeaponModel = GetWeaponInfoFileKeyFieldAsset_Global( "mp_weapon_vinson", "playermodel" )
- entity playerWeapon = CreatePropDynamic( playerWeaponModel, fpProxy.GetAttachmentOrigin( attachID ), fpProxy.GetAttachmentAngles( attachID ) )
- file.playerAnimWeapon = playerWeapon
- playerWeapon.DisableHibernation()
- playerWeapon.SetParent( fpProxy, "PROPGUN", false, 0.0 )
-
- AddAnimEvent( player, "gun_catch", AnimEventCallback_MeetOG_PlayerCatchesWeapon )
-
- FirstPersonSequenceStruct playerSequence_meetOG
-
- float viewAnimDelay = 4.0
- //playerSequence_meetOG.setInitialTime = viewAnimDelay // DEPRECATED animators will adjust so start position is good again}
- playerSequence_meetOG.blendTime = 0.0
- playerSequence_meetOG.teleport = false
- playerSequence_meetOG.attachment = "REF"
- playerSequence_meetOG.firstPersonAnim = "pov_intro_scene_player"
- playerSequence_meetOG.thirdPersonAnim = "pt_intro_scene_player"
- playerSequence_meetOG.viewConeFunction = TrainingPod_ViewConeLock_SemiStrict
- playerSequence_meetOG.renderWithViewModels = true
-
- // HACK delay sequence so it transitions better from previous anim
- TrainingPod_ViewConeLock_SemiStrict( player ) // set this to cover any time between viewmodel anims
- thread FirstPersonSequence_Delayed( viewAnimDelay, playerSequence_meetOG, player, animEnt )
- //thread FirstPersonSequence( playerSequence_meetOG, player, animEnt )
-
- // gradual DOF racking during the scene
- RackDoF_NearDepth( player, 0, 22, 12.0 )
- RackDoF_FarDepth( player, 350, 950, 20.0 )
-
- // find longest anim duration
- array<string> sceneAnims = [ anim_og, anim_bt, anim_anderson, anim_redshirt ]//, "pt_intro_scene_player" ]
- float sceneDuration = -1
- foreach ( anim in sceneAnims )
- {
- entity animActor = og
- if ( anim.find( "BT_") != null )
- animActor = bt
- else if ( anim.find( "_player") != null )
- animActor = player
-
- float duration = animActor.GetSequenceDuration( anim )
- if ( duration > sceneDuration )
- sceneDuration = duration
- }
- Assert( sceneDuration > 0 )
-
- float fadeTime = SP_LEVEL_TRANSITION_FADETIME
-
- wait sceneDuration - fadeTime
- FlagSet( "CadillacMoment_MeetOG_StartFadeOut" )
-
- wait fadeTime
- FlagSet( "CadillacMoment_MeetOG_Done" )
-}
-
-void function FirstPersonSequence_Delayed( float delay, FirstPersonSequenceStruct sequence, entity player, entity animEnt )
-{
- EndSignal( player, "OnDestroy" )
-
- if ( delay > 0 )
- wait delay
-
- thread FirstPersonSequence( sequence, player, animEnt )
-}
-
-void function MeetOG_LoudspeakerVO( entity player )
-{
- EndSignal( player, "OnDestroy" )
- FlagWait( "SimPodShutdown_LoudspeakerVO_Done" )
-
- array<string> aliases
- // "Incoming hostile ship - Designation: IMS Malta. Battle stations."
- aliases.append( "outro_08" )
- // "Caution - Fuel leak in Cargo Bay eighty - five. Activating airlock procedures."
- aliases.append( "outro_12" )
- // "Titan bays two through five, drop clearance confirmed."
- aliases.append( "outro_03" )
- // "All available medical personnel, report to Med Central for tasking."
- aliases.append( "outro_05" )
- // "We need all Riflemen to docking bay four. Dropships standing by."
- aliases.append( "outro_07" )
- // "Infantry teams Stork three, Elk four, Shark six, Badger one, prepare for emergency atmospheric drop sequence"
- aliases.append( "outro_04" )
- // "Titan mech team - Rabbit six, prep the Vanguards."
- aliases.append( "outro_06" )
- // "Infantry teams 2nd Militia Fusiliers, Raptor three, target the IMS Malta."
- aliases.append( "outro_11" )
- // "Special Recon Squad deploy from Drop Bay thirty-seven - now."
- aliases.append( "outro_10" )
-
- thread LoopLoudspeakerVO( aliases )
-}
-
-void function AnimEventCallback_MeetOG_PlayerCatchesWeapon( entity player )
-{
- Assert( IsValid( file.playerAnimWeapon ) )
- file.playerAnimWeapon.RenderWithViewModels( true )
-
- thread MeetOG_PlayerCatchesWeapon_RackNearDOF( player )
-}
-
-void function MeetOG_PlayerCatchesWeapon_RackNearDOF( entity player )
-{
- EndSignal( player, "OnDestroy" )
-
- wait 0.7
-
- RackDOF_NearDepth_ToDefault( player, 1.5 )
-
- wait 2.0
-
- RackDoF_NearDepth( player, 0, 22, 1.25 )
-}
-
-
-// ------ OG HELMET TURNING ON ------
-void function AnimEventCallback_MeetOG_HelmetTurnsOn( entity og )
-{
- thread MeetOG_HelmetTurnsOn( og )
-}
-
-// script MeetOG_HelmetTurnsOn( GetOGPilot() )
-void function MeetOG_HelmetTurnsOn( entity og )
-{
- entity og = file.ogPilot
- entity ogHelmet = file.ogHelmet
- EndSignal( og, "OnDestroy" )
- EndSignal( ogHelmet, "OnDestroy" )
-
- // setting his team to friendly makes the helmet light up
- if ( og.GetTeam() == TEAM_MILITIA )
- SetTeam( og, TEAM_SPECTATOR )
-
- ogHelmet.Hide()
- Training_OGPilot_SetHelmetOn( og, true )
- wait 0.2
-
- SetTeam( og, TEAM_MILITIA )
- wait 0.1
- SetTeam( og, TEAM_SPECTATOR )
- wait 0.4
- SetTeam( og, TEAM_MILITIA )
- wait 0.1
- SetTeam( og, TEAM_SPECTATOR )
- wait 0.1
- SetTeam( og, TEAM_MILITIA )
-}
-
-#if DEV
-void function MeetOG_HelmetTurnsOff( entity og )
-{
- entity og = file.ogPilot
- entity ogHelmet = file.ogHelmet
-
- if ( og.GetTeam() == TEAM_SPECTATOR )
- SetTeam( og, TEAM_MILITIA )
-
- ogHelmet.Show()
- Training_OGPilot_SetHelmetOn( og, false )
-}
-#endif
-
-
-// ------ POD OUTRO BACKGROUND SKITS ------
-void function MeetOG_BackgroundSkits( entity player, float delay = 0.0 )
-{
- string endFlag = "CadillacMoment_MeetOG_Done"
- FlagEnd( endFlag )
-
- if ( delay > 0 )
- wait delay
-
- printt( "!!!! Pod Outro Background Skits START !!!!" )
-
- thread PodOutro_TitanRacks( endFlag )
-
- thread PodOutro_Background_Runners( player )
- thread PodOutro_Foreground_Runners( player )
-
- thread PodOutro_Background_ATC_Marvins()
-
- OnThreadEnd(
- function() : ()
- {
- DeleteAllSkitGuys()
- }
- )
-
- WaitForever()
-}
-
-void function PodOutro_TitanRacks( string endFlag )
-{
- FlagEnd( endFlag )
-
- array<HangarTitanGroup> hangarTitanGroups
-
- OnThreadEnd(
- function() : ( hangarTitanGroups )
- {
- foreach ( group in hangarTitanGroups )
- HangarTitanGroup_Cleanup( group )
- }
- )
-
- float wait_earlyEnd = 24.0
- bool cleanupAfterAnim = false
-
- // --- BAY 1 ---
- HangarTitanGroup bay1
- entity rack_bay1 = GetEntByScriptName( "hangar_titan_rack_1" )
- bay1.ref = rack_bay1
- bay1.rack = rack_bay1
- bay1.titan = GetEntByScriptName( "hangar_titan_1" )
- bay1.titanAnim = "bt_rack_prep_titan2"
- bay1.rackAnim = "rack_rack_prep_rack2"
- bay1.marvinAnim = "mv_rack_prep_marvin2"
- bay1.pilotAnim = "pt_rack_prep_pilot2"
- bay1.pilotModel = PILOT_MODEL_BAY1
- HangarTitanGroup_Init( bay1 )
- hangarTitanGroups.append( bay1 )
- thread HangarTitanGroup_Animate( bay1, endFlag, -1, cleanupAfterAnim )
-
-
- // --- BAY 2 ---
- //thread PodOutro_TitanBoot( endFlag, 15.0 )
-
- HangarTitanGroup bay2
- entity rack_bay2 = GetEntByScriptName( "hangar_titan_rack_2" )
- bay2.ref = rack_bay2
- bay2.rack = rack_bay2
- bay2.titan = GetEntByScriptName( "hangar_titan_2" )
- bay2.titanAnim = "bt_rack_prep_titan1"
- bay2.rackAnim = "rack_rack_prep_rack1"
- bay2.marvinAnim = "mv_rack_prep_marvin1"
- bay2.pilotAnim = "pt_rack_prep_pilot1"
- bay2.pilotModel = PILOT_MODEL_BAY2
- HangarTitanGroup_Init( bay2 )
- hangarTitanGroups.append( bay2 )
- waitthread HangarTitanGroup_Animate( bay2, endFlag, -1, cleanupAfterAnim )
-}
-
-void function PodOutro_TitanBoot( string endFlag, float delay )
-{
- FlagEnd( endFlag )
-
- entity refTitan = GetEntByScriptName( "hangar_titan_2" )
- refTitan.Hide()
-
- vector refOrg = refTitan.GetOrigin()
- vector refAng = refTitan.GetAngles()
- refOrg += < -20, 40, 0> // HACK
- refOrg = OriginToGround( refOrg )
-
- entity animref = CreateScriptRef( refOrg, refAng )
-
- entity titan = CreatePropScript( BUDDY_MODEL, refOrg, refAng )
- titan.DisableHibernation()
-
- AddAnimEvent( titan, "hatch_closed", TitanBoot_HatchClosed )
- entity cockpitLightFX = PlayFXOnEntity( FX_COCKPIT_LIGHT, titan, "HIJACK" )
-
- SkitGuyInfo titanInfo = AddSkitGuy_Manually( "bootup_titan", titan )
-
- SkitGuyInfo titanPilotInfo = SpawnSkitGuy( "bootup_pilot", "", animref.GetOrigin(), animref.GetAngles(), TEAM_MILITIA, "npc_soldier" )
- entity titanPilot = titanPilotInfo.guy
- titanPilot.SetParent( titan, "HIJACK", false, 0.0 )
- titanPilot.MarkAsNonMovingAttachment()
-
- SkitGuyInfo crewInfo = SpawnSkitGuy( "bootup_crew", "", animref.GetOrigin(), animref.GetAngles(), TEAM_MILITIA, "npc_soldier_bish" )
- entity crew = crewInfo.guy
-
- OnThreadEnd(
- function() : ( titanPilotInfo, crewInfo, titanInfo, cockpitLightFX, animref, refTitan )
- {
- if ( IsValid_ThisFrame( cockpitLightFX ) )
- {
- EntFireByHandle( cockpitLightFX, "Stop", "", 0, null, null )
- cockpitLightFX.ClearParent()
- cockpitLightFX.Destroy()
- }
-
- if ( IsAlive( titanInfo.guy ) )
- StopSoundOnEntity( titanInfo.guy, "Wargames_MCOR_TitanActivate" )
-
- if ( IsValid( animref ) )
- animref.Destroy()
-
- DeleteSkitGuy( titanPilotInfo )
- DeleteSkitGuy( crewInfo )
- DeleteSkitGuy( titanInfo )
-
- if ( IsValid( refTitan ) )
- refTitan.Show()
- }
- )
-
- EmitSoundOnEntity( titan, "Wargames_MCOR_TitanActivate" )
-
- string pilotAnim = "pt_titan_activation_pilot"
- string pilotAnim_idle = "pt_titan_activation_pilot_idle"
- string titanAnim = "at_titan_activation_training_meetOG"
- string titanAnim_idle = "at_titan_activation_idle"
- string titanAnim_endIdle = "at_titan_activation_training_meetOG_end_idle"
- string crewAnim = "pt_titan_activation_crew"
- string crewAnim_idle = "pt_titan_activation_crew_idle"
-
- if ( delay > 0 )
- {
- thread PlayAnim( crew, crewAnim_idle, animref, null, 0.0 )
- thread PlayAnim( titan, titanAnim_idle, animref, null, 0.0 )
- titanPilot.Anim_ScriptedPlay( pilotAnim_idle )
- titanPilot.Anim_EnableUseAnimatedRefAttachmentInsteadOfRootMotion()
-
- wait delay
-
- titanPilot.Anim_Stop()
- crew.Anim_Stop()
- titan.Anim_Stop()
- }
-
- titanPilot.Anim_ScriptedPlay( pilotAnim )
- titanPilot.Anim_EnableUseAnimatedRefAttachmentInsteadOfRootMotion()
- thread PlayAnim( crew, crewAnim, animref, null, DEFAULT_SCRIPTED_ANIMATION_BLEND_TIME )
- thread PlayAnim( titan, titanAnim, animref, null, DEFAULT_SCRIPTED_ANIMATION_BLEND_TIME )
-
- // end it early so he doesn't make stomping sounds when the pod is closed
- //wait 15.0
- float duration = titan.GetSequenceDuration( titanAnim )
- wait duration - 0.1
-
- printt( "Ending titan boot anim" )
-
- thread PlayAnim( titan, titanAnim_endIdle, animref, null, DEFAULT_SCRIPTED_ANIMATION_BLEND_TIME )
- crew.Freeze()
-
- WaitForever()
-}
-
-void function TitanBoot_HatchClosed( entity titan )
-{
- SkitGuyInfo info = GetSkitGuyInfo_ByName( "bootup_pilot" )
- DeleteSkitGuy( info )
-}
-
-void function PodOutro_Background_Runners( entity player )
-{
- EndSignal( player, "OnDestroy" )
-
- // right to left, across the whole hangar
- array<Point> path1 = []
- ScriptedPath_AddPoint( path1, < 11080.5, -10017.2, -6079.97 >, < 0, 177.587, 0 > )
- ScriptedPath_AddPoint( path1, < 9619.14, -10004.8, -6079.97 >, < 0, 183.021, 0 > )
-
- // right to left, starts closer to player POV
- array<Point> path2 = []
- ScriptedPath_AddPoint( path2, < 11000, -9946.33, -6079.97 >, < 0, 177.587, 0 > )
- ScriptedPath_AddPoint( path2, < 9619.14, -10004.8, -6079.97 >, < 0, 183.021, 0 > )
-
- wait 2.0 // wait for OG's first line to be nearly over
-
- printt( "BACKGROUND RUNNER GROUP 1" )
-
- thread SpawnSkitGuy_AndRun( "runner_1_1", path2, 0.85, TEAM_MILITIA, "npc_soldier_specialist_militia", "mp_weapon_hemlok_smg" )
- wait 1.0
- thread SpawnSkitGuy_AndRun( "runner_1_2", path2, 0.85, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
-
- wait 6.5 // wait until OG hands the eye to BT
-
- printt( "BACKGROUND RUNNER GROUP 2" )
-
- thread SpawnSkitGuy_AndRun( "runner_2_1", path2, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
- wait 1.0
- thread SpawnSkitGuy_AndRun( "runner_2_2", path2, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_shotgun" )
-
- wait 4.5 // wait until OG is shaking Anderson's hand
-
- printt( "BACKGROUND RUNNER GROUP 3" )
-
- thread SpawnSkitGuy_AndRun( "runner_3_1", path2, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
- wait 1.0
- thread SpawnSkitGuy_AndRun( "runner_3_2", path2, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_shotgun" )
- wait 1.0
- thread SpawnSkitGuy_AndRun( "runner_3_3", path2, 0.8, TEAM_MILITIA, "npc_soldier_specialist_militia", "mp_weapon_hemlok_smg" )
- wait 1.0
- thread SpawnSkitGuy_AndRun( "runner_3_4", path2, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
-
- wait 4.5 // wait until OG is mounting up
-
- printt( "BACKGROUND RUNNER GROUP 4" )
-
- thread SpawnSkitGuy_AndRun( "runner_4_1", path2, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
- wait 1.0
- thread SpawnSkitGuy_AndRun( "runner_4_2", path2, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_shotgun" )
-
- wait 6.5 // wait until OG thumbs up
-
- printt( "BACKGROUND RUNNER GROUP 5" )
-
- thread SpawnSkitGuy_AndRun( "runner_5_1", path2, 0.85, TEAM_MILITIA, "npc_soldier_specialist_militia", "mp_weapon_hemlok_smg" )
- wait 1.2
- thread SpawnSkitGuy_AndRun( "runner_5_2", path2, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
- wait 1.0
- thread SpawnSkitGuy_AndRun( "runner_5_3", path2, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_shotgun" )
- wait 1.5
- thread SpawnSkitGuy_AndRun( "runner_5_4", path2, 0.85, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
- wait 1.0
- thread SpawnSkitGuy_AndRun( "runner_5_3", path2, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_shotgun" )
- wait 1.5
- thread SpawnSkitGuy_AndRun( "runner_5_4", path2, 0.85, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
-
- /*
- wait 5.0
-
- wait 4.0
-
- thread SpawnSkitGuy_AndRun( "runner_2_1", path2, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
- wait 1.0
- thread SpawnSkitGuy_AndRun( "runner_2_2", path2, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_shotgun" )
- */
-}
-
-void function PodOutro_Foreground_Runners( entity player )
-{
- EndSignal( player, "OnDestroy" )
-
- // right in front of pod
- array<Point> pathClose = []
- ScriptedPath_AddPoint( pathClose, < 10728.2, -10194.2, -6055.97 >, < 0, 178.246, 0 > )
- ScriptedPath_AddPoint( pathClose, < 10236.8, -10180.3, -6055.97 >, < 0, 178.41, 0 > )
-
- wait 11.0 // wait for OG to hand eyeball to BT
-
- thread SpawnSkitGuy_AndRun( "close_runner_1", pathClose, 0.7, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
- wait 1.2
- thread SpawnSkitGuy_AndRun( "close_runner_2", pathClose, 0.75, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
-
- wait 10.0 // wait for OG to start embarking BT
-
- thread SpawnSkitGuy_AndRun( "close_runner_4", pathClose, 0.75, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
- wait 1.3
- thread SpawnSkitGuy_AndRun( "close_runner_5", pathClose, 0.8, TEAM_MILITIA, "npc_soldier_specialist_militia", "mp_weapon_g2" )
-
- wait 11 // wait for grunt to hand player the weapon
-
- thread SpawnSkitGuy_AndRun( "close_runner_10", pathClose, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
- wait 1.8
- thread SpawnSkitGuy_AndRun( "close_runner_11", pathClose, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
- wait 1.0
- thread SpawnSkitGuy_AndRun( "close_runner_12", pathClose, 0.8, TEAM_MILITIA, "npc_soldier", "mp_weapon_rspn101" )
-}
-
-void function PodOutro_Background_ATC_Marvins()
-{
- // 1, 2, 3- matches titan bay numbering (right to left)
- // plain numbers = farther from camera
- // "a" variants = closer to camera
- //SkitGuyInfo marvin_1 = SpawnSkitGuy( "atc_marvin_1", "", < 10600, -9841.5, -6079.97 >, < 0, -20, 0 >, TEAM_MILITIA )
- //thread ATC_Marvin_Think( marvin_1, "mv_trafic_controller_A", 0.0 )
- //SkitGuyInfo marvin_1a = SpawnSkitGuy( "atc_marvin_1a", "", < 10683.8, -10077.7, -6094.65 >, < 0, 20, 0 >, TEAM_MILITIA )
- //thread ATC_Marvin_Think( marvin_1a, "mv_trafic_controller_B", 0.0 )
- SkitGuyInfo marvin_2 = SpawnSkitGuy( "atc_marvin_2", "", < 10460.6, -9861.5, -6079.97 >, < 0, -30, 0 >, TEAM_MILITIA )
- thread ATC_Marvin_Think( marvin_2, "mv_trafic_controller_B", 0.25 )
- //SkitGuyInfo marvin_2a = SpawnSkitGuy( "atc_marvin_2a", "", < 10410.6, -10075.6, -6079.97 >, < 0, 30, 0 >, TEAM_MILITIA )
- //thread ATC_Marvin_Think( marvin_2a, "mv_trafic_controller_A", 0.25 )
- SkitGuyInfo marvin_3 = SpawnSkitGuy( "atc_marvin_3", "", < 10214.8, -9891.5, -6079.97 >, < 0, -10, 0 >, TEAM_MILITIA )
- thread ATC_Marvin_Think( marvin_3, "mv_trafic_controller_A", 0.5 )
- SkitGuyInfo marvin_3a = SpawnSkitGuy( "atc_marvin_3a", "", < 10207.5, -10079.4, -6079.97 >, < 0, 10, 0 >, TEAM_MILITIA )
- thread ATC_Marvin_Think( marvin_3a, "mv_trafic_controller_B", 0.5 )
-}
-
-void function ATC_Marvin_Think( SkitGuyInfo marvinInfo, string anim, float skipAheadTime = 0.0 )
-{
- entity marvin = marvinInfo.guy
-
- EndSignal( marvin, "OnDestroy" )
-
- entity batonRight = CreatePropDynamic( SAFETY_BATON_MODEL )
- batonRight.SetOrigin( marvin.GetAttachmentOrigin( marvin.LookupAttachment( "R_HAND" ) ) )
- // HACK adjust the angles since the tags are different
- vector angs = marvin.GetAttachmentAngles( marvin.LookupAttachment( "R_HAND" ) ) + Vector( 0, 0, 180 )
- batonRight.SetAngles( angs )
- batonRight.SetParent( marvin, "R_HAND", true )
-
- entity batonLeft = CreatePropDynamic( SAFETY_BATON_MODEL )
- batonLeft.SetParent( marvin, "L_HAND" )
-
- marvin.NotSolid() // don't want other NPCs to path around the ATC marvins
-
- array<entity> cleanupEnts = [ batonRight, batonLeft ]
-
- OnThreadEnd(
- function() : ( cleanupEnts )
- {
- foreach ( ent in cleanupEnts )
- {
- if ( IsValid( ent ) )
- {
- ent.ClearParent()
- ent.Destroy()
- }
- }
- }
- )
-
- WaitFrame()
- marvinInfo.skitAnim = anim
- /*
- array<string> anims = [ "mv_trafic_controller_A", "mv_trafic_controller_B" ]
- while( 1 )
- {
- marvin.Anim_Play( anims.getrandom() )
- marvin.SetPlaybackRate( RandomFloatRange( 0.9, 1.0 ) )
- waitthread WaittillAnimDone( marvin )
- }
- */
- marvin.SetPlaybackRate( RandomFloatRange( 0.9, 1.0 ) )
- SkitGuy_PlayAnim( marvinInfo, skipAheadTime )
-
- WaitForever()
-}
-
-
-
-// =======================================
-// ============ GAUNTLET MODE ============
-// =======================================
-// Just runs the Gauntlet over and over.
-
-void function Training_Setup_GauntletMode( entity player )
-{
- Training_EnvArtColorCorrection_SetEnabled( true )
-
- entity ogStart = GetEntByScriptName( "og_near_leaderboard" )
- entity og = Training_SpawnOGPilot( ogStart )
- Training_OG_Idles( ogStart, "OG_Leaderboard_D_idle" )
-
- //TeleportPlayerAndBT( "playerstart_gauntlet_challenge" )
- // HACK better start position
- player.SetOrigin( < -5179, 279.129, 32.0313 > )
- player.SetAngles( < 0, 80.7242, 0 > )
-}
-
-void function Training_GauntletModeStart( entity player )
-{
- file.gauntletMode = true
-
- waitthread Training_GauntletChallenge( player )
-}
-
-void function GauntletMode_Finished( entity player )
-{
- Assert( file.gauntletMode )
-
- float fadeTime = 3.0
- ScreenFade( player, 0, 0, 0, 255, fadeTime, -1, FFADE_OUT | FFADE_STAYOUT )
- wait fadeTime
-
- // Dump player back to menu
- ClientCommand( player, "disconnect" )
-
- WaitForever() // defensive- don't want any extra stuff happening right before level transition
-}
-
-
-
-#if DEV
-// ===============================================
-// ============ RECORD GAUNTLET GHOSTS ===========
-// ===============================================
-void function TrainingGauntlet_RecordGhostStart_FirstRun( entity player )
-{
- TrainingGauntlet_RecordGhost_CommonStart( player, GetTrainingGauntlet(), GHOST_NAME_FIRSTRUN )
-}
-
-void function TrainingGauntlet_RecordGhostStart_Challenge_WIP( entity player )
-{
- TrainingGauntlet_RecordGhost_CommonStart( player, GetTrainingGauntlet(), GHOST_NAME_CHAL_WIP )
-}
-
-void function TrainingGauntlet_RecordGhostStart_Challenge_01( entity player )
-{
- TrainingGauntlet_RecordGhost_CommonStart( player, GetTrainingGauntlet(), GHOST_NAME_CHAL_01 )
-}
-
-void function TrainingGauntlet_RecordGhostStart_Challenge_02( entity player )
-{
- TrainingGauntlet_RecordGhost_CommonStart( player, GetTrainingGauntlet(), GHOST_NAME_CHAL_02 )
-}
-
-void function TrainingGauntlet_RecordGhostStart_Challenge_03( entity player )
-{
- TrainingGauntlet_RecordGhost_CommonStart( player, GetTrainingGauntlet(), GHOST_NAME_CHAL_03 )
-}
-
-void function TrainingGauntlet_RecordGhostStart_Challenge_04( entity player )
-{
- TrainingGauntlet_RecordGhost_CommonStart( player, GetTrainingGauntlet(), GHOST_NAME_CHAL_04 )
-}
-
-void function TrainingGauntlet_RecordGhostStart_Challenge_05( entity player )
-{
- TrainingGauntlet_RecordGhost_CommonStart( player, GetTrainingGauntlet(), GHOST_NAME_CHAL_05 )
-}
-
-void function TrainingGauntlet_RecordGhostStart_Challenge_06( entity player )
-{
- TrainingGauntlet_RecordGhost_CommonStart( player, GetTrainingGauntlet(), GHOST_NAME_CHAL_06 )
-}
-
-void function TrainingGauntlet_RecordGhostStart_Challenge_07( entity player )
-{
- TrainingGauntlet_RecordGhost_CommonStart( player, GetTrainingGauntlet(), GHOST_NAME_CHAL_07 )
-}
-
-void function TrainingGauntlet_RecordGhostStart_Challenge_08( entity player )
-{
- TrainingGauntlet_RecordGhost_CommonStart( player, GetTrainingGauntlet(), GHOST_NAME_CHAL_08 )
-}
-
-void function TrainingGauntlet_RecordGhostStart_Challenge_09( entity player )
-{
- TrainingGauntlet_RecordGhost_CommonStart( player, GetTrainingGauntlet(), GHOST_NAME_CHAL_09 )
-}
-
-
-void function TrainingGauntlet_RecordGhost_CommonStart( entity player, GauntletInfo gauntlet, string ghostFileName )
-{
- thread TrainingGauntlet_TeleportPlayerAtFinishLine( player )
-
- TeleportPlayerAndBT( "gauntlet_startpoint" )
-
- Gauntlet_Player_GhostRecordOrPlayback( player, gauntlet, ghostFileName )
-
- while ( 1 )
- wait 5
-}
-#endif //DEV
-
-
-
-// ============================================
-// ============ TRAINING POD STUFF ============
-// ============================================
-void function SetupTrainingPod()
-{
- file.trainingPod = GetEntByScriptName( "training_pod" )
- file.trainingPod.DisableHibernation()
-
- TrainingPod_SetupInteriorDLights()
-
- array<string> laserAttachNames = [ "fx_laser_L", "fx_laser_R" ]
-
- foreach ( attachName in laserAttachNames )
- {
- entity emitterEnt = CreateScriptMover( file.trainingPod.GetOrigin() )
- int attachID = file.trainingPod.LookupAttachment( attachName )
- vector attachAng = file.trainingPod.GetAttachmentAngles( attachID )
-
- TrainingPod_LaserEmitter emitter
- emitter.ent = emitterEnt
- emitter.attachName = attachName
- emitter.ogAng = attachAng
-
- file.trainingPodLaserEmitters.append( emitter )
- }
-
- // HACK we do this later as well to reset the emitter positions, so it's a separate function
- TrainingPod_SnapLaserEmittersToAttachPoints()
-
- //file.trainingPod.SetAngles( Vector( 0, 109, 0 ) ) // these angles are a little better for seeing the room
-}
-
-void function TrainingPod_SetupInteriorDLights()
-{
- entity pod = file.trainingPod
-
- TrainingPod_dLightMapping m1
- m1.scriptAlias = "console1"
- m1.fxName = FX_POD_DLIGHT_CONSOLE1
- m1.attachName = "light_console1"
- file.trainingPodDLightMappings.append( m1 )
-
- TrainingPod_dLightMapping m2
- m2.scriptAlias = "console2"
- m2.fxName = FX_POD_DLIGHT_CONSOLE2
- m2.attachName = "light_console2"
- file.trainingPodDLightMappings.append( m2 )
-
- //TrainingPod_dLightMapping m3
- //m3.scriptAlias = "backlight_side_L"
- //m3.fxName = FX_POD_DLIGHT_BACKLIGHT_SIDE
- //m3.attachName = "light_back1"
- //file.trainingPodDLightMappings.append( m3 )
-
- //TrainingPod_dLightMapping m4
- //m4.scriptAlias = "backlight_side_R"
- //m4.fxName = FX_POD_DLIGHT_BACKLIGHT_SIDE
- //m4.attachName = "light_back2"
- //file.trainingPodDLightMappings.append( m4 )
-
- //TrainingPod_dLightMapping m5
- //m5.scriptAlias = "backlight_top"
- //m5.fxName = FX_POD_DLIGHT_BACKLIGHT_TOP
- //m5.attachName = "light_backtop"
- //file.trainingPodDLightMappings.append( m5 )
-}
-
-void function TrainingPod_TurnOnInteriorDLights_Delayed( entity player, float delay )
-{
- player.EndSignal( "OnDestroy" )
-
- wait delay
-
- TrainingPod_TurnOnInteriorDLight( "console1" )
- TrainingPod_TurnOnInteriorDLight( "console2" )
-}
-
-void function TrainingPod_TurnOnInteriorDLight( string scriptAlias )
-{
- entity pod = file.trainingPod
-
- int idx
- TrainingPod_dLightMapping thisMapping
- foreach ( mappingIdx, mapping in file.trainingPodDLightMappings )
- {
- if ( mapping.scriptAlias == scriptAlias )
- {
- thisMapping = mapping
- idx = mappingIdx
- break
- }
- }
-
- Assert ( thisMapping.scriptAlias != "", "Couldn't find pod dlight mapping for alias " + scriptAlias )
-
- entity fxHandle = PlayLoopFXOnEntity( thisMapping.fxName, pod, thisMapping.attachName )
- file.trainingPodDLightMappings[ idx ].fxHandle = fxHandle
-}
-
-void function TrainingPod_KillInteriorDLights_Delayed( entity player, float delay )
-{
- player.EndSignal( "OnDestroy" )
-
- wait delay
-
- TrainingPod_KillInteriorDLights()
-}
-
-void function TrainingPod_KillInteriorDLights()
-{
- foreach ( idx, mapping in file.trainingPodDLightMappings )
- {
- if ( !IsValid_ThisFrame( mapping.fxHandle ) )
- continue
-
- KillFX( mapping.fxHandle )
-
- file.trainingPodDLightMappings[ idx ].fxHandle = null
- }
-}
-
-void function TrainingPod_SnapLaserEmittersToAttachPoints()
-{
- foreach ( TrainingPod_LaserEmitter emitter in file.trainingPodLaserEmitters )
- {
- int attachID = file.trainingPod.LookupAttachment( emitter.attachName )
- vector attachOrg = file.trainingPod.GetAttachmentOrigin( attachID )
- vector attachAng = file.trainingPod.GetAttachmentAngles( attachID )
-
- emitter.ent.ClearParent()
- emitter.ent.SetOrigin( attachOrg ) // HACK set this to ANYTHING (even 0, 0, 0) and the position is correct, otherwise it's offset from the attachpoint when parented
- emitter.ent.SetParent( file.trainingPod, emitter.attachName )
- }
-}
-
-void function TrainingPod_Interior_BootSequence( entity player )
-{
- player.EndSignal( "OnDestroy" )
-
- entity pod = file.trainingPod
-
- TrainingPod_InteriorFX_CommonSetup( pod )
-
- FlagSet( "PodIntro_InteriorBootSequence_Starting" )
-
- EmitSoundOnEntity( player, "NPE_Scr_SimPod_PowerUp" )
-
- // Transition screen FX
- thread PlayFXOnEntity_Delayed( player, FX_POD_SCREEN_IN, player, 2.35 )
-
- // GLOW LIGHTS
- TrainingPod_GlowLightsTurnOn()
-
- // LASERS
- float longestSweepTime = -1
- foreach ( emitter in file.trainingPodLaserEmitters )
- {
- float sweepTime = RandomFloatRange( 2.9, 3.15 )
- if ( sweepTime > longestSweepTime )
- longestSweepTime = sweepTime
-
- thread LaserSweep( player, sweepTime, emitter, pod, "top" )
- }
-
- wait longestSweepTime
-
- player.Signal( "PodInteriorSequenceDone" )
-}
-
-void function TrainingPod_InteriorFX_CommonSetup( entity pod )
-{
- if ( file.trainingPodLaserEmitters.len() )
- {
- TrainingPod_KillLasers( pod )
- TrainingPod_ResetLaserEmitterRotation( pod )
- }
-
- TrainingPod_KillGlowFX( pod )
-}
-
-// NOTE startPosition is actually inverted from what I think it should be. Tag orientation issue, maybe?
-void function LaserSweep( entity player, float totalTime, TrainingPod_LaserEmitter emitter, entity pod, string startPosition = "bottom" )
-{
- //float startTime = Time()
-
- player.EndSignal( "OnDestroy" )
- emitter.ent.EndSignal( "OnDeath" )
-
- emitter.sweepDone = false
-
- //printt( "emitter og angles:", emitter.GetAngles() )
-
- vector vecToPlayerEye = ( player.EyePosition() + Vector( 0, 0, 7 ) ) - emitter.ent.GetOrigin() // eye position offset is a HACK, not sure why I need to do that here.
- vector centerAng = VectorToAngles( vecToPlayerEye )
- vector topAng = centerAng + Vector( -270, 0, 0 )
- vector bottomAng = centerAng + Vector( -90, 0, 0 )
-
- //vector topAng = emitter.GetAngles() + < 90, -8, 0 >
- //vector bottomAng = emitter.GetAngles() + < -90, 8, 0 >
-
- //printt( "==== starting at:", startPosition )
- //printt( "topAng:", topAng )
- //printt( "bottomAng:", bottomAng )
- //printt( "centerAng:", centerAng )
-
- vector lastBigSweepAng
-
- if ( startPosition == "bottom")
- {
- emitter.ent.SetAbsAngles( bottomAng )
- lastBigSweepAng = bottomAng
- }
- else
- {
- emitter.ent.SetAbsAngles( topAng )
- lastBigSweepAng = topAng
- }
- //printt( "setting start angles to:", lastBigSweepAng )
-
- entity fxHandle = PlayLoopFXOnEntity( FX_POD_LASER, emitter.ent )
- emitter.fxHandle = fxHandle
-
- int numBigSweeps = 2
- float finalCenterTime = totalTime * 0.15
- float bigSweepTime = ( totalTime - finalCenterTime ) / numBigSweeps
-
- float bigSweep_AccelTime = 0
- float bigSweep_DecelTime = bigSweepTime * 0.2
-
- // do the big sweeps
- vector nextBigSweepAng
- for ( int i = 0; i < numBigSweeps; i++ )
- {
- nextBigSweepAng = topAng
- if ( lastBigSweepAng == topAng )
- nextBigSweepAng = bottomAng
-
- //printt( "rotating to", nextBigSweepAng )
-
- emitter.ent.NonPhysicsRotateTo( nextBigSweepAng, bigSweepTime, bigSweep_AccelTime, bigSweep_DecelTime )
-
- float waitTime = bigSweepTime
- if ( i < numBigSweeps - 1 )
- waitTime = bigSweepTime - 0.1
-
- wait waitTime
-
- lastBigSweepAng = nextBigSweepAng
- }
-
- // finish with centering move
- //printt( "centering to", centerAng )
-
- float finalCenter_AccelTime = 0
- float finalCenter_DecelTime = finalCenterTime * 0.2
-
- emitter.ent.NonPhysicsRotateTo( centerAng, finalCenterTime, finalCenter_AccelTime, finalCenter_DecelTime )
- wait finalCenterTime
-
- emitter.sweepDone = true
- //printt( "laser sweep done, total time", Time() - startTime, "should have been", totalTime )
-}
-
-void function TrainingPod_KillLasers( entity pod, bool doEndCap = false )
-{
- foreach ( emitter in file.trainingPodLaserEmitters )
- {
- if ( IsValid_ThisFrame( emitter.fxHandle ) )
- {
- if ( !doEndCap )
- {
- //printt( "killing laser FX", emitter.fxHandle )
- KillFX( emitter.fxHandle )
- }
- else
- {
- //printt( "killing laser FX with endcap", emitter.fxHandle )
- KillFXWithEndcap( emitter.fxHandle )
- }
- }
-
- emitter.fxHandle = null
- }
-}
-
-void function TrainingPod_ResetLaserEmitterRotation( entity pod )
-{
- if ( !file.trainingPodLaserEmitters.len() )
- return
-
- foreach ( emitter in file.trainingPodLaserEmitters )
- {
- //reset to start position
- emitter.ent.NonPhysicsRotateTo( emitter.ogAng, 0.05, 0.0, 0.0 )
- }
-}
-
-void function TrainingPod_GlowLightsArraySetup()
-{
- array<TrainingPod_GlowLightRow> rows
-
- // rows are set up bottom to top
- // lights are set up outside to in (in = door close seam; opposite for each side)
- // process two rows per loop (one for each door side)
-
- TrainingPod_GlowLightRow row1
- row1.fxSpotsL = [ "fx_glow_L_door012", "fx_glow_L_door013" ]
- row1.fxSpotsR = [ "fx_glow_R_door014", "fx_glow_R_door013" ]
- rows.append( row1 )
-
- TrainingPod_GlowLightRow row2
- row2.fxSpotsL = [ "fx_glow_L_door014", "fx_glow_L_door011" ]
- row2.fxSpotsR = [ "fx_glow_R_door012", "fx_glow_R_door011" ]
- rows.append( row2 )
-
- TrainingPod_GlowLightRow row3
- row3.fxSpotsL = [ "fx_glow_L_door09", "fx_glow_L_door010" ]
- row3.fxSpotsR = [ "fx_glow_R_door09", "fx_glow_R_door010" ]
- rows.append( row3 )
-
- TrainingPod_GlowLightRow row4
- row4.fxSpotsL = [ "fx_glow_L_door07", "fx_glow_L_door08" ]
- row4.fxSpotsR = [ "fx_glow_R_door07", "fx_glow_R_door08" ]
- rows.append( row4 )
-
- TrainingPod_GlowLightRow row5
- row5.fxSpotsL = [ "fx_glow_L_door05", "fx_glow_L_door06" ]
- row5.fxSpotsR = [ "fx_glow_R_door05", "fx_glow_R_door06" ]
- rows.append( row5 )
-
- TrainingPod_GlowLightRow row6
- row6.fxSpotsL = [ "fx_glow_L_door03", "fx_glow_L_door04" ]
- row6.fxSpotsR = [ "fx_glow_R_door03", "fx_glow_R_door04" ]
- rows.append( row6 )
-
- TrainingPod_GlowLightRow row7
- row7.fxSpotsL = [ "fx_glow_L_door01", "fx_glow_L_door02" ]
- row7.fxSpotsR = [ "fx_glow_R_door01", "fx_glow_R_door02" ]
- rows.append( row7 )
-
- file.trainingPodGlowLightRows = rows
-}
-
-void function TrainingPod_GlowLightsTurnOn( bool instantOn = false )
-{
- //float startTime = Time()
-
- entity pod = file.trainingPod
-
- foreach ( TrainingPod_GlowLightRow row in file.trainingPodGlowLightRows )
- {
- float loopTime = Time()
-
- array<string> group1 = [ row.fxSpotsL[0], row.fxSpotsR[0] ]
- array<string> group2 = [ row.fxSpotsL[1], row.fxSpotsR[1] ]
- table< int, array < string > > lightgroups
- lightgroups[0] <- group1
- lightgroups[1] <- group2
-
- foreach ( idx, group in lightgroups )
- {
- foreach ( attachName in group )
- {
- entity fxHandle = PlayLoopFXOnEntity( FX_POD_GLOWLIGHT, pod, attachName )
- file.trainingPodGlowLightFXHandles.append( fxHandle )
- }
-
- if ( !instantOn )
- wait 0.1
- }
-
- /*
- // both sides have same number of lights
- int numLights = 2
- for ( int i = 0; i < numLights; i++ )
- {
- foreach ( var side in row )
- {
- string attachName = side[ i ]
- entity fxHandle = PlayLoopFXOnEntity( FX_POD_GLOWLIGHT, pod, attachName )
- file.trainingPodGlowLightFXHandles.append( fxHandle )
- }
-
- if ( lightWait > 0 )
- wait lightWait
- }
-
- if ( rowWait > 0)
- wait rowWait
- */
- }
-
- //printt( "glow lights turn on took", Time() - startTime, "secs" )
-}
-
-void function TrainingPod_KillGlowFX( entity pod )
-{
- foreach ( fxHandle in file.trainingPodGlowLightFXHandles )
- {
- if ( !IsValid_ThisFrame( fxHandle ) )
- continue
-
- KillFX( fxHandle )
- }
-
- file.trainingPodGlowLightFXHandles = []
-}
-
-void function TrainingPod_Interior_ShutdownSequence( entity player, float shutdownTime )
-{
- player.EndSignal( "OnDestroy" )
-
- entity pod = file.trainingPod
-
- TrainingPod_InteriorFX_CommonSetup( pod )
-
- // TURN ON GLOW LIGHTS
- TrainingPod_GlowLightsTurnOn( true )
-
- // TURN ON LASERS
- TrainingPod_LasersInstantOn( player, pod )
-
- player.WaitSignal( "TrainingPod_BeginInteriorShutdown" )
-
- thread TrainingPod_LasersShutDown( player, pod, shutdownTime * 0.6 )
- thread TrainingPod_GlowLightsShutDown( player, pod, shutdownTime )
-
- wait shutdownTime
- printt( "interior shutdown done" )
-}
-
-void function TrainingPod_LasersInstantOn( entity player, entity pod )
-{
- foreach ( emitter in file.trainingPodLaserEmitters )
- {
- float dist = Distance( player.EyePosition(), emitter.ent.GetOrigin() )
- Assert( dist <= 30, "player is usually about 20 units away when we try to set the laser angles. If very far away, the math will crash the game. Dist: " + dist )
-
- vector vecToPlayerEye = ( player.EyePosition() + Vector( 0, 0, 7 ) ) - emitter.ent.GetOrigin() // eye position offset is a HACK, not sure why I need to do that here.
- vector centerAng = VectorToAngles( vecToPlayerEye )
- emitter.ent.NonPhysicsRotateTo( centerAng, 0.1, 0.0, 0.0 ) // SETANGLES DOES NOT WORK! You have to rotate it for the FX to follow.
-
- emitter.fxHandle = PlayLoopFXOnEntity( FX_POD_LASER, emitter.ent )
- }
-}
-
-void function TrainingPod_LasersShutDown( entity player, entity pod, float shutdownTime )
-{
- player.EndSignal( "OnDestroy" )
-
- foreach ( emitter in file.trainingPodLaserEmitters )
- {
- vector vecToPlayerEye = ( player.EyePosition() + Vector( 0, 0, 7 ) ) - emitter.ent.GetOrigin() // eye position offset is a HACK, not sure why I need to do that here.
- vector centerAng = VectorToAngles( vecToPlayerEye )
- emitter.ent.NonPhysicsRotateTo( centerAng, 0.1, 0.0, 0.0 ) // SETANGLES DOES NOT WORK! You have to rotate it for the FX to follow.
- }
-
- wait shutdownTime * 0.25
-
- float moveDownTime = shutdownTime * 0.75
- float accelTime = moveDownTime * 0.25
- float decelTime = moveDownTime * 0.1
-
- foreach ( TrainingPod_LaserEmitter emitter in file.trainingPodLaserEmitters )
- {
- vector finalAng = emitter.ent.GetAngles() + Vector( 30, 0, 0 ) // not sure why adding pitch makes them appear to drop down
- emitter.ent.NonPhysicsRotateTo( finalAng, moveDownTime, accelTime, decelTime )
- }
-
- wait moveDownTime
- TrainingPod_KillLasers( pod, true )
-}
-
-void function TrainingPod_GlowLightsShutDown( entity player, entity pod, float shutdownTime )
-{
- player.EndSignal( "OnDestroy" )
-
- float shutdownDelay = shutdownTime * 0.65
- float finishEarly = shutdownTime * 0.1
- float glowLightShutDownDuration = shutdownTime - shutdownDelay - finishEarly
-
- wait shutdownDelay
-
- Assert( glowLightShutDownDuration > 0.0 )
-
- float timePerLight = glowLightShutDownDuration / file.trainingPodGlowLightFXHandles.len().tofloat()
-
- foreach ( entity fxHandle in file.trainingPodGlowLightFXHandles )
- {
- if ( !IsValid_ThisFrame( fxHandle ) )
- continue
-
- thread KillFXWithEndcap( fxHandle )
- wait timePerLight
- }
-
- file.trainingPodGlowLightFXHandles = []
-}
-
-void function TrainingPod_ViewConeLock_Shared( entity player )
-{
- player.PlayerCone_FromAnim()
- player.PlayerCone_SetMinYaw( -25 )
- player.PlayerCone_SetMaxYaw( 25 )
- player.PlayerCone_SetMinPitch( -30 )
-}
-
-void function TrainingPod_ViewConeLock_PodOpen( entity player )
-{
- TrainingPod_ViewConeLock_Shared( player )
- player.PlayerCone_SetMaxPitch( 35 )
-}
-
-void function TrainingPod_ViewConeLock_PodClosed( entity player )
-{
- TrainingPod_ViewConeLock_Shared( player )
- player.PlayerCone_SetMaxPitch( 32 )
-}
-
-void function TrainingPod_ViewConeLock_SemiStrict( entity player )
-{
- player.PlayerCone_FromAnim()
- player.PlayerCone_SetMinYaw( -10 )
- player.PlayerCone_SetMaxYaw( 10 )
- player.PlayerCone_SetMinPitch( -10 )
- player.PlayerCone_SetMaxPitch( 10 )
-}
-
-void function TrainingPod_ViewConeLock_Strict( entity player )
-{
- player.PlayerCone_FromAnim()
- player.PlayerCone_SetMinYaw( 0 )
- player.PlayerCone_SetMaxYaw( 0 )
- player.PlayerCone_SetMinPitch( 0 )
- player.PlayerCone_SetMaxPitch( 0 )
-}
-
-
-// ==================================================
-// ============ CLIENT COMMAND CALLBACKS ============
-// ==================================================
-
-bool function ClientCommand_Training_SetInputType( entity player, array<string> args )
-{
- int inputType = args[0].tointeger()
-
- Assert( inputType == INPUT_TYPE_CONTROLLER || inputType == INPUT_TYPE_KBM )
- //printt( "Training- client input type updated:", inputType )
- file.playerInputType = inputType
- return true
-}
-
-bool function ClientCommand_Training_PlayerPressedUse( entity player, array<string> args )
-{
- FlagSet( "PlayerPressedUse" )
- return true
-}
-
-bool function ClientCommand_Training_PlayerReloaded( entity player, array<string> args )
-{
- FlagSet( "PlayerReloaded" )
- return true
-}
-
-bool function ClientCommand_LookTarget_Top( entity player, array<string> args )
-{
- player.ResetIdleTimer()
- printt( "ClientCommand_LookTarget_Top" )
- FlagSet( "PlayerLookedAtTopTarget" )
- return true
-}
-
-bool function ClientCommand_LookTarget_Bottom( entity player, array<string> args )
-{
- player.ResetIdleTimer()
- printt( "ClientCommand_LookTarget_Bottom" )
- FlagSet( "PlayerLookedAtBottomTarget" )
- return true
-}
-
-
-
-// ===============================
-// ============ DOORS ============
-// ===============================
-void function DoorOpenFast( string doorEntName )
-{
- entity door = GetEntByScriptName( doorEntName )
- door.Hide()
- door.NotSolid()
-
- entity navBlocker = door.GetLinkEnt()
- navBlocker.NotSolid()
- ToggleNPCPathsForEntity( navBlocker, true )
-}
-
-void function DoorCloseFast( string doorEntName )
-{
- entity door = GetEntByScriptName( doorEntName )
- door.Show()
- door.Solid()
-
- entity navBlocker = door.GetLinkEnt()
- navBlocker.Solid()
- ToggleNPCPathsForEntity( navBlocker, false )
-}
-
-
-void function OpenZenGardenExitDoor()
-{
- DoorOpenFast( "zengarden_door" )
-}
-
-void function CloseZenGardenExitDoor()
-{
- DoorCloseFast( "zengarden_door" )
-}
-
-void function OpenGauntletDoor()
-{
- DoorOpenFast( "gauntlet_door" )
-}
-
-
-
-// ===================================
-// ========= LOUDSPEAKER VO ==========
-// ===================================
-void function LoudspeakerVO_Setup()
-{
- vector loudspeakerPos = <10524, -9660, -5896> // HACK
- file.loudspeaker = CreateScriptMover( loudspeakerPos, <0,0,0> )
-
- // ======= PA ANNOUNCEMENTS: POD INTRO =======
- // "Inbound to Planet Typhon. Subspace rendezvous in approximately 20 minutes."
- RegisterLoudspeakerVO( "intro_0", "diag_sp_addtional_TR411_01_mcor_shipPA", 8.0 )
-
- // "Major Anderson, please report to the briefing room."
- RegisterLoudspeakerVO( "intro_1", "diag_sp_addtional_TR411_02_mcor_grunt1", 3.0 )
-
- // "Reminder to dock personnel: Titan ordnance is a Type 3 Hazardous Material."
- RegisterLoudspeakerVO( "intro_2", "diag_sp_addtional_TR411_03_mcor_shipPA", 6.0 )
-
- // "Captain Cole to communications."
- RegisterLoudspeakerVO( "intro_3", "diag_sp_addtional_TR411_04_mcor_grunt1", 3.0 )
-
- // "Running Lifeboat diagnostic test two point one. All Mark Eight lifeboats are in the green."
- RegisterLoudspeakerVO( "intro_4", "diag_sp_addtional_TR411_05_mcor_shipPA", 6.0 )
-
- // "3rd Militia Grenadiers - prep dropship MacAllan 17."
- RegisterLoudspeakerVO( "intro_5", "diag_sp_addtional_TR411_06_mcor_grunt1", 4.0 )
-
-
- // ======= PA ANNOUNCEMENTS: MEET OG =======
- // "Prepare for Typhon atmospheric entry in less than three minutes."
- RegisterLoudspeakerVO( "outro_01", "diag_sp_addtional_TR411_07_mcor_shipPA", 7.0 )
-
- // "Powering down all non-essential systems."
- RegisterLoudspeakerVO( "outro_01_1", "diag_sp_outro_TR171_01_01_mcor_shipPA", 4.0 )
-
- // "All personnel to battle stations."
- RegisterLoudspeakerVO( "outro_01_2", "diag_sp_outro_TR171_02_01_mcor_shipPA", 3.0 )
-
- // "This is not a drill."
- RegisterLoudspeakerVO( "outro_01_3", "diag_sp_outro_TR171_03_01_mcor_shipPA", 3.0 )
-
- // "Titan bays two through five, drop clearance confirmed."
- RegisterLoudspeakerVO( "outro_03", "diag_sp_addtional_TR411_09_mcor_shipPA", 5.0 )
-
- // "Infantry teams Stork three, Elk four, Shark six, Badger one, prepare for emergency atmospheric drop sequence"
- RegisterLoudspeakerVO( "outro_04", "diag_sp_addtional_TR411_10_mcor_grunt1", 7.0 )
-
- // "All available medical personnel, report to Med Central for tasking."
- RegisterLoudspeakerVO( "outro_05", "diag_sp_addtional_TR411_11_mcor_grunt2", 5.0 )
-
- // "Titan mech team - Rabbit six, prep the Vanguards."
- RegisterLoudspeakerVO( "outro_06", "diag_sp_addtional_TR411_12_mcor_grunt3", 4.0 )
-
- // "We need all Riflemen to docking bay four. Dropships standing by."
- RegisterLoudspeakerVO( "outro_07", "diag_sp_addtional_TR411_13_mcor_grunt1", 5.0 )
-
- // "Incoming hostile ship - Designation: IMS Malta. Battle stations."
- RegisterLoudspeakerVO( "outro_08", "diag_sp_addtional_TR411_14_mcor_shipPA", 6.0 )
-
- // "Special Recon Squad deploy from Drop Bay thirty-seven - now."
- RegisterLoudspeakerVO( "outro_10", "diag_sp_addtional_TR411_16_mcor_grunt2", 5.0 )
-
- // "Infantry teams 2nd Militia Fusiliers, Raptor three, target the IMS Malta."
- RegisterLoudspeakerVO( "outro_11", "diag_sp_addtional_TR411_17_mcor_grunt3", 6.0 )
-
- // "Caution - Fuel leak in Cargo Bay eighty - five. Decompressing for fire suppression."
- RegisterLoudspeakerVO( "outro_12", "diag_sp_addtional_TR411_18_mcor_shipPA", 6.0 )
-}
-
-void function RegisterLoudspeakerVO( string scriptAlias, string soundAlias, float duration = 6.0 )
-{
- Assert( !( scriptAlias in file.loudspeakerVO ), "duplicate scriptAlias " + scriptAlias )
-
- LoudspeakerVO_Info voInfo
- voInfo.scriptAlias = scriptAlias
- voInfo.soundAlias = soundAlias
- voInfo.duration = duration
-
- file.loudspeakerVO[ scriptAlias ] <- voInfo
-}
-
-void function PlayLoudspeakerVO( string scriptAlias, float delay = 0.0 )
-{
- Assert( scriptAlias in file.loudspeakerVO )
- LoudspeakerVO_Info voInfo = file.loudspeakerVO[ scriptAlias ]
-
- string soundAlias = voInfo.soundAlias
-
- if ( delay > 0 )
- wait delay
-
- entity emitter = file.loudspeaker
- emitter.Signal( "LoudspeakerVO_Stop" )
- emitter.EndSignal( "LoudspeakerVO_Stop" )
-
- OnThreadEnd(
- function() : ( emitter, soundAlias )
- {
- if ( IsValid( emitter ) )
- FadeOutSoundOnEntity( emitter, soundAlias, 2.0 )
- }
- )
-
- //printt( "playing loudspeaker VO", scriptAlias, "/", soundAlias )
- EmitSoundOnEntity( emitter, soundAlias )
- wait voInfo.duration
-}
-
-void function LoopLoudspeakerVO( array<string> scriptAliases, string endFlag = "", float minPause = -1, float maxPause = -1 )
-{
- if ( endFlag != "" )
- {
- if ( Flag( endFlag ) )
- return
-
- FlagEnd( endFlag )
- }
-
- while ( 1 )
- {
- foreach ( scriptAlias in scriptAliases )
- {
- waitthread PlayLoudspeakerVO( scriptAlias )
-
- if ( minPause > 0 && maxPause >= minPause )
- wait RandomFloatRange( minPause, maxPause )
- }
- }
-}
-
-
-
-// ==============================
-// ============ MISC ============
-// ==============================
-
-entity function Training_SpawnAnOG( entity startSpot )
-{
- entity og = CreateSoldier( TEAM_MILITIA, startSpot.GetOrigin(), startSpot.GetAngles() )
- og.kv.spawnflags = SF_NPC_ALLOW_SPAWN_SOLID
- DispatchSpawn( og )
-
- TakeAllWeapons( og )
-
- og.SetModel( OG_PILOT_MODEL )
-
- og.SetTitle( "#TRAINING_OG_PILOT_NAME" )
- ShowName( og )
-
- Training_OGPilot_SetHelmetOn( og, true )
-
- og.DisableHibernation()
- og.SetNoTarget( true )
- og.UseSequenceBounds( true )
- MakeInvincible( og )
- og.kv.scriptedAnimForceInterrupt = true
-
- og.DisableNPCFlag( NPC_ALLOW_FLEE | NPC_ALLOW_HAND_SIGNALS )
- og.SetHologram()
-
- return og
-}
-
-void function Training_OGPilot_SetHelmetOn( entity og, bool setOn )
-{
- int headIdx = og.FindBodyGroup( "head" )
-
- int submodelIdx = OG_PILOT_MODEL_HEAD_IDX_BARE
- if ( setOn )
- submodelIdx = OG_PILOT_MODEL_HEAD_IDX_HELMET
-
- og.SetBodygroup( headIdx, submodelIdx )
-
- /*
- int decalIdx = og.FindBodyGroup( "decal" )
- if ( decalIdx == -1 )
- return
-
- submodelIdx = OG_PILOT_MODEL_DECAL_IDX_BARE
- if ( setOn )
- submodelIdx = OG_PILOT_MODEL_DECAL_IDX
-
- og.SetBodygroup( decalIdx, submodelIdx )
- */
-}
-
-entity function Training_SpawnOGPilot( entity startSpot )
-{
- if ( IsValid( file.ogPilot ) )
- file.ogPilot.Destroy()
-
- entity og = Training_SpawnAnOG( startSpot )
- file.ogPilot = og
-
- return og
- }
-
-entity function Training_SpawnOGTwin( entity startSpot )
-{
- if ( IsValid( file.ogTwin ) )
- file.ogTwin.Destroy()
-
- entity ogTwin = Training_SpawnAnOG( startSpot )
- file.ogTwin = ogTwin
-
- return ogTwin
-}
-
-entity function GetOGPilot()
-{
- Assert( IsValid( file.ogPilot ) )
- return file.ogPilot
-}
-
-entity function GetOGTwin()
-{
- if ( !IsValid( file.ogTwin ) )
- return null
-
- return file.ogTwin
-}
-
-
-void function Training_OG_NagPlayerUntilFlag_Sitting( entity player, array<string> nagAliases, float nagInterval, entity idleRef, string endFlag, string talkAnim = "", string idleAnim = "" )
-{
- entity og = GetOGPilot()
- Training_NPC_NagPlayerUntilFlag_Sitting( og, player, nagAliases, nagInterval, idleRef, endFlag, talkAnim, idleAnim )
-}
-
-void function Training_OG_NagPlayerUntilFlag( entity player, array<string> nagAliases, float nagInterval, entity idleRef, string endFlag, string talkAnim = "", string idleAnim = "" )
-{
- entity og = GetOGPilot()
- Training_NPC_NagPlayerUntilFlag( og, player, nagAliases, nagInterval, idleRef, endFlag, talkAnim, idleAnim )
-}
-
-void function Training_NPC_NagPlayerUntilFlag_Sitting( entity npc, entity player, array<string> nagAliases, float nagInterval, entity idleRef, string endFlag, string talkAnim = "", string idleAnim = "" )
-{
- if ( talkAnim == "" )
- talkAnim = ANIM_OG_SITTING_TALK
-
- if ( idleAnim == "" )
- idleAnim = ANIM_OG_SITTING_IDLE
-
- Training_OG_NagPlayerUntilFlag( player, nagAliases, nagInterval, idleRef, endFlag, talkAnim, idleAnim )
-}
-
-void function Training_NPC_NagPlayerUntilFlag( entity npc, entity player, array<string> nagAliases, float nagInterval, entity idleRef, string endFlag, string talkAnim = "", string idleAnim = "" )
-{
- player.EndSignal( "OnDestroy" )
-
- if ( talkAnim == "" )
- talkAnim = ANIM_OG_STANDING_TALK
-
- if ( idleAnim == "" )
- idleAnim = ANIM_OG_STANDING_IDLE
-
- int nagIdx = 0
- float nextNagTime = Time() + nagInterval
-
- while ( !Flag( endFlag ) )
- {
- if ( Time() > nextNagTime )
- {
- waitthread Training_OG_Talks( nagAliases[nagIdx], idleRef, talkAnim, idleAnim, true )
- nextNagTime = Time() + nagInterval
-
- nagIdx++
- if ( nagIdx >= nagAliases.len() )
- nagIdx = 0
- }
-
- wait 0.1
- }
-}
-
-void function Training_OG_Talks_Sitting( string voScriptAlias, entity idleRef, string talkAnim = "", string idleAnim = "", bool useBlend = false )
-{
- entity og = GetOGPilot()
- Training_NPC_Talks_Sitting( og, voScriptAlias, idleRef, talkAnim, idleAnim, useBlend )
-}
-
-void function Training_OG_Talks_Leaning( string voScriptAlias, entity idleRef, string talkAnim = "", string idleAnim = "", bool useBlend = false )
-{
- entity og = GetOGPilot()
- Training_NPC_Talks_Leaning( og, voScriptAlias, idleRef, talkAnim, idleAnim, useBlend )
-}
-
-void function Training_OG_Talks( string voScriptAlias, entity idleRef, string talkAnim = "", string idleAnim = "", bool useBlend = false )
-{
- entity og = GetOGPilot()
- Training_NPC_Talks( og, voScriptAlias, idleRef, talkAnim, idleAnim, useBlend )
-}
-
-void function Training_OG_Idles_Sitting( entity idleRef, string anim = "", bool useBlend = false )
-{
- entity og = GetOGPilot()
- Training_NPC_Idles_Sitting( og, idleRef, anim, useBlend )
-}
-
-void function Training_OG_Idles_SittingAndTalking( entity idleRef, string anim = "", bool useBlend = false )
-{
- entity og = GetOGPilot()
- Training_NPC_Idles_SittingAndTalking( og, idleRef, anim, useBlend )
-}
-
-void function Training_OG_Idles_Talking( entity idleRef, string anim = "", bool useBlend = false )
-{
- entity og = GetOGPilot()
- Training_NPC_Idles_Talking( og, idleRef, anim, useBlend )
-}
-
-void function Training_OG_Idles( entity idleRef, string anim = "", bool useBlend = false )
-{
- entity og = GetOGPilot()
- thread Training_NPC_Idles( og, idleRef, anim, useBlend )
-}
-
-void function Training_OG_ScriptedAnim( entity idleRef, string anim, bool useBlend = false )
-{
- entity og = GetOGPilot()
- Training_NPC_ScriptedAnim( og, idleRef, anim, useBlend )
-}
-
-
-void function Training_NPC_Talks_Sitting( entity npc, string voScriptAlias, entity idleRef, string talkAnim = "", string idleAnim = "", bool useBlend = false )
-{
- if ( talkAnim == "" )
- talkAnim = ANIM_OG_SITTING_TALK
-
- if ( idleAnim == "" )
- idleAnim = ANIM_OG_SITTING_IDLE
-
- Training_NPC_Talks( npc, voScriptAlias, idleRef, talkAnim, idleAnim, useBlend )
-}
-
-void function Training_NPC_Talks_Leaning( entity npc, string voScriptAlias, entity idleRef, string talkAnim = "", string idleAnim = "", bool useBlend = false )
-{
- if ( talkAnim == "" )
- talkAnim = ANIM_OG_LEANING_TALK
-
- if ( idleAnim == "" )
- idleAnim = ANIM_OG_LEANING_IDLE
-
- Training_NPC_Talks( npc, voScriptAlias, idleRef, talkAnim, idleAnim, useBlend )
-}
-
-void function Training_NPC_Talks( entity npc, string voScriptAlias, entity idleRef, string talkAnim = "", string idleAnim = "", bool useBlend = false )
-{
- npc.EndSignal( "OnDestroy" )
- npc.EndSignal( "NPC_NewCommand" )
-
- if ( talkAnim == "" )
- talkAnim = ANIM_OG_STANDING_TALK
-
- if ( idleAnim == "" )
- idleAnim = ANIM_OG_STANDING_IDLE
-
- npc.Anim_Stop()
- if ( useBlend )
- thread PlayAnim( npc, talkAnim, idleRef )
- else
- thread PlayAnim( npc, talkAnim, idleRef, null, 0.0 )
-
- OnThreadEnd(
- function() : ( npc, idleRef, idleAnim, useBlend )
- {
- if ( IsValid( npc ) )
- Training_NPC_Idles( npc, idleRef, idleAnim, useBlend )
- }
- )
-
- waitthread PlayDialogue( voScriptAlias, npc )
-}
-
-void function Training_NPC_Idles_Sitting( entity npc, entity idleRef, string anim = "", bool useBlend = false )
-{
- if ( anim == "" )
- anim = ANIM_OG_SITTING_IDLE
-
- Training_NPC_Idles( npc, idleRef, anim, useBlend )
-}
-
-void function Training_NPC_Idles_SittingAndTalking( entity npc, entity idleRef, string anim = "", bool useBlend = false )
-{
- if ( anim == "" )
- anim = ANIM_OG_SITTING_TALK
-
- Training_NPC_Idles( npc, idleRef, anim, useBlend )
-}
-
-void function Training_NPC_Idles_Talking( entity npc, entity idleRef, string anim = "", bool useBlend = false )
-{
- if ( anim == "" )
- anim = ANIM_OG_STANDING_TALK
-
- thread Training_NPC_Idles( npc, idleRef, anim, useBlend )
-}
-
-void function Training_NPC_Idles( entity npc, entity idleRef, string anim = "", bool useBlend = false )
-{
- npc.Signal( "NPC_NewCommand" )
-
- if ( anim == "" )
- anim = ANIM_OG_STANDING_IDLE
-
- npc.Anim_Stop()
-
- if ( useBlend )
- thread PlayAnim( npc, anim, idleRef )
- else
- thread PlayAnim( npc, anim, idleRef, null, 0.0 )
-}
-
-void function Training_NPC_ScriptedAnim( entity npc, entity idleRef, string anim, bool useBlend = false )
-{
- npc.Signal( "NPC_NewCommand" )
-
- npc.Anim_Stop()
-
- if ( useBlend )
- PlayAnim( npc, anim, idleRef )
- else
- PlayAnim( npc, anim, idleRef, null, 0.0 )
-}
-
-void function Training_OG_Moves_ToSitting( entity moveToRef, string destAnim = "", float moveTimeOverride = -1 )
-{
- if ( destAnim == "" )
- destAnim = ANIM_OG_SITTING_IDLE
-
- Training_OG_Moves( moveToRef, destAnim, moveTimeOverride, true )
-}
-
-void function Training_OG_Moves( entity moveToRef, string destAnim = "", float moveTimeOverride = -1, bool destAnim_isSitting = false )
-{
- entity og = GetOGPilot()
- og.Signal( "NPC_NewCommand" )
-
- int ogAttachIdx = og.LookupAttachment( "CHESTFOCUS" )
- vector startOrigin = og.GetAttachmentOrigin( ogAttachIdx )
-
- const vector standingOffset = <0, 0, 42>
- const vector sittingOffset = <0, 0, 20>
- vector destHeightOffset = destAnim_isSitting ? sittingOffset : standingOffset
- vector endOrigin = moveToRef.GetOrigin() + destHeightOffset
-
- og.Freeze()
-
- file.ogPilot = null
-
- if ( IsValid( og ) )
- {
- og.NotSolid()
- DissolveGhost( og )
- }
-
- entity newOG = Training_SpawnOGPilot( moveToRef )
- newOG.Hide()
-
- entity mover = CreateScriptMover( startOrigin, <0,0,0> )
- int moverAttachIdx = mover.LookupAttachment( "REF" )
- EmitSoundOnEntity( mover, "og_dissolve_trail" )
- file.ogPathMover = mover
-
- newOG.EndSignal( "OnDestroy" )
- mover.EndSignal( "OnDestroy" )
-
- OnThreadEnd(
- function() : ( mover, newOG, moveToRef, destAnim_isSitting, destAnim, ogAttachIdx )
- {
- if ( IsValid( mover ) )
- {
- StopSoundOnEntity( mover, "og_dissolve_trail" )
- mover.Destroy()
- file.ogPathMover = null
- }
-
- if ( IsValid( newOG ) )
- {
- StartParticleEffectOnEntity( newOG, GetParticleSystemIndex( GHOST_FLASH_EFFECT ), FX_PATTACH_POINT, ogAttachIdx )
- newOG.Show()
-
- if ( destAnim_isSitting )
- Training_OG_Idles_Sitting( moveToRef, destAnim )
- else
- Training_OG_Idles( moveToRef, destAnim )
- }
- }
- )
-
- StartParticleEffectOnEntity( mover, GetParticleSystemIndex( GHOST_TRAIL_EFFECT ), FX_PATTACH_POINT_FOLLOW, moverAttachIdx )
- StartParticleEffectOnEntity( mover, GetParticleSystemIndex( GHOST_FLASH_EFFECT ), FX_PATTACH_POINT, moverAttachIdx )
- wait 0.5
-
- float moveSpeed = 1350.0
- float moveDist = Distance( startOrigin, endOrigin )
- float moveTime = moveDist / moveSpeed
- if ( moveTimeOverride > 0 )
- moveTime = moveTimeOverride
-
- float accel = moveTime * 0.1
- float decel = moveTime * 0.1
- mover.NonPhysicsMoveTo( endOrigin, moveTime, accel, decel )
- wait moveTime - 0.1
-
- EmitSoundAtPosition( TEAM_UNASSIGNED, endOrigin, "PathHologram_Materialized_training" )
- StartParticleEffectOnEntity( mover, GetParticleSystemIndex( GHOST_FLASH_EFFECT ), FX_PATTACH_POINT, moverAttachIdx )
- wait 0.1
-}
-
-entity function TeleportOG( string entName )
-{
- Assert( IsValid( file.ogPilot ) )
-
- file.ogPilot.Signal( "NPC_NewCommand" )
- file.ogPilot.Anim_Stop()
-
- entity teleportSpot = GetEntByScriptName( entName )
-
- vector org = teleportSpot.GetOrigin()
- vector ang = teleportSpot.GetAngles()
- file.ogPilot.SetOrigin( org )
- file.ogPilot.SetAngles( ang )
-
- return teleportSpot
-}
-
-void function NPC_DisableArrivals( entity npc )
-{
- printt( "disabling arrivals" )
- npc.EnableNPCMoveFlag( NPCMF_DISABLE_ARRIVALS )
-}
-
-void function NPC_EnableArrivals( entity npc )
-{
- printt( "enabling arrivals" )
- npc.DisableNPCMoveFlag( NPCMF_DISABLE_ARRIVALS )
-}
-
-
-void function PlayerAndOGTeleport_Fancy( entity player, vector destPos, string ogTeleportSpotName, vector destAng = < -1, -1, -1 > )
-{
- EndSignal( player, "OnDeath" )
- thread FancyTeleport_EffectsAndSound( player, destPos )
-
- player.WaitSignal( "FancyTeleportStart" )
-
- entity ogTeleportSpot = TeleportOG( ogTeleportSpotName )
- Training_OG_Idles_Sitting( ogTeleportSpot )
-
- MakeInvincible( player )
- WaitEndFrame() // player will take damage from random hazard triggers otherwise
-
- player.SetOrigin( destPos )
- if ( destAng != < -1, -1, -1 > )
- player.SetAngles( destAng )
-
- ClearInvincible( player )
-}
-
-void function FancyTeleport_EffectsAndSound( entity player, vector teleportPos )
-{
- EndSignal( player, "OnDeath" )
-
- float statusEffect_severity = 2.5
- float statusEffect_totalDuration = 0.8
- float statusEffect_easeOutTime = 0.1
- StatusEffect_AddTimed( player, eStatusEffect.timeshift_visual_effect, statusEffect_severity, statusEffect_totalDuration, statusEffect_easeOutTime )
-
- wait 0.1
-
- Remote_CallFunction_Replay( player, "ScriptCallback_PodTransition_PlayerScreenFX" )
-
- EmitSoundOnEntity( player, "Timeshift_Scr_DeviceShift2Present" )
-
- wait 0.25 // let screen FX fade screen
-
- player.Signal( "FancyTeleportStart" )
-
- //wait holdTime - 0.1
-
- wait 0.5 // let white screen fade
-
- EmitSoundOnEntity( player, "training_scr_zen_player_fall" )
-
- wait 0.2 // let screen clear before pulsing
-
- entity pulseFXHandle = PlayFX( FX_FANCY_TELEPORT_ENV_PULSE, teleportPos, <0,0,0> )
- EffectSetControlPointVector( pulseFXHandle, 1, <2.5,50,0> )
- thread KillFX_Delayed( pulseFXHandle, 0.5 )
-}
-
-entity function WaitForPlayerActiveWeapon( entity player )
-{
- player.EndSignal( "OnDestroy" )
-
- entity weapon = null
- while ( !weapon )
- {
- WaitFrame()
- weapon = player.GetActiveWeapon()
- }
-
- return weapon
-}
-
-
-void function GhostRecorder_RepeatUntilFlag( entity player, string endFlag, entity animRef, asset recordedAnim, float extraRepeatDelay = 0.0, bool silentDissolve = false )
-{
- EndSignal( player, "OnDestroy" )
- EndSignal( level, "StopRepeatingGhostRecorder" )
-
- if ( Flag( endFlag ) )
- return
- FlagEnd( endFlag )
-
- string dissolveSFX = "object_dissolve_training"
- if ( silentDissolve )
- dissolveSFX = ""
-
- table<int,entity> t = {}
- t[0] <- null
-
- OnThreadEnd(
- function() : ( t, dissolveSFX )
- {
- if ( !t.len() )
- return
-
- entity ghost = t[0]
-
- if ( IsValid( ghost ) )
- {
- StopSoundOnEntity( ghost, "PathHologram_Sustain_Loop_3P" )
- DissolveGhost( ghost, dissolveSFX )
- }
- }
- )
-
- var rec = LoadRecordedAnimation( recordedAnim )
- float duration = GetRecordedAnimationDuration( rec )
-
- const float ghostFadeTime = 1.2
-
- while ( 1 )
- {
- entity ghost = CreateGhost( animRef.GetOrigin() )
- t[0] = ghost
-
- EmitSoundOnEntity( ghost, "PathHologram_Sustain_Loop_3P" )
-
- ghost.PlayRecordedAnimation( rec, <0,0,0>, <0,0,0>, DEFAULT_SCRIPTED_ANIMATION_BLEND_TIME, animRef )
- wait duration - ghostFadeTime
-
- DissolveGhost( ghost, dissolveSFX )
-
- wait ghostFadeTime
- wait extraRepeatDelay
- }
-}
-
-void function Training_TeleportEffect( entity player )
-{
- player.EndSignal( "OnDestroy" )
-
- player.MovementDisable()
-
- OnThreadEnd(
- function() : ( player )
- {
- if ( IsValid( player ) )
- player.MovementEnable()
- }
- )
-
- float fadeTime = 0.3
- float holdTime = 0.5
-
- ScreenFade( player, 255, 255, 255, 254, fadeTime, holdTime, FFADE_IN | FFADE_PURGE )
- EmitSoundOnEntity( player, "NPE_VisualImpair" )
- wait fadeTime
- wait holdTime
- FadeOutSoundOnEntity( player, "NPE_VisualImpair", fadeTime )
-}
-
-void function TakeAmmoFromPlayerASAP( entity player )
-{
- player.EndSignal( "OnDestroy" )
-
- entity weapon = WaitForPlayerActiveWeapon( player )
-
- array<entity> weapons = player.GetMainWeapons()
-
- foreach ( weapon in weapons )
- {
- weapon.SetWeaponPrimaryAmmoCount( 0 )
- weapon.SetWeaponPrimaryClipCount( 0 )
- }
-
- // take offhand weapons player may have collected
- array<entity> offhands = player.GetOffhandWeapons()
- foreach ( index, weapon in clone offhands )
- player.TakeOffhandWeapon( index )
-}
-
-void function Training_WeaponPickups_Init( entity player )
-{
- Assert( Flag( "EntitiesDidLoad" ) )
-
- LeveledScriptedWeapons leveledScriptedWeapons = GetAllLeveledScriptWeapons()
-
- foreach ( ent in leveledScriptedWeapons.infoTargets )
- thread Training_RecreateWeaponPickup_Think( ent, player )
-}
-
-void function Training_SetWeaponPickupsEmptyAmmo()
-{
- file.weaponPickupsHaveAmmo = false
-
- LeveledScriptedWeapons leveledScriptedWeapons = GetAllLeveledScriptWeapons()
- foreach ( ent in leveledScriptedWeapons.infoTargets )
- {
- // fix for player picking up a weapon right before calling this- attachedEnt is empty because it hasn't been recreated yet
- // - actual fix is to thread, wait for attachedEnts to get the recreated weapon again, and timeout, but going with less risk for now
- if ( !ent.e.attachedEnts.len() )
- continue
-
- entity weaponEnt = ent.e.attachedEnts[0]
- if ( !IsValid( weaponEnt ) )
- continue
-
- weaponEnt.SetWeaponPrimaryAmmoCount( 0 )
- weaponEnt.SetWeaponPrimaryClipCount( 0 )
- }
-}
-
-void function Training_SetWeaponPickupsFullAmmo()
-{
- file.weaponPickupsHaveAmmo = true
-
- LeveledScriptedWeapons leveledScriptedWeapons = GetAllLeveledScriptWeapons()
- foreach ( ent in leveledScriptedWeapons.infoTargets )
- {
- // fix for player picking up a weapon right before calling this- attachedEnt is empty because it hasn't been recreated yet
- // - actual fix is to thread, wait for attachedEnts to get the recreated weapon again, and timeout, but going with less risk for now
- if ( !ent.e.attachedEnts.len() )
- continue
-
- entity weaponEnt = ent.e.attachedEnts[0]
- if( !IsValid( weaponEnt ) )
- continue
-
- string weaponClass = weaponEnt.GetWeaponClassName()
- int defaultTotal = GetWeaponInfoFileKeyField_GlobalInt( weaponClass, "ammo_default_total" )
- int defaultMag = GetWeaponInfoFileKeyField_GlobalInt( weaponClass, "ammo_clip_size" )
-
- weaponEnt.SetWeaponPrimaryAmmoCount( defaultTotal )
- }
-}
-
-void function Training_RecreateWeaponPickup_Think( entity ent, entity player )
-{
- EndSignal( player, "OnDestroy" )
- EndSignal( ent, "OnDestroy" )
-
- const float MATCHING_PICKUP_DIST = 0.5
- const float NEARBY_SIMILAR_DIST = 200.0
-
- string pickupEntWeaponClass = ent.GetValueForKey( "script_weapon" )
-
- while ( ent.e.attachedEnts.len() && IsValid( ent.e.attachedEnts[0] ) )
- {
- entity weaponEnt = ent.e.attachedEnts[0]
-
- while ( IsValid( weaponEnt ) && !weaponEnt.GetOwner() )
- wait 0.1
-
- // this is the most reliable way to get a good push vector for if we need to kick another weapon out (pickup ent angles are often not optimal)
- vector playerPos_onPickup = player.GetOrigin()
- vector vecToPlayer_whenPickedUp = Normalize( playerPos_onPickup - ent.GetOrigin() )
-
- ent.e.attachedEnts.remove( 0 )
-
- wait 2.2 // don't respawn it right away
-
- bool oldWeapon_similarPickupNearby = false
- bool pickupEnt_similarPickupNearby = false
-
- // previous player weapon may be here after swapping
- array<entity> allPickups = GetWeaponArray( true )
- entity oldWeapon
- foreach ( pickup in allPickups )
- {
- float distToThisPickup = Distance( pickup.GetOrigin(), ent.GetOrigin() )
- if ( distToThisPickup <= MATCHING_PICKUP_DIST )
- {
- oldWeapon = pickup
- break
- }
- }
-
- if ( IsValid( oldWeapon ) )
- {
- foreach ( pickup in allPickups )
- {
- if ( oldWeapon == pickup )
- continue
-
- float distToThisPickup = Distance( pickup.GetOrigin(), ent.GetOrigin() )
- if ( distToThisPickup <= NEARBY_SIMILAR_DIST )
- {
- string pickupWeaponClass = pickup.GetWeaponClassName()
-
- if ( pickupWeaponClass == oldWeapon.GetWeaponClassName() && !oldWeapon_similarPickupNearby )
- {
- //printt( "found similar pickup nearby to one the player dropped:", pickupWeaponClass )
- oldWeapon_similarPickupNearby = true
- }
-
- if ( pickupWeaponClass == pickupEntWeaponClass && !pickupEnt_similarPickupNearby )
- {
- //printt( "found similar pickup nearby to one that would be recreated:", pickupWeaponClass )
- pickupEnt_similarPickupNearby = true
- }
- }
- }
- }
-
- bool recreatePickup = true
- bool destroyOldWeapon = false
- if ( IsValid( oldWeapon ) )
- {
- if ( oldWeapon.GetWeaponClassName() == pickupEntWeaponClass )
- {
- printt( "old weapon that is here is the same kind of weapon as we would spawn, so don't recreate:", pickupEntWeaponClass )
- recreatePickup = false // old weapon that is here is the same kind of weapon as we would spawn, so don't recreate
- }
-
- if ( oldWeapon_similarPickupNearby )
- {
- printt( "Old weapon can be destroyed, because a similar pickup is nearby:", oldWeapon.GetWeaponClassName() )
- destroyOldWeapon = true
- }
-
- if ( !oldWeapon_similarPickupNearby && pickupEnt_similarPickupNearby )
- {
- printt( "old weapon is unique to this area and pickup ent has a similar pickup nearby, so don't recreate pickup ent. Old weapon:", oldWeapon.GetWeaponClassName(), "/ pickup ent class:", pickupEntWeaponClass )
- recreatePickup = false
- }
- }
-
- if ( recreatePickup )
- {
- if ( IsValid( oldWeapon ) )
- {
- if ( destroyOldWeapon )
- {
- printt( "destroying old weapon because similar pickup is nearby:", oldWeapon.GetWeaponClassName() )
- oldWeapon.Destroy()
- }
- else
- {
- MoveOldWeapon( ent, oldWeapon, vecToPlayer_whenPickedUp ) // kick the old weapon out of this spot
- }
- }
-
- // cover respawn with a flash effect
- EmitSoundAtPosition( TEAM_UNASSIGNED, ent.GetOrigin(), "training_scr_rack_weapon_appear" )
- StartParticleEffectInWorld( GetParticleSystemIndex( GHOST_FLASH_EFFECT ), ent.GetOrigin(), ent.GetAngles() )
- CreateScriptWeapon( ent )
-
- // defensive checks
- if ( !ent.e.attachedEnts.len() || !IsValid( ent.e.attachedEnts[0] ) )
- {
- printt( "WARNING! Recreated script pickup FAILED to recreate:", pickupEntWeaponClass, "on ent", ent )
- continue
- }
-
- entity recreatedPickup = ent.e.attachedEnts[0]
- printt( "training: recreated weapon pickup:", pickupEntWeaponClass, "by spawning:", recreatedPickup )
-
- if ( !file.weaponPickupsHaveAmmo )
- {
- recreatedPickup.SetWeaponPrimaryAmmoCount( 0 )
- recreatedPickup.SetWeaponPrimaryClipCount( 0 )
- }
- }
- else
- {
- if ( IsValid( oldWeapon ) )
- ent.e.attachedEnts.append( oldWeapon )
- }
- }
-
- printt( "WARNING- Stopping think on pickupEntWeapon:", pickupEntWeaponClass )
-}
-
-void function MoveOldWeapon( entity pickupEnt, entity oldWeapon, vector pushVec = <0,0,0> )
-{
- // recreate weapon as unconstrained so we can physics push it
- entity recreatedOldWeapon = Training_RecreatePlayerWeaponPickup( oldWeapon )
- string recreatedClassName = recreatedOldWeapon.GetWeaponClassName()
-
- float velocityScalar = 300.0
-
- var hasSubClass = GetWeaponInfoFileKeyField_Global( recreatedClassName, "weaponSubClass" )
- if ( hasSubClass )
- {
- string weaponSubClass = GetWeaponInfoFileKeyField_GlobalString( recreatedClassName, "weaponSubClass" )
-
- switch ( weaponSubClass )
- {
- case "offhand":
- case "pistol":
- velocityScalar = 200
- break
-
- case "smg":
- velocityScalar = 300
- break
-
- case "rifle":
- velocityScalar = 400
- break
-
- case "lmg":
- case "at":
- velocityScalar = 500
- break
- }
- }
-
- if ( pushVec == <0,0,0> )
- pushVec = AnglesToForward( pickupEnt.GetAngles() )
-
- //vector pushAng = VectorToAngles( pushVec )
- //vector addVec = AnglesToUp( pushAng ) * (velocityScalar * 0.2)
- //pushVec += addVec
- pushVec += <0,0,1>
-
- printt( "moving old weapon:", oldWeapon.GetWeaponClassName(), "with velocity scalar:", velocityScalar )
- recreatedOldWeapon.SetVelocity( pushVec * velocityScalar )
-}
-
-entity function Training_RecreatePlayerWeaponPickup( entity oldWeapon )
-{
- if ( file.scriptCreatedWeaponPickups.len() >= MAX_RECREATED_OLD_WEAPONS )
- {
- entity cleanupWeapon = file.scriptCreatedWeaponPickups[0]
-
- if ( IsValid( cleanupWeapon ) )
- cleanupWeapon.Destroy()
-
- file.scriptCreatedWeaponPickups.remove( 0 )
- }
-
- string oldWeaponClass = oldWeapon.GetWeaponClassName()
-
- entity weapon = CreateWeaponEntityByNameWithPhysics( oldWeaponClass, oldWeapon.GetOrigin(), oldWeapon.GetAngles() )
- weapon.SetVelocity( <0,0,0> )
-
- SetTargetName( weapon, "_old_player_weapon_" + oldWeaponClass )
- weapon.kv.fadedist = -1
-
- array<string> existingMods = oldWeapon.GetMods()
- weapon.SetMods( existingMods )
-
- bool doMarkAsLoadoutPickup = false
- if ( doMarkAsLoadoutPickup )
- weapon.MarkAsLoadoutPickup()
-
- HighlightWeapon( weapon )
-
- oldWeapon.Destroy()
-
- file.scriptCreatedWeaponPickups.append( weapon )
-
- return weapon
-}
-
-
-void function Training_WeaponRacks_SetSolidity( bool doSolid )
-{
- array<entity> racks = GetEntArrayByScriptName( "ineedguns_racks" )
-
- foreach ( rack in racks )
- {
- if ( doSolid )
- rack.Solid()
- else
- rack.NotSolid()
- }
-}
-
-
-bool function GetAutosprintEnabled()
-{
- int autosprintSetting = GetConVarInt( AUTOSPRINT_CONVAR_NAME )
- bool autoSprintEnabled = autosprintSetting > 0 && autosprintSetting < 3 // 0 = none, 3 = titans only
- return autoSprintEnabled
-}
-
-
-void function EmitSoundOnEntity_Delayed( entity ent, string alias, float delay )
-{
- ent.EndSignal( "OnDestroy" )
-
- if ( delay > 0 )
- wait delay
-
- EmitSoundOnEntity( ent, alias )
-}
-
-void function PlayFXOnEntity_Delayed( entity player, asset fxAsset, entity ent, float delay )
-{
- player.EndSignal( "OnDestroy" )
- ent.EndSignal( "OnDeath" )
-
- wait delay
-
- PlayFXOnEntity( fxAsset, ent )
-}
-
-void function KillFX_Delayed( entity fxHandle, float delay )
-{
- fxHandle.EndSignal( "OnDestroy" )
-
- if ( delay > 0.0 )
- wait delay
-
- KillFX( fxHandle )
-}
-
-void function KillFX( entity fxHandle )
-{
- if ( !IsValid_ThisFrame( fxHandle ) )
- return
-
- fxHandle.SetStopType( "DestroyImmediately" )
- fxHandle.ClearParent()
- fxHandle.Destroy()
-}
-
-void function KillFXWithEndcap( entity fxHandle, float killDelay = 1.0 )
-{
- if ( !IsValid_ThisFrame( fxHandle ) )
- return
-
- EffectStop( fxHandle )
- wait killDelay
-
- if ( !IsValid_ThisFrame( fxHandle ) )
- return
-
- fxHandle.ClearParent()
- fxHandle.Destroy()
-}
-
-
-void function FlagSetDelayed( string setFlag, float delay )
-{
- thread FlagSetDelayed_Think( setFlag, delay )
-}
-
-void function FlagSetDelayed_Think( string setFlag, float delay )
-{
- EndSignal( level, "OnDestroy" )
-
- if ( delay > 0 )
- wait delay
-
- FlagSet( setFlag )
-}
-
-
-void function Training_PlayerQuickdeathSFX( entity player )
-{
- EndSignal( player, "OnDestroy" )
-
- while ( 1 )
- {
- WaitSignal( player, "QuickDeath" )
- EmitSoundOnEntity( player, "training_scr_zen_player_fall" )
- }
-}
-
-
-void function Training_EnvArtColorCorrection_SetEnabled( bool isEnabled )
-{
- Assert( IsValid( file.envArt_colorCorrectionEnt ), "Called too early?" )
-
- string setEnabledStr = "Disable"
- if ( isEnabled)
- setEnabledStr = "Enable"
-
- EntFireByHandle( file.envArt_colorCorrectionEnt, setEnabledStr, "", 0, null, null )
-}
-
-
-void function SetDoF_Hangar( entity player )
-{
- Remote_CallFunction_Replay( player, "ScriptCallback_DoF_SetNearDepth", 0, 18 )
- Remote_CallFunction_Replay( player, "ScriptCallback_DoF_SetFarDepth", 450, 1250 )
-}
-
-void function SetDoF_Default( entity player )
-{
- Remote_CallFunction_Replay( player, "ScriptCallback_DoF_SetNearDepthToDefault" )
- Remote_CallFunction_Replay( player, "ScriptCallback_DoF_SetFarDepthToDefault" )
-}
-
-void function RackDoF_NearDepth( entity player, float nearDepthStart, float nearDepthEnd, float rackTime )
-{
- Remote_CallFunction_Replay( player, "ScriptCallback_DoF_SetNearDepth", nearDepthStart, nearDepthEnd, rackTime )
-}
-
-void function RackDOF_NearDepth_ToDefault( entity player, float duration )
-{
- Remote_CallFunction_Replay( player, "ScriptCallback_DoF_SetNearDepthToDefault", duration )
-}
-
-void function RackDoF_FarDepth( entity player, float farDepthStart, float farDepthEnd, float rackTime )
-{
- Remote_CallFunction_Replay( player, "ScriptCallback_DoF_SetFarDepth", farDepthStart, farDepthEnd, rackTime )
-}
-
-void function SimpleScreenShake( entity player, float duration, float amplitude, float blurMaxIntensity = 0.75 )
-{
- Remote_CallFunction_Replay( player, "ScriptCallback_SimpleScreenShake", duration, amplitude, blurMaxIntensity )
-}
-
-void function SetWeaponHUDEnabled( entity player, bool setEnabled )
-{
- file.displayWeaponHUD = setEnabled
- Remote_CallFunction_Replay( player, "ScriptCallback_SetWeaponHUDEnabled", setEnabled )
-}
-
-
-
-// ---------------------
-// ----- SKIT GUYS -----
-// ---------------------
-SkitGuyInfo function AddSkitGuy_Manually( string name, entity guy )
-{
- if ( SkitGuyExists( name ) )
- DeleteSkitGuy( GetSkitGuyInfo_ByName( name ) )
-
- SkitGuyInfo info
- info.id = file.skitguys.len()
- info.guy = guy
- info.name = name
-
- file.skitguys.append( info )
-
- return info
-}
-
-SkitGuyInfo function SpawnSkitGuy( string name, string anim, vector origin, vector angles, int team = TEAM_IMC, string aiSettings = "", string weapon = "mp_weapon_semipistol", bool isRunner = false )
-{
- if ( SkitGuyExists( name ) )
- DeleteSkitGuy( GetSkitGuyInfo_ByName( name ) )
-
- string guyType = "grunt"
- if ( name.find( "marvin" ) != null )
- guyType = "marvin"
-
- // spawn the guy
- entity guy
- if ( guyType == "marvin" )
- {
- Assert( !isRunner, "Marvins don't run!" )
-
- guy = CreateEntity( "npc_marvin" )
-
- DispatchSpawn( guy )
-
- SetTeam( guy, TEAM_SPECTATOR )
- guy.SetNPCMoveSpeedScale( 0.6 )
-
- //TakeAllJobs( guy )
- }
- else
- {
- guy = CreateSoldier( team, <0,0,0>, <0,0,0> ) // spawn the guy at worldspawn to avoid "npc spawned in solid" red text`
- SetSpawnOption_Weapon( guy, weapon )
- if ( aiSettings != "" )
- SetSpawnOption_AISettings( guy, aiSettings )
-
- if ( isRunner )
- guy.kv.alwaysAlert = 1
-
- DispatchSpawn( guy )
- }
-
- guy.SetTitle( "" )
-
- entity ref = CreateOwnedScriptMover( guy )
- ref.SetOrigin( origin )
- ref.SetAngles( angles )
-
- guy.SetOrigin( ref.GetOrigin() )
- guy.SetAngles( ref.GetAngles() )
-
- MakeInvincible( guy )
- guy.SetEfficientMode( true )
- guy.EnableNPCFlag( NPC_IGNORE_ALL | NPC_DISABLE_SENSING )
- guy.DisableNPCFlag( NPC_ALLOW_PATROL | NPC_ALLOW_INVESTIGATE | NPC_ALLOW_FLEE | NPC_ALLOW_HAND_SIGNALS )
-
- SkitGuyInfo info
- info.id = file.skitguys.len()
- info.guy = guy
- info.skitRef = ref
- info.skitAnim = anim
- info.name = name
-
- file.skitguys.append( info )
-
- return info
-}
-
-void function SpawnSkitGuy_AndRun( string name, array<Point> path, float moveSpeedScale, int team, string aiSettings = "", string weaponName = "" )
-{
- SkitGuyInfo runnerInfo
- runnerInfo = SpawnSkitGuy( name, "", path[0].origin, path[0].angles, team, aiSettings, weaponName, true )
-
- entity runner = runnerInfo.guy
- EndSignal( runner, "OnDestroy" )
-
- OnThreadEnd(
- function() : ( runnerInfo )
- {
- DeleteSkitGuy( runnerInfo )
- }
- )
-
- waitthread ScriptedPath_Run( runnerInfo, path, moveSpeedScale )
-}
-
-void function SpawnSkitGuy_AndRunForever( string name, array<Point> path, float moveSpeedScale, int team, string aiSettings = "", string weaponName = "" )
-{
- SkitGuyInfo runnerInfo
- while ( 1 )
- {
- runnerInfo = SpawnSkitGuy( name, "", path[0].origin, path[0].angles, team, aiSettings, weaponName )
- waitthread ScriptedPath_Run( runnerInfo, path, moveSpeedScale )
- }
-}
-
-void function SkitGuy_PlayAnim( SkitGuyInfo info, float skipAheadTime = 0 )
-{
- Assert( info.skitAnim != "" )
- Assert( IsValid( info.skitRef ) )
-
- entity guy = info.guy
-
- thread PlayAnim( guy, info.skitAnim, info.skitRef, null, 0.0, skipAheadTime )
-}
-
-bool function SkitGuyExists( string name )
-{
- foreach ( info in file.skitguys )
- {
- if ( info.name == name )
- return true
- }
-
- return false
-}
-
-SkitGuyInfo function GetSkitGuyInfo_ByName( string guyName )
-{
- SkitGuyInfo thisInfo
- foreach ( info in file.skitguys )
- {
- if ( info.name == guyName )
- {
- thisInfo = info
- return thisInfo
- }
- }
-
- Assert( false, "couldn't find skit guy info by name: " + guyName )
- unreachable
-}
-
-void function DeleteAllSkitGuys()
-{
- array<string> deleteNames = []
-
- foreach ( skitInfo in file.skitguys )
- deleteNames.append( skitInfo.name )
-
- foreach ( name in deleteNames )
- {
- if ( !SkitGuyExists( name ) )
- continue
-
- SkitGuyInfo deleteInfo = GetSkitGuyInfo_ByName( name )
- DeleteSkitGuy( deleteInfo )
- }
-}
-
-void function DeleteSkitGuy( SkitGuyInfo info )
-{
- KillSkitGuy( info )
-
- int removeIdx = -1
- foreach ( idx, guyInfo in file.skitguys )
- {
- if ( guyInfo.id == info.id )
- {
- removeIdx = idx
- break
- }
- }
-
- if ( removeIdx == -1 )
- {
- printt( "WARNING: SkitGuy was already deleted!" )
- return
- }
-
-
- file.skitguys.remove( removeIdx )
-}
-
-void function KillSkitGuy( SkitGuyInfo info )
-{
- entity guy = info.guy
- entity skitRef = info.skitRef
-
- if ( IsValid( skitRef ) )
- skitRef.Destroy()
-
- info.skitRef = null
-
- if ( IsAlive( guy ) )
- {
- guy.Anim_Stop()
- ClearInvincible( guy )
- }
-
- if ( IsValid( guy ) )
- guy.Destroy()
-
- info.guy = null
-}
-
-#if DEV
-string function NudgeSkitGuy( string name, float offsetX, float offsetY = 0.0, float offsetZ = 0.0 )
-{
- if ( !SkitGuyExists( name ) )
- {
- return "WARNING: SKIT GUY NAME NOT RECOGNIZED: " + name
- }
-
- SkitGuyInfo info = GetSkitGuyInfo_ByName( name )
- entity guy = info.guy
- entity skitRef = info.skitRef
- string name = info.name
-
- vector offset = <offsetX, offsetY, offsetZ>
-
- if ( IsValid( skitRef ) )
- skitRef.SetOrigin( skitRef.GetOrigin() + offset )
- else
- guy.SetOrigin( guy.GetOrigin() + offset )
-
- if ( info.skitAnim != "" )
- SkitGuy_PlayAnim( info )
-
- printt( "NUDGED:")
- return PrintSkitGuy( info )
-}
-
-string function PrintSkitGuy( SkitGuyInfo info )
-{
- entity guy = info.guy
- entity skitRef = info.skitRef
- string name = info.name
-
- string returnStr = name + " origin/angles: " + CreateOriginAnglesString( guy.GetOrigin(), guy.GetAngles() )
- if ( IsValid( skitRef ) )
- returnStr = name + " ref origin/angles: " + CreateOriginAnglesString( skitRef.GetOrigin(), skitRef.GetAngles() )
-
- return returnStr
-}
-#endif //DEV
-
-
-
-// ------------------------------
-// ----- SCRIPTED NPC PATHS -----
-// ------------------------------
-void function ScriptedPath_AddPoint( array<Point> pathpoints, vector origin, vector angles )
-{
- Point pathpoint
- pathpoint.origin = origin
- pathpoint.angles = angles
-
- pathpoints.append( pathpoint )
-}
-
-void function ScriptedPath_Walk( SkitGuyInfo info, array<Point> path, float moveSpeedScale = 0.8, string idleAnim = "" )
-{
- NPC_ScriptedPath( SCRIPTED_PATH_WALK, info, path, moveSpeedScale, idleAnim )
-}
-
-void function ScriptedPath_Run( SkitGuyInfo info, array<Point> path, float moveSpeedScale = 1.0, string idleAnim = "" )
-{
- NPC_ScriptedPath( SCRIPTED_PATH_RUN, info, path, moveSpeedScale, idleAnim )
-}
-
-void function NPC_ScriptedPath( int pathFollowType, SkitGuyInfo info, array<Point> path, float moveSpeedScale = 1.0, string idleAnim = "" )
-{
- entity guy = info.guy
-
- guy.EndSignal( "OnDestroy" )
-
- guy.Anim_Stop()
-
- guy.EnableNPCMoveFlag( NPCMF_DISABLE_MOVE_TRANSITIONS )
- guy.EnableNPCMoveFlag( NPCMF_DISABLE_ARRIVALS )
- guy.SetNPCMoveSpeedScale( moveSpeedScale )
-
- if ( pathFollowType == SCRIPTED_PATH_RUN )
- guy.SetAlert() // change his alert state so he will run
-
- if ( pathFollowType == SCRIPTED_PATH_WALK )
- guy.SetMoveAnim( "patrol_walk_bored" )
-
- string waitSignal = "OnEnterGoalRadius" //"OnFinishedAssault"
- float pathfindingFailTimeout = 20.0
-
- guy.SetOrigin( path[0].origin )
- guy.SetAngles( path[0].angles )
-
- for ( int i = 1; i < path.len(); i++ )
- {
- Point pathpoint = path[i]
- float goalradius = 64.0 // MINIMUM
- //guy.DisableArrivalOnce( true ) // always want arrivals disabled because they are blended from run anim, not walking
-
- guy.AssaultPoint( pathpoint.origin )
- guy.AssaultSetGoalRadius( goalradius )
-
- WaitSignalTimeout( guy, pathfindingFailTimeout, waitSignal )
-
- if ( Distance( guy.GetOrigin(), pathpoint.origin ) >= goalradius )
- {
- printt( guy, " scripted pathfinding stopped, quitting." )
- break
- }
- }
-
- if ( idleAnim != "" )
- {
- guy.DisableBehavior( "Assault" )
-
- while ( !guy.IsInterruptable() )
- wait 0.1
-
- entity ref = CreateOwnedScriptMover( guy )
- thread PlayAnim( guy, idleAnim, ref, null, 0.4 )
-
- WaitForever()
- }
- else
- {
- DeleteSkitGuy( info )
- }
-}
-
-
-
-// -----------------------------
-// ----- TITAN GROUP SKITS -----
-// -----------------------------
-void function HangarTitanGroup_Init( HangarTitanGroup group )
-{
- group.rack_ogPos = group.rack.GetOrigin()
- group.rack_ogAng = group.rack.GetAngles()
-
- if ( IsValid( group.titan ) )
- {
- if ( group.titanSkin == -1 )
- group.titanSkin = 1
- }
-
- if ( group.marvinAnim != "" )
- {
- group.marvin = CreatePropDynamic( MARVIN_MODEL )
- group.marvin.DisableHibernation()
- }
-
- if ( group.pilotAnim != "" )
- {
- group.pilot = CreatePropDynamic( group.pilotModel )
- group.pilot.DisableHibernation()
- }
-
- HangarTitanGroup_SetMaxSequenceDuration( group )
-
- group.isInited = true
-}
-
-void function HangarTitanGroup_SetMaxSequenceDuration( HangarTitanGroup group )
-{
- table<string,entity> sceneActors = {}
- sceneActors[ group.titanAnim ] <- group.titan
- sceneActors[ group.rackAnim ] <- group.rack
- sceneActors[ group.marvinAnim ] <- group.marvin
-
- if ( IsValid( group.titan ) )
- {
- // set titan to use non posed model
- group.titan.SetModel( BUDDY_MODEL )
- group.titan.SetSkin( group.titanSkin )
- }
-
- float maxDuration = 0
- foreach ( anim, actor in sceneActors )
- {
- if ( !IsValid( actor ) )
- continue
-
- float animDuration = actor.GetSequenceDuration( anim )
- if ( animDuration > maxDuration )
- maxDuration = animDuration
- }
-
- group.sequenceDuration = maxDuration
-
- if ( IsValid( group.titan ) )
- {
- // set titan back to posed anim
- group.titan.SetModel( BUDDY_MODEL_POSED_NO_ANIMS )
- //group.titan.SetSkin( group.titanSkin )
- }
-}
-
-void function HangarTitanGroup_Animate( HangarTitanGroup group, string endFlag = "", float duration = -1, bool doCleanup = true )
-{
- if ( endFlag != "" )
- FlagEnd( endFlag )
-
- Assert( group.isInited, "Need to call HangarTitanGroup_Init on this group before using" )
-
- entity ref = group.ref
- entity titan = group.titan
- entity rack = group.rack
- entity marvin = group.marvin
- entity pilot = group.pilot
- string titanAnim = group.titanAnim
- string rackAnim = group.rackAnim
- string marvinAnim = group.marvinAnim
- string pilotAnim = group.pilotAnim
- float animInitialTime = group.animInitialTime
-
- EndSignal( rack, "OnDestroy" )
-
- if ( IsValid( marvin ) )
- EndSignal( marvin, "OnDestroy")
-
- if ( IsValid( titan ) )
- {
- EndSignal( titan, "OnDestroy" )
-
- // set titan to use non posed model
- titan.SetModel( BUDDY_MODEL )
- titan.SetSkin( group.titanSkin )
- }
-
- OnThreadEnd(
- function() : ( doCleanup, group )
- {
- if ( doCleanup )
- HangarTitanGroup_Cleanup( group )
- }
- )
-
- if ( duration == -1 || group.sequenceDuration < duration )
- duration = group.sequenceDuration
-
- thread PlayAnim( rack, rackAnim, ref, null, 0.0, animInitialTime )
-
- if ( IsValid( titan) )
- thread PlayAnim( titan, titanAnim, ref, null, 0.0, animInitialTime )
-
- if ( IsValid( marvin ) )
- thread PlayAnim( marvin, marvinAnim, ref, null, 0.0, animInitialTime )
-
- if ( IsValid( pilot ) )
- thread PlayAnim( pilot, pilotAnim, ref, null, 0.0, animInitialTime )
-
- wait duration
-}
-
-void function HangarTitanGroup_Cleanup( HangarTitanGroup group )
-{
- HangarTitanGroup_Reset( group )
-
- if ( IsValid( group.marvin ) )
- group.marvin.Destroy()
-
- if ( IsValid( group.pilot ) )
- group.pilot.Destroy()
-}
-
-void function HangarTitanGroup_Reset( HangarTitanGroup group )
-{
- entity titan = group.titan
- entity rack = group.rack
-
- if ( IsValid( titan ) )
- {
- titan.Anim_Stop()
- titan.SetModel( BUDDY_MODEL_POSED_NO_ANIMS )
- //titan.SetSkin( group.titanSkin )
- }
-
- if ( IsValid( rack ) )
- {
- rack.Anim_Stop()
- rack.SetOrigin( group.rack_ogPos )
- rack.SetAngles( group.rack_ogAng )
- }
-}
-
-
-
-#if DEV
-void function skyboxchange( string tName )
-{
- entity cam = GetEnt( tName )
- GetPlayerArray()[0].SetSkyCamera( cam )
-}
-
-
-// ======================================================
-// ============ GHOST RECORDER DEV FUNCTIONS ============
-// ======================================================
-void function wallruntest()
-{
- entity preWallrunRef = GetEntByScriptName( "basic_movement_wallrun_start_ref" )
- var rec = LoadRecordedAnimation( $"anim_recording/training_record_zengarden_wallrun.rpak" )
- file.ogPilot.Anim_Stop()
- file.ogPilot.PlayRecordedAnimation( rec, <0,0,0>, <0,0,0>, DEFAULT_SCRIPTED_ANIMATION_BLEND_TIME, preWallrunRef )
-}
-
-void function Record_ZenGarden_Wallrun()
-{
- thread RecordAnimation_Think( "training_record_zengarden_wallrun", "basic_movement_wallrun_start_ref" )
-}
-
-void function Record_ZenGarden_Slide()
-{
- thread RecordAnimation_Think( "training_record_zengarden_slide", "zengarden_slide_ref" )
-}
-
-void function Record_ZenGarden_DoubleJump()
-{
- thread RecordAnimation_Think( "training_record_zengarden_doublejump", "zengarden_doublejump_ref" )
-}
-
-void function RecordAnimation_Think( string filename, string refName )
-{
- entity player = file.player
- player.Signal( "RecordAnimation_Start" )
- player.EndSignal( "RecordAnimation_Start" )
-
- TeleportPlayerAndBT( refName )
-
- player.EndSignal( "OnDestroy" )
-
- entity ref = GetEntByScriptName( refName )
-
- printt( "READY TO RECORD: " + filename )
-
- //start recording
- player.WaitSignal( "ButtonPressedAttack" )
- printt( "RECORDING STARTED" )
-
- player.StartRecordingAnimation( ref.GetOrigin(), ref.GetAngles() )
-
- //stop
- player.WaitSignal( "ButtonPressedAttack" )
-
- var recording = player.StopRecordingAnimation()
-
-#if PC_PROG
- SaveRecordedAnimation( recording, filename )
-#endif
- printt( "STOP RECORD player org/ang:", player.GetOrigin(), player.GetAngles() )
-}
-#endif //DEV
diff --git a/Northstar.Custom/keyvalues/playlists_v2.txt b/Northstar.Custom/keyvalues/playlists_v2.txt
new file mode 100644
index 00000000..30ea6980
--- /dev/null
+++ b/Northstar.Custom/keyvalues/playlists_v2.txt
@@ -0,0 +1,572 @@
+playlists
+{
+ Gamemodes
+ {
+ sbox
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_sbox
+ lobbytitle #PL_sbox_lobby
+ description #PL_sbox_desc
+ abbreviation #PL_sbox_abbr
+
+ max_teams 1
+ classic_mp 0
+ }
+ }
+ fw
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_fw
+ lobbytitle #PL_fw_lobby
+ description #PL_fw_desc
+ abbreviation #PL_fw_abbr
+
+ max_players 16
+ max_teams 2
+ classic_mp 1
+ scorelimit 100 // score is a percentage so ofc need max to be 100%
+ }
+ }
+ gg
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_gg
+ lobbytitle #PL_gg_lobby
+ description #PL_gg_desc
+ hint #PL_gg_hint
+ abbreviation #PL_gg_abbr
+ max_players 12
+ max_teams 12
+ classic_mp 1
+
+ scorelimit 21 // temp until we have a way of dynamically setting non-default scorelimit in code
+
+ gamemode_score_hint #GAMEMODE_SCORE_HINT_FFA
+ gamemode_bullet_001 #GAMEMODE_BULLET_FFA_001
+ gamemode_bullet_002 #GAMEMODE_BULLET_FFA_002
+ gamemode_bullet_003 #GAMEMODE_BULLET_FFA_003
+ gamemode_bullet_004 #GAMEMODE_BULLET_FFA_004
+ gamemode_bullet_005 #GAMEMODE_BULLET_FFA_005
+ }
+ }
+ tt
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_tt
+ lobbytitle #PL_tt_lobby
+ description #PL_tt_desc
+ hint #PL_tt_hint
+ abbreviation #PL_tt_abbr
+ max_players 12
+ max_teams 2
+ classic_mp 1
+
+ scorelimit 20
+
+ gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
+ }
+ }
+ inf
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_inf
+ lobbytitle #PL_inf_lobby
+ description #PL_inf_desc
+ hint #PL_inf_hint
+ abbreviation #PL_inf_abbr
+ max_players 12
+ max_teams 2
+ classic_mp 1
+
+ gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
+ }
+ }
+ arena
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_arena
+ lobbytitle #PL_arena_lobby
+ description #PL_arena_desc
+ hint #PL_arena_hint
+ abbreviation #PL_arena_abbr
+ max_players 6
+ max_teams 2
+ classic_mp 1
+ boost_store_mode arena
+ boost_store_team_reserve 1
+ scorelimit 5
+ timelimit 2
+ roundtimelimit 2
+ roundscorelimit 5
+
+ gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
+ }
+ }
+ kr
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_kr
+ lobbytitle #PL_kr_lobby
+ description #PL_kr_desc
+ hint #PL_kr_hint
+ abbreviation #PL_kr_abbr
+
+ max_players 16
+ max_teams 16
+ classic_mp 1
+ timelimit 7.5
+ scorelimit 99999 // arbitrarily high number
+
+ gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
+ }
+ }
+ fastball
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_fastball
+ lobbytitle #PL_fastball_lobby
+ description #PL_fastball_desc
+ hint #PL_fastball_hint
+ abbreviation #PL_fastball_abbr
+
+ max_players 16
+ max_teams 2
+ classic_mp 1
+ scorelimit 5
+ timelimit 2
+ roundtimelimit 2
+ roundscorelimit 5
+
+ gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
+ }
+ }
+ ctf_comp
+ {
+ inherit defaults
+ vars
+ {
+ name #GAMEMODE_ctf_comp
+ lobbytitle #PL_capture_the_flag_lobby
+ description #PL_capture_the_flag_desc
+ hint #PL_capture_the_flag_hint
+ abbreviation #PL_capture_the_flag_abbr
+ image ctf
+ respawn_delay 8
+ scorelimit 5
+ suddendeath_timelimit 2
+ timelimit 12
+ max_players 10
+ phase_shift_drop_flag 1
+ ctf_flag_return_time 1
+ color "0 119 245 255"
+
+ gamemode_score_hint #GAMEMODE_SCORE_HINT_CTF
+ gamemode_bullet_001 #GAMEMODE_BULLET_CTF_001
+ gamemode_bullet_002 #GAMEMODE_BULLET_CTF_002
+ gamemode_bullet_003 #GAMEMODE_BULLET_CTF_003
+ gamemode_bullet_004 #GAMEMODE_BULLET_CTF_004
+ gamemode_bullet_005 #GAMEMODE_BULLET_CTF_005
+ }
+ }
+ }
+ Playlists
+ {
+ gg
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_gg
+ lobbytitle #PL_gg_lobby
+ description #PL_gg_desc
+ abbreviation #PL_gg_abbr
+ image varietypack
+ //mixtape_slot 7
+ mixtape_timeout 120
+ visible 0
+ }
+ gamemodes
+ {
+ gg
+ {
+ maps
+ {
+ mp_forwardbase_kodai 1
+ mp_grave 1
+ mp_homestead 1
+ mp_thaw 1
+ mp_black_water_canal 1
+ mp_eden 1
+ mp_drydock 1
+ mp_crashsite3 1
+ mp_complex3 1
+ mp_angel_city 1
+ mp_colony02 1
+ mp_glitch 1
+ mp_lf_stacks 1
+ mp_lf_deck 1
+ mp_lf_meadow 1
+ mp_lf_traffic 1
+ mp_lf_township 1
+ mp_lf_uma 1
+ mp_relic02 1
+ mp_wargames 1
+ mp_rise 1
+ }
+ }
+ }
+ }
+ tt
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_tt
+ lobbytitle #PL_tt_lobby
+ description #PL_tt_desc
+ hint #PL_tt_hint
+ abbreviation #PL_tt_abbr
+ visible 0
+ }
+ gamemodes
+ {
+ tt
+ {
+ maps
+ {
+ mp_forwardbase_kodai 1
+ mp_grave 1
+ mp_homestead 1
+ mp_thaw 1
+ mp_black_water_canal 1
+ mp_eden 1
+ mp_drydock 1
+ mp_crashsite3 1
+ mp_complex3 1
+ mp_angel_city 1
+ mp_colony02 1
+ mp_glitch 1
+ mp_relic02 1
+ mp_wargames 1
+ mp_rise 1
+ }
+ }
+ }
+ }
+ inf
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_inf
+ lobbytitle #PL_inf_lobby
+ description #PL_inf_desc
+ hint #PL_inf_hint
+ abbreviation #PL_inf_abbr
+ visible 0
+ }
+ gamemodes
+ {
+ inf
+ {
+ maps
+ {
+ mp_forwardbase_kodai 1
+ mp_grave 1
+ mp_homestead 1
+ mp_thaw 1
+ mp_black_water_canal 1
+ mp_eden 1
+ mp_drydock 1
+ mp_crashsite3 1
+ mp_complex3 1
+ mp_angel_city 1
+ mp_colony02 1
+ mp_glitch 1
+ mp_lf_stacks 1
+ mp_lf_deck 1
+ mp_lf_meadow 1
+ mp_lf_traffic 1
+ mp_lf_township 1
+ mp_lf_uma 1
+ mp_relic02 1
+ mp_wargames 1
+ mp_rise 1
+ }
+ }
+ }
+ }
+ arena
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_arena
+ lobbytitle #PL_arena_lobby
+ description #PL_arena_desc
+ hint #PL_arena_hint
+ abbreviation #PL_arena_abbr
+ max_players 6
+ max_teams 2
+ classic_mp 1
+ boost_store_mode arena
+ boost_store_team_reserve 1
+ scorelimit 5
+ timelimit 2
+ roundtimelimit 2
+ roundscorelimit 5
+
+ gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
+ }
+ gamemodes
+ {
+ arena
+ {
+ maps
+ {
+ mp_forwardbase_kodai 1
+ mp_grave 1
+ mp_homestead 1
+ mp_thaw 1
+ mp_black_water_canal 1
+ mp_eden 1
+ mp_drydock 1
+ mp_crashsite3 1
+ mp_complex3 1
+ mp_angel_city 1
+ mp_colony02 1
+ mp_glitch 1
+ mp_lf_stacks 1
+ mp_lf_deck 1
+ mp_lf_meadow 1
+ mp_lf_traffic 1
+ mp_lf_township 1
+ mp_lf_uma 1
+ mp_relic02 1
+ mp_wargames 1
+ mp_rise 1
+ }
+ }
+ }
+ }
+ kr
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_kr
+ lobbytitle #PL_kr_lobby
+ description #PL_kr_desc
+ hint #PL_kr_hint
+ abbreviation #PL_kr_abbr
+
+ max_players 16
+ max_teams 16
+ classic_mp 1
+ timelimit 7.5
+ scorelimit 99999 // arbitrarily high number
+ }
+ gamemodes
+ {
+ kr
+ {
+ maps
+ {
+ mp_forwardbase_kodai 1
+ mp_grave 1
+ mp_homestead 1
+ mp_thaw 1
+ mp_black_water_canal 1
+ mp_eden 1
+ mp_drydock 1
+ mp_crashsite3 1
+ mp_complex3 1
+ mp_angel_city 1
+ mp_colony02 1
+ mp_glitch 1
+ mp_lf_stacks 1
+ mp_lf_deck 1
+ mp_lf_meadow 1
+ mp_lf_traffic 1
+ mp_lf_township 1
+ mp_lf_uma 1
+ mp_relic02 1
+ mp_wargames 1
+ mp_rise 1
+ }
+ }
+ }
+ }
+ fastball
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_fastball
+ lobbytitle #PL_fastball_lobby
+ description #PL_fastball_desc
+ hint #PL_fastball_hint
+ abbreviation #PL_fastball_abbr
+
+ max_players 16
+ max_teams 2
+ classic_mp 1
+ scorelimit 5
+ roundtimelimit 2
+ roundscorelimit 5
+
+ gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
+ }
+ gamemodes
+ {
+ fastball
+ {
+ maps
+ {
+ mp_forwardbase_kodai 1
+ mp_grave 1
+ mp_homestead 1
+ mp_thaw 1
+ mp_black_water_canal 1
+ mp_eden 1
+ mp_drydock 1
+ mp_crashsite3 1
+ mp_complex3 1
+ mp_angel_city 1
+ mp_colony02 1
+ mp_glitch 1
+ mp_relic02 1
+ mp_wargames 1
+ mp_rise 1
+ }
+ }
+ }
+ }
+ fw
+ {
+ inherit defaults
+ vars
+ {
+ name #PL_fw
+ lobbytitle #PL_fw_lobby
+ description #PL_fw_desc
+ hint #PL_fw_hint
+ abbreviation #PL_fw_abbr
+
+ max_players 16
+ max_teams 2
+ classic_mp 1
+ scorelimit 100
+
+ gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
+ }
+ gamemodes
+ {
+ fw
+ {
+ maps
+ {
+ mp_forwardbase_kodai 1
+ mp_grave 1
+ mp_homestead 1
+ mp_thaw 1
+ mp_black_water_canal 1
+ mp_eden 1
+ mp_drydock 1
+ mp_crashsite3 1
+ mp_complex3 1
+ mp_angel_city 1
+ mp_colony02 1
+ mp_glitch 1
+ mp_relic02 1
+ mp_wargames 1
+ mp_rise 1
+ }
+ }
+ }
+ }
+ ctf_comp
+ {
+ inherit defaults
+ vars
+ {
+ name #GAMEMODE_ctf_comp
+ lobbytitle #PL_capture_the_flag_lobby
+ description #PL_capture_the_flag_desc
+ abbreviation #PL_capture_the_flag_abbr
+ image ctf
+ mixtape_slot 4
+ mixtape_timeout 120
+ visible 1
+
+ // comp-exclusive settings
+ // note: these don't display right on the private match menu yet
+ pilot_health_multiplier 1.25
+ respawn_delay 7.0
+
+ boosts_enabled 1 // this is actually disabled lol
+ earn_meter_pilot_overdrive 0
+ earn_meter_pilot_multiplier 0.5
+ earn_meter_titan_multiplier 0.5
+
+ scorelimit 6
+ timelimit 14
+ }
+ gamemodes
+ {
+ ctf
+ {
+ maps
+ {
+ mp_complex3 1
+ mp_drydock 1
+ mp_glitch 1
+ mp_homestead 2
+ mp_eden 1
+ mp_forwardbase_kodai 1
+ mp_black_water_canal 1
+ mp_glitch 1
+ mp_angel_city 1
+ mp_colony02 1
+ mp_relic02 1
+ mp_grave 1
+ mp_homestead 1
+ mp_drydock 1
+ mp_glitch 1
+ mp_thaw 1
+ mp_eden 2
+ mp_black_water_canal 1
+ mp_glitch 1
+ mp_relic02 1
+ mp_wargames 1
+ mp_rise 1
+ mp_crashsite3 1
+ mp_lf_stacks 1
+ mp_lf_deck 1
+ mp_lf_meadow 1
+ mp_lf_traffic 1
+ mp_lf_township 1
+ mp_lf_uma 1
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Northstar.Custom/keyvalues/scripts/weapons/mp_titanweapon_particle_accelerator.txt b/Northstar.Custom/keyvalues/scripts/weapons/mp_titanweapon_particle_accelerator.txt
new file mode 100644
index 00000000..a30ed8f8
--- /dev/null
+++ b/Northstar.Custom/keyvalues/scripts/weapons/mp_titanweapon_particle_accelerator.txt
@@ -0,0 +1,4 @@
+WeaponData
+{
+ "playermodel" "models/SPOILER_w_titan_particle_accelerator.mdl"
+}
diff --git a/Northstar.Custom/mod.json b/Northstar.Custom/mod.json
index 75a14291..d1ebeec3 100644
--- a/Northstar.Custom/mod.json
+++ b/Northstar.Custom/mod.json
@@ -1,25 +1,25 @@
{
- "ApiId" : "Northstar.Custom",
"Name" : "Northstar.Custom",
- "Description" : "Additional content for coop and custom multiplayer servers",
- "Authors" : [
- "BobTheBob"
- ],
- "Contacts" : [
- "BobTheBob#1150"
- ],
- "Version" : "0.1",
- "CustomScripts": [
+ "LoadPriority": 1,
+
+ "Scripts": [
{
"Path": "northstar_custom_autoprecache.gnut",
"RunOn": "( CLIENT || SERVER ) && MP",
- "ClientCallback": "NorthstarCustomAutoprecache",
- "ServerCallback": "NorthstarCustomAutoprecache",
+ "ClientCallback": {
+ "After": "NorthstarCustomAutoprecache"
+ },
+
+ "ServerCallback": {
+ "After": "NorthstarCustomAutoprecache"
+ }
},
{
"Path": "_northstar_devcommands.gnut",
"RunOn": "SERVER && MP",
- "ServerCallback": "NorthstarDevCommands_Init"
+ "ServerCallback": {
+ "After": "NorthstarDevCommands_Init"
+ }
},
{
@@ -30,8 +30,13 @@
{
"Path": "gamemodes/sh_gamemode_sbox.gnut",
"RunOn": "( CLIENT || SERVER ) && MP",
- "ClientPreCallback": "Sh_GamemodeSbox_Init",
- "ServerPreCallback": "Sh_GamemodeSbox_Init"
+ "ClientPreCallback": {
+ "Before": "Sh_GamemodeSbox_Init"
+ },
+
+ "ServerPreCallback": {
+ "Before": "Sh_GamemodeSbox_Init"
+ }
},
{
"Path": "gamemodes/_gamemode_sbox.gnut",
@@ -50,28 +55,58 @@
{
"Path": "weapons/toolgun/sh_toolgun_tool_throw.nut",
"RunOn": "( CLIENT || SERVER ) && MP",
- "ClientCallback": "ToolgunToolThrowEntity_Init",
- "ServerCallback": "ToolgunToolThrowEntity_Init"
+ "ClientCallback": {
+ "After": "ToolgunToolThrowEntity_Init"
+ },
+
+ "ServerCallback": {
+ "After": "ToolgunToolThrowEntity_Init"
+ }
},
{
"Path": "weapons/toolgun/sh_toolgun_tool_explode.nut",
"RunOn": "( CLIENT || SERVER ) && MP",
- "ClientCallback": "ToolgunToolCreateExplosion_Init",
- "ServerCallback": "ToolgunToolCreateExplosion_Init"
+ "ClientCallback": {
+ "After": "ToolgunToolCreateExplosion_Init"
+ },
+
+ "ServerCallback": {
+ "After": "ToolgunToolCreateExplosion_Init"
+ }
},
+ // fortwar
{
"Path": "gamemodes/sh_gamemode_fw_custom.nut",
"RunOn": "( CLIENT || SERVER ) && MP",
- "ClientPreCallback": "SHCreateGamemodeFW_Init",
- "ServerPreCallback": "SHCreateGamemodeFW_Init"
+ "ClientCallback": {
+ "Before": "SHCreateGamemodeFW_Init"
+ },
+
+ "ServerCallback": {
+ "Before": "SHCreateGamemodeFW_Init"
+ }
+ },
+ {
+ "Path": "gamemodes/sh_gamemode_fw.nut",
+ "RunOn": "( CLIENT || SERVER ) && MP"
+ },
+ {
+ "Path": "gamemodes/cl_gamemode_fw.nut",
+ "RunOn": "CLIENT && MP"
},
+ // gungame
{
"Path": "gamemodes/sh_gamemode_gg.gnut",
"RunOn": "( CLIENT || SERVER ) && MP",
- "ClientPreCallback": "Sh_GamemodeGG_Init",
- "ServerPreCallback": "Sh_GamemodeGG_Init"
+ "ClientCallback": {
+ "Before": "Sh_GamemodeGG_Init"
+ },
+
+ "ServerCallback": {
+ "Before": "Sh_GamemodeGG_Init"
+ }
},
{
"Path": "gamemodes/_gamemode_gg.gnut",
@@ -82,11 +117,17 @@
"RunOn": "CLIENT && MP"
},
+ // titan tag
{
"Path": "gamemodes/sh_gamemode_tt.gnut",
"RunOn": "( CLIENT || SERVER ) && MP",
- "ClientPreCallback": "Sh_GamemodeTT_Init",
- "ServerPreCallback": "Sh_GamemodeTT_Init"
+ "ClientCallback": {
+ "Before": "Sh_GamemodeTT_Init"
+ },
+
+ "ServerCallback": {
+ "Before": "Sh_GamemodeTT_Init"
+ }
},
{
"Path": "gamemodes/_gamemode_tt.gnut",
@@ -97,11 +138,17 @@
"RunOn": "CLIENT && MP"
},
+ // infection
{
"Path": "gamemodes/sh_gamemode_inf.gnut",
"RunOn": "( CLIENT || SERVER ) && MP",
- "ClientPreCallback": "Sh_GamemodeInfection_Init",
- "ServerPreCallback": "Sh_GamemodeInfection_Init"
+ "ClientCallback": {
+ "Before": "Sh_GamemodeInfection_Init",
+ },
+
+ "ServerCallback": {
+ "Before": "Sh_GamemodeInfection_Init"
+ }
},
{
"Path": "gamemodes/_gamemode_inf.gnut",
@@ -112,11 +159,40 @@
"RunOn": "CLIENT && MP"
},
+ // arena
+ {
+ "Path": "_droppod_spawn.gnut",
+ "RunOn": "SERVER && MP",
+ "ServerCallback": {
+ "After": "DropPodSpawn_Init"
+ }
+ },
{
"Path": "gamemodes/sh_gamemode_arena.gnut",
"RunOn": "( CLIENT || SERVER ) && MP",
- "ClientPreCallback": "Sh_GamemodeArena_Init",
- "ServerPreCallback": "Sh_GamemodeArena_Init"
+ "ClientCallback": {
+ "Before": "Sh_GamemodeArena_Init"
+ },
+
+ "ServerCallback": {
+ "Before": "Sh_GamemodeArena_Init"
+ }
+ },
+ {
+ "Path": "gamemodes/sh_arena_loadouts.gnut",
+ "RunOn": "UI || MP",
+
+ "ClientCallback": {
+ "After": "InitialiseArenaLoadouts"
+ },
+
+ "ServerCallback": {
+ "After": "InitialiseArenaLoadouts"
+ },
+
+ "UICallback": {
+ "After": "InitialiseArenaLoadouts"
+ }
},
{
"Path": "gamemodes/_gamemode_arena.gnut",
@@ -127,11 +203,17 @@
"RunOn": "CLIENT && MP"
},
+ // amped killrace
{
"Path": "gamemodes/sh_gamemode_kr.gnut",
"RunOn": "( CLIENT || SERVER ) && MP",
- "ClientPreCallback": "Sh_GamemodeKR_Init",
- "ServerPreCallback": "Sh_GamemodeKR_Init"
+ "ClientCallback": {
+ "Before": "Sh_GamemodeKR_Init"
+ },
+
+ "ServerCallback": {
+ "Before": "Sh_GamemodeKR_Init"
+ }
},
{
"Path": "gamemodes/_gamemode_kr.gnut",
@@ -142,11 +224,17 @@
"RunOn": "CLIENT && MP"
},
+ // fastball
{
"Path": "gamemodes/sh_gamemode_fastball.gnut",
"RunOn": "( CLIENT || SERVER ) && MP",
- "ClientPreCallback": "Sh_GamemodeFastball_Init",
- "ServerPreCallback": "Sh_GamemodeFastball_Init"
+ "ClientCallback": {
+ "Before": "Sh_GamemodeFastball_Init"
+ },
+
+ "ServerCallback": {
+ "Before": "Sh_GamemodeFastball_Init"
+ }
},
{
"Path": "gamemodes/_gamemode_fastball.gnut",
@@ -161,33 +249,66 @@
"RunOn": "CLIENT && MP"
},
+ // ctf comp
{
"Path": "gamemodes/sh_gamemode_ctf_comp.gnut",
"RunOn": "( CLIENT || SERVER ) && MP",
- "ClientPreCallback": "ShGamemodeCTFComp_Init",
- "ServerPreCallback": "ShGamemodeCTFComp_Init"
+ "ClientCallback": {
+ "Before": "ShGamemodeCTFComp_Init"
+ },
+
+ "ServerCallback": {
+ "Before": "ShGamemodeCTFComp_Init"
+ }
},
{
"Path": "titan/sh_first_person_embark.gnut",
"RunOn": "( CLIENT || SERVER ) && MP",
- "ClientPreCallback": "FirstPersonEmbark_Init",
- "ServerPreCallback": "FirstPersonEmbark_Init"
+ "ClientCallback": {
+ "Before": "FirstPersonEmbark_Init",
+ },
+
+ "ServerCallback": {
+ "Before": "FirstPersonEmbark_Init"
+ }
},
+
+ // riffs, playlist vars etc
{
"Path": "gamemodes/_riff_instagib.gnut",
"RunOn": "SERVER && MP",
- "ServerCallback": "RiffInstagib_Init"
+ "ServerCallback": {
+ "After": "RiffInstagib_Init"
+ }
},
- ],
- "IncludeAdditionalPreexistingScripts": [
+
{
- "Path": "gamemodes/sh_gamemode_fw.nut",
- "RunOn": "( CLIENT || SERVER ) && MP"
+ "Path": "_custom_air_accel.gnut",
+ "RunOn": "MP",
+ "ClientCallback": {
+ "After": "CustomAirAccelVars_Init"
+ },
+
+ "ServerCallback": {
+ "After": "CustomAirAccelVars_Init"
+ }
},
+
{
- "Path": "gamemodes/cl_gamemode_fw.nut",
- "RunOn": "CLIENT && MP"
- }
+ "Path": "_promode.gnut",
+ "RunOn": "MP",
+ "ClientCallback": {
+ "After": "Promode_Init"
+ },
+
+ "ServerCallback": {
+ "After": "Promode_Init"
+ }
+ },
+ ],
+
+ "Localisation": [
+ "resource/northstar_custom_%language%.txt"
]
} \ No newline at end of file
diff --git a/Northstar.Custom/mod/resource/northstar_custom_english.txt b/Northstar.Custom/mod/resource/northstar_custom_english.txt
new file mode 100644
index 00000000..47c6a8bc
--- /dev/null
+++ b/Northstar.Custom/mod/resource/northstar_custom_english.txt
@@ -0,0 +1,69 @@
+"lang"
+{
+ "Language" "english"
+ "Tokens"
+ {
+ "PL_sbox" "Sandbox"
+ "PL_sbox_lobby" "Sandbox Lobby"
+ "PL_sbox_desc" "like gmod but worse"
+ "PL_sbox_abbr" "SBOX"
+ "GAMEMODE_SBOX" "Sandbox"
+
+ "PL_gg" "Gun Game"
+ "PL_gg_lobby" "Gun Game Lobby"
+ "PL_gg_desc" "Get a kill with each gun to win."
+ "PL_gg_abbr" "GG"
+ "GAMEMODE_GG" "Gun Game"
+
+ "PL_tt" "Titan Tag"
+ "PL_tt_lobby" "Titan Tag Lobby"
+ "PL_tt_desc" "Earn points while in your titan. Destroy a titan to get your own."
+ "PL_tt_abbr" "TT"
+ "GAMEMODE_TT" "Titan Tag"
+
+ "PL_inf" "Infection"
+ "PL_inf_lobby" "Infection Lobby"
+ "PL_inf_desc" "Survivors are infected when killed."
+ "PL_inf_abbr" "INF"
+ "GAMEMODE_INF" "Infection"
+ "INFECTION_YOU_ARE_INFECTED" "You've been Infected!"
+ "INFECTION_KILL_SURVIVORS" "Infect All Remaining Survivors."
+ "INFECTION_FIRST_INFECTED" "%s1 is the First Infected."
+ "INFECTION_LAST_SURVIVOR" "%s1 is the Last Survivor!"
+ "INFECTION_KILL_LAST_SURVIVOR" "Infect them before time runs out!"
+ "INFECTION_YOU_ARE_LAST_SURVIVOR" "You are the Last Survivor!"
+ "INFECTION_SURVIVE_LAST_SURVIVOR" "Survive."
+
+ // these are defined in r1_english but titan war is a shit name so i'm changing it to another one that was referenced in development
+ "GAMEMODE_fw" "Frontier War"
+ "PL_fw" "Frontier War"
+ "PL_fw_lobby" "Frontier War Lobby"
+ "PL_fw_desc" "Destroy the enemy's harvester and protect your own"
+ "PL_fw_abbr" "FW"
+
+ "GAMEMODE_kr" "Amped Killrace"
+ "PL_kr" "Amped Killrace"
+ "PL_kr_lobby" "Amped Killrace Lobby"
+ "PL_kr_desc" "Get kills to increase the length of your killrace. Collect the flag to start it. Set the record to win"
+ "PL_kr_abbr" "KR"
+ "SCOREBOARD_KR_RECORD" "Kill Record"
+ "KR_NEW_RACER" "%s1 is the amped killracer"
+ "KR_YOU_ARE_NEW_RACER" "You are the amped killracer"
+ "KR_YOU_SET_NEW_RECORD" "Set a New Kill Record!"
+ "KR_FLAG_INCOMING" "Flag incoming"
+ "KR_COLLECT_FLAG" "Collect it to become the Killracer!"
+ "KR_ENEMY_KILLRACE_OVER" "%s1's killrace is over"
+ "KR_YOUR_KILLRACE_OVER" "Your killrace is over"
+ "KR_YOUR_KILLRACE_SCORE" "You got %s1 kills."
+
+ "GAMEMODE_fastball" "Fastball"
+ "PL_fastball" "Fastball"
+ "PL_fastball_lobby" "Fastball Lobby"
+ "PL_fastball_desc" "Permadeath. Hack control panels to win rounds and respawn your teammates."
+ "PL_fastball_abbr" "FB"
+ "FASTBALL_PANEL_CAPTURED" "%s1 captured panel %s2"
+ "SCOREBOARD_FASTBALL_HACKS" "Panels Captured"
+
+ "GAMEMODE_ctf_comp" "Competitive CTF"
+ }
+}
diff --git a/Northstar.Custom/scripts/levels/mp_box.rson b/Northstar.Custom/mod/scripts/levels/mp_box.rson
index 1a8d1ee7..1a8d1ee7 100644
--- a/Northstar.Custom/scripts/levels/mp_box.rson
+++ b/Northstar.Custom/mod/scripts/levels/mp_box.rson
diff --git a/Northstar.Custom/mod/scripts/vscripts/_custom_air_accel.gnut b/Northstar.Custom/mod/scripts/vscripts/_custom_air_accel.gnut
new file mode 100644
index 00000000..5c228af4
--- /dev/null
+++ b/Northstar.Custom/mod/scripts/vscripts/_custom_air_accel.gnut
@@ -0,0 +1,23 @@
+global function CustomAirAccelVars_Init
+
+void function CustomAirAccelVars_Init()
+{
+ AddPrivateMatchModeSettingArbitrary( "Pilot", "custom_air_accel_pilot", "500" ) // 500 is the default airaccel
+
+ #if SERVER
+ AddCallback_OnPlayerRespawned( ApplyCustomPlayerAirAccel )
+ AddCallback_OnPilotBecomesTitan( ApplyCustomPlayerAirAccelFromTitan ) // not sure if necessary but assuming it is
+ #endif
+}
+
+#if SERVER
+void function ApplyCustomPlayerAirAccel( entity player )
+{
+ player.kv.airAcceleration = GetCurrentPlaylistVarInt( "custom_air_accel_pilot", int( player.GetPlayerSettingsField( "airAcceleration" ) ) )
+}
+
+void function ApplyCustomPlayerAirAccelFromTitan( entity player, entity titan )
+{
+ player.kv.airAcceleration = GetCurrentPlaylistVarInt( "custom_air_accel_pilot", int( player.GetPlayerSettingsField( "airAcceleration" ) ) )
+}
+#endif \ No newline at end of file
diff --git a/Northstar.Custom/mod/scripts/vscripts/_droppod_spawn.gnut b/Northstar.Custom/mod/scripts/vscripts/_droppod_spawn.gnut
new file mode 100644
index 00000000..7447fc59
--- /dev/null
+++ b/Northstar.Custom/mod/scripts/vscripts/_droppod_spawn.gnut
@@ -0,0 +1,79 @@
+untyped
+global function DropPodSpawn_Init
+global function SpawnPlayersInDropPod
+
+struct {
+ array< entity > droppods
+} file
+
+void function DropPodSpawn_Init()
+{
+ AddCallback_OnRoundEndCleanup( CleanupSpawningDropPods )
+}
+
+void function CleanupSpawningDropPods()
+{
+ foreach ( entity pod in file.droppods )
+ pod.Destroy()
+
+ file.droppods.clear()
+}
+
+void function SpawnPlayersInDropPod( array< entity > players, vector targetOrigin, vector angles, float destructionTime = -1 )
+{
+ entity pod = CreateDropPod( targetOrigin, angles )
+
+ file.droppods.append( pod )
+ svGlobal.levelEnt.EndSignal( "CleanUpEntitiesForRoundEnd" )
+
+ // TODO: we need to make a door for this, CreateDropPodDoor in _droppod_fireteam is just busted for some reason tho
+
+ entity camera = CreateEntity( "point_viewcontrol" )
+ camera.SetParent( pod, "ATTACH", false )
+ camera.SetLocalOrigin( < 0, 150, 450 > )
+ camera.SetAngles( < 60, -90, 0 > )
+
+ foreach ( entity player in players )
+ {
+ if ( !IsAlive( player ) )
+ player.RespawnPlayer( null )
+
+ player.SetOrigin( pod.GetOrigin() )
+ player.SetAngles( pod.GetAngles() )
+ player.SetParent( pod )
+ player.FreezeControlsOnServer()
+ AddCinematicFlag( player, CE_FLAG_HIDE_MAIN_HUD )
+ player.SetViewEntity( camera, true )
+ }
+
+ // wait for this
+ LaunchAnimDropPod( pod, "pod_testpath", targetOrigin, angles )
+
+ foreach ( entity player in players )
+ {
+ player.ClearParent()
+ player.ClearViewEntity()
+ player.UnfreezeControlsOnServer()
+ RemoveCinematicFlag( player, CE_FLAG_HIDE_MAIN_HUD )
+ }
+
+ // wait a frame, otherwise this won't properly work
+ WaitFrame()
+ vector doorPos = pod.GetAttachmentOrigin( pod.LookupAttachment( "hatch" ) )
+
+ foreach ( entity player in players )
+ {
+ vector viewAngles = doorPos - player.GetOrigin()
+ viewAngles.x = 3.0
+
+ player.SetAngles( viewAngles )
+ }
+
+ if ( destructionTime != -1 )
+ {
+ wait destructionTime
+ pod.Dissolve( ENTITY_DISSOLVE_NORMAL, < 0, 0, 0 >, 0 )
+
+ file.droppods.remove( file.droppods.find( pod ) )
+ }
+} \ No newline at end of file
diff --git a/Northstar.Custom/scripts/vscripts/_northstar_devcommands.gnut b/Northstar.Custom/mod/scripts/vscripts/_northstar_devcommands.gnut
index 960e619e..960e619e 100644
--- a/Northstar.Custom/scripts/vscripts/_northstar_devcommands.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/_northstar_devcommands.gnut
diff --git a/Northstar.Custom/mod/scripts/vscripts/_promode.gnut b/Northstar.Custom/mod/scripts/vscripts/_promode.gnut
new file mode 100644
index 00000000..3e6d6d65
--- /dev/null
+++ b/Northstar.Custom/mod/scripts/vscripts/_promode.gnut
@@ -0,0 +1,25 @@
+untyped
+global function Promode_Init
+global function PromodeEnabled
+
+void function Promode_Init()
+{
+ AddPrivateMatchModeSettingEnum( "Promode", "promode_enable", [ "Disabled", "Enabled" ], "0" )
+
+ #if SERVER
+ AddCallback_OnPlayerRespawned( GivePromodeWeaponMod )
+ #endif
+}
+
+bool function PromodeEnabled()
+{
+ return GetCurrentPlaylistVarInt( "promode_enable", 0 ) == 1
+}
+
+#if SERVER
+void function GivePromodeWeaponMod( entity player )
+{
+ if ( PromodeEnabled() )
+ player.GiveExtraWeaponMod( "promode" )
+}
+#endif \ No newline at end of file
diff --git a/Northstar.Custom/mod/scripts/vscripts/burnmeter/sh_boost_store.gnut b/Northstar.Custom/mod/scripts/vscripts/burnmeter/sh_boost_store.gnut
new file mode 100644
index 00000000..515ffd9d
--- /dev/null
+++ b/Northstar.Custom/mod/scripts/vscripts/burnmeter/sh_boost_store.gnut
@@ -0,0 +1,762 @@
+global function ShInitBoostStore
+global function ShInitBoostStoreForMode
+global function GetAvailableBoosts
+global function BoostStoreEnabled
+global function CanPurchaseBoost
+global function CanAffordBoost
+global function GetPlaylistBoostCost
+
+#if CLIENT || SERVER
+global function BoostStoreOpen
+#endif
+
+#if SERVER
+global function SetBoostPurchaseCallback
+global function SetBoostRefundCallback
+global function SetTeamReserveInteractCallback
+global function AddMoneyToPlayer
+global function SetMoneyForPlayer
+global function CreateBoostStoreLocation
+global function OpenBoostStores
+global function CloseBoostStores
+global function GetBoostStores
+global function BurnRewardRefundThink
+global function SetJoinInProgressBonus
+#endif
+
+#if CLIENT
+global function ServerCallback_EnableDropshipBoostStore
+global function ServerCallback_DisableDropshipBoostStore
+global function ServerCallback_BoostStoreTitanHint
+#endif
+
+#if UI
+global function UpdatePlayerMoney
+global function ServerCallback_UpdateTurretCount
+global function ServerCallback_UpdatePlayerHasBattery
+global function ServerCallback_UpdateAmpedWeaponState
+#endif
+
+global function GetPlayerMoney
+global function GetTeamReserve
+global function UpdateTeamReserve
+
+const int MAX_MONEY = 5000
+const float BOOST_STORE_TRIGGER_RADIUS = 300
+const int BOOST_STORE_DEFAULT_EXCHANGE = 100
+
+global struct BoostStoreData
+{
+ string itemRef
+ string modesAllowed
+ string additionalDesc
+ int cost
+ bool autoActivate
+ asset storeIcon
+ asset lockedStoreIcon
+ string additionalDescFail
+}
+
+struct
+{
+ array<BoostStoreData> allBoosts
+ array<BoostStoreData> availableBoosts
+ table<entity,int> playerBonusData
+ int joinInProgressBonus = 0
+ array<string> joinInProgressGivenToPlayers
+
+ int teamReserveAmount = 0
+
+ var boostStoreHintRui
+
+ #if UI
+ int playerMoney = 0
+ int turretCount = 0
+ int maxTurretCount = 5
+ bool playerHasBattery = false
+ bool playerHasAmpedWeapons = false
+ #endif
+
+ array<entity> storeLocations
+ table<string,bool functionref(entity)> boostPurchaseExtraChecks
+ void functionref(entity,BoostStoreData) boostPurchaseCallback
+ void functionref( entity, string ) boostRefundCallback
+ void functionref( entity, string, int ) teamReserveDepositOrWithdrawCallback
+} file
+
+void function ShInitBoostStore()
+{
+ var dataTable = GetDataTable( $"datatable/burn_meter_store.rpak" )
+ int len = GetDatatableRowCount( dataTable )
+ for ( int i=0; i<len; i++ )
+ {
+ string allowedModes = GetDataTableString( dataTable, i, GetDataTableColumnByName( dataTable, "modes" ) )
+ string itemRef = GetDataTableString( dataTable, i, GetDataTableColumnByName( dataTable, "itemRef" ) )
+ string additionalDesc = GetDataTableString( dataTable, i, GetDataTableColumnByName( dataTable, "extraDesc" ) )
+ int cost = GetDataTableInt( dataTable, i, GetDataTableColumnByName( dataTable, "cost" ) )
+ bool autoActivate = GetDataTableBool( dataTable, i, GetDataTableColumnByName( dataTable, "autoActivate" ) )
+ asset storeIcon = GetDataTableAsset( dataTable, i, GetDataTableColumnByName( dataTable, "storeIcon" ) )
+ asset lockedStoreIcon = GetDataTableAsset( dataTable, i, GetDataTableColumnByName( dataTable, "lockedStoreIcon" ) )
+ string additionalDescFail = GetDataTableString( dataTable, i, GetDataTableColumnByName( dataTable, "extraDescFail" ) )
+ BoostStoreData data
+ data.itemRef = itemRef
+ data.cost = cost
+ data.modesAllowed = allowedModes
+ data.additionalDesc = additionalDesc
+ data.autoActivate = autoActivate
+ data.storeIcon = storeIcon
+ data.lockedStoreIcon = lockedStoreIcon
+ data.additionalDescFail = additionalDescFail
+ file.allBoosts.append( data )
+ }
+
+ foreach ( turretType in GetAllBoostTurretTypes() )
+ {
+ file.boostPurchaseExtraChecks[ turretType ] <- CheckTooManyTurrets
+ }
+
+ file.boostPurchaseExtraChecks[ "burnmeter_instant_battery" ] <- CheckHasNoBattery
+ file.boostPurchaseExtraChecks[ "burnmeter_amped_weapons_permanent" ] <- CheckHasNoAmpedWeapons
+
+ #if UI
+ AddUICallback_OnLevelInit( ShInitBoostStoreForMode )
+ #else
+ if ( !IsLobby() )
+ ShInitBoostStoreForMode()
+ #endif
+
+ #if SERVER
+ if ( !BoostStoreEnabled() )
+ return
+
+ AddCallback_OnClientConnected( Store_OnClientConnected )
+ AddClientCommandCallback( "PurchaseBoost", ClientCommand_PurchaseBoost )
+ AddClientCommandCallback( "TeamReserveDeposit", ClientCommand_Deposit )
+ AddClientCommandCallback( "TeamReserveWithdraw", ClientCommand_Withdraw )
+ RegisterSignal( "BoostRefunded" )
+ RegisterSignal( "CancelRefund" )
+ #endif
+}
+
+#if SERVER
+void function SetJoinInProgressBonus( int moneyToAdd )
+{
+ file.joinInProgressBonus = file.joinInProgressBonus + moneyToAdd
+}
+
+void function SetBoostPurchaseCallback( void functionref( entity, BoostStoreData ) func )
+{
+ file.boostPurchaseCallback = func
+}
+
+void function SetBoostRefundCallback( void functionref( entity, string ) func )
+{
+ file.boostRefundCallback = func
+}
+
+void function SetTeamReserveInteractCallback( void functionref( entity, string, int ) func )
+{
+ file.teamReserveDepositOrWithdrawCallback = func
+}
+
+void function Store_OnClientConnected( entity player )
+{
+ file.playerBonusData[ player ] <- 0
+ string playerUID = player.GetUID()
+ if ( !file.joinInProgressGivenToPlayers.contains( playerUID ) )
+ {
+ AddMoneyToPlayer( player, file.joinInProgressBonus )
+ file.joinInProgressGivenToPlayers.append( playerUID )
+ }
+}
+#endif
+
+void function ShInitBoostStoreForMode()
+{
+ string boostStoreMode = GetCurrentPlaylistVarString( "boost_store_mode", "off" )
+ file.availableBoosts.clear()
+
+ if ( boostStoreMode == "off" )
+ return
+
+ foreach ( data in file.allBoosts )
+ {
+ array<string> tokens = split( data.modesAllowed, " " )
+ if ( tokens.contains( boostStoreMode ) )
+ {
+ file.availableBoosts.append( data )
+ }
+ }
+ file.availableBoosts.sort( SortCompareBoostCost )
+ printt( file.availableBoosts.len() )
+}
+
+int function SortCompareBoostCost( BoostStoreData a, BoostStoreData b )
+{
+ int acost = GetPlaylistBoostCost( a.itemRef, a.cost )
+ int bcost = GetPlaylistBoostCost( b.itemRef, b.cost )
+
+ if ( acost > bcost )
+ return 1
+
+ if ( bcost > acost )
+ return -1
+
+ return 0
+}
+
+array<BoostStoreData> function GetAvailableBoosts()
+{
+ // custom stuff for arena
+ string boostStoreMode = GetCurrentPlaylistVarString( "boost_store_mode", "off" )
+ if ( boostStoreMode == "arena" )
+ {
+ array<BoostStoreData> arenaLoadouts = PopulateArenaLoadouts()
+
+ #if SERVER
+ // bit of a hack, but assign weapon checks to weapon refs
+ foreach ( BoostStoreData data in arenaLoadouts )
+ if ( data.itemRef in eDamageSourceId )
+ file.boostPurchaseExtraChecks[ data.itemRef ] <- bool function( entity player ) { return player.GetMainWeapons().len() != 3 }
+ #endif
+
+ return arenaLoadouts
+ }
+
+ return file.availableBoosts
+}
+
+bool function CanAffordBoost( entity player, BoostStoreData data )
+{
+ int money = GetPlayerMoney( player )
+ return money >= GetPlaylistBoostCost( data.itemRef, data.cost )
+}
+
+bool function CanPurchaseBoost( entity player, BoostStoreData data, bool checkMoney = true )
+{
+ bool canBuy = true
+
+ if ( checkMoney )
+ canBuy = canBuy && CanAffordBoost( player, data )
+
+ if ( data.itemRef in file.boostPurchaseExtraChecks )
+ {
+ canBuy = canBuy && file.boostPurchaseExtraChecks[ data.itemRef ]( player )
+ }
+
+ return canBuy
+}
+
+#if SERVER
+bool function ClientCommand_PurchaseBoost( entity player, array<string> args )
+{
+ // bob note: readded this check, why the fuck is it not a check in vanilla
+ if ( !BoostStoreOpen() )
+ return true
+
+ if ( player.IsPhaseShifted() )
+ return false
+
+ if ( !IsAlive( player ) )
+ return false
+
+ if ( player.IsTitan() )
+ return false
+
+ array<BoostStoreData> availableBoosts = GetAvailableBoosts()
+
+ if ( args.len() == 0 )
+ return false
+
+ foreach ( data in availableBoosts )
+ {
+ if ( data.itemRef == args[0] )
+ {
+ if ( IsItemLocked( player, data.itemRef ) )
+ break
+
+ if ( CanPurchaseBoost( player, data ) )
+ {
+ if ( file.boostPurchaseCallback != null )
+ file.boostPurchaseCallback( player, data )
+
+ AddMoneyToPlayer( player, -1*GetPlaylistBoostCost( data.itemRef, data.cost ) )
+ BurnReward burnReward = BurnReward_GetByRef( data.itemRef )
+ if ( !data.autoActivate )
+ {
+ BurnMeter_GiveRewardDirect( player, data.itemRef )
+ }
+ else
+ {
+ RunBurnCardUseFunc( player, data.itemRef )
+ Remote_CallFunction_NonReplay( player, "ServerCallback_RewardUsed", burnReward.id )
+ EmitSoundOnEntityOnlyToPlayer( player, player, "HUD_Boost_Card_Earned_1P" )
+ }
+ EmitSoundOnEntityOnlyToPlayer( player, player, "UI_InGame_FD_ArmoryPurchase" )
+ MessageToTeam( player.GetTeam(), eEventNotifications.FD_BoughtItem, null, player, burnReward.id )
+ break
+ }
+ }
+ }
+
+ return true
+}
+
+bool function ClientCommand_Deposit( entity player, array<string> args )
+{
+ // if ( !BoostStoreOpen() )
+ // return true
+
+ int depositAmount = minint( file.playerBonusData[ player ], BOOST_STORE_DEFAULT_EXCHANGE )
+ file.teamReserveAmount += depositAmount
+ AddMoneyToPlayer( player, -1*depositAmount )
+
+ if ( IsValid( file.teamReserveDepositOrWithdrawCallback ) )
+ file.teamReserveDepositOrWithdrawCallback( player, "deposit", depositAmount )
+
+ foreach ( player in GetPlayerArray() )
+ {
+ Remote_CallFunction_UI( player, "ServerCallback_UpdateTeamReserve", file.teamReserveAmount )
+ }
+
+ return true
+}
+
+
+bool function ClientCommand_Withdraw( entity player, array<string> args )
+{
+ // if ( !BoostStoreOpen() )
+ // return true
+
+ if ( GetPlayerMoney( player ) >= MAX_MONEY )
+ return true
+
+ int withdrawAmount = minint( file.teamReserveAmount, BOOST_STORE_DEFAULT_EXCHANGE )
+ file.teamReserveAmount -= withdrawAmount
+ AddMoneyToPlayer( player, withdrawAmount )
+
+ if ( IsValid( file.teamReserveDepositOrWithdrawCallback ) )
+ file.teamReserveDepositOrWithdrawCallback( player, "withdraw", withdrawAmount )
+
+ foreach ( player in GetPlayerArray() )
+ {
+ Remote_CallFunction_UI( player, "ServerCallback_UpdateTeamReserve", file.teamReserveAmount )
+ }
+
+ return true
+}
+
+void function AddMoneyToPlayer( entity player, int points )
+{
+ SetMoneyForPlayer( player, file.playerBonusData[ player ] + points )
+}
+
+void function SetMoneyForPlayer( entity player, int points )
+{
+ file.playerBonusData[ player ] = int( Clamp( float( points ), 0, MAX_MONEY ) )
+
+ int bonusPoints = file.playerBonusData[ player ]
+ int bonusPointStack = int( max( ( bonusPoints - ( bonusPoints % 256 ) ) / 256, 0 ) )
+ int bonusPointRemainder = ( bonusPoints % 256 )
+
+ player.SetPlayerNetInt( "FD_money", bonusPointRemainder )
+ player.SetPlayerNetInt( "FD_money256", bonusPointStack )
+ player.SetTitle( "$" + bonusPoints )
+
+ Remote_CallFunction_UI( player, "ServerCallback_UpdateMoney", file.playerBonusData[ player ] )
+}
+
+void function CreateBoostStoreLocation( int team, vector origin, vector angles, bool showOnMinimap = true )
+{
+ if ( !BoostStoreEnabled() )
+ return
+
+ entity crate = CreatePropDynamic( MODEL_ATTRITION_BANK, origin, angles, 6 )
+
+ entity invisibleCrate = CreatePropScript( MODEL_ATTRITION_BANK, origin, angles, 6 )
+ SetTargetName( invisibleCrate, "boostStore" )
+ SetTeam( invisibleCrate, team )
+ invisibleCrate.Hide()
+ invisibleCrate.NotSolid()
+
+ // just to create an association
+ crate.SetParent( invisibleCrate )
+
+ thread PlayAnim( crate, "mh_inactive_idle", crate.GetParent() )
+ if ( BoostStoreOpen() )
+ thread EnableBoostStoreCrate( crate )
+
+ crate.SetUsePrompts( "#BOOST_STORE_HOLD_USE", "#BOOST_STORE_PRESS_USE" )
+ crate.SetForceVisibleInPhaseShift( true )
+
+ file.storeLocations.append( crate )
+
+ if ( showOnMinimap )
+ {
+ invisibleCrate.Minimap_SetObjectScale( MINIMAP_LOADOUT_CRATE_SCALE )
+ invisibleCrate.Minimap_SetAlignUpright( true )
+ invisibleCrate.Minimap_AlwaysShow( TEAM_IMC, null )
+ invisibleCrate.Minimap_AlwaysShow( TEAM_MILITIA, null )
+ invisibleCrate.Minimap_SetHeightTracking( true )
+ invisibleCrate.Minimap_SetZOrder( MINIMAP_Z_OBJECT )
+ invisibleCrate.Minimap_SetCustomState( eMinimapObject_prop_script.BOOST_STORE )
+ }
+ if ( !GetGlobalNetBool("boostStoreOpen") )
+ {
+ invisibleCrate.Minimap_Hide( TEAM_IMC, null )
+ invisibleCrate.Minimap_Hide( TEAM_MILITIA, null )
+ }
+
+ thread CreateBoostStoreHintTrigger( crate )
+ thread BoostStoreThink( crate )
+}
+
+void function EnableBoostStoreCrate( entity crate )
+{
+ crate.EndSignal( "OnDestroy" )
+ crate.SetUsable()
+
+ entity parentCrate = crate.GetParent()
+ int team = parentCrate.GetTeam()
+ if ( team == TEAM_MILITIA || team == TEAM_IMC )
+ crate.SetUsableByGroup( "friendlies pilot" )
+ else
+ crate.SetUsableByGroup( "pilot" )
+
+ SetTeam( crate, team )
+
+ waitthread PlayAnim( crate, "mh_inactive_2_active", crate.GetParent() )
+ thread PlayAnim( crate, "mh_active_idle", crate.GetParent() )
+ EmitSoundOnEntity( crate, "Mobile_Hardpoint_Idle" )
+}
+
+void function DisableBoostStoreCrate( entity crate )
+{
+ crate.EndSignal( "OnDestroy" )
+ crate.UnsetUsable()
+ SetTeam( crate, TEAM_UNASSIGNED )
+ FadeOutSoundOnEntity( crate, "Mobile_Hardpoint_Idle", 1.0 )
+ waitthread PlayAnim( crate, "mh_active_2_inactive", crate.GetParent() )
+ thread PlayAnim( crate, "mh_inactive_idle", crate.GetParent() )
+}
+
+void function CreateBoostStoreHintTrigger( entity crate )
+{
+ entity trig = CreateEntity( "trigger_cylinder" )
+ trig.SetRadius( BOOST_STORE_TRIGGER_RADIUS )
+ trig.SetAboveHeight( 200 )
+ trig.SetBelowHeight( 0)
+ trig.SetOrigin( crate.GetOrigin() )
+ trig.kv.triggerFilterNpc = "none"
+ trig.kv.triggerFilterPlayer = "all"
+ DispatchSpawn( trig )
+
+ trig.EndSignal( "OnDestroy" )
+ crate.EndSignal( "OnDestroy" )
+
+ OnThreadEnd(
+ function() : ( trig )
+ {
+ if ( IsValid( trig ) )
+ trig.Destroy()
+ }
+ )
+
+ trig.SetEnterCallback( BoostHintTrigEnter )
+
+ WaitForever()
+}
+
+void function BoostHintTrigEnter( entity trigger, entity ent )
+{
+ if ( !ent.IsPlayer() )
+ return
+ if ( !ent.IsTitan() )
+ return
+ if ( !GetGlobalNetBool( "boostStoreOpen" ) )
+ return
+ vector org = trigger.GetOrigin()
+ Remote_CallFunction_NonReplay( ent, "ServerCallback_BoostStoreTitanHint", org.x, org.y, org.z )
+}
+
+void function CloseBoostStores()
+{
+ foreach ( crate in file.storeLocations )
+ thread DisableBoostStoreCrate( crate )
+ SetGlobalNetBool("boostStoreOpen", false)
+}
+
+void function OpenBoostStores()
+{
+ foreach ( crate in file.storeLocations )
+ thread EnableBoostStoreCrate( crate )
+ SetGlobalNetBool("boostStoreOpen", true)
+}
+
+array<entity> function GetBoostStores()
+{
+ return file.storeLocations
+}
+
+void function BurnRewardRefundThink( entity useEnt, entity ent )
+{
+ useEnt.EndSignal( "OnDestroy" )
+ ent.EndSignal( "OnDestroy" )
+ ent.EndSignal( "OnDeath" )
+ ent.EndSignal( "CancelRefund" )
+ useEnt.SetUsable()
+ useEnt.SetUsableByGroup( "owner pilot" )
+ useEnt.SetUsePrompts( "#REFUND_HOLD_USE", "#REFUND_PRESS_USE" )
+
+ entity player = expect entity( useEnt.WaitSignal( "OnPlayerUse" ).player )
+ {
+ if ( ent.e.burnReward == "" )
+ return
+
+ BurnMeter_GiveRewardDirect( player, ent.e.burnReward )
+ entity weapon = player.GetOffhandWeapon( OFFHAND_INVENTORY )
+
+ // Defensive: meaning the boost didn't make it to the inventory for some reason
+ if ( weapon == null )
+ return
+
+ if ( IsTurret( ent ) )
+ {
+ weapon.w.savedKillCount = int( ent.kv.killCount )
+ ent.DisableTurret()
+ ent.Signal( "StopTurretLaser" )
+ }
+ weapon.e.fd_roundDeployed = ent.e.fd_roundDeployed
+
+ EmitSoundAtPosition( TEAM_UNASSIGNED, ent.GetOrigin(), "Emplacement_Move_Dissolve" )
+ ent.Signal( "BoostRefunded" )
+ ent.UnsetUsable()
+ ent.SetInvulnerable()
+ ent.Dissolve( ENTITY_DISSOLVE_CORE, Vector( 0, 0, 0 ), 100 )
+
+ if ( file.boostRefundCallback != null )
+ file.boostRefundCallback( player, ent.e.burnReward )
+ }
+}
+
+void function BoostStoreThink( entity crate )
+{
+ while( IsValid( crate ) )
+ {
+ entity player = expect entity( crate.WaitSignal( "OnPlayerUse" ).player )
+ if ( IsValid( player ) )
+ OpenBoostStoreMenu( player )
+ }
+}
+
+void function OpenBoostStoreMenu( entity player )
+{
+ if ( !BoostStoreEnabled() )
+ return
+
+ CalculatePlayerTurretCount( player )
+ Remote_CallFunction_UI( player, "ServerCallback_UpdateMoney", file.playerBonusData[ player ] )
+ Remote_CallFunction_UI( player, "ServerCallback_UpdateTeamReserve", file.teamReserveAmount )
+ Remote_CallFunction_UI( player, "ServerCallback_UpdatePlayerHasBattery", PlayerHasBattery( player ) )
+ Remote_CallFunction_UI( player, "ServerCallback_UpdateAmpedWeaponState", PlayerHasAmpedWeapons( player ) )
+ Remote_CallFunction_UI( player, "ServerCallback_OpenBoostStore" )
+}
+#endif
+
+#if CLIENT
+void function ServerCallback_BoostStoreTitanHint( float x, float y, float z )
+{
+ vector org = <x,y,z>
+ thread ServerCallback_BoostStoreTitanHint_Internal( org )
+}
+
+void function ServerCallback_BoostStoreTitanHint_Internal( vector org )
+{
+ entity player = GetLocalViewPlayer()
+
+ player.EndSignal( "OnDeath" )
+
+ float titanHullCompensate = 75.0
+ float maxDist = ((BOOST_STORE_TRIGGER_RADIUS+titanHullCompensate) * (BOOST_STORE_TRIGGER_RADIUS+titanHullCompensate))
+ float minDot = 0.8
+ float fadeTime = 0.25
+ float hintTime = 3.5
+ float showHintTime = -999.0
+ bool hintShowing = false
+
+ OnThreadEnd(
+ function() : ( )
+ {
+ HidePlayerHint( "#BOOST_STORE_NEED_PILOT_HINT" )
+ }
+ )
+
+ while ( player.IsTitan() )
+ {
+ float dist = DistanceSqr( org, player.GetOrigin() )
+
+ bool showHint = false
+
+ if ( dist <= maxDist )
+ {
+ if ( PlayerCanSeePos( player, org, false, 35.0 ) )
+ {
+ if ( Time() - showHintTime + fadeTime >= hintTime )
+ {
+ AddPlayerHint( hintTime, fadeTime, $"", "#BOOST_STORE_NEED_PILOT_HINT" )
+ showHintTime = Time()
+ }
+ showHint = true
+ }
+ }
+ else
+ {
+ return
+ }
+
+ if ( !showHint && Time() - showHintTime + fadeTime < hintTime )
+ {
+ showHintTime = -999.0
+ HidePlayerHint( "#BOOST_STORE_NEED_PILOT_HINT" )
+ }
+
+ WaitFrame()
+ }
+}
+
+
+void function OpenBoostStoreMenu( entity player )
+{
+ if ( !BoostStoreEnabled() )
+ return
+
+ RunUIScript( "OpenBoostStore" )
+}
+
+void function ServerCallback_EnableDropshipBoostStore()
+{
+ if ( !BoostStoreEnabled() )
+ return
+
+ RegisterButtonPressedCallback( BUTTON_A, OpenBoostStoreMenu )
+ RegisterButtonPressedCallback( KEY_SPACE, OpenBoostStoreMenu )
+ if ( file.boostStoreHintRui != null )
+ RuiDestroyIfAlive( file.boostStoreHintRui )
+ file.boostStoreHintRui = CreatePermanentCockpitRui( $"ui/hint_display.rpak" )
+ RuiSetString( file.boostStoreHintRui, "hintText", Localize( "#BOOST_STORE_DROPSHIP_PRESS_USE" ) )
+}
+
+void function ServerCallback_DisableDropshipBoostStore()
+{
+ if ( !BoostStoreEnabled() )
+ return
+
+ if ( file.boostStoreHintRui != null )
+ {
+ RuiDestroyIfAlive( file.boostStoreHintRui )
+ DeregisterButtonPressedCallback( BUTTON_A, OpenBoostStoreMenu )
+ DeregisterButtonPressedCallback( KEY_SPACE, OpenBoostStoreMenu )
+ file.boostStoreHintRui = null
+ }
+}
+#endif
+
+bool function BoostStoreEnabled()
+{
+ return ( GetCurrentPlaylistVarString( "boost_store_mode", "off" ) != "off" )
+}
+
+#if CLIENT || SERVER
+bool function BoostStoreOpen()
+{
+ return GetGlobalNetBool("boostStoreOpen" )
+}
+#endif
+
+int function GetTeamReserve()
+{
+ return file.teamReserveAmount
+}
+
+void function UpdateTeamReserve( int reserveMoney )
+{
+ file.teamReserveAmount = reserveMoney
+}
+
+
+int function GetPlayerMoney( entity player )
+{
+ #if SERVER
+ return file.playerBonusData[ player ]
+ #endif
+
+ #if CLIENT
+ int money = player.GetPlayerNetInt( "FD_money" )
+ int money256 = player.GetPlayerNetInt( "FD_money256" )
+ return ( money256 * 256 ) + money
+ #endif
+
+ #if UI
+ return file.playerMoney
+ #endif
+}
+
+bool function CheckTooManyTurrets( entity player )
+{
+ #if SERVER || CLIENT
+ return player.GetPlayerNetInt( "burn_numTurrets" ) < GetGlobalNetInt( "burn_turretLimit" )
+ #elseif UI
+ return file.turretCount < file.maxTurretCount
+ #endif
+}
+
+bool function CheckHasNoBattery( entity player )
+{
+ #if SERVER || CLIENT
+ return !PlayerHasBattery( player )
+ #elseif UI
+ return !file.playerHasBattery
+ #endif
+}
+
+bool function CheckHasNoAmpedWeapons( entity player )
+{
+ #if SERVER || CLIENT
+ return !PlayerHasAmpedWeapons( player )
+ #elseif UI
+ return !file.playerHasAmpedWeapons
+ #endif
+}
+
+#if UI
+void function ServerCallback_UpdatePlayerHasBattery( bool hasBattery )
+{
+ file.playerHasBattery = hasBattery
+}
+
+void function ServerCallback_UpdateAmpedWeaponState( bool hasAmpedWeapons )
+{
+ file.playerHasAmpedWeapons = hasAmpedWeapons
+}
+
+void function ServerCallback_UpdateTurretCount( int count, int max )
+{
+ file.turretCount = count
+ file.maxTurretCount = max
+}
+
+void function UpdatePlayerMoney( int money )
+{
+ file.playerMoney = money
+}
+#endif
+
+int function GetPlaylistBoostCost( string ref, int originalCost )
+{
+ int cost = GetCurrentPlaylistVarInt( "override_boost_cost_" + ref, -1 )
+
+ if ( cost > 0 )
+ return cost
+
+ return originalCost
+} \ No newline at end of file
diff --git a/Northstar.Custom/mod/scripts/vscripts/burnmeter/sh_burnmeter.gnut b/Northstar.Custom/mod/scripts/vscripts/burnmeter/sh_burnmeter.gnut
new file mode 100644
index 00000000..3f914745
--- /dev/null
+++ b/Northstar.Custom/mod/scripts/vscripts/burnmeter/sh_burnmeter.gnut
@@ -0,0 +1,488 @@
+global function ShBurnMeter_Init
+global function BurnReward_GetById
+global function BurnReward_GetByRef
+global function BurnReward_GetRandom
+global function GetSelectedBurnCardRef
+global function GetBoostSkin
+#if SERVER || CLIENT
+global function BurnMeterEnabled
+global function CanUseWeaponAsBurnCard
+global function TryUsingBurnCardWeapon
+global function TryUsingBurnCardWeaponInCriticalSection
+global function BurnMeterPlayer_CanUseEquipped
+global function OnWeaponAttemptOffhandSwitch_burncardweapon
+global function BurnMeterPlayer_CanUseReward
+global function BurnMeterPlayer_GetRewardOrGoal
+global function BurnReward_GetTopInventoryItemBurnCard
+global function OnWeaponPrimaryAttack_nuke_eject
+global function BurnMeter_HarvesterShieldCanUse
+#endif
+
+global function GetAllBoostTurretTypes
+
+global const BURN_METER_SMALL_POINT_VALUE = 1
+global const BURN_METER_MID_POINT_VALUE = 2
+global const BURN_METER_LARGE_POINT_VALUE = 5
+global const BURN_METER_EXTRA_LARGE_POINT_VALUE = 10
+
+global const BURN_METER_RADAR_JAMMER_PULSE_DURATION = 6.0
+global const BURN_METER_RADAR_JAMMER_EASE_OFF_TIME = 1.0
+
+global enum eBurnMeterRewardAvailableFor
+{
+ PILOT_ONLY,
+ TITAN_ONLY,
+ PILOT_AND_TITAN,
+ SPECIAL_PLAYERS_ONLY,
+}
+
+global struct BurnReward
+{
+ int id = -1
+ string ref = ""
+ string localizedName = ""
+ string description = ""
+ asset image = $""
+ float cost
+ int userType = -1
+ int skinIndex = 0
+ string weaponName = ""
+ string extraWeaponMod = ""
+ string activationText = ""
+
+ void functionref( entity ) ornull rewardAvailableCallback = null
+}
+
+global struct BurnStruct
+{
+ table< string, BurnReward > burnRewards
+ array< BurnReward > allCards //Kinda inefficient to store the same burn cards 3 times (once in burnRewards, once in foil/normal, once in allcards. Prefer speed over memory? )
+ array< BurnReward > allowedCards
+
+}
+
+global BurnStruct burn
+
+global table< string, bool functionref( entity ) > burnMeterCanUseFuncTable
+
+struct
+{
+
+ bool shouldCycleOnRelease = false
+
+} file
+
+array<string> turretBurnCards = [
+ "burnmeter_ap_turret_weapon",
+ "burnmeter_at_turret_weapon",
+ "burnmeter_ap_turret_weapon_infinite",
+ "burnmeter_at_turret_weapon_infinite",
+]
+
+void function ShBurnMeter_Init()
+{
+
+ #if SERVER || CLIENT
+ //burnMeterCanUseFuncTable[ "burnmeter_random_foil" ] <- BurnMeter_RandomFoilCanUse
+ burnMeterCanUseFuncTable[ "burnmeter_emergency_titan" ] <- BurnMeter_EmergencyTitanCanUse
+ burnMeterCanUseFuncTable[ "burnmeter_nuke_titan" ] <- BurnMeter_NukeTitanCanUse
+ // burnMeterCanUseFuncTable[ "burnmeter_harvester_shield" ] <- BurnMeter_HarvesterShieldCanUse
+ #endif
+
+
+
+ var dataTable = GetDataTable( $"datatable/burn_meter_rewards.rpak" )
+
+ for ( int row = 0; row < GetDatatableRowCount( dataTable ); row++ )
+ {
+ BurnReward burnReward
+ burnReward.id = row
+ burnReward.ref = GetDataTableString( dataTable, row, GetDataTableColumnByName( dataTable, BURN_REF_COLUMN_NAME ) )
+ burnReward.localizedName = GetDataTableString( dataTable, row, GetDataTableColumnByName( dataTable, BURN_NAME_COLUMN_NAME ) )
+ burnReward.description = GetDataTableString( dataTable, row, GetDataTableColumnByName( dataTable, BURN_DESCRIPTION_COLUMN_NAME ) )
+ burnReward.image = GetDataTableAsset( dataTable, row, GetDataTableColumnByName( dataTable, BURN_IMAGE_COLUMN_NAME ) )
+ burnReward.cost = GetDataTableFloat( dataTable, row, GetDataTableColumnByName( dataTable, BURN_COST_COLUMN_NAME ) )
+ string userType = GetDataTableString( dataTable, row, GetDataTableColumnByName( dataTable, BURN_AVAILABLE_COLUMN_NAME ) )
+ burnReward.userType = eBurnMeterRewardAvailableFor[userType]
+ burnReward.weaponName = GetDataTableString( dataTable, row, GetDataTableColumnByName( dataTable, BURN_WEAPON_COLUMN_NAME ) )
+ burnReward.extraWeaponMod = GetDataTableString( dataTable, row, GetDataTableColumnByName( dataTable, BURN_EXTRA_WEAPON_MOD_NAME ) )
+ burnReward.activationText = GetDataTableString( dataTable, row, GetDataTableColumnByName( dataTable, "activationText" ) )
+ burnReward.skinIndex = GetDataTableInt( dataTable, row, GetDataTableColumnByName( dataTable, "skinIndex" ) )
+
+ if ( IsDisabledRef( burnReward.ref ) )
+ continue
+
+#if SERVER || CLIENT
+ if ( burnReward.weaponName != "" )
+ PrecacheWeapon( burnReward.weaponName )
+ #endif
+
+ burn.burnRewards[burnReward.ref] <- burnReward
+
+ bool selectable = GetDataTableBool( dataTable, row, GetDataTableColumnByName( dataTable, "selectable" ) )
+ burn.allCards.append( burnReward )
+ if ( selectable )
+ burn.allowedCards.append( burnReward )
+ }
+
+ #if CLIENT
+ //Registering here instead of in CreateWeaponData() in _items.nut to remove dependence on HUD script with items. If more weapons other than smart pistol run into this problem, just add a column in burn_meter_rewards to specify we need to do this. ( ticks are fine because they have a damagedef associated with them )
+ RegisterWeaponDamageSourceName( "mp_weapon_smart_pistol", expect string( GetWeaponInfoFileKeyField_GlobalNotNull( "mp_weapon_smart_pistol", "shortprintname" ) ) )
+
+ RegisterConCommandTriggeredCallback( "-offhand4", CycleOnRelease )
+ #endif
+}
+
+#if SERVER || CLIENT
+bool function BurnMeterEnabled()
+{
+ return Riff_BoostAvailability() != eBoostAvailability.Disabled
+}
+#endif
+
+BurnReward function BurnReward_GetById( int id )
+{
+ return burn.allCards[ id ]
+}
+
+
+BurnReward function BurnReward_GetByRef( string ref )
+{
+ Assert( ref in burn.burnRewards )
+
+ // more hacks for arena
+ if ( !( ref in burn.burnRewards ) && GetCurrentPlaylistVarString( "boost_store_mode", "off" ) == "arena" )
+ return GetArenaLoadoutItemAsBurnReward( ref )
+
+ return burn.burnRewards[ref]
+}
+
+int function GetBoostSkin( string ref )
+{
+ BurnReward reward = BurnReward_GetByRef( ref )
+ //printt( "ref: " + ref + ", Boost skin: " + reward.skinIndex )
+ return reward.skinIndex
+}
+
+
+BurnReward function BurnReward_GetRandom()
+{
+ return burn.allowedCards.getrandom()
+}
+
+string function GetSelectedBurnCardRef( entity player )
+{
+ int burnCardID = expect int ( player.GetPersistentVar( "burnmeterSlot" ) )
+ BurnReward burnCard = burn.allCards[ burnCardID ]
+ string ref = burnCard.ref
+
+ #if SERVER
+ if ( GetItemDisplayData( ref ).hidden )
+ ClientCommand( player, "disconnect" )
+ #endif
+
+ #if SERVER || CLIENT
+
+ if ( Riff_TitanAvailability() == eTitanAvailability.Never )
+ {
+ //JFS: Batteries and Titan turrets are useless in PvP, turn them into amped weapons instead. Not an elegant solution at all. Fix next game. (Make boosts editable mid-match? )
+ if ( ref == "burnmeter_emergency_battery" || ref == "burnmeter_at_turret_weapon" )
+ ref = "burnmeter_amped_weapons"
+ }
+
+ if ( GetCurrentPlaylistVarInt( "featured_mode_all_ticks", 0 ) >= 1 )
+ {
+ if ( ref == "burnmeter_ticks" || ref == "burnmeter_random_foil" )
+ ref = "burnmeter_amped_weapons"
+ }
+ #endif
+
+ return ref
+}
+
+
+#if SERVER || CLIENT
+bool function CanUseWeaponAsBurnCard( entity weapon, entity ownerPlayer )
+{
+ Assert( weapon.HasMod( "burn_card_weapon_mod" ) )
+
+ if ( !BurnMeterPlayer_CanUseEquipped( ownerPlayer ) )
+ {
+ weapon.EmitWeaponSound( "CoOp_SentryGun_DeploymentDeniedBeep" )
+ return false
+ }
+
+ return true
+}
+
+bool function TryUsingBurnCardWeapon( entity weapon, entity ownerPlayer )
+{
+ Assert( weapon.HasMod( "burn_card_weapon_mod" ) )
+
+ if ( !CanUseWeaponAsBurnCard( weapon, ownerPlayer ) )
+ return false
+
+ #if SERVER
+ UseBurnCardWeapon( weapon, ownerPlayer )
+ #endif
+
+ return true
+}
+
+bool function TryUsingBurnCardWeaponInCriticalSection( entity weapon, entity ownerPlayer )
+{
+ Assert( weapon.HasMod( "burn_card_weapon_mod" ) )
+
+ if ( !CanUseWeaponAsBurnCard( weapon, ownerPlayer ) )
+ return false
+
+ #if SERVER
+ UseBurnCardWeaponInCriticalSection( weapon, ownerPlayer )
+ #endif
+
+ return true
+}
+
+
+
+bool function BurnMeterPlayer_CanUseReward( entity player, BurnReward burnReward )
+{
+ if ( !BurnMeterPlayer_CanUseGlobal( player ) )
+ return false
+
+ switch( burnReward.userType )
+ {
+ case eBurnMeterRewardAvailableFor.PILOT_ONLY:
+ return !player.IsTitan()
+
+ case eBurnMeterRewardAvailableFor.TITAN_ONLY:
+ return player.IsTitan()
+
+ case eBurnMeterRewardAvailableFor.PILOT_AND_TITAN:
+ return true
+
+ case eBurnMeterRewardAvailableFor.SPECIAL_PLAYERS_ONLY:
+ return BurnMeterPlayer_CanUseSpecial( player, burnReward ) //TODO: Note that for the case of reaperfall we also send the message to the client if they can't summon reaper in the validation function. Not ideal...
+ }
+
+ unreachable
+
+}
+
+
+bool function BurnMeterPlayer_CanUseEquipped( entity player )
+{
+ BurnReward burnReward = BurnReward_GetTopInventoryItemBurnCard( player )
+ return BurnMeterPlayer_CanUseReward( player, burnReward )
+}
+
+
+EarnObject function BurnMeterPlayer_GetRewardOrGoal( entity player )
+{
+ if ( PlayerEarnMeter_IsRewardEnabled( player ) ) // TODO: more robust
+ return PlayerEarnMeter_GetReward( player )
+ else
+ return PlayerEarnMeter_GetGoal( player )
+
+ unreachable
+}
+
+
+bool function BurnMeterPlayer_CanUseGlobal( entity player )
+{
+ if ( player.IsBot() )
+ return false
+
+ if ( !IsAlive( player ) )
+ return false
+
+ if ( player.IsPhaseShifted() )
+ return false
+
+ if ( player.ContextAction_IsInVehicle() ) //no rewards when in dropship
+ return false
+
+ if ( !IsBurnMeterRewardAvailableForGameState() )
+ return false
+
+ return true
+}
+
+
+bool function IsBurnMeterRewardAvailableForGameState() //Based off IsReplacementTitanAvailable
+{
+ int currentGameState = GetGameState()
+
+ switch ( currentGameState ) //need to add a new entry in here for every new game state we make
+ {
+ case eGameState.WaitingForCustomStart:
+ case eGameState.WaitingForPlayers:
+ case eGameState.PickLoadout:
+ case eGameState.Prematch:
+ case eGameState.SwitchingSides:
+ case eGameState.Postmatch:
+ return false
+
+ case eGameState.Playing:
+ case eGameState.SuddenDeath:
+ return true
+
+ case eGameState.WinnerDetermined:
+ case eGameState.Epilogue:
+ {
+ if ( IsRoundBased() )
+ {
+ // TODO: make this work on the client
+ #if SERVER
+ if ( !IsRoundBasedGameOver() )
+ return false
+
+ if ( !ShouldRunEvac() )
+ return false
+ #endif
+ }
+
+ return true
+ }
+
+ default:
+ Assert( false, "Unknown Game State: " + currentGameState )
+ return false
+ }
+
+ unreachable
+}
+
+
+bool function OnWeaponAttemptOffhandSwitch_burncardweapon( entity weapon )
+{
+ entity ownerPlayer = weapon.GetWeaponOwner()
+ Assert( ownerPlayer.IsPlayer() )
+
+ if ( ownerPlayer.IsUsingOffhandWeapon() )
+ return false
+
+ if ( weapon.HasMod( "burn_card_weapon_mod" ) )
+ {
+ bool canUse = BurnMeterPlayer_CanUseEquipped( ownerPlayer )
+
+ return canUse
+ }
+ else
+ return true
+
+ unreachable
+}
+
+BurnReward function BurnReward_GetTopInventoryItemBurnCard( entity player )
+{
+ int burnRewardID = player.GetPlayerNetInt( TOP_INVENTORY_ITEM_BURN_CARD_ID )
+ return BurnReward_GetById( burnRewardID )
+}
+
+bool function BurnMeterPlayer_CanUseSpecial( entity player, BurnReward burnReward )
+{
+ Assert( burnReward.ref in burnMeterCanUseFuncTable )
+ return burnMeterCanUseFuncTable[ burnReward.ref ]( player )
+}
+
+bool function BurnMeter_HarvesterShieldCanUse( entity player )
+{
+// entity harvester = GetGlobalNetEnt( "FD_activeHarvester" )
+ bool canUse = GetGlobalNetTime( "FD_harvesterInvulTime" ) < Time()
+ // harvester.GetShieldHealth() < harvester.GetShieldHealthMax()
+
+ if ( !canUse )
+ {
+ #if CLIENT
+ AddPlayerHint( 3.0, 0.5, $"", "#HINT_HARVESTER_BOOST_CANT_USE" )
+ #endif
+ }
+
+ return canUse
+}
+
+bool function BurnMeter_NukeTitanCanUse( entity player )
+{
+ bool canUse = BurnMeter_EmergencyTitanCanUse( player )
+
+ if ( !canUse )
+ {
+ #if CLIENT
+ AddPlayerHint( 5.0, 0.5, $"", "#HINT_NUKE_TITAN_CANT_USE" )
+ #endif
+ }
+
+ return canUse
+}
+
+bool function BurnMeter_EmergencyTitanCanUse( entity player )
+{
+ if ( IsAlive( player.GetPetTitan() ) )
+ return false
+
+ #if SERVER
+ if ( !IsReplacementTitanAvailableForGameState() )
+ return false
+
+ if ( player.isSpawning )
+ return false
+
+ return true
+ #endif
+
+ #if CLIENT
+ return true
+ #endif
+}
+
+bool function BurnMeter_SummonReaperCanUse( entity player )
+{
+ array< entity > allReapers = GetNPCArrayByClass( "npc_super_spectre" )
+
+ int playerTeam = player.GetTeam()
+
+ foreach( reaper in allReapers )
+ {
+ if ( reaper.GetTeam() == playerTeam )
+ {
+ #if SERVER
+ MessageToPlayer( player, eEventNotifications.BurnMeter_CantSummonReaper )
+ #endif
+
+ return false
+ }
+ }
+ return true
+}
+
+var function OnWeaponPrimaryAttack_nuke_eject( entity weapon, WeaponPrimaryAttackParams attackParams )
+{
+ #if CLIENT
+ entity weaponOwner = weapon.GetWeaponOwner()
+ if ( weaponOwner.IsPlayer() && IsValid( weaponOwner.GetCockpit() ) )
+ {
+ weaponOwner.ClientCommand( "TitanEject " + 3 )
+ PlayerEjects( weaponOwner, weaponOwner.GetCockpit() ) //Note that this can be run multiple times in a frame, e.g. get damaged by 4 pellets of a shotgun that brings the Titan into a doomed state with auto eject. Not ideal
+ }
+ #endif
+ return 0
+}
+
+#endif
+
+#if CLIENT
+void function CycleOnRelease( entity player )
+{
+ if ( file.shouldCycleOnRelease )
+ {
+ CycleInventory( player )
+ file.shouldCycleOnRelease = false
+ }
+}
+#endif
+
+array<string> function GetAllBoostTurretTypes()
+{
+ return turretBurnCards
+} \ No newline at end of file
diff --git a/Northstar.Custom/scripts/vscripts/client/cl_gamestate.gnut b/Northstar.Custom/mod/scripts/vscripts/client/cl_gamestate.gnut
index 93be01ea..93be01ea 100644
--- a/Northstar.Custom/scripts/vscripts/client/cl_gamestate.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/client/cl_gamestate.gnut
diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_arena.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_arena.gnut
new file mode 100644
index 00000000..1765fd9b
--- /dev/null
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_arena.gnut
@@ -0,0 +1,185 @@
+global function GameModeArena_Init
+
+struct {
+ bool inBuyPhase
+
+ entity imcBoostStore
+ entity militiaBoostStore
+
+ entity imcShield
+ entity militiaShield
+} file
+
+void function GameModeArena_Init()
+{
+ SetSpawnpointGamemodeOverride( TEAM_DEATHMATCH )
+
+ SetShouldUseRoundWinningKillReplay( true )
+ SetRoundBased( true )
+ SetRespawnsEnabled( false )
+ SetLoadoutGracePeriodEnabled( false ) // prevent modifying loadouts with grace period
+ Riff_ForceTitanAvailability( eTitanAvailability.Never )
+ Riff_ForceBoostAvailability( eBoostAvailability.Disabled )
+ Riff_ForceSetEliminationMode( eEliminationMode.Pilots )
+
+ ClassicMP_SetCustomIntro( GameModeArena_BuyPhaseSetup, 30.0 )
+ AddCallback_EntitiesDidLoad( CreateBoostStores )
+ AddCallback_OnPlayerRespawned( SetupArenaLoadoutForPlayer )
+}
+
+// intro / buy phase
+
+void function GameModeArena_BuyPhaseSetup()
+{
+ AddCallback_OnClientConnected( SpawnPlayerIntoArenasIntro )
+ AddCallback_GameStateEnter( eGameState.Prematch, void function() { thread BuyPhase() } )
+}
+
+void function SpawnPlayerIntoArenasIntro( entity player )
+{
+ if ( GetGameState() == eGameState.Prematch )
+ RespawnAsPilot( player )
+}
+
+void function CreateBoostStores()
+{
+ array<entity> startspawns = GetEntArrayByClass_Expensive( "info_spawnpoint_human_start" ) // easier to do this than use a spawn callback imo
+
+ vector imcAverageOrigin
+ float imcAverageAngle
+ int imcNumSpawns
+
+ vector militiaAverageOrigin
+ float militiaAverageAngle
+ int militiaNumSpawns
+
+ foreach ( entity startspawn in startspawns )
+ {
+ if ( !startspawn.HasKey( "gamemode_tdm" ) || startspawn.kv.gamemode_tdm == "0" )
+ continue
+
+ if ( startspawn.GetTeam() == TEAM_IMC )
+ {
+ imcAverageOrigin += startspawn.GetOrigin()
+ imcAverageAngle += startspawn.GetAngles().y
+ imcNumSpawns++
+ }
+ else
+ {
+ militiaAverageOrigin += startspawn.GetOrigin()
+ militiaAverageAngle += startspawn.GetAngles().y
+ militiaNumSpawns++
+ }
+ }
+
+ // create imc boost store
+ vector finalPositionImc = < imcAverageOrigin.x / imcNumSpawns, imcAverageOrigin.y / imcNumSpawns, imcAverageOrigin.z / imcNumSpawns >
+ finalPositionImc += ( 200 * AnglesToForward( < 0, imcAverageAngle / imcNumSpawns, 0 > ) )
+ CreateBoostStoreLocation( TEAM_IMC, finalPositionImc, < 0, 0, 0 >, true )
+
+ vector finalPositionMilitia = < militiaAverageOrigin.x / militiaNumSpawns, militiaAverageOrigin.y / militiaNumSpawns, militiaAverageOrigin.z / militiaNumSpawns >
+ finalPositionMilitia += ( 200 * AnglesToForward( < 0, militiaAverageAngle / militiaNumSpawns, 0 > ) )
+ CreateBoostStoreLocation( TEAM_MILITIA, finalPositionMilitia, < 0, 0, 0 >, true )
+
+ // createbooststorelocation is void so have to do this
+ // also boost store code is just fully fucked lol, teams only get set on open so can't compare teams at this point
+ // sorry if someone else makes their own boost stores lol this'll just break
+ // if there's some way to get the invisible crates used for boost stores i will be very happy
+
+ if ( GetBoostStores().len() != 2 )
+ print( "_gamemode_arena.gnut: there are more than 2 boost stores, very bad no good" )
+
+ file.imcBoostStore = GetBoostStores()[0]
+ file.militiaBoostStore = GetBoostStores()[1]
+}
+
+void function BuyPhase()
+{
+ ClassicMP_OnIntroStarted()
+
+ foreach ( entity player in GetPlayerArray() )
+ {
+ ScreenFadeFromBlack( player )
+ RespawnAsPilot( player )
+
+ AddMoneyToPlayer( player, GetCashBoostForRoundCount( GetRoundsPlayed() ) )
+ }
+
+ SetJoinInProgressBonus( GetCashBoostForRoundCount( GetRoundsPlayed() ) )
+
+ // sort of a hack, set up a new intro here, so dropship intro only ever plays once
+
+ //file.imcShield = CreateBubbleShieldWithSettings( TEAM_IMC, file.imcBoostStore.GetOrigin(), <0,0,0>, null, 15.0 )
+ //file.militiaShield = CreateBubbleShieldWithSettings( TEAM_MILITIA, file.militiaBoostStore.GetOrigin(), <0,0,0>, null, 15.0 )
+
+ entity imcShield = CreateEntity( "prop_dynamic" )
+ imcShield.SetValueForModelKey( $"models/fx/xo_shield.mdl" )
+ imcShield.kv.solid = 0
+ imcShield.kv.rendercolor = "255 255 255" // white
+ imcShield.kv.modelscale = 2.25
+ imcShield.SetOrigin( file.imcBoostStore.GetOrigin() )
+ DispatchSpawn( imcShield )
+
+ entity militiaShield = CreateEntity( "prop_dynamic" )
+ militiaShield.SetValueForModelKey( $"models/fx/xo_shield.mdl" )
+ militiaShield.kv.solid = 0
+ militiaShield.kv.rendercolor = "255 255 255" // white
+ militiaShield.kv.modelscale = 2.25
+ militiaShield.SetOrigin( file.militiaBoostStore.GetOrigin() )
+ DispatchSpawn( militiaShield )
+
+ // current problem, there is seemingly no way of getting a shield we can resize which actually resizes the collision
+ // could probably just damage players that try to leave lol
+
+ OpenBoostStores()
+
+ thread DamageLeavingPlayers( imcShield.GetOrigin(), militiaShield.GetOrigin() )
+
+ wait 30.0 // intro length
+
+ CloseBoostStores()
+ imcShield.Destroy()
+ militiaShield.Destroy()
+
+ foreach ( entity player in GetPlayerArray() )
+ if ( player.GetMainWeapons().len() != 3 )
+ player.GiveWeapon( "mp_weapon_semipistol" )
+
+ ClassicMP_OnIntroFinished()
+}
+
+void function DamageLeavingPlayers( vector imcOrigin, vector militiaOrigin )
+{
+ while ( GetGameState() == eGameState.Prematch )
+ {
+ wait 0.5
+ foreach ( entity player in GetPlayerArray() )
+ {
+ vector pos = imcOrigin
+ if ( player.GetTeam() == TEAM_MILITIA )
+ pos = militiaOrigin
+
+ if ( Distance( player.GetOrigin(), pos ) > 510.0 ) // roughly the size of the shield
+ player.TakeDamage( 25, svGlobal.worldspawn, svGlobal.worldspawn, {} )
+ }
+ }
+}
+
+void function SetupArenaLoadoutForPlayer( entity player )
+{
+ PilotLoadoutDef playerLoadout = clone GetActivePilotLoadout( player )
+
+ if ( GetGameState() == eGameState.Prematch ) // buy phase
+ {
+ playerLoadout.primary = ""
+ playerLoadout.primaryMods = []
+ playerLoadout.secondary = ""
+ playerLoadout.secondaryMods = []
+ playerLoadout.weapon3 = ""
+ playerLoadout.weapon3Mods = []
+ playerLoadout.ordnance = ""
+ playerLoadout.special = ""
+ }
+
+ GivePilotLoadout( player, playerLoadout )
+} \ No newline at end of file
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_fastball.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball.gnut
index 815a2bb2..b59cd2dd 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_fastball.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball.gnut
@@ -75,7 +75,7 @@ void function GamemodeFastball_Init()
FastballAddBuddySpawnForLevel( "mp_grave", TEAM_MILITIA, < 11026.8, -5163.18, 1885.64 >, < 0, 155.05, 0 > )
FastballAddBuddySpawnForLevel( "mp_grave", TEAM_IMC, < -1952, -3120, 1993.33 >, < 0, 0, 0 > )
FastballAddPanelSpawnsForLevel( "mp_grave", [
- < 5204.54, -2726.54, 2376.03 >, < 0, 90, 0 >,
+ < 5204.54, -2726.54, 2376.03 >, < 0, -90, 0 >,
< 6001.58, -4126.61, 2252.03 >, < 0, -135, 0 >,
< 3595.96, -4568.04, 2376.03 >, < 0, -135, 0 >
])
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_fastball_intro.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball_intro.gnut
index 75482558..75482558 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_fastball_intro.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball_intro.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_gg.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_gg.gnut
index b9ee40f1..b9ee40f1 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_gg.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_gg.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_inf.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_inf.gnut
index 8706d53b..8706d53b 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_inf.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_inf.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_kr.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_kr.gnut
index cf9d6bc5..cf9d6bc5 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_kr.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_kr.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_sbox.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_sbox.gnut
index 27581aea..27581aea 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_sbox.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_sbox.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_tt.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_tt.gnut
index 6a53ef87..6a53ef87 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_tt.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_tt.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/_riff_instagib.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_riff_instagib.gnut
index b3868359..b3868359 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/_riff_instagib.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_riff_instagib.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_arena.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_arena.gnut
index a0e8618f..632a7efc 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_arena.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_arena.gnut
@@ -8,10 +8,15 @@ struct {
void function ClGameModeArena_Init()
{
AddCallback_OnClientScriptInit( CreateArenaUI )
+
+ RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_INTRO, "music_mp_fd_intro_easy", TEAM_MILITIA )
+ RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_INTRO, "music_mp_fd_intro_easy", TEAM_IMC )
}
void function CreateArenaUI( entity player )
{
+ AddEventNotificationCallback( eEventNotifications.FD_BoughtItem, void function( entity e, var v ) {} )
+
var rui = CreateCockpitRui( $"ui/fd_score_splash.rpak", 500 )
RuiTrackInt( rui, "pointValue", player, RUI_TRACK_SCRIPT_NETWORK_VAR_INT, GetNetworkedVariableIndex( "FD_money" ) )
RuiTrackInt( rui, "pointStack", player, RUI_TRACK_SCRIPT_NETWORK_VAR_INT, GetNetworkedVariableIndex( "FD_money256" ) )
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_fastball.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_fastball.gnut
index 80dc548a..80dc548a 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_fastball.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_fastball.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_gg.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_gg.gnut
index de8a3449..de8a3449 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_gg.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_gg.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_inf.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_inf.gnut
index 56763bd4..56763bd4 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_inf.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_inf.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_kr.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_kr.gnut
index 269057c7..269057c7 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_kr.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_kr.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_tt.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_tt.gnut
index b73ed958..b73ed958 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/cl_gamemode_tt.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_tt.gnut
diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_arena_loadouts.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_arena_loadouts.gnut
new file mode 100644
index 00000000..ae0fa7d6
--- /dev/null
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_arena_loadouts.gnut
@@ -0,0 +1,98 @@
+// the purpose of this script is basically just to provide methods that are used in modified burnmeter and boost_store scripts to get custom items to work
+
+global function InitialiseArenaLoadouts
+global function PopulateArenaLoadouts
+global function GetArenaLoadoutForRoundCount
+global function GetArenaLoadoutItemAsBurnReward
+global function GetCashBoostForRoundCount
+
+#if SERVER
+ global function GivePlayerArenaLoadoutItem
+#endif
+
+const int ABILITY_ROUND = 2
+const int CRATE_ROUND = 4
+const int TITAN_ROUND = 7
+
+struct {
+ array<BoostStoreData> tier0Weapons
+ array<BoostStoreData> tier1Weapons
+ array<BoostStoreData> antiTitanWeapons
+
+ BoostStoreData droppodRespawn
+ BoostStoreData titanBattery
+ BoostStoreData titanfall
+} file
+
+void function InitialiseArenaLoadouts()
+{
+ BoostStoreData g2Data = { itemRef="mp_weapon_g2", modesAllowed="arena", cost=75, ... }
+ file.tier0Weapons.append( g2Data )
+
+ BoostStoreData flatlineData = { itemRef="mp_weapon_vinson", modesAllowed="arena", cost=125, ... }
+ file.tier0Weapons.append( flatlineData )
+
+ BoostStoreData wingmanData = { itemRef="mp_weapon_wingman", modesAllowed="arena", cost=50, ... }
+ file.tier0Weapons.append( wingmanData )
+
+ BoostStoreData respawnData = { itemRef="droppodRespawn", modesAllowed="arena", cost=50, ... }
+ file.tier0Weapons.append( respawnData )
+
+ #if SERVER
+ SetBoostPurchaseCallback( GivePlayerArenaLoadoutItem )
+ #endif
+}
+
+array<BoostStoreData> function PopulateArenaLoadouts()
+{
+ return GetArenaLoadoutForRoundCount( 0 )
+}
+
+array<BoostStoreData> function GetArenaLoadoutForRoundCount( int round )
+{
+ return file.tier0Weapons
+}
+
+BurnReward function GetArenaLoadoutItemAsBurnReward( string itemRef )
+{
+ BurnReward reward
+ reward.ref = itemRef
+ reward.localizedName = itemRef
+
+ return reward
+}
+
+bool function ArenaLoadoutItemIsWeapon( string item )
+{
+ if ( item.find( "mp_weapon" ) == 0 )
+ return true
+
+ return false
+}
+
+int function GetCashBoostForRoundCount( int round )
+{
+ if ( round == 0 )
+ return 150
+
+ if ( round < 4 )
+ return 250
+
+ return 350
+}
+
+#if SERVER
+ void function GivePlayerArenaLoadoutItem( entity player, BoostStoreData item )
+ {
+ if ( ArenaLoadoutItemIsWeapon( item.itemRef ) )
+ {
+ array<string> mods
+ // apply mods
+ //if ( item.itemRef = "mp_weapon_wingman" )
+
+ player.GiveWeapon( item.itemRef, mods )
+ player.SetActiveWeaponByName( item.itemRef )
+ return
+ }
+ }
+#endif \ No newline at end of file
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_arena.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_arena.gnut
index b634f1d3..b634f1d3 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_arena.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_arena.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_bomb.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_bomb.gnut
index e69de29b..e69de29b 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_bomb.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_bomb.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_ctf_comp.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_ctf_comp.gnut
index 1a1ce645..1a1ce645 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_ctf_comp.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_ctf_comp.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_fastball.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_fastball.gnut
index 2462d537..2462d537 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_fastball.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_fastball.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_fw_custom.nut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_fw_custom.nut
index 8c6e3f63..8c6e3f63 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_fw_custom.nut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_fw_custom.nut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_gg.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_gg.gnut
index c4021a3c..c4021a3c 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_gg.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_gg.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_inf.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_inf.gnut
index bcd86378..bcd86378 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_inf.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_inf.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_kr.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_kr.gnut
index 7cd91de9..7cd91de9 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_kr.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_kr.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_sbox.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_sbox.gnut
index 893d9410..893d9410 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_sbox.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_sbox.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_tt.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_tt.gnut
index f3fbff28..f3fbff28 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/sh_gamemode_tt.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_tt.gnut
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/sh_riff_floor_is_lava.nut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_riff_floor_is_lava.nut
index 3a8ac8e7..3a8ac8e7 100644
--- a/Northstar.Custom/scripts/vscripts/gamemodes/sh_riff_floor_is_lava.nut
+++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_riff_floor_is_lava.nut
diff --git a/Northstar.Custom/scripts/vscripts/lobby/sh_private_lobby_custom_modes_init.gnut b/Northstar.Custom/mod/scripts/vscripts/lobby/sh_private_lobby_custom_modes_init.gnut
index 81c08f22..81c08f22 100644
--- a/Northstar.Custom/scripts/vscripts/lobby/sh_private_lobby_custom_modes_init.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/lobby/sh_private_lobby_custom_modes_init.gnut
diff --git a/Northstar.Custom/scripts/vscripts/mp/levels/mp_box.nut b/Northstar.Custom/mod/scripts/vscripts/mp/levels/mp_box.nut
index a1828009..a1828009 100644
--- a/Northstar.Custom/scripts/vscripts/mp/levels/mp_box.nut
+++ b/Northstar.Custom/mod/scripts/vscripts/mp/levels/mp_box.nut
diff --git a/Northstar.Custom/scripts/vscripts/northstar_custom_autoprecache.gnut b/Northstar.Custom/mod/scripts/vscripts/northstar_custom_autoprecache.gnut
index 62d089f7..1d5b7ba9 100644
--- a/Northstar.Custom/scripts/vscripts/northstar_custom_autoprecache.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/northstar_custom_autoprecache.gnut
@@ -10,5 +10,5 @@ void function NorthstarCustomAutoprecache()
PrecacheWeapon( "mp_weapon_toolgun" )
// will include this as a custom asset when mod v2 is written
- //PrecacheModel( $"models/titans/buddy/titan_buddy.mdl" )
+ PrecacheModel( $"models/SPOILER_w_titan_particle_accelerator.mdl" )
} \ No newline at end of file
diff --git a/Northstar.Custom/scripts/vscripts/titan/sh_first_person_embark.gnut b/Northstar.Custom/mod/scripts/vscripts/titan/sh_first_person_embark.gnut
index 0c95ae4c..0c95ae4c 100644
--- a/Northstar.Custom/scripts/vscripts/titan/sh_first_person_embark.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/titan/sh_first_person_embark.gnut
diff --git a/Northstar.Custom/scripts/vscripts/titan/sh_titan_embark.gnut b/Northstar.Custom/mod/scripts/vscripts/titan/sh_titan_embark.gnut
index f9df2730..f9df2730 100644
--- a/Northstar.Custom/scripts/vscripts/titan/sh_titan_embark.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/titan/sh_titan_embark.gnut
diff --git a/Northstar.Custom/scripts/vscripts/weapons/mp_weapon_peacekraber.nut b/Northstar.Custom/mod/scripts/vscripts/weapons/mp_weapon_peacekraber.nut
index a9da541f..a9da541f 100644
--- a/Northstar.Custom/scripts/vscripts/weapons/mp_weapon_peacekraber.nut
+++ b/Northstar.Custom/mod/scripts/vscripts/weapons/mp_weapon_peacekraber.nut
diff --git a/Northstar.Custom/scripts/vscripts/weapons/mp_weapon_toolgun.nut b/Northstar.Custom/mod/scripts/vscripts/weapons/mp_weapon_toolgun.nut
index 94bd7429..94bd7429 100644
--- a/Northstar.Custom/scripts/vscripts/weapons/mp_weapon_toolgun.nut
+++ b/Northstar.Custom/mod/scripts/vscripts/weapons/mp_weapon_toolgun.nut
diff --git a/Northstar.Custom/scripts/vscripts/weapons/toolgun/sh_toolgun_tool_explode.nut b/Northstar.Custom/mod/scripts/vscripts/weapons/toolgun/sh_toolgun_tool_explode.nut
index 512c538c..512c538c 100644
--- a/Northstar.Custom/scripts/vscripts/weapons/toolgun/sh_toolgun_tool_explode.nut
+++ b/Northstar.Custom/mod/scripts/vscripts/weapons/toolgun/sh_toolgun_tool_explode.nut
diff --git a/Northstar.Custom/scripts/vscripts/weapons/toolgun/sh_toolgun_tool_throw.nut b/Northstar.Custom/mod/scripts/vscripts/weapons/toolgun/sh_toolgun_tool_throw.nut
index d6975c6d..d6975c6d 100644
--- a/Northstar.Custom/scripts/vscripts/weapons/toolgun/sh_toolgun_tool_throw.nut
+++ b/Northstar.Custom/mod/scripts/vscripts/weapons/toolgun/sh_toolgun_tool_throw.nut
diff --git a/Northstar.Custom/scripts/vscripts/weapons/toolgun/sh_toolgun_tools.gnut b/Northstar.Custom/mod/scripts/vscripts/weapons/toolgun/sh_toolgun_tools.gnut
index 4d7e9d89..4d7e9d89 100644
--- a/Northstar.Custom/scripts/vscripts/weapons/toolgun/sh_toolgun_tools.gnut
+++ b/Northstar.Custom/mod/scripts/vscripts/weapons/toolgun/sh_toolgun_tools.gnut
diff --git a/Northstar.Custom/scripts/weapons/melee_pilot_emptyhanded.txt b/Northstar.Custom/mod/scripts/weapons/melee_pilot_emptyhanded.txt
index 032867af..032867af 100644
--- a/Northstar.Custom/scripts/weapons/melee_pilot_emptyhanded.txt
+++ b/Northstar.Custom/mod/scripts/weapons/melee_pilot_emptyhanded.txt
diff --git a/Northstar.Custom/scripts/weapons/melee_pilot_kunai.txt b/Northstar.Custom/mod/scripts/weapons/melee_pilot_kunai.txt
index e8b7c181..e8b7c181 100644
--- a/Northstar.Custom/scripts/weapons/melee_pilot_kunai.txt
+++ b/Northstar.Custom/mod/scripts/weapons/melee_pilot_kunai.txt
diff --git a/Northstar.Custom/scripts/weapons/mp_weapon_peacekraber.txt b/Northstar.Custom/mod/scripts/weapons/mp_weapon_peacekraber.txt
index c5e61f93..c5e61f93 100644
--- a/Northstar.Custom/scripts/weapons/mp_weapon_peacekraber.txt
+++ b/Northstar.Custom/mod/scripts/weapons/mp_weapon_peacekraber.txt
diff --git a/Northstar.Custom/scripts/weapons/mp_weapon_sniper.txt b/Northstar.Custom/mod/scripts/weapons/mp_weapon_sniper.txt
index ede43d7d..ede43d7d 100644
--- a/Northstar.Custom/scripts/weapons/mp_weapon_sniper.txt
+++ b/Northstar.Custom/mod/scripts/weapons/mp_weapon_sniper.txt
diff --git a/Northstar.Custom/scripts/weapons/mp_weapon_toolgun.txt b/Northstar.Custom/mod/scripts/weapons/mp_weapon_toolgun.txt
index 37e9bc25..37e9bc25 100644
--- a/Northstar.Custom/scripts/weapons/mp_weapon_toolgun.txt
+++ b/Northstar.Custom/mod/scripts/weapons/mp_weapon_toolgun.txt
diff --git a/Northstar.Custom/playlists_v2.txt b/Northstar.Custom/playlists_v2.txt
deleted file mode 100644
index 56b56603..00000000
--- a/Northstar.Custom/playlists_v2.txt
+++ /dev/null
@@ -1,5859 +0,0 @@
-playlists
-{
- version stable
- versionNum 3246
- Gamemodes
- {
- defaults
- {
- vars
- {
- pve_menu 0
- enable_emotes 0
- boost_store_mode off
-
- enable_lts_style_loadout_select 0
- pick_loadout_extension 0
- pick_loadout_every_round 0
- pick_loadout_warp_sound 1
- tts_menu_join_in_progress 0
- tts_menu_show_score 1
- ingame_menu_fd_mode 0
- limited_editions_available 1
-
- ai_attack_tethers 1
- enable_sun_flare_mp_thaw 0
- enable_sun_flare_mp_forwardbase_kodai 0
- enable_sun_flare_mp_colony02 0
- enable_coliseum_updates 1
- enable_coliseum_party 1
- enable_spectre_hacking 0
- maphack_on_minimap_only 0
- mp_angel_city_available 1
- angel_city_replacement groundwar
- angel_city_replacement_index 8
- double_xp_enabled 0
- skyshow_enabled 0
- loadout_selection_enabled 1
- ai_kill_credit 3
- always_enable_autotitans 1
- at_turrets_enabled 1
- burn_meter_enabled 1
- classic_mp 1
- cmdlineMapLoad 0
- em_npc_fast_kills 20
- em_npc_kills 20
- em_player_fast_kills 5
- em_player_kills 8
- enable_titanfalls 1
- evac_dropship_kill_credit 60
- event_airdrops_enabled 0
- event_airdrops_respawnTime 180
- firstpersonspectate_enabled 1
- gamemode_uses_custom_countdown 0
- hud_score_enabled 1
- infinite_doomed_state 1
- loadout_grace_period 20.0
- lobby_countdown 60
- lobby_countdown_min 30
- max_players 16
- max_teams 2
- matchLossProtectionThreshold 10
- megaturret_kill_credit 20
- minimap_sonar_pulse_on_respawn 0
- player_embark_in_solid_checks 1
- player_kill_credit 10
- power_ups_enabled 0
- r2_titan_models 1
- ranked_wlpct_at 0.05
- ranked_wlpct_cp 0.15
- ranked_wlpct_ctf 0.15
- ranked_wlpct_def 0.1
- ranked_wlpct_lts 0.15
- ranked_wlpct_mfd 0.1
- ranked_wlpct_ps 0.05
- ranking_supported 1
- riff_ai_lethality 1
- riff_allow_npcs 2
- riff_ammo_limit 0
- riff_elimination 0
- riff_floorislava 0
- riff_minimap_state 0
- riff_osp 0
- riff_spawn_as_titan 0
- riff_titan_availability 0
- riff_titan_exit_enabled 0
- riff_titan_queue 0
- riff_wave_spawn 0
- rodeo_battery_disembark_to_pickup 1
- maxExtraRounds -1
- rts_style_health_bars 1
- run_evac 0
- script_leak 0
- spectre_kill_credit 9
- target_health_bar 1
- titan_build_credit_enabled 1
- titan_build_time 180
- titan_build_time_use_set_file 0
- titan_core_build_time 200
- titan_core_from_titan_damage 1
- titan_doomstate_variation default
- titan_health_bar_display default
- titan_health_chicklet_fx 0
- titan_kill_credit 30
- titan_mode_change_allowed 1
- titan_rebuild_time 180
- titan_shield_decay 0
- titan_shield_regen 0
- titan_spawn_deploy_enabled 1
- vortex_blocks_melee 0
- waiting_for_players_countdown_seconds 0
- waiting_for_players_percentage_desired 70
- waiting_for_players_timeout_seconds 45
- wait_before_restarting_matchmaking_time 20
- gm_hardcore_settings 0
- spawn_zone_enabled 0
- is_e3_mode 0
- fast_tdm 0
- arena_loadout 0
- fd_difficulty 0
- featured_mode_amped_tacticals 0
- featured_mode_tactikill 0
- featured_mode_all_grapple 0
- featured_mode_all_holopilot 0
- featured_mode_all_phase 0
- featured_mode_all_ticks 0
- featured_mode_rocket_arena 0
- featured_mode_turbo_titans 0
- featured_mode_shotguns_snipers 0
-
- // defaults for private_match settings, as all gamemodes don't explicitly set their own
- boosts_enabled 0
- respawn_delay 0.0
-
- //No longer used? No references in script for these
- xp2coins_modifier 0.1
- titan_shield_health 0
- titan_rodeo_variation 1
- titan_segmented_health 0
- titan_health_regen 0
- titan_burncard_rate 28
- shop_price_modifier 1.0
- show_enemy_death_icons 0
- show_friendly_icon 1
- rtdm_roundscorelimit 2
- rtdm_roundtimelimit 4
- rtdm_scorelimit 20
- prematch_time 30
- always_titan 0
- amped_capture_points 0
- nwrp_enabled 1
- pilot_burncard_rate 55
- kill_for_titan 6
- hud_weapons_enabled 1
- grunt_burncard_rate 95
- bc_base_cards 46
- bc_stash_bonus_per_gen 6
- burncards_enabled 0
- cinematic_mode 0
- coins_bc_sale_modifier 1.0
- coins_earn_modifier 1.0
- em_decay_hold 10
- force_quick_play 0
- //End of list
-
- faq_patchnotes_version 11
- faq_patchnotes_count 10
-
- faq_community_version 10
- faq_community_url_00 "https://www.youtube.com/embed/SbdQPdaPme4?autoplay=1"
- faq_community_url_01 "https://forums.titanfall.com/en-us/discussion/14073/postcards-from-the-frontier-the-patch-notes#latest"
- faq_community_url_02 "https://www.youtube.com/embed/KyywlZHh3-Q?autoplay=1"
- faq_community_url_03 "https://www.youtube.com/embed/1LAlKi6E8DY?autoplay=1"
- faq_community_url_04 "https://www.youtube.com/embed/pzmrZBiLyhE?autoplay=1"
- faq_community_url_05 "https://www.youtube.com/embed/XBP3Ic0UiQY?autoplay=1"
- faq_community_url_06 "https://gfycat.com/gifs/detail/ScornfulAnyHamadryad"
- faq_community_url_07 "https://www.youtube.com/embed/fE7_tVG_t28?autoplay=1"
- faq_community_url_08 "https://www.youtube.com/embed/RO7QJ5YEa24?autoplay=1"
- faq_community_url_09 "https://www.youtube.com/embed/rMeaxj8k_3U?autoplay=1"
- faq_community_url_10 "https://www.youtube.com/embed/JKiuY3Ocwzo?autoplay=1"
- faq_community_url_11 "https://www.youtube.com/embed/fCCckqclBoA?autoplay=1"
- faq_community_url_12 "https://www.youtube.com/embed/4MMtDSrcXYU?autoplay=1"
- faq_community_url_13 "http://www.youtube.com/embed/I_6hViuy3kc?autoplay=1"
- faq_community_url_14 "http://www.youtube.com/embed/Wtu3fUs9i7M?autoplay=1"
- faq_community_url_15 "http://www.youtube.com/embed/EXwdWuSuiYA?autoplay=1"
- faq_community_url_16 "http://www.youtube.com/embed/nHvoaAAhGno?autoplay=1"
- faq_community_count 17
-
- mixtape_matchmaking 1 // 0 = old style, 1 = new style
- mixtape_version 2 // bump to re-trigger the "NEW!" notify.
- mixtape_checkbox_memory_version 2 // bump to re-enable all checkboxes
- mixtape_skip_button 0 // disable to not show the 'Y Skip' prompt
- mixtape_onboarding "aitdm,cp,aitdm,cp,ffa "
-
- gamemode_name ""
- gamemode_hint ""
- gamemode_score_hint ""
- gamemode_bullet_001 ""
- gamemode_bullet_002 ""
- gamemode_bullet_003 ""
- gamemode_bullet_004 ""
- gamemode_bullet_005 ""
-
- coliseum_primary "mp_weapon_lstar"
- coliseum_primary_attachment ""
- coliseum_primary_mod1 ""
- coliseum_primary_mod2 ""
- coliseum_primary_mod3 ""
- coliseum_secondary "mp_weapon_softball"
- coliseum_secondary_mod1 ""
- coliseum_secondary_mod2 ""
- coliseum_secondary_mod3 ""
- coliseum_weapon3 ""
- coliseum_weapon3_mod1 ""
- coliseum_weapon3_mod2 ""
- coliseum_weapon3_mod3 ""
- coliseum_melee "melee_pilot_emptyhanded"
- coliseum_special "mp_ability_heal"
- coliseum_ordnance "mp_weapon_frag_drone"
- coliseum_passive1 "pas_fast_health_regen"
- coliseum_passive2 "pas_wallhang"
-
- idlekick_minutes 3
- idlekick_min_alive_seconds 40
-
- fd_tutorial_title "#WATCH_TUTORIAL"
- fd_tutorial_url "https://www.youtube.com/watch?v=8wS8NQ0XW-w"
-
- "generic_dialog_header_30" "#MATCHMAKING_PENALTY_ACTIVE"
- "generic_dialog_message_36" "#MATCHMAKING_PENALTY_GE_5"
- "generic_dialog_message_35" "#MATCHMAKING_PENALTY_5"
- "generic_dialog_message_34" "#MATCHMAKING_PENALTY_4"
- "generic_dialog_message_33" "#MATCHMAKING_PENALTY_3"
- "generic_dialog_message_32" "#MATCHMAKING_PENALTY_2"
- "generic_dialog_message_31" "#MATCHMAKING_PENALTY_1"
- }
- maps
- {
- mp_black_water_canal 1
- mp_complex3 1
- mp_crashsite3 1
- mp_drydock 1
- mp_eden 1
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_angel_city 1
- mp_colony02 1
- mp_relic02 1
- mp_wargames 1
- mp_glitch 1
- mp_rise 1
- }
- }
- at
- {
- inherit defaults
- vars
- {
- name #PL_attrition
- lobbytitle #PL_attrition_lobby
- description #PL_attrition_desc
- hint #PL_attrition_hint
- abbreviation #PL_attrition_abbr
- em_player_fast_kills 12
- em_player_kills 15
- max_players 10
- riff_allow_npcs 1
- scorelimit 5000
- suddendeath_timelimit 2
- timelimit 15
- titan_build_time 240
- titan_rebuild_time 240
- spawn_zone_enabled 1
- color "183 60 0 255"
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_AT
- gamemode_bullet_001 #GAMEMODE_BULLET_AT_001
- gamemode_bullet_002 #GAMEMODE_BULLET_AT_002
- gamemode_bullet_003 #GAMEMODE_BULLET_AT_003
- gamemode_bullet_004 #GAMEMODE_BULLET_AT_004
- gamemode_bullet_005 #GAMEMODE_BULLET_AT_005
- }
- }
- coliseum
- {
- inherit defaults
- vars
- {
- name #PL_coliseum
- lobbytitle #PL_coliseum_lobby
- description #PL_coliseum_desc
- hint #PL_coliseum_hint
- image coliseum
- classic_mp 1
- infinite_doomed_state 0
- power_ups_enabled 1
- roundscorelimit 3
- roundtimelimit 3.0
- suddendeath_timelimit 0.5
- max_players 2
- scorelimit 3
- timelimit 15
- loadout_selection_enabled 0
- waiting_for_players_countdown_seconds 10
- waiting_for_players_percentage_desired 100
- waiting_for_players_timeout_seconds 60
-
- color "88 151 220 255"
- }
- maps
- {
- mp_coliseum 1
- mp_coliseum_column 1
- }
- }
- cp
- {
- inherit defaults
- vars
- {
- name #PL_hardpoint
- lobbytitle #PL_hardpoint_lobby
- description #PL_hardpoint_desc
- hint #PL_hardpoint_hint
- abbreviation #PL_hardpoint_abbr
- image cp
- amped_capture_points 1
- scorelimit 400
- suddendeath_timelimit 2
- timelimit 10
- max_players 12
- color "161 204 255 255"
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_CP
- gamemode_bullet_001 #GAMEMODE_BULLET_CP_001
- gamemode_bullet_002 #GAMEMODE_BULLET_CP_002
- gamemode_bullet_003 #GAMEMODE_BULLET_CP_003
- gamemode_bullet_004 #GAMEMODE_BULLET_CP_004
- gamemode_bullet_005 #GAMEMODE_BULLET_CP_005
- }
- }
- ctf
- {
- inherit defaults
- vars
- {
- name #PL_capture_the_flag
- lobbytitle #PL_capture_the_flag_lobby
- description #PL_capture_the_flag_desc
- hint #PL_capture_the_flag_hint
- abbreviation #PL_capture_the_flag_abbr
- image ctf
- respawn_delay 8
- scorelimit 5
- suddendeath_timelimit 2
- timelimit 12
- max_players 10
- phase_shift_drop_flag 1
- ctf_flag_return_time 1
- color "0 119 245 255"
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_CTF
- gamemode_bullet_001 #GAMEMODE_BULLET_CTF_001
- gamemode_bullet_002 #GAMEMODE_BULLET_CTF_002
- gamemode_bullet_003 #GAMEMODE_BULLET_CTF_003
- gamemode_bullet_004 #GAMEMODE_BULLET_CTF_004
- gamemode_bullet_005 #GAMEMODE_BULLET_CTF_005
- }
- }
- ffa
- {
- inherit defaults
- vars
- {
- name #PL_ffa
- lobbytitle #PL_ffa_lobby
- description #PL_ffa_desc
- hint #PL_ffa_hint
- abbreviation #PL_ffa_abbr
- image ffa
- at_turrets_enabled 1
- max_players 12
- max_teams 12
- scorelimit 25
- waiting_for_players_countdown_seconds 1
- waiting_for_players_percentage_desired 10
- color "246 127 1 255"
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_FFA
- gamemode_bullet_001 #GAMEMODE_BULLET_FFA_001
- gamemode_bullet_002 #GAMEMODE_BULLET_FFA_002
- gamemode_bullet_003 #GAMEMODE_BULLET_FFA_003
- gamemode_bullet_004 #GAMEMODE_BULLET_FFA_004
- gamemode_bullet_005 #GAMEMODE_BULLET_FFA_005
- }
- }
- fra
- {
- inherit defaults
- vars
- {
- name #PL_fra
- lobbytitle #PL_fra_lobby
- description #PL_fra_desc
- hint #PL_fra_hint
- abbreviation #PL_fra_abbr
- image ffa
- at_turrets_enabled 1
- max_players 12
- max_teams 12
- scorelimit 35
- waiting_for_players_countdown_seconds 1
- waiting_for_players_percentage_desired 10
- earn_meter_tick_disabled 1
- color "254 184 0 255"
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_FFA
- gamemode_bullet_001 #GAMEMODE_BULLET_FFA_001
- gamemode_bullet_002 #GAMEMODE_BULLET_FFA_002
- gamemode_bullet_003 #GAMEMODE_BULLET_FFA_003
- gamemode_bullet_004 #GAMEMODE_BULLET_FFA_004
- gamemode_bullet_005 #GAMEMODE_BULLET_FFA_005
- }
- }
- lts
- {
- inherit defaults
- vars
- {
- name #PL_last_titan_standing
- lobbytitle #PL_last_titan_standing_lobby
- description #PL_last_titan_standing_desc
- hint #PL_last_titan_standing_hint
- abbreviation #PL_last_titan_standing_abbr
- image lts
- pick_loadout_extension 20.0
- pick_loadout_every_round 1
- pick_loadout_warp_sound 0
- tts_menu_join_in_progress 0
- tts_menu_show_score 1
- loadout_grace_period 0.0
- max_players 10
- roundscorelimit 3
- roundtimelimit 3.0
- scorelimit 0
- timelimit 3.0
- waiting_for_players_percentage_desired 100
- waiting_for_players_countdown_seconds 30
- maxExtraRounds 3
- color "128 128 128 255"
-
- idlekick_minutes 1
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_LTS
- gamemode_bullet_001 #GAMEMODE_BULLET_LTS_001
- gamemode_bullet_002 #GAMEMODE_BULLET_LTS_002
- gamemode_bullet_003 #GAMEMODE_BULLET_LTS_003
- gamemode_bullet_004 #GAMEMODE_BULLET_LTS_004
- gamemode_bullet_005 #GAMEMODE_BULLET_LTS_005
- }
- }
- ps
- {
- inherit defaults
- vars
- {
- name #PL_pilot_skirmish
- lobbytitle #PL_pilot_skirmish_lobby
- description #PL_pilot_skirmish_desc
- hint #PL_pilot_skirmish_hint
- abbreviation #PL_pilot_skirmish_abbr
- image ps
- scorelimit 100
- timelimit 10
- max_players 16
- spawn_zone_enabled 1
- color "193 23 23 255"
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_PS
- gamemode_bullet_001 #GAMEMODE_BULLET_PS_001
- gamemode_bullet_002 #GAMEMODE_BULLET_PS_002
- gamemode_bullet_003 #GAMEMODE_BULLET_PS_003
- gamemode_bullet_004 #GAMEMODE_BULLET_PS_004
- gamemode_bullet_005 #GAMEMODE_BULLET_PS_005
- }
- }
- tdm
- {
- inherit defaults
- vars
- {
- name #PL_pilot_hunter
- lobbytitle #PL_pilot_hunter_lobby
- description #PL_pilot_hunter_desc
- hint #PL_pilot_hunter_hint
- abbreviation #PL_pilot_hunter_abbr
- image tdm
- scorelimit 75
- suddendeath_timelimit 2
- timelimit 10
- max_players 12
- gm_hardcore_settings 0
- spawn_zone_enabled 1
- color "60 183 0 255"
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
- gamemode_bullet_001 #GAMEMODE_BULLET_TDM_001
- gamemode_bullet_002 #GAMEMODE_BULLET_TDM_002
- gamemode_bullet_003 #GAMEMODE_BULLET_TDM_003
- gamemode_bullet_004 #GAMEMODE_BULLET_TDM_004
- gamemode_bullet_005 #GAMEMODE_BULLET_TDM_005
- }
- }
- ttdm
- {
- inherit defaults
- vars
- {
- name #PL_titan_brawl
- lobbytitle #PL_titan_brawl_lobby
- description #PL_titan_brawl_desc
- hint #PL_titan_brawl_hint
- abbreviation #PL_titan_brawl_abbr
- image lts
- scorelimit 30
- suddendeath_timelimit 2
- timelimit 10
- max_players 10
- respawn_delay 10
- color "23 193 23 255"
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_TTDM
- gamemode_bullet_001 #GAMEMODE_BULLET_TTDM_001
- gamemode_bullet_002 #GAMEMODE_BULLET_TTDM_002
- gamemode_bullet_003 #GAMEMODE_BULLET_TTDM_003
- gamemode_bullet_004 #GAMEMODE_BULLET_TTDM_004
- gamemode_bullet_005 #GAMEMODE_BULLET_TTDM_005
- }
- }
- aitdm
- {
- inherit defaults
- vars
- {
- name "#PL_aitdm"
- lobbytitle #PL_aitdm_lobby
- description #PL_aitdm_desc
- hint #PL_aitdm_hint
- abbreviation #PL_aitdm_abbr
- scorelimit 650
- suddendeath_timelimit 2
- timelimit 15
- max_players 12
- gm_hardcore_settings 0
- spawn_zone_enabled 0
- earn_meter_tick_frac 0
- escalation_enabled 1
- skyshow_enabled 1
- riff_allow_npcs 1
- enable_spectre_hacking 1
- color "88 220 151 255"
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
- gamemode_bullet_001 #GAMEMODE_BULLET_TDM_001
- gamemode_bullet_002 #GAMEMODE_BULLET_TDM_002
- gamemode_bullet_003 #GAMEMODE_BULLET_TDM_003
- gamemode_bullet_004 #GAMEMODE_BULLET_TDM_004
- gamemode_bullet_005 #GAMEMODE_BULLET_TDM_005
- }
- }
- mfd
- {
- inherit defaults
- vars
- {
- name #PL_marked_for_death
- lobbytitle #PL_marked_for_death_lobby
- description #PL_marked_for_death_desc
- hint #PL_marked_for_death_hint
- abbreviation #PL_marked_for_death_abbr
- image mfd
- scorelimit 10
- timelimit 12
- max_players 12
- gm_hardcore_settings 0
- spawn_zone_enabled 1
- earn_meter_tick_rate 3.6
- earn_meter_pilot_multiplier 0.8
- color "0 245 119 255"
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_MFD
- }
- }
- speedball
- {
- inherit defaults
- vars
- {
- name #PL_live_fire
- lobbytitle #PL_live_fire_lobby
- description #PL_live_fire_desc
- hint #PL_speedball_hint
- abbreviation #PL_live_fire_abbr
- image lf
- scorelimit 5
- roundscorelimit 5
- roundtimelimit 1.0
- suddendeath_timelimit 0
- timelimit 12
- max_players 12
- maxExtraRounds 3
- phase_shift_drop_flag 1
- ctf_flag_return_time 1
- color "127 246 1 255"
-
- idlekick_minutes 1
- idlekick_min_alive_seconds 20
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_SPEEDBALL
- gamemode_bullet_001 #GAMEMODE_BULLET_PS_001
- gamemode_bullet_002 #GAMEMODE_BULLET_PS_002
- gamemode_bullet_003 #GAMEMODE_BULLET_PS_003
- gamemode_bullet_004 #GAMEMODE_BULLET_PS_004
- gamemode_bullet_005 #GAMEMODE_BULLET_PS_005
- }
- }
- fd
- {
- inherit defaults
- vars
- {
- hint #PL_fd_desc
- ingame_menu_fd_mode 1
- pick_loadout_extension 30.0
- pick_loadout_every_round 0
- pick_loadout_warp_sound 1
- tts_menu_join_in_progress 1
- tts_menu_show_score 0
- roundscorelimit 3
- roundtimelimit 60.0
- em_player_fast_kills 12
- em_player_kills 15
- max_players 4
- riff_allow_npcs 1
- scorelimit 2500
- suddendeath_timelimit 2
- titan_build_time 240
- titan_rebuild_time 240
- spawn_zone_enabled 1
- respawn_delay 4
- timelimit 30
- skyshow_enabled 1
- max_teams 1
- riff_wave_spawn 4
- wave_spawn_interval 25
- boost_store_mode fd
- titan_loadout_experiment 0
- use_new_tacticals 0
- earn_meter_tick_frac 0
- ai_attack_tethers 0
- waiting_for_players_percentage_desired 100
- fd_titan_health_adjust 0
- fd_reaper_health_adjust 0
- fd_mortar_spectre_setup_time 5
- fd_grunt_at_weapon_users 0
- fd_grunt_shield_captains 0
- fd_player_damage_scalar 1.0
- fd_harvester_health 25000
- fd_harvester_shield 6000
- fd_harvester_regen_delay 10.0
- fd_harvester_regen_time 10.0
- fd_money_per_round 600
- fd_wave_buy_time 60.0
- fd_pro_titan_shields 0
- fd_at_unlimited_ammo 1
- enable_match_progress_update 0
- color "0 184 254 255"
- aegis_upgrades 1
-
- riff_team_share_earn_meter 2
- riff_team_share_earn_meter_scale 0.25
- earn_meter_titan_multiplier 0.5
- earn_meter_pilot_multiplier 0.5
-
- override_boost_cost_burnmeter_harvester_shield -1
- override_boost_cost_burnmeter_arc_trap -1
- override_boost_cost_burnmeter_ap_turret_weapon_infinite -1
- override_boost_cost_burnmeter_rodeo_grenade -1
- override_boost_cost_burnmeter_amped_weapons_permanent -1
- override_boost_cost_burnmeter_instant_battery -1
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_FD
- gamemode_bullet_001 #GAMEMODE_BULLET_FD_001
- gamemode_bullet_002 #GAMEMODE_BULLET_FD_002
- gamemode_bullet_003 #GAMEMODE_BULLET_FD_003
- gamemode_bullet_004 #GAMEMODE_BULLET_FD_004
- gamemode_bullet_005 #GAMEMODE_BULLET_FD_005
- }
- maps
- {
- mp_forwardbase_kodai 1
- mp_black_water_canal 1
- mp_homestead 1
- mp_wargames 1
- mp_rise 1
- mp_thaw 1
- mp_drydock 1
- mp_angel_city 1
- }
- }
- fd_easy
- {
- inherit fd
- vars
- {
- name #PL_fd_easy
- lobbytitle #PL_fd_easy_lobby
- description #PL_fd_easy_desc
- abbreviation #FD_DIFFICULTY_EASY
-
- image fd_easy
- fd_difficulty 0
- boost_store_team_reserve 1
- fd_titan_health_adjust -5000
- fd_reaper_health_adjust -2000
- fd_mortar_spectre_setup_time 10
- fd_grunt_at_weapon_users 0
- fd_grunt_shield_captains 0
- fd_player_damage_scalar 1.0
- fd_money_per_round 700
- fd_pro_titan_shields 0
- fd_harvester_shield 6000
- fd_at_unlimited_ammo 1
-
- earn_meter_pilot_multiplier 0.7
- }
- }
- fd_normal
- {
- inherit fd
- vars
- {
- name #PL_fd_normal
- lobbytitle #PL_fd_normal_lobby
- description #PL_fd_normal_desc
- abbreviation #FD_DIFFICULTY_NORMAL
- image fd_normal
- fd_difficulty 1
- boost_store_team_reserve 1
- fd_titan_health_adjust -2500
- fd_reaper_health_adjust -1000
- fd_mortar_spectre_setup_time 10
- fd_grunt_at_weapon_users 0
- fd_grunt_shield_captains 0
- fd_player_damage_scalar 1.0
- fd_money_per_round 700
- fd_pro_titan_shields 0
- fd_harvester_shield 6000
- fd_at_unlimited_ammo 1
-
- earn_meter_pilot_multiplier 0.7
- }
- }
- fd_hard
- {
- inherit fd
- vars
- {
- name #PL_fd_hard
- lobbytitle #PL_fd_hard_lobby
- description #PL_fd_hard_desc
- abbreviation #FD_DIFFICULTY_HARD
- image fd_hard
- fd_difficulty 2
- boost_store_team_reserve 1
- fd_titan_health_adjust 0
- fd_reaper_health_adjust 0
- fd_mortar_spectre_setup_time 5
- fd_grunt_at_weapon_users 2
- fd_grunt_shield_captains 0
- fd_player_damage_scalar 1.5
- fd_money_per_round 600
- fd_pro_titan_shields 0
- fd_harvester_shield 5000
- fd_at_unlimited_ammo 1
-
- earn_meter_pilot_multiplier 0.7
- }
- }
- fd_master
- {
- inherit fd
- vars
- {
- name #PL_fd_master
- lobbytitle #PL_fd_master_lobby
- description #PL_fd_master_desc
- abbreviation #FD_DIFFICULTY_MASTER
- image fd_master
- fd_difficulty 3
- boost_store_team_reserve 1
-
- fd_titan_health_adjust 0
- fd_reaper_health_adjust 0
- fd_mortar_spectre_setup_time 5
- fd_grunt_at_weapon_users 4
- fd_grunt_shield_captains 1
- fd_player_damage_scalar 2.5
- fd_money_per_round 600
- fd_pro_titan_shields 1
- fd_harvester_shield 4000
- fd_at_unlimited_ammo 0
-
- earn_meter_pilot_multiplier 0.7
- }
- }
- fd_insane
- {
- inherit fd
- vars
- {
- name #PL_fd_insane
- lobbytitle #PL_fd_insane_lobby
- description #PL_fd_insane_desc
- abbreviation #FD_DIFFICULTY_INSANE
- image fd_insane
- fd_difficulty 4
- boost_store_team_reserve 1
- riff_minimap_state 1
- roundscorelimit 1
-
- fd_titan_health_adjust 0
- fd_reaper_health_adjust 0
- fd_mortar_spectre_setup_time 5
- fd_grunt_at_weapon_users 4
- fd_grunt_shield_captains 1
- fd_player_damage_scalar 2.5
- fd_money_per_round 600
- fd_pro_titan_shields 1
- fd_harvester_shield 4000
- fd_at_unlimited_ammo 0
-
- earn_meter_pilot_multiplier 0.5
- }
- }
-
-// temp before we have a modular way of doing this in the sdk: custom shit lol
- sbox
- {
- inherit defaults
- vars
- {
- name #PL_sbox
- lobbytitle #PL_sbox_lobby
- description #PL_sbox_desc
- abbreviation #PL_sbox_abbr
-
- max_teams 1
- classic_mp 0
- }
- }
- fw
- {
- inherit defaults
- vars
- {
- name #PL_fw
- lobbytitle #PL_fw_lobby
- description #PL_fw_desc
- abbreviation #PL_fw_abbr
-
- max_players 16
- max_teams 2
- classic_mp 1
- scorelimit 100 // score is a percentage so ofc need max to be 100%
- }
- }
- gg
- {
- inherit defaults
- vars
- {
- name #PL_gg
- lobbytitle #PL_gg_lobby
- description #PL_gg_desc
- hint #PL_gg_hint
- abbreviation #PL_gg_abbr
- max_players 12
- max_teams 12
- classic_mp 1
-
- scorelimit 21 // temp until we have a way of dynamically setting non-default scorelimit in code
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_FFA
- gamemode_bullet_001 #GAMEMODE_BULLET_FFA_001
- gamemode_bullet_002 #GAMEMODE_BULLET_FFA_002
- gamemode_bullet_003 #GAMEMODE_BULLET_FFA_003
- gamemode_bullet_004 #GAMEMODE_BULLET_FFA_004
- gamemode_bullet_005 #GAMEMODE_BULLET_FFA_005
- }
- }
- tt
- {
- inherit defaults
- vars
- {
- name #PL_tt
- lobbytitle #PL_tt_lobby
- description #PL_tt_desc
- hint #PL_tt_hint
- abbreviation #PL_tt_abbr
- max_players 12
- max_teams 2
- classic_mp 1
-
- scorelimit 20
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
- }
- }
- inf
- {
- inherit defaults
- vars
- {
- name #PL_inf
- lobbytitle #PL_inf_lobby
- description #PL_inf_desc
- hint #PL_inf_hint
- abbreviation #PL_inf_abbr
- max_players 12
- max_teams 2
- classic_mp 1
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
- }
- }
- arena
- {
- inherit defaults
- vars
- {
- name #PL_arena
- lobbytitle #PL_arena_lobby
- description #PL_arena_desc
- hint #PL_arena_hint
- abbreviation #PL_arena_abbr
- max_players 6
- max_teams 2
- classic_mp 1
- boost_store_mode arena
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
- }
- }
- kr
- {
- inherit defaults
- vars
- {
- name #PL_kr
- lobbytitle #PL_kr_lobby
- description #PL_kr_desc
- hint #PL_kr_hint
- abbreviation #PL_kr_abbr
-
- max_players 16
- max_teams 16
- classic_mp 1
- timelimit 7.5
- scorelimit 99999 // arbitrarily high number
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
- }
- }
- fastball
- {
- inherit defaults
- vars
- {
- name #PL_fastball
- lobbytitle #PL_fastball_lobby
- description #PL_fastball_desc
- hint #PL_fastball_hint
- abbreviation #PL_fastball_abbr
-
- max_players 16
- max_teams 2
- classic_mp 1
- scorelimit 5
- timelimit 2
- roundtimelimit 2
- roundscorelimit 5
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
- }
- }
- ctf_comp
- {
- inherit defaults
- vars
- {
- name #GAMEMODE_ctf_comp
- lobbytitle #PL_capture_the_flag_lobby
- description #PL_capture_the_flag_desc
- hint #PL_capture_the_flag_hint
- abbreviation #PL_capture_the_flag_abbr
- image ctf
- respawn_delay 8
- scorelimit 5
- suddendeath_timelimit 2
- timelimit 12
- max_players 10
- phase_shift_drop_flag 1
- ctf_flag_return_time 1
- color "0 119 245 255"
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_CTF
- gamemode_bullet_001 #GAMEMODE_BULLET_CTF_001
- gamemode_bullet_002 #GAMEMODE_BULLET_CTF_002
- gamemode_bullet_003 #GAMEMODE_BULLET_CTF_003
- gamemode_bullet_004 #GAMEMODE_BULLET_CTF_004
- gamemode_bullet_005 #GAMEMODE_BULLET_CTF_005
- }
- }
-
-
-// END OF MP GAMEMODES LINE ----------------------------------------------------
- solo
- {
- inherit defaults
- maps
- {
- sp_beacon 1
- }
- }
- }
- Playlists
- {
- defaults
- {
- vars
- {
- name #PL_default_name
- lobbytitle #PL_default_lobbytitle
- description #PL_default_description
- image default
- visible 0
- }
- }
- rise_247
- {
- inherit defaults
- vars
- {
- name "#PL_rise"
- lobbytitle #PL_rise_lobby
- description #PL_rise_desc
- abbreviation #PL_rise_abbr
- image aitdm
- visible 0
- }
- gamemodes
- {
- ctf
- {
- maps
- {
- mp_rise 1
- }
- }
- aitdm
- {
- maps
- {
- mp_rise 1
- }
- }
- cp
- {
- vars
- {
-
- }
-
- maps
- {
- mp_rise 1
- }
- }
- at
- {
- maps
- {
- mp_rise 1
- }
- }
- lts
- {
- maps
- {
- mp_rise 1
- }
- }
- }
- }
- aitdm
- {
- inherit defaults
- vars
- {
- name "#PL_aitdm"
- lobbytitle #PL_aitdm_lobby
- description #PL_aitdm_desc
- abbreviation #PL_aitdm_abbr
- image aitdm
- mixtape_slot 0
- visible 1
- }
- gamemodes
- {
- aitdm
- {
- }
- }
- }
- amped_tacticals_aitdm
- {
- inherit defaults
- vars
- {
- name "#PL_amped_tacticals"
- lobbytitle #PL_amped_tacticals_lobby
- description #PL_amped_tacticals_desc
- abbreviation #PL_amped_tacticals_abbr
- image aitdm
- //mixtape_slot 0
- visible 0
- featured_mode_amped_tacticals 1
- }
- gamemodes
- {
- aitdm
- {
- }
- }
- }
- tactikill_aitdm
- {
- inherit defaults
- vars
- {
- name "#PL_tactikill"
- lobbytitle #PL_tactikill_lobby
- description #PL_tactikill_desc
- abbreviation #PL_tactikill_abbr
- image aitdm
- //mixtape_slot 0
- visible 0
- featured_mode_tactikill 1
- }
- gamemodes
- {
- aitdm
- {
- }
- }
- }
- grapple_aitdm
- {
- inherit defaults
- vars
- {
- name "#PL_all_grapple"
- lobbytitle #PL_all_grapple_lobby
- description #PL_all_grapple_desc
- abbreviation #PL_all_grapple_abbr
- image aitdm
- //mixtape_slot 0
- visible 0
- featured_mode_all_grapple 1
- }
- gamemodes
- {
- aitdm
- {
- }
- }
- }
- phase_aitdm
- {
- inherit defaults
- vars
- {
- name "#PL_all_phase"
- lobbytitle #PL_all_phase_lobby
- description #PL_all_phase_desc
- abbreviation #PL_all_phase_abbr
- image aitdm
- mixtape_promo_slot 8
- visible 1
- featured_mode_all_phase 1
- }
- gamemodes
- {
- aitdm
- {
- }
- }
- }
- spicy_aitdm
- {
- inherit defaults
- vars
- {
- name "#PL_all_spicy"
- lobbytitle #PL_all_spicy_lobby
- description #PL_all_spicy_desc
- abbreviation #PL_all_spicy_abbr
- image aitdm
- mixtape_promo_slot 7
- visible 1
- featured_mode_all_ticks 1
- }
- gamemodes
- {
- aitdm
- {
- }
- }
- }
- at
- {
- inherit defaults
- vars
- {
- name #PL_attrition
- lobbytitle #PL_attrition_lobby
- description #PL_attrition_desc
- abbreviation #PL_attrition_abbr
- image at
- mixtape_slot 1
- visible 1
- }
- gamemodes
- {
- at
- {
- }
- }
- }
- cp
- {
- inherit defaults
- vars
- {
- name #PL_hardpoint
- lobbytitle #PL_hardpoint_lobby
- description #PL_hardpoint_desc
- abbreviation #PL_hardpoint_abbr
- image cp
- mixtape_slot 2
- visible 1
- }
- gamemodes
- {
- cp
- {
- }
- }
- }
- lts
- {
- inherit defaults
- vars
- {
- name #PL_last_titan_standing
- lobbytitle #PL_last_titan_standing_lobby
- description #PL_last_titan_standing_desc
- abbreviation #PL_last_titan_standing_abbr
- image lts
- mixtape_slot 3
- visible 1
- }
- gamemodes
- {
- lts
- {
- }
- }
- }
- alts
- {
- inherit defaults
- vars
- {
- name #PL_aegis_last_titan_standing
- lobbytitle #PL_aegis_last_titan_standing_lobby
- description #PL_aegis_last_titan_standing_desc
- abbreviation #PL_aegis_last_titan_standing_abbr
- image lts
- visible 0
- aegis_upgrades 1
- ingame_menu_fd_mode 1
- }
- gamemodes
- {
- lts
- {
- }
- }
- }
- turbo_lts
- {
- inherit defaults
- vars
- {
- name #PL_turbo_last_titan_standing
- lobbytitle #PL_turbo_last_titan_standing_lobby
- description #PL_turbo_last_titan_standing_desc
- abbreviation #PL_turbo_last_titan_standing_abbr
- image lts
- mixtape_promo_slot 0
- visible 1
- featured_mode_turbo_titans 1
- earn_meter_titan_multiplier 2.0
- }
- gamemodes
- {
- lts
- {
- }
- }
- }
- ctf
- {
- inherit defaults
- vars
- {
- name #PL_capture_the_flag
- lobbytitle #PL_capture_the_flag_lobby
- description #PL_capture_the_flag_desc
- abbreviation #PL_capture_the_flag_abbr
- image ctf
- mixtape_slot 4
- mixtape_timeout 120
- visible 1
- }
- gamemodes
- {
- ctf
- {
- vars
- {
- scorelimit 5
- }
-
- maps
- {
- mp_complex3 1
- mp_drydock 2
- mp_glitch 1
- mp_homestead 2
- mp_eden 2
- mp_forwardbase_kodai 1
- mp_black_water_canal 2
- mp_glitch 1
- mp_angel_city 1
- mp_colony02 1
- mp_relic02 1
- mp_grave 2
- mp_homestead 2
- mp_drydock 2
- mp_glitch 1
- mp_thaw 1
- mp_eden 2
- mp_black_water_canal 2
- mp_glitch 1
- mp_relic02 1
- }
- }
- }
- }
- ps
- {
- inherit defaults
- vars
- {
- name #PL_pilot_skirmish
- lobbytitle #PL_pilot_skirmish_lobby
- description #PL_pilot_skirmish_desc
- abbreviation #PL_pilot_skirmish_abbr
- image ps
- mixtape_slot 5
- visible 1
- }
- gamemodes
- {
- ps
- {
- vars
- {
-
- }
-
- maps
- {
- mp_black_water_canal 1
- mp_complex3 1
- mp_crashsite3 1
- mp_drydock 1
- mp_eden 1
- mp_forwardbase_kodai 1
- mp_angel_city 1
- mp_colony02 1
- mp_relic02 1
- mp_grave 1
- mp_thaw 1
- mp_homestead 1
- mp_glitch 1
- }
- }
- }
- }
- ttdm
- {
- inherit defaults
- vars
- {
- name #PL_titan_brawl
- lobbytitle #PL_titan_brawl_lobby
- description #PL_titan_brawl_desc
- abbreviation #PL_titan_brawl_abbr
- image ttdm
- visible 1
- max_players 10
- scorelimit 30
- mixtape_slot 7
- boosts_enabled 1
- respawn_delay 10
- }
- gamemodes
- {
- ttdm
- {
- maps
- {
- mp_glitch 1
- mp_colony02 1
- mp_wargames 1
- mp_eden 1
- mp_drydock 1
- mp_black_water_canal 1
- mp_thaw 1
- mp_homestead 1
- mp_forwardbase_kodai 1
- mp_angel_city 1
- mp_grave 1
- mp_rise 1
- }
- }
- }
- }
- turbo_ttdm
- {
- inherit defaults
- vars
- {
- name #PL_titan_brawl_turbo
- lobbytitle #PL_titan_brawl_turbo_lobby
- description #PL_titan_brawl_turbo_desc
- abbreviation #PL_titan_brawl_turbo_abbr
- image ttdm
- visible 1
- max_players 10
- scorelimit 30
- mixtape_slot 8
- boosts_enabled 1
- respawn_delay 10
-
- featured_mode_turbo_titans 1
- earn_meter_titan_multiplier 2.0
- }
- gamemodes
- {
- ttdm
- {
- maps
- {
- mp_glitch 1
- mp_colony02 1
- mp_wargames 1
- mp_eden 1
- mp_drydock 1
- mp_black_water_canal 1
- mp_thaw 1
- mp_homestead 1
- mp_forwardbase_kodai 1
- mp_angel_city 1
- mp_grave 1
- mp_rise 1
- }
- }
- }
- }
- attdm
- {
- inherit defaults
- vars
- {
- name #PL_aegis_titan_brawl
- lobbytitle #PL_aegis_titan_brawl_lobby
- description #PL_aegis_titan_brawl_desc
- abbreviation #PL_aegis_titan_brawl_abbr
- image ttdm
- visible 0
- max_players 10
- scorelimit 30
-// mixtape_promo_slot 0
- boosts_enabled 1
- respawn_delay 10
- aegis_upgrades 1
- ingame_menu_fd_mode 1
- }
- gamemodes
- {
- ttdm
- {
- maps
- {
- mp_glitch 1
- mp_colony02 1
- mp_wargames 1
- mp_eden 1
- mp_drydock 1
- mp_black_water_canal 1
- mp_thaw 1
- mp_homestead 1
- mp_forwardbase_kodai 1
- mp_angel_city 1
- mp_grave 1
- mp_rise 1
- }
- }
- }
- }
- tdm
- {
- inherit defaults
- vars
- {
- name #PL_pilot_hunter
- lobbytitle #PL_pilot_hunter_lobby
- description #PL_pilot_hunter_desc
- abbreviation #PL_pilot_hunter_abbr
- image tdm
- visible 1
- max_players 16
- //mixtape_slot ##
- }
- gamemodes
- {
- tdm {}
- }
- }
- ffa
- {
- inherit defaults
- vars
- {
- name #PL_ffa
- lobbytitle #PL_ffa_lobby
- description #PL_ffa_desc
- abbreviation #PL_ffa_abbr
- image ffa
- //mixtape_slot 7
- mixtape_timeout 120
- visible 0
- }
- gamemodes
- {
- ffa
- {
- }
- }
- }
- fra
- {
- inherit defaults
- vars
- {
- name #PL_fra
- lobbytitle #PL_fra_lobby
- description #PL_fra_desc
- abbreviation #PL_fra_abbr
- image ffa
- //mixtape_promo_slot 7
- visible 0
- }
- gamemodes
- {
- fra
- {
- }
- }
- }
- coliseum
- {
- inherit defaults
- vars
- {
- name #PL_coliseum
- lobbytitle #PL_coliseum_lobby
- description #PL_coliseum_desc
- image coliseum
- mixtape_promo_slot 4
- visible 1
- }
- gamemodes
- {
- coliseum {}
- }
- }
- private_match
- {
- inherit defaults
- vars
- {
- name #PL_private_match
- lobbytitle #PL_private_match_lobby
- description #PL_private_match_desc
- image private_match
-
- max_players 16
- lobby_countdown 15
- ranking_supported 0
- mixtape_promo_slot 1
- double_xp_enabled 0
- visible 1
-
- // default custom settings
- match_visibility 2
- pilot_health_multiplier 1.0
- earn_meter_pilot_multiplier 1.0
- earn_meter_pilot_overdrive 1
- earn_meter_titan_multiplier 1.0
- }
- gamemodes
- {
- aitdm
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
-
- tdm
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
-
- cp
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_lf_stacks 1
- mp_lf_deck 1
- mp_lf_meadow 1
- mp_lf_traffic 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
-
- at
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
-
- ctf
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_lf_stacks 1
- mp_lf_deck 1
- mp_lf_meadow 1
- mp_lf_traffic 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
-
- lts
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
-
- ps
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_lf_stacks 1
- mp_lf_deck 1
- mp_lf_meadow 1
- mp_lf_traffic 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
-
- speedball
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_lf_stacks 1
- mp_lf_deck 1
- mp_lf_meadow 1
- mp_lf_traffic 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
-
- mfd
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_lf_stacks 1
- mp_lf_deck 1
- mp_lf_meadow 1
- mp_lf_traffic 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
-
- ttdm
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
-
- fd_easy
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_black_water_canal 1
- mp_homestead 1
- mp_wargames 1
- mp_rise 1
- mp_thaw 1
- mp_drydock 1
- mp_angel_city 1
- }
- }
-
- fd_normal
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_black_water_canal 1
- mp_homestead 1
- mp_wargames 1
- mp_rise 1
- mp_thaw 1
- mp_drydock 1
- mp_angel_city 1
- }
- }
-
- fd_hard
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_black_water_canal 1
- mp_homestead 1
- mp_wargames 1
- mp_rise 1
- mp_thaw 1
- mp_drydock 1
- mp_angel_city 1
- }
- }
-
- fd_master
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_black_water_canal 1
- mp_homestead 1
- mp_wargames 1
- mp_rise 1
- mp_thaw 1
- mp_drydock 1
- mp_angel_city 1
- }
- }
-
- fd_insane
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_black_water_canal 1
- mp_homestead 1
- mp_wargames 1
- mp_rise 1
- mp_thaw 1
- mp_drydock 1
- mp_angel_city 1
- }
- }
- }
- }
- nitro_mixtape
- {
- inherit defaults
- vars
- {
- name #PL_nitro_mixtape
- lobbytitle #PL_nitro_mixtape_lobby
- description #PL_nitro_mixtape_desc
- abbreviation #PL_nitro_mixtape_abbr
- image lf
- visible 1
- scorelimit 5
- //mixtape_promo_slot 0
- boosts_enabled 1
- phase_shift_drop_flag 1
- ctf_flag_return_time 1
- }
- gamemodes
- {
- ctf
- {
- maps
- {
- mp_lf_stacks 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_lf_traffic 1
- mp_lf_deck 1
- mp_lf_meadow 1
- }
- }
- mfd
- {
- maps
- {
- mp_lf_stacks 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_lf_traffic 1
- mp_lf_deck 1
- mp_lf_meadow 1
- }
- }
- ps
- {
- maps
- {
- mp_lf_stacks 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_lf_traffic 1
- mp_lf_deck 1
- mp_lf_meadow 1
- }
- }
- }
- }
- nitro_ffa
- {
- inherit defaults
- vars
- {
- name #PL_nitro_ffa
- lobbytitle #PL_nitro_ffa_lobby
- description #PL_nitro_ffa_desc
- abbreviation #PL_nitro_ffa_abbr
- image lf
- visible 0
- scorelimit 5
-// mixtape_promo_slot 0
- boosts_enabled 1
- phase_shift_drop_flag 1
- max_players 6
- max_teams 6
- }
- gamemodes
- {
- ffa
- {
- maps
- {
- mp_lf_stacks 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_lf_traffic 1
- mp_lf_deck 1
- mp_lf_meadow 1
- }
- }
- }
- }
- ctf_lf
- {
- inherit defaults
- vars
- {
- name #PL_ctf_lf
- lobbytitle #PL_ctf_lf_lobby
- description #PL_ctf_lf_desc
- abbreviation #PL_ctf_lf_abbr
- image lf
- visible 0
- scorelimit 5
- //mixtape_promo_slot 8
- boosts_enabled 1
- phase_shift_drop_flag 1
- ctf_flag_return_time 1
- }
- gamemodes
- {
- ctf
- {
- maps
- {
- mp_lf_stacks 1
- mp_lf_deck 1
- mp_lf_meadow 1
- mp_lf_traffic 1
- mp_glitch 1
- mp_lf_township 1
- mp_lf_uma 1
- }
- }
- }
- }
- lf
- {
- inherit defaults
- vars
- {
- name #PL_live_fire
- lobbytitle #PL_live_fire_lobby
- description #PL_live_fire_desc
- abbreviation #PL_live_fire_abbr
- image lf
- visible 1
- scorelimit 50
- mixtape_slot 6
- }
- gamemodes
- {
- speedball
- {
- maps
- {
- mp_lf_stacks 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_lf_traffic 1
- mp_lf_deck 1
- mp_lf_meadow 1
- }
- }
- }
- }
- rocket_lf
- {
- inherit defaults
- vars
- {
- name #PL_rocket_arena
- lobbytitle #PL_rocket_arena_lobby
- description #PL_rocket_arena_desc
- abbreviation #PL_rocket_arena_abbr
- image lf
- visible 1
- scorelimit 50
- roundtimelimit 2.0
- mixtape_promo_slot 6
- featured_mode_rocket_arena 1
- boosts_enabled 1
- }
- gamemodes
- {
- speedball
- {
- maps
- {
- mp_lf_stacks 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_lf_traffic 1
- mp_lf_deck 1
- mp_lf_meadow 1
- }
- }
- }
- }
- holopilot_lf
- {
- inherit defaults
- vars
- {
- name #PL_all_holopilot
- lobbytitle #PL_all_holopilot_lobby
- description #PL_all_holopilot_desc
- abbreviation #PL_all_holopilot_abbr
- image lf
- visible 0
- scorelimit 50
- //mixtape_slot 6
- featured_mode_all_holopilot 1
- }
- gamemodes
- {
- speedball
- {
- maps
- {
- mp_lf_stacks 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_lf_traffic 1
- mp_lf_deck 1
- mp_lf_meadow 1
- }
- }
- }
- }
- mfd
- {
- inherit defaults
- vars
- {
- name #PL_marked_for_death
- lobbytitle #PL_marked_for_death_lobby
- description #PL_marked_for_death_desc
- abbreviation #PL_marked_for_death_abbr
- image mfd
- visible 0
-// mixtape_promo_slot 5
- }
- gamemodes
- {
- mfd {}
- }
- }
- //DEV
- fnf
- {
- inherit defaults
- vars
- {
- name "Friday Night Fights"
- lobbytitle "Friday Night Fights Lobby"
- description "Fights on Friday"
- image varietypack
- visible 0
-// mixtape_promo_slot 4
- }
- gamemodes
- {
- ctf
- {
- maps
- {
- mp_relic02 1
-
- }
- }
-
- lts
- {
- maps
- {
- mp_relic02 1
- }
- }
- }
- }
- //DEV
- fd
- {
- inherit defaults
- vars
- {
- name #MATCHMAKING_PVE_PLAY_BUTTON
- lobbytitle #PL_fd_lobby
- description #COOP_DESC
- image ffa
- visible 1
- mixtape_promo_slot 9
- riff_team_share_earn_meter 2
- riff_team_share_earn_meter_scale 0.25
- earn_meter_titan_multiplier 0.5
- ingame_menu_fd_mode 1
- promo_note #PL_promo_coop
- }
- gamemodes
- {
- fd
- {}
- }
- }
- //DEV
- fd_easy
- {
- inherit defaults
- vars
- {
- name #PL_fd_easy
- lobbytitle #PL_fd_easy_lobby
- description #PL_fd_easy_desc
- abbreviation #FD_DIFFICULTY_EASY
- image fd_easy
- visible 1
- }
- gamemodes
- {
- fd
- {}
- }
- gamemodesWithAncestor
- {
- fd_easy
- {}
- }
- }
- //DEV
- fd_normal
- {
- inherit defaults
- vars
- {
- name #PL_fd_normal
- lobbytitle #PL_fd_normal_lobby
- description #PL_fd_normal_desc
- abbreviation #FD_DIFFICULTY_NORMAL
- image fd_normal
- visible 1
- }
- gamemodes
- {
- fd
- {}
- }
- gamemodesWithAncestor
- {
- fd_normal
- {}
- }
- }
- //DEV
- fd_hard
- {
- inherit defaults
- vars
- {
- name #PL_fd_hard
- lobbytitle #PL_fd_hard_lobby
- description #PL_fd_hard_desc
- abbreviation #FD_DIFFICULTY_HARD
- image fd_hard
- visible 1
- }
- gamemodes
- {
- fd
- {}
- }
- gamemodesWithAncestor
- {
- fd_hard
- {}
- }
- }
- //DEV
- fd_master
- {
- inherit defaults
- vars
- {
- name #PL_fd_master
- lobbytitle #PL_fd_master_lobby
- description #PL_fd_master_desc
- abbreviation #FD_DIFFICULTY_MASTER
- image fd_master
- visible 1
- }
- gamemodes
- {
- fd
- {}
- }
- gamemodesWithAncestor
- {
- fd_master
- {}
- }
- }
- fd_insane
- {
- inherit fd
- vars
- {
- name #PL_fd_insane
- lobbytitle #PL_fd_insane_lobby
- description #PL_fd_insane_desc
- image fd_insane
- visible 1
- mixtape_promo_slot 5
- promo_note #MP_HOMESTEAD
- }
- gamemodes
- {
- fd
- {}
- }
- gamemodesWithAncestor
- {
- fd_insane
- {
- maps
- {
- mp_homestead 1
- }
- }
- }
- }
- //DEV
- fd_dev
- {
- inherit fd_hard
- vars
- {
- pick_loadout_extension 0
- }
- }
-
- gg
- {
- inherit defaults
- vars
- {
- name #PL_gg
- lobbytitle #PL_gg_lobby
- description #PL_gg_desc
- abbreviation #PL_gg_abbr
- image ffa
- //mixtape_slot 7
- mixtape_timeout 120
- visible 0
- }
- gamemodes
- {
- gg
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_lf_stacks 1
- mp_lf_deck 1
- mp_lf_meadow 1
- mp_lf_traffic 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
- }
- }
- tt
- {
- inherit defaults
- vars
- {
- name #PL_tt
- lobbytitle #PL_tt_lobby
- description #PL_tt_desc
- hint #PL_tt_hint
- abbreviation #PL_tt_abbr
- visible 0
- }
- gamemodes
- {
- tt
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
- }
- }
- inf
- {
- inherit defaults
- vars
- {
- name #PL_inf
- lobbytitle #PL_inf_lobby
- description #PL_inf_desc
- hint #PL_inf_hint
- abbreviation #PL_inf_abbr
- visible 0
- }
- gamemodes
- {
- inf
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_lf_stacks 1
- mp_lf_deck 1
- mp_lf_meadow 1
- mp_lf_traffic 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
- }
- }
- arena
- {
- inherit defaults
- vars
- {
- name #PL_arena
- lobbytitle #PL_arena_lobby
- description #PL_arena_desc
- hint #PL_arena_hint
- abbreviation #PL_arena_abbr
- max_players 6
- max_teams 2
- classic_mp 1
- boost_store_mode arena
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
- }
- gamemodes
- {
- arena
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_lf_stacks 1
- mp_lf_deck 1
- mp_lf_meadow 1
- mp_lf_traffic 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
- }
- }
- kr
- {
- inherit defaults
- vars
- {
- name #PL_kr
- lobbytitle #PL_kr_lobby
- description #PL_kr_desc
- hint #PL_kr_hint
- abbreviation #PL_kr_abbr
-
- max_players 16
- max_teams 16
- classic_mp 1
- timelimit 7.5
- scorelimit 99999 // arbitrarily high number
- }
- gamemodes
- {
- kr
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_lf_stacks 1
- mp_lf_deck 1
- mp_lf_meadow 1
- mp_lf_traffic 1
- mp_lf_township 1
- mp_lf_uma 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
- }
- }
- fastball
- {
- inherit defaults
- vars
- {
- name #PL_fastball
- lobbytitle #PL_fastball_lobby
- description #PL_fastball_desc
- hint #PL_fastball_hint
- abbreviation #PL_fastball_abbr
-
- max_players 16
- max_teams 2
- classic_mp 1
- scorelimit 5
- roundtimelimit 2
- roundscorelimit 5
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
- }
- gamemodes
- {
- fastball
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
- }
- }
- fw
- {
- inherit defaults
- vars
- {
- name #PL_fw
- lobbytitle #PL_fw_lobby
- description #PL_fw_desc
- hint #PL_fw_hint
- abbreviation #PL_fw_abbr
-
- max_players 16
- max_teams 2
- classic_mp 1
- scorelimit 100
-
- gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM
- }
- gamemodes
- {
- fw
- {
- maps
- {
- mp_forwardbase_kodai 1
- mp_grave 1
- mp_homestead 1
- mp_thaw 1
- mp_black_water_canal 1
- mp_eden 1
- mp_drydock 1
- mp_crashsite3 1
- mp_complex3 1
- mp_angel_city 1
- mp_colony02 1
- mp_glitch 1
- mp_relic02 1
- mp_wargames 1
- mp_rise 1
- }
- }
- }
- }
- ctf_comp
- {
- inherit defaults
- vars
- {
- name #GAMEMODE_ctf_comp
- lobbytitle #PL_capture_the_flag_lobby
- description #PL_capture_the_flag_desc
- abbreviation #PL_capture_the_flag_abbr
- image ctf
- mixtape_slot 4
- mixtape_timeout 120
- visible 1
-
- // comp-exclusive settings
- // note: these don't display right on the private match menu yet
- pilot_health_multiplier 1.25
- respawn_delay 7.0
-
- boosts_enabled 1 // this is actually disabled lol
- earn_meter_pilot_overdrive 0
- earn_meter_pilot_multiplier 0.5
- earn_meter_titan_multiplier 0.5
-
- scorelimit 6
- timelimit 14
- }
- gamemodes
- {
- ctf
- {
- maps
- {
- mp_complex3 1
- mp_drydock 2
- mp_glitch 1
- mp_homestead 2
- mp_eden 2
- mp_forwardbase_kodai 1
- mp_black_water_canal 2
- mp_glitch 1
- mp_angel_city 1
- mp_colony02 1
- mp_relic02 1
- mp_grave 2
- mp_homestead 2
- mp_drydock 2
- mp_glitch 1
- mp_thaw 1
- mp_eden 2
- mp_black_water_canal 2
- mp_glitch 1
- mp_relic02 1
- }
- }
- }
- }
-
-
-// END OF MP PLAYLISTS LINE ----------------------------------------------------
-
- "Load a map on the command line"
- {
- inherit defaults
- vars
- {
- name #PL_load_a_map_on_the_command_line
- description #PL_settings_for_when_someone_loads_a_map_on_the_command_line_do_not_edit_the_cmdlinemapload_1_below_-_this_makes_this_work
-
- cmdlineMapLoad 1
-
- classic_mp 0
- prematch_time 4
- titan_build_time 5
- titan_build_time_use_set_file 0
- titan_rebuild_time 5
- }
- gamemodes
- {
- tdm
- {
- maps
- {
- mp_lobby 1
- }
- }
- }
- }
- buildain
- {
- inherit defaults
- vars
- {
- name #PL_pl_rebuild_all_paths
- description #PL_pl_run_with_ai_ainrebuildonmapstart_2
-
- classic_mp 0
- ranking_supported 0
- }
- gamemodes
- {
- tdm
- {
- maps
- {
- mp_titan_melee 1
- mp_titan_rodeo 1
- mp_angel_city 1
- mp_colony02 1
- mp_crashsite2 1
- mp_beacon 1
- mp_test_engagement_range 1
- mp_thaw 1
- mp_homestead 1
- mp_grave 1
- mp_forwardbase_kodai 1
- mp_box 1
- mp_lobby 1
- }
- }
- }
- }
- solo
- {
- inherit defaults
- vars
- {
- always_enable_autotitans 1
- burn_meter_enabled 0
- cinematic_mode 1
- classic_mp 0
- hud_score_enabled 0
- max_players 16
- max_teams 1
- ranking_supported 0
- riff_allow_npcs 1
- riff_minimap_state 1
- riff_titan_availability 3
- riff_titan_exit_enabled 3
- rodeo_battery_disembark_to_pickup 0
- titan_build_time 300
- titan_health_bar_display default
- titan_mode_change_allowed 0
- titan_rebuild_time 195
- titan_segmented_health 0
- titan_shield_regen 1
- }
- gamemodes
- {
- solo {}
- }
- }
- new_titan_models
- {
- inherit defaults
- vars
- {
- classic_mp 0
- prematch_time 4
- r2_titan_models 1
- titan_build_time 20
- titan_rebuild_time 20
- }
- gamemodes
- {
- solo
- {
- maps
- {
- sp_enemies 1
- }
- }
- }
- }
- }
- "LocalizedStrings"
- {
- "lang"
- {
- "Language" "german"
- "Tokens"
- {
- "COMMUNITYUPDATE_00_A" "Dein Abenteuer in der beeindruckenden Welt des Grenzlandes geht mit \"Postkarten aus dem Grenzland\", dem neuesten DLC für Titanfall 2, weiter. Mit neuen und bekannten Schauplätzen und einer neuen Sammlung von Elitewaffen-Kriegslackierungen hat das Grenzland nie besser ausgesehen.\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_00_Q" "\"Postkarten aus dem Grenzland\"-Trailer"
- "COMMUNITYUPDATE_01_A" "Informiere dich über alle im \"Postkarten aus dem Grenzland\"-Patch enthaltenen Änderungen.\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_01_Q" "Postkarten aus dem Grenzland: Die Patch-Notizen"
- "COMMUNITYUPDATE_02_A" "Das demnächst für Mobilgeräte erscheinende Titanfall: Assault ist ein Echtzeit-RTS im Titanfall-Universum, das wir mit Particle City entwickeln. Hier siehst du das Spiel in Aktion.\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_02_Q" "Titanfall: Assault-Veröffentlichungstrailer"
- "COMMUNITYUPDATE_03_A" "Iniquity führt uns durch das Tutorial und gibt uns grundlegende Tipps zu Titanfall: Assault. Der perfekte Weg, mehr über das Spiel zu erfahren.\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_03_Q" "Titanfall: Assault: \"Die Grundlagen\"-Video"
- "COMMUNITYUPDATE_04_A" "Höre den Machern von Grenzlandverteidigung zu, wenn sie über die Geschichte und Entwicklung des Modus sprechen und sieh uns zu, wie wir einige Runden spielen!\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_04_Q" "Respawn spielt Grenzlandverteidigung"
- "COMMUNITYUPDATE_05_A" "Kevin Younger hat eine witzige Montage aus zahlreichen coolen Moves mit der Impulsklinge zusammengestellt!\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_05_Q" "Community-Beiträge: Komm zum Punkt"
- "COMMUNITYUPDATE_06_A" "ConzeyG zeigt uns über reddit die brutale Effizienz des Northstar, wenn er im Todgeweiht-Modus Piloten erledigt.\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_06_Q" "Community-Beiträge - Northstar-Pilotenjagd"
- "COMMUNITYUPDATE_07_A" "Jetzt verfügbar! Grenzlandverteidigung und Rise kehren mit brandneuen, kaufbaren Kriegslackierungen und einer neuen Live Fire-Karte zurück. Hier siehst du alles in Aktion.\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_07_Q" "\"Operation Frontier Shield\" Gameplay-Trailer"
- "COMMUNITYUPDATE_08_A" "Jetzt verfügbar! Die legendäre Kriegsspiele-Karte kehrt in Titanfall 2 zurück und sieht besser denn je aus. Erlebe außerdem die neue Exekution und die neue Live Fire-Karte \"Verkehr\" in Aktion.\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_08_Q" "\"Die Kriegsspiele\" Gameplay-Trailer"
- "COMMUNITYUPDATE_09_A" "Dieser DLC enthält mit dem Monarch den 7. Multiplayer-Titan, eine überarbeitete Version der Relikt-Karte, eine neue Exekution sowie kaufbare Ronin- und Tone-Prime-Titans, mehr Tarnungen, Banner und Nose-Arts. Hier kannst du dir die Action ansehen.\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_09_Q" "\"Monarch's Reign\" Gameplay-Trailer"
- "COMMUNITYUPDATE_10_A" "Im Grenzland ist nicht alles so, wie es scheint – bereite dich auf den neuesten kostenlosen Inhaltspack zum Herunterladen für Titanfall 2 vor: Störimpuls im Grenzland – mit der neuen Karte \"Glitch\". Die Inspiration dafür war Captain Lastimosas Heimatplanet Harmony, wo vertikale Höhenunterschiede und lange, gewundene Pfade das Landschaftsbild dominieren – ideal, um mit Wandlaufkombinationen elegant über die Karte zu gleiten. Eine neue Live Fire-Karte ist ebenfalls am Start: Deck, mit engen Innenräumen, offenen Höfen und wachsamen Drohnen, die über dir kreisen. Falls du dich überfordert fühlst, kannst du auf die hilfreichen M.R.V.N.s zugreifen, die dir jetzt als brandneue Gruppierung ihre fröhliche Roboterhand reichen. Und zu guter Letzt kannst du noch die neue Impulsklingen-Exekution freischalten, wann immer du es für notwendig hältst, dich durchzusetzen.\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_10_Q" "\"Störimpuls im Grenzland\" Gameplay-Trailer"
- "COMMUNITYUPDATE_11_A" "Kehre auf eine der Lieblingskarten der Fans aus Titanfall 1 zurück: Kolonie. Bringe all die neuen Taktiken und Titans aus Titanfall 2 ein, die alle Piloten & Titans nutzen müssen, um an diesem idyllischen Ort voller enger und verwinkelter Gassen und ungeschützter Dächer zu überleben. Ab dem 30. März für alle Spieler kostenlos erhältlich! Der Kolonierückkehr-DLC enthält außerdem klassische Waffen wie das Sturmgewehr R-101, eine neue Haken-Exekution sowie neue kosmetische Optionen, damit du perfekt aussiehst, wenn du die Stadt im Chaos versinken lässt.\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_11_Q" "Trailer - Kolonierückkehr-DLC"
- "COMMUNITYUPDATE_12_A" "Vorstellung von Live Fire: ein rasanter 6 vs. 6 Piloten-Modus, der aufregende Nahkämpfe an vorderster Front bietet. Enthält zwei neue, speziell für Live Fire entworfene Karten: Stacks und Meadow. Die beiden kostenlosen Karten sind eng umgrenzte Todeszonen, die perfekt auf die Rasanz und Intensität des Modus abgestimmt sind.\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_12_Q" "Trailer - Live Fire-DLC"
- "COMMUNITYUPDATE_13_A" "Erlebe eine Neuauflage der beliebten `1Angel City`0-Karte aus dem ersten Titanfall. Mach dich bereit für die ersten kostenlosen Inhalte zum Herunterladen für Titanfall 2. `1Angel City's Most Wanted`0 ist ab dem 1. Dezember für alle Spieler verfügbar. Die Inhalte bieten neue kosmetische Optionen, die dem Grenzland noch mehr Flair verleihen. \n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_13_Q" "Trailer - Angel City-DLC"
- "COMMUNITYUPDATE_14_A" "Willkommen zurück!\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_14_Q" "Trailer - Encore"
- "COMMUNITYUPDATE_15_A" "Zwei Legenden, ein Erbe.\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_15_Q" "Trailer - Become One"
- "COMMUNITYUPDATE_16_A" "Grenzenlos.\n\n\nZum Ansehen `2%[A_BUTTON|MOUSE1]%`0 drücken."
- "COMMUNITYUPDATE_16_Q" "Trailer - Piloten-Gameplay"
- "COMMUNITYUPDATE_DESC" "`3Titanfall Community-Updates`0\n\nInfos und Links aus dem ganzen Netz.\n\nWeitere Infos:\n`2%$rui/bullet_point%`0Folge uns auf Twitter `1@Respawn`0\n`2%$rui/bullet_point%`0Folge uns auf `1facebook.com/RespawnEntertainment`0\n`2%$rui/bullet_point%`0Besuche uns auf `1www.respawn.com`0"
- "COMMUNITYUPDATE_NAME" "Community"
- "KNB_SUBJECT_00_DESC" "`3Was ist neu in Titanfall?`0\n\nHier erfährst du, was sich in Titanfall 2 geändert hat!"
- "KNB_SUBJECT_00_NAME" "Spiel-Updates"
- "KNB_SUBJECT_00_SUB_00_A" "`2%$rui/bullet_point%`010 Neue Rufzeichen-Banner der Community\n\n`2%$rui/bullet_point%`0Alle Fürsprechergeschenke können jetzt mit Credits erworben werden\n\n`2%$rui/bullet_point%`0Neue kaufbare Store-Inhalte\n\n"
- "KNB_SUBJECT_00_SUB_00_Q" "%$rui/hud/scoreboard/status_titan% 28. November - Erntezeit"
- "KNB_SUBJECT_00_SUB_01_A" "`2%$rui/bullet_point%`0Pistolen-Primärslot\n\n`2%$rui/bullet_point%`0Halloween-Banner\n\n`2%$rui/bullet_point%`0Balance-Änderungen\n\n`2%$rui/bullet_point%`0Neue kaufbare Store-Inhalte\n\n"
- "KNB_SUBJECT_00_SUB_01_Q" "%$rui/hud/scoreboard/status_titan% 31. Oktober - Süßes und Saures"
- "KNB_SUBJECT_00_SUB_02_A" "`2%$rui/bullet_point%`0Grenzlandverteidigung - Unterstützung für 3 weitere Karten - Drydock, Angel City und Exoplanet.\n\n`2%$rui/bullet_point%`0Neue Live Fire-Karte - UMA\n\n`2%$rui/bullet_point%`0Neue Piloten-Exekution - Loch in der Wand\n\n`2%$rui/bullet_point%`0Neue kaufbare Store-Inhalte"
- "KNB_SUBJECT_00_SUB_02_Q" "%$rui/hud/scoreboard/status_titan% 29. August - Postkarten aus dem Grenzland"
- "KNB_SUBJECT_00_SUB_03_A" "`2%$rui/bullet_point%`0Grenzlandverteidigung - Ein neuer Koop-Modus, bei dem du mit drei anderen Spielern ein wichtiges Einsatzziel gegen immer stärker werdende Wellen von KI-Einheiten verteidigst. Kommunikation und Anpassung sind hier entscheidend, um zu überleben.\n\n`2%$rui/bullet_point%`0Neue Karte - Aufstieg\n\n`2%$rui/bullet_point%`0Neue Live Fire-Karte - Township\n\n`2%$rui/bullet_point%`0Neue kaufbare Store-Inhalte"
- "KNB_SUBJECT_00_SUB_03_Q" "%$rui/hud/scoreboard/status_titan% 25. Juli - Operation Frontier Shield"
- "KNB_SUBJECT_00_SUB_04_A" "`2%$rui/bullet_point%`0Neue Karte - Kriegsspiele\n\n`2%$rui/bullet_point%`0Neue Live Fire-Karte - Verkehr\n\n`2%$rui/bullet_point%`0Neue Piloten-Exekution - Schattenboxen\n\n`2%$rui/bullet_point%`03. Waffenslot\n\n`2%$rui/bullet_point%`0Privatspiel-Einstellungen"
- "KNB_SUBJECT_00_SUB_04_Q" "%$rui/hud/scoreboard/status_titan% 27. Juni - Kriegsspiele"
- "KNB_SUBJECT_00_SUB_05_A" "`2%$rui/bullet_point%`0Neuer Titan – Monarch\n\n`2%$rui/bullet_point%`0Neue Karte – Relikt\n\n`2%$rui/bullet_point%`0Neue Piloten-Exekution – Jetzt siehst du mich\n\n`2%$rui/bullet_point%`0Neue, käuflich zu erwerbende Store-Inhalte"
- "KNB_SUBJECT_00_SUB_05_Q" "%$rui/hud/scoreboard/status_titan% 30. Mai – Monarch's Reign"
- "KNB_SUBJECT_00_SUB_06_A" "`2%$rui/bullet_point%`0Neue Karte – Glitch\n\n`2%$rui/bullet_point%`0Neue Live Fire-Karte – Deck\n\n`2%$rui/bullet_point%`0Neue Gruppierung – M.R.V.N.\n\n`2%$rui/bullet_point%`0Neue Piloten-Exekution – Komm zum Punkt\n\n`2%$rui/bullet_point%`0Maximalgeneration auf 100 erhöht"
- "KNB_SUBJECT_00_SUB_06_Q" "%$rui/hud/scoreboard/status_titan% 25. April – Störimpuls im Grenzland"
- "KNB_SUBJECT_00_SUB_07_A" "`2%$rui/bullet_point%`0Neue Karte – Kolonie\n\n`2%$rui/bullet_point%`0Neue Piloten-Exekution – Curb-Check\n\n`2%$rui/bullet_point%`0Neue Waffe – R-101\n\n`2%$rui/bullet_point%`0Neue, käuflich zu erwerbende Store-Inhalte"
- "KNB_SUBJECT_00_SUB_07_Q" "%$rui/hud/scoreboard/status_titan% 30. März – Kolonierückkehr"
- "KNB_SUBJECT_00_SUB_08_A" "`2%$rui/bullet_point%`0Live Fire – ein neuer Pilot vs. Pilot Eliminierungsmodus! In diesem rundenbasierten 6 vs. 6-Modus ohne Respawns habt ihr nur eine Minute Zeit, das gegnerische Team zu besiegen und die Runde zu gewinnen. Ihr gewinnt die Runde aber auch, wenn euer Team am Ende der Runde die neutrale Flagge hält. Das Team, das zuerst 5 Runden gewinnt, wird zum Sieger erklärt.\n\n`2%$rui/bullet_point%`0Neue Live Fire-Karte – Meadow\n\n`2%$rui/bullet_point%`0Neue Live Fire-Karte – Stacks\n\n`2%$rui/bullet_point%`0Neue Piloten-Exekution – Später Treffer"
- "KNB_SUBJECT_00_SUB_08_Q" "%$rui/hud/scoreboard/status_titan% 23. Februar – Live Fire"
- "KNB_SUBJECT_00_SUB_09_A" "`2%$rui/bullet_point%`0Neue Karte – Angel City\n\n`2%$rui/bullet_point%`0Neue Waffe – B3 Wingman Elite\n\n`2%$rui/bullet_point%`0Neue Piloten-Exekution – Innenleben\n\n`2%$rui/bullet_point%`0Neue Titan-Kits\n\n`2%$rui/bullet_point%`0Neue, käuflich zu erwerbende Store-Inhalte"
- "KNB_SUBJECT_00_SUB_09_Q" "%$rui/hud/scoreboard/status_titan% 30. November – Angel City's Most Wanted"
- "MP_ANGEL_CITY_FD_WAVE_1" "An den Himmel gekettet"
- "MP_ANGEL_CITY_FD_WAVE_2" "Formlosigkeit"
- "MP_ANGEL_CITY_FD_WAVE_3" "Auflehnung"
- "MP_ANGEL_CITY_FD_WAVE_4" "Ein störrischer Haufen"
- "MP_ANGEL_CITY_FD_WAVE_5" "Reißleine"
- "MP_DRYDOCK_FD_WAVE_1" "Auf in fremde Gewässer"
- "MP_DRYDOCK_FD_WAVE_2" "Sie haben keine Kugeln!"
- "MP_DRYDOCK_FD_WAVE_3" "Von der Forschung geblendet"
- "MP_DRYDOCK_FD_WAVE_4" "Hochdrucksystem"
- "MP_DRYDOCK_FD_WAVE_5" "Auge des Sturms"
- "MP_THAW_FD_WAVE_1" "Lagebewusstsein"
- "MP_THAW_FD_WAVE_2" "Zahlenmäßige Stärke"
- "MP_THAW_FD_WAVE_3" "Handlanger 21"
- "MP_THAW_FD_WAVE_4" "Spaß im Feuer"
- "MP_THAW_FD_WAVE_5" "Nutzt eure Waffen"
- "NO_PRICE" "Angebot abgelaufen"
- "NO_PRICE_TWO_LINES" "Angebot\nabgelaufen"
- "PL_aegis_last_titan_standing" "Aegis-LTS"
- "PL_aegis_last_titan_standing_abbr" "ALTS"
- "PL_aegis_last_titan_standing_desc" "Aegis-Upgrades aktiviert. Rundenbasiertes Eliminierungsmatch. Sieger ist, wer zuerst 3 Runden für sich entscheidet.\n^FFC83200Spieler: 5 vs. 5 * Starte als Titan\nZeitlimit: 3 Min. pro Runde * Keine Respawns\nMax. Party-Größe: 5"
- "PL_aegis_last_titan_standing_lobby" "PL_aegis_last_titan_standing_lobby"
- "PL_aegis_titan_brawl" "Aegis Titan Brawl"
- "PL_aegis_titan_brawl_abbr" "ATB"
- "PL_aegis_titan_brawl_desc" "Eliminiere gegnerische Titans. Aegis-Upgrades aktiviert.\n^FFC83200Spieler: 5 vs. 5\nZeitlimit: 10 Min.\nMax. Party-Größe: 5"
- "PL_aegis_titan_brawl_hint" "Neutralisiere gegnerische Titans.\nKein Ausstieg"
- "PL_aegis_titan_brawl_lobby" "Aegis Titan Brawl-Lobby"
- "PL_aitdm" "Materialschlacht"
- "PL_aitdm_abbr" "MAT"
- "PL_aitdm_desc" "Töte alle Gegner.\n^FFC83200Spieler: 6 vs. 6 *KI\nZeitlimit: 10 Min.\nMax. Party-Größe: 6"
- "PL_aitdm_lobby" "Materialschlacht-Lobby"
- "PL_all_grapple" "Angriff auf Titanfall"
- "PL_all_grapple_abbr" "MAT"
- "PL_all_grapple_desc" "Klassische Materialschlacht-Regeln, allerdings werden alle Taktikfähigkeiten durch \"Haken\" ersetzt.\n^FFC83200Spieler: 6 vs. 6 *KI\nZeitlimit: 10 Min.\nMax. Party-Größe: 6"
- "PL_all_grapple_lobby" "Angriff auf Titanfall-Lobby"
- "PL_all_holopilot" "Totale Verwirrung"
- "PL_all_holopilot_abbr" "LF"
- "PL_all_holopilot_desc" "Klassische Live-Fire-Regeln, allerdings werden alle Taktikfähigkeiten durch \"Holopilot\" ersetzt.^FFC83200\nSpieler: 6 vs. 6 *Keine Titans\nZeitlimit: 60 Sek. *Keine Respawns\nMax. Party-Größe: 6"
- "PL_all_holopilot_lobby" "Totale Verwirrung-Lobby"
- "PL_all_phase" "Die andere Seite"
- "PL_all_phase_abbr" "MAT"
- "PL_all_phase_desc" "Klassische Materialschlacht-Regeln, allerdings werden alle Taktikfähigkeiten durch \"Phase\" ersetzt.\n^FFC83200Spieler: 6 vs. 6 *KI\nZeitlimit: 10 Min.\nMax. Party-Größe: 6"
- "PL_all_phase_lobby" "Die andere Seite-Lobby"
- "PL_all_spicy" "Würzige Materialschlacht"
- "PL_all_spicy_abbr" "MAT"
- "PL_all_spicy_desc" "Klassische Materialschlacht-Regeln, allerdings werden alle Taktikfähigkeiten durch Ticks ersetzt.\n^FFC83200Spieler: 6 vs. 6 *KI\nZeitlimit: 10 Min.\nMax. Party-Größe: 6"
- "PL_all_spicy_lobby" "Würzige Materialschlacht-Lobby"
- "PL_amped_tacticals" "Verstärkte Taktiken"
- "PL_amped_tacticals_abbr" "MAT"
- "PL_amped_tacticals_desc" "Klassische Materialschlacht-Regeln, allerdings sind alle Taktikfähigkeiten effektiver.\n^FFC83200Spieler: 6 vs. 6 *KI\nZeitlimit: 10 Min.\nMax. Party-Größe: 6"
- "PL_amped_tacticals_lobby" "Verstärkte Taktiken-Lobby"
- "PL_ANGEL_CITY" "Angel City 24/7"
- "PL_angel_city_abbr" "AC"
- "PL_angel_city_desc" "Ganz Angel City, die ganze Zeit.\n^FFC83200*Kopfgeldjagd *Materialschlacht\n*Verstärkter Hardpoint"
- "PL_angel_city_lobby" "Angel City 24/7-Lobby"
- "PL_at_coop" "Flucht (Koop)"
- "PL_at_coop_desc" "Du bist nur mit einer Pistole bewaffnet aus einem Gefängnis entkommen. Überlebe, bis du evakuiert werden kannst. Neutralisiere Gegner, um Geld zu erhalten und Waffen zu kaufen. \n^FFC83200Spieler: 6\nMax. Party-Größe: 6"
- "PL_at_coop_lobby" "Flucht-Lobby"
- "PL_attrition" "Kopfgeldjagd"
- "PL_attrition_abbr" "KGJ"
- "PL_attrition_desc" "Neutralisiere Gegner, um Geld zu erhalten. Verdiene mehr, indem du deine Boni an ausgewiesenen Stellen 'auf die Bank bringst'.\n^FFC83200Spieler: 5 vs. 5 * KI\nZeitlimit: 10 Min.\nMax. Party-Größe: 5"
- "PL_attrition_lobby" "Kopfgeldjagd-Lobby"
- "PL_capture_the_flag" "Capture the Flag"
- "PL_capture_the_flag_abbr" "CTF"
- "PL_capture_the_flag_desc" "Stiehl die feindliche Flagge und bringe sie zu deiner Basis, während du das feindliche Team davon abhältst, sich deine Flagge zu schnappen!\n^FFC83200Spieler: 5 vs. 5\nZeitlimit: 12 Min.\nMax. Party-Größe: 5"
- "PL_capture_the_flag_lobby" "CTF-Lobby"
- "PL_coliseum" "Kolosseum"
- "PL_coliseum_desc" "Duell mit erweiterter Beweglichkeit in einem Käfig. Schalte deinen Gegner aus, um zu gewinnen. Wer 3 von 5 Runden gewinnt, erhält ein Freund-Geschenk.^FFC83200\nSpieler: 1 vs. 1 *Keine Titans\nZeitlimit: 3 Min. *Keine Respawns\n**^FFFFFF00ERFORDERT KOLOSSEUM-TICKET oder BEZAHLTE TEILNAHMEGEBÜHR"
- "PL_coliseum_lobby" "Kolosseum-Lobby"
- "PL_colony" "Kolonie 24/7"
- "PL_colony_abbr" "KOL"
- "PL_colony_desc" "Kolonie, rund um die Uhr. ^CCCCCC00Sucht nach Spielen in den Modi ^FFC83200Materialschlacht^CCCCCC00, ^FFC83200Piloten vs. Piloten^CCCCCC00 und ^FFC83200Last Titan Standing^CCCCCC00."
- "PL_colony_lobby" "Kolonie 24/7-Lobby"
- "PL_ctf_lf" "CTF (Nitro)"
- "PL_ctf_lf_abbr" "CTF-N"
- "PL_ctf_lf_desc" "Rasantes Capture the Flag auf ausgewählten Karten.\n^FFC83200Spieler: 5 vs. 5\nMax. Party-Größe: 5\n^F4D5A600Flagge wird sofort zurückgebracht"
- "PL_ctf_lf_lobby" "CTF Nitro-Lobby"
- "PL_default_description" "Standardbeschreibung"
- "PL_default_lobbytitle" "Standard-Lobbytitel"
- "PL_default_name" "Standardname"
- "PL_don" "Doppelt oder nichts"
- "PL_fd" "Grenzlandverteidigung"
- "PL_fd_desc" "Verteidige dich gegen Wellen von Truppen der Restflotte"
- "PL_fd_easy" "Grenzlandverteidigung: Leicht"
- "PL_fd_easy_desc" "Zerschlage den Gegner"
- "PL_fd_easy_lobby" "Grenzlandverteidigung: Leicht-Lobby"
- "PL_fd_hard" "Grenzlandverteidigung: Schwer"
- "PL_fd_hard_desc" "Können ist erforderlich"
- "PL_fd_hard_lobby" "Grenzlandverteidigung: Schwer-Lobby"
- "PL_fd_insane" "Grenzlandverteidigung: Wahnsinn"
- "PL_fd_insane_desc" "Du wirst nicht überleben"
- "PL_fd_insane_lobby" "Grenzlandverteidigung: Wahnsinn – Lobby"
- "PL_fd_lobby" "Grenzlandverteidigung-Lobby"
- "PL_fd_master" "Grenzlandverteidigung: Meister"
- "PL_fd_master_desc" "Nur die Besten der Besten werden erfolgreich sein"
- "PL_fd_master_lobby" "Grenzlandverteidigung: Meister – Lobby"
- "PL_fd_normal" "Grenzlandverteidigung: Normal"
- "PL_fd_normal_desc" "Empfohlen für erfahrene Spieler"
- "PL_fd_normal_lobby" "Grenzlandverteidigung: Normal – Lobby"
- "PL_ffa" "Frei für alle"
- "PL_ffa_abbr" "FFA"
- "PL_ffa_desc" "Jeder Pilot kämpft für sich selbst. Eliminiere alle Gegner.\n^FFC83200Spieler: 1 vs. 11\nZeitlimit: 10 Min.\nMax. Party-Größe: 1"
- "PL_ffa_lobby" "Frei für alle-Lobby"
- "PL_fra" "Free Agents"
- "PL_fra_abbr" "FRA"
- "PL_fra_desc" "Du kämpfst für dich selbst. Eliminiere Gegner, um zu siegen. Sammle 3 Batterien für einen Titanfall.\n^FFC83200Spieler: 1 vs. 11\nZeitlimit: 15 Min.\nMax. Party-Größe: 1"
- "PL_fra_lobby" "Free Agents-Lobby"
- "PL_groud_war_lobby" "8 vs. 8 Mixtape-Lobby"
- "PL_ground_war" "8 vs. 8 Mixtape"
- "PL_ground_war_abbr" "8 vs. 8"
- "PL_ground_war_desc" "Enthält Gefecht und Verstärkter Hardpoint mit einer hohen Spielerzahl auf allen Karten.\n^FFC83200Spieler: 8 vs. 8"
- "PL_hardpoint" "Verstärkter Hardpoint"
- "PL_hardpoint_abbr" "VHP"
- "PL_hardpoint_desc" "Erobere und halte einen Hardpoint, um Punkte zu erringen. Verstärkte Hardpoints bringen die doppelte Punktzahl.\n^FFC83200Spieler: 6 vs. 6\nZeitlimit: 10 Min.\nMax. Party-Größe: 6"
- "PL_hardpoint_lobby" "Verstärkter Hardpoint-Lobby"
- "PL_hunted" "Gejagt"
- "PL_iron_last_titan_standing" "Eiserner LTS"
- "PL_iron_last_titan_standing_abbr" "ELTS"
- "PL_iron_last_titan_standing_desc" "Nur Titans. Rundenbasiertes Eliminierungsmatch. Sieger ist, wer zuerst 3 Runden gewinnt.\n^FFC83200Spieler: 5 vs. 5 *KEINE PILOTEN\nZeitlimit: 3 Min. pro Runde * Keine Respawns\nMax. Party-Größe: 5"
- "PL_iron_last_titan_standing_lobby" "PL_iron_last_titan_standing_lobby"
- "PL_last_titan_standing" "Last Titan Standing"
- "PL_last_titan_standing_abbr" "LTS"
- "PL_last_titan_standing_desc" "Alle Spieler beginnen dieses rundenbasierte Eliminierungsmatch in Titans. Sieger ist, wer zuerst 3 Runden für sich entscheidet.\n^FFC83200Spieler: 5 vs. 5 * Starte als Titan\nZeitlimit: 3 Min. pro Runde * Keine Respawns\nMax. Party-Größe: 5"
- "PL_last_titan_standing_lobby" "LTS-Lobby"
- "PL_limited_time_mode" "Befristeter Modus"
- "PL_live_fire" "Live Fire"
- "PL_live_fire_abbr" "LF"
- "PL_live_fire_desc" "Rasanter Kampf in einer Live Fire-Arena. Gewinne die Runde, indem du alle gegnerischen Piloten neutralisierst oder am Ende der Runde die Flagge hältst.^FFC83200\nSpieler: 6 vs. 6 *Keine Titans\nZeitlimit: 60 Sek. *Keine Respawns\nMax. Party-Größe: 6"
- "PL_live_fire_lobby" "Live Fire-Lobby"
- "PL_load_a_map_on_the_command_line" "Lade eine Karte auf der Befehlszeile -devonly"
- "PL_marked_for_death" "Todgeweiht"
- "PL_marked_for_death_abbr" "TG"
- "PL_marked_for_death_desc" "Eliminiere oder beschütze die markierten Ziele.\n^FFC83200Spieler: 6 vs. 6 \nZeitlimit: 12 Min.\nMax. Party-Größe: 6"
- "PL_marked_for_death_lobby" "Todgeweiht-Lobby"
- "PL_nitro_ffa" "FFA (Nitro)"
- "PL_nitro_ffa_abbr" "FFA-N"
- "PL_nitro_ffa_desc" "Rasantes Free for All auf ausgewählten Karten.\n^FFC83200Spieler: 6\n^F4D5A600Keine Titans\nKeine Boosts"
- "PL_nitro_ffa_lobby" "FFA Nitro-Lobby"
- "PL_nitro_mixtape" "Mixtape (Nitro)"
- "PL_nitro_mixtape_abbr" "MXT-N"
- "PL_nitro_mixtape_desc" "Rasantes CTF, TG und PvP auf ausgewählten Karten.\n^FFC83200Spieler: 5 vs. 5\nMax. Party-Größe: 5\n^F4D5A600Flagge wird sofort zurückgebracht"
- "PL_nitro_mixtape_lobby" "Mixtape-Lobby"
- "PL_pilot_hunter" "Gefecht"
- "PL_pilot_hunter_abbr" "GEF"
- "PL_pilot_hunter_desc" "Neutralisiere gegnerische Piloten und Titans. \n^FFC83200Spieler: 8 vs. 8\nZeitlimit: 10 Min.\nMax. Party-Größe: 8"
- "PL_pilot_hunter_lobby" "Gefecht-Lobby"
- "PL_pilot_skirmish" "Piloten vs. Piloten"
- "PL_pilot_skirmish_abbr" "PvP"
- "PL_pilot_skirmish_desc" "Neutralisiere gegnerische Piloten. Titanfalls nicht erlaubt.\n^FFC83200Spieler: 8 vs. 8 * Keine Titans\nZeitlimit: 10 Min.\nMax. Party-Größe: 8"
- "PL_pilot_skirmish_lobby" "PvP-Lobby"
- "PL_pl_rebuild_all_paths" "Neuaufbau aller Wege"
- "PL_pl_run_with_ai_ainrebuildonmapstart_2" "Mit ai_ainRebuildOnMapStart 2 laufen lassen"
- "PL_private_match" "Privatspiel-Beta"
- "PL_private_match_desc" "Spiele ein benutzerdefiniertes Privatspiel auf einer Karte und einem Modus deiner Wahl.\n^FFC83200Wähle NETWORK EINLADEN oder FREUNDE EINLADEN, um zu spielen\n^FFC83200Spieler: 1-16\nKeine Fortschritte"
- "PL_private_match_lobby" "Privatspiel-Beta-Lobby"
- "PL_promo_coop" "4-Spieler-KOOP"
- "PL_raid" "Überfall"
- "PL_rise" "Aufstieg 24/7"
- "PL_rise_abbr" "AUF"
- "PL_rise_desc" "Aufstieg rund um die Uhr. ^CCCCCC00Sucht nach Spielen in den Modi ^FFC83200CTF^CCCCCC00, ^FFC83200Verstärkter Hardpoint^CCCCCC00, ^FFC83200Piloten vs. Piloten^CCCCCC00, ^FFC83200Live Fire^CCCCCC00 und ^FFC83200Last Titan Standing^CCCCCC00."
- "PL_rise_lobby" "Aufstieg 24/7 – Lobby"
- "PL_rocket_arena" "Raketenarena"
- "PL_rocket_arena_abbr" "LF"
- "PL_rocket_arena_desc" "Klassische Live-Fire-Regeln mit modifizierten EPGs.^FFC83200\nSpieler: 6 vs. 6 *Keine Titans\nZeitlimit: 90 Sek. *Keine Respawns\nMax. Party-Größe: 6"
- "PL_rocket_arena_lobby" "Raketenarena-Lobby"
- "PL_settings_for_when_someone_loads_a_map_on_the_command_line_do_not_edit_the_cmdlinemapload_1_below_-_this_makes_this_work" "Einstellungen, wenn jemand eine Karte auf der Befehlszeile lädt. Nicht cmdlineMapLoad 1 bearbeiten - dadurch funktioniert es."
- "PL_speedball" "Live Fire"
- "PL_speedball_desc" "Kämpfe um die neutrale Flagge. Eliminiere das gegnerische Team oder halte am Ende der Spielzeit die Flagge, um die Runde zu gewinnen. Wer zuerst 5 Runden für sich entscheidet, gewinnt.\n^FFC83200Spieler: 6 vs. 6 *Keine Titans\nZeitlimit: 60 Sekunden pro Runde *Keine Respawns\nMax. Party-Größe: 6"
- "PL_speedball_lobby" "Live Fire-Lobby"
- "PL_tactikill" "Taktikill-Materialschlacht"
- "PL_tactikill_abbr" "MAT"
- "PL_tactikill_desc" "Klassische Materialschlacht-Regeln, allerdings werden alle Taktikfähigkeiten durch einen Kill zurückgesetzt.\n^FFC83200Spieler: 6 vs. 6 *KI\nZeitlimit: 10 Min.\nMax. Party-Größe: 6"
- "PL_tactikill_lobby" "Taktikill-Materialschlacht-Lobby"
- "PL_titan_brawl" "Titan Brawl"
- "PL_titan_brawl_abbr" "TB"
- "PL_titan_brawl_desc" "Eliminiere gegnerische Titans. Piloten nicht erlaubt.\n^FFC83200Spieler: 5 vs. 5\nZeitlimit: 10 Min.\nMax. Party-Größe: 5"
- "PL_titan_brawl_hint" "Neutralisiere gegnerische Titans.\nKein Ausstieg."
- "PL_titan_brawl_lobby" "Titan Brawl-Lobby"
- "PL_titan_brawl_turbo" "Turbo-Titan-Brawl"
- "PL_titan_brawl_turbo_abbr" "TTDM"
- "PL_titan_brawl_turbo_desc" "Klassische Titan-Brawl-Regeln mit schnellerer Jetschub-und System-Regeneration.\n^FFC83200Spieler: 5 vs. 5\nZeitlimit: 10 Min.\nMax. Party-Größe: 5"
- "PL_titan_brawl_turbo_hint" "Neutralisiere gegnerische Titans.\nKein Ausstieg"
- "PL_titan_brawl_turbo_lobby" "Turbo-Titan-Brawl-Lobby"
- "PL_turbo_last_titan_standing" "Turbo-LTS"
- "PL_turbo_last_titan_standing_abbr" "LTS"
- "PL_turbo_last_titan_standing_desc" "Klassische LTS-Regeln mit schnellerer Jetschub-und System-Regeneration.\n^FFC83200Spieler: 5 vs. 5 *Starte als Titan\nZeitlimit: 3 Min. pro Runde\nMax. Party-Größe: 5"
- "PL_turbo_last_titan_standing_lobby" "Turbo-LTS-Lobby"
- "PL_variety_pack" "Mixtape"
- "PL_variety_pack_desc" "Variierende Spielerzahlen und verschiedene Karten in diesen Modi:\n^FFC83200*Kopfgeldjagd *Materialschlacht\n*Last Titan Standing *Verstärkter Hardpoint\n*Piloten vs. Piloten *Capture the Flag"
- "PL_variety_pack_lobby" "Mixtape-Lobby"
- "PL_wargames" "Kriegsspiele 24/7"
- "PL_wargames_abbr" "KSP"
- "PL_wargames_desc" "Alle Kriegsspiele, rund um die Uhr. ^CCCCCC00Sucht nach Spielen in den Modi ^FFC83200Materialschlacht^CCCCCC00, ^FFC83200CTF^CCCCCC00, ^FFC83200Piloten vs. Piloten^CCCCCC00, ^FFC83200Verstärkter Hardpoint^CCCCCC00 und ^FFC83200Last Titan Standing^CCCCCC00."
- "PL_wargames_lobby" "Kriegsspiele 24/7 – Lobby"
- "WATCH_TUTORIAL" "TUTORIAL ANSEHEN"
- }
- }
- "lang"
- {
- "Language" "portuguese"
- "Tokens"
- {
- "COMMUNITYUPDATE_00_A" "Sua aventura pelas paisagens incríveis da Fronteira continua com o mais recente DLC para Titanfall 2: Cartões-postais da Fronteira. Trazendo locais novos e familiares junto de uma nova coleção de Pinturas de Guerra para Armas de Elite, a Fronteira nunca esteve tão apresentável.\n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_00_Q" "Trailer de Cartões-postais da Fronteira"
- "COMMUNITYUPDATE_01_A" "Leia sobre todas as mudanças trazidas pelo patch Cartões-postais da Fronteira.\n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_01_Q" "Cartões-postais da Fronteira: Detalhes"
- "COMMUNITYUPDATE_02_A" "Em breve nos dispositivos móveis, Titanfall: Assault é um empolgante jogo de estratégia em tempo real situado no universo de Titanfall criado em parceria com Particle City. Veja o jogo em ação aqui!\n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_02_Q" "Trailer de lançamento de Titanfall: Assault"
- "COMMUNITYUPDATE_03_A" "Iniquity nos guia pelo tutorial e oferece dicas básicas para Titanfall: Assault, a forma perfeita de conhecer o jogo.\n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_03_Q" "Titanfall: Assault - Vídeo \"Aprenda o básico\""
- "COMMUNITYUPDATE_04_A" "Ouça algumas das principais pessoas por trás de Defesa da Fronteira falarem sobre a história e criação do modo e nos veja jogar algumas rodadas!\n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_04_Q" "Respawn Joga: Defesa da Fronteira"
- "COMMUNITYUPDATE_05_A" "Kevin Younger criou uma montagem divertida mostrando vários movimentos impressionantes com a Lâmina Sônica.\n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_05_Q" "Criações da Comunidade: Direto ao Ponto"
- "COMMUNITYUPDATE_06_A" "ConzeyG via Reddit demonstra eficiência brutal com a Northstar eliminando Pilotos no modo Marcado para Morrer.\n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_06_Q" "Criações da Comunidade: Caça com a Northstar"
- "COMMUNITYUPDATE_07_A" "Já disponível! Defesa da Fronteira retorna junto de Elevação, além de novas pinturas de guerra à venda e um novo mapa de Queima-roupa. Veja tudo aqui.\n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_07_Q" "Trailer de Operação Escudo da Fronteira"
- "COMMUNITYUPDATE_08_A" "Já disponível! O icônico mapa Jogos de Guerra retorna para Titanfall 2 mais bonito do que nunca. Confira também a nova execução e o novo mapa de Queima-roupa, Tráfego, em ação.\n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_08_Q" "Trailer de jogabilidade de \"Jogos de Guerra\""
- "COMMUNITYUPDATE_09_A" "Este DLC adiciona o 7º Titã do multiplayer: Monarch, uma versão remasterizada do mapa Relíquia, uma nova execução, além de colocar à venda os Titãs Prime Ronin e Tone, mais camuflagens, fundos de distintivo e decorações. Assista à ação aqui.\n\n\nAperte `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_09_Q" "Trailer de jogabilidade: Reino do Monarca"
- "COMMUNITYUPDATE_10_A" "Nem tudo é o que parece na Fronteira - prepare-se para entrar no mais novo pacote de DLC gratuito para Titanfall 2: Falha na Fronteira, trazendo o novo mapa \"Falha\". Inspirado no planeta natal do Capitão Lastimosa, Harmony, o ambiente é dominado por quedas verticais e longos caminhos tortuosos, em um cenário perfeito para encadear longas corridas por paredões e pairar por toda parte. E um novo mapa de Queima-roupa se junta ao conjunto: Convés, com seus espaços internos estreitos, pátios expostos e drones vigilantes circulando sobre sua cabeça. Se você se sentir sobrecarregado, os sempre prestativos Marvins agora estão na área como uma facção inteiramente nova, para dar aquela mãozinha robótica. Finalmente, está disponível a nova execução Lâmina Sônica, para ser usada sempre que for preciso marcar presença.\n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_10_Q" "Trailer de jogabilidade: Falha na Fronteira"
- "COMMUNITYUPDATE_11_A" "É o retorno de um mapa icônico para multiplayer, favorito dos fãs do primeiro Titanfall: Colônia. Com a adição das novas táticas e Titãs de Titanfall 2, os Pilotos e Titãs terão que redobrar a atenção para sobreviver nesta vila idílica e compacta, cheia de becos estreitos, curvas cegas e telhados expostos. Disponível gratuitamente para todos os jogadores a partir do dia 30 de março. O pacote do DLC \"Colônia Renascida\" inclui o retorno de armas clássicas, como o fuzil de assalto modificado R-101, uma nova execução corpo a corpo e novas opções estéticas para você ter o melhor visual enquanto pinta a cidade de vermelho.\n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_11_Q" "Trailer de jogabilidade: Colônia Renascida"
- "COMMUNITYUPDATE_12_A" "Apresentamos Queima-roupa, um modo de jogo ultrarrápido exclusivo para confrontos 6 contra 6 entre Pilotos, com foco na competição e no combate a curta distância. Contém dois novos mapas, criados especialmente para esse modo: Pilhas e Prado. São ambientes fechados e mortais, criados sob medida para a natureza ágil e intensa desse modo. \n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_12_Q" "Trailer: Bem-vindo a Queima-roupa"
- "COMMUNITYUPDATE_13_A" "Experimente a versão renovada de um mapa favorito dos fãs no primeiro Titanfall: `1Angel City`0. Aguarde o primeiro DLC grátis de Titanfall 2, `1O Mais Procurado de Angel City`0, disponível dia 1º de dezembro para todos os jogadores. Esse conteúdo inclui novas opções estéticas para adicionar ainda mais bom gosto à Fronteira. \n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_13_Q" "Trailer: Bem-vindo a Angel City"
- "COMMUNITYUPDATE_14_A" "Que bom que você voltou.\n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_14_Q" "Trailer: \"Bis\""
- "COMMUNITYUPDATE_15_A" "Duas lendas, um legado.\n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_15_Q" "Trailer de jogabilidade: Tornem-se Um"
- "COMMUNITYUPDATE_16_A" "Sem limites.\n\n\nPressione `2%[A_BUTTON|MOUSE1]%`0 para visualizar."
- "COMMUNITYUPDATE_16_Q" "Trailer de jogabilidade (multiplayer): Pilotos"
- "COMMUNITYUPDATE_DESC" "`3Atualizações da Comunidade de Titanfall`0\n\nInformações e links da web.\n\nPara mais:\n`2%$rui/bullet_point%`0Siga-nos no Twitter `1@Respawn`0\n`2%$rui/bullet_point%`0Curta nossa página em `1facebook.com/RespawnEntertainment`0\n`2%$rui/bullet_point%`0Junte-se a nós em `1www.respawn.com`0"
- "COMMUNITYUPDATE_NAME" "Comunidade"
- "KNB_SUBJECT_00_DESC" "`3Quais as novidades de Titanfall?`0\n\nConfira aqui o que mudou em Titanfall 2!"
- "KNB_SUBJECT_00_NAME" "Atualizações do jogo"
- "KNB_SUBJECT_00_SUB_00_A" "`2%$rui/bullet_point%`010 Novas insígnias de Distintivos criadas pela comunidade\n\n`2%$rui/bullet_point%`0Agora é possível comprar todos os presentes do colaborador com créditos\n\n`2%$rui/bullet_point%`0Novo conteúdo da loja para comprar\n\n"
- "KNB_SUBJECT_00_SUB_00_Q" "%$rui/hud/scoreboard/status_titan% 28 de novembro - Época de Colheita"
- "KNB_SUBJECT_00_SUB_01_A" "`2%$rui/bullet_point%`0Espaço Principal de Pistola\n\n`2%$rui/bullet_point%`0Insígnias de Dia das Bruxas\n\n`2%$rui/bullet_point%`0Alterações no Equilíbrio\n\n`2%$rui/bullet_point%`0Novo Conteúdo Para Compras na Loja\n\n"
- "KNB_SUBJECT_00_SUB_01_Q" "%$rui/hud/scoreboard/status_titan% 31 de outubro - Travessuras e Gostosuras"
- "KNB_SUBJECT_00_SUB_02_A" "`2%$rui/bullet_point%`0Defesa da Fronteira - Suporte para mais 3 mapas - Doca Seca, Angel City e Exoplaneta.\n\n`2%$rui/bullet_point%`0Novo mapa do Queima-roupa - UMA\n\n`2%$rui/bullet_point%`0Nova execução de Piloto - Parede Perfurada\n\n`2%$rui/bullet_point%`0Novo conteúdo à venda na Loja"
- "KNB_SUBJECT_00_SUB_02_Q" "%$rui/hud/scoreboard/status_titan% 29 de agosto - Cartões-postais da Fronteira"
- "KNB_SUBJECT_00_SUB_03_A" "`2%$rui/bullet_point%`0Defesa da Fronteira - Um novo modo cooperativo no qual você une forças com até três jogadores para defender um objetivo vital contra as ondas cada vez mais intensas de combatentes da IA. Comunicação e adaptabilidade são as chaves para sobreviver.\n\n`2%$rui/bullet_point%`0Novo Mapa - Elevação\n\n`2%$rui/bullet_point%`0Novo mapa do Queima-roupa - Cidade\n\n`2%$rui/bullet_point%`0Novo conteúdo na Loja"
- "KNB_SUBJECT_00_SUB_03_Q" "%$rui/hud/scoreboard/status_titan% 25/07 - Operação Escudo da Fronteira"
- "KNB_SUBJECT_00_SUB_04_A" "`2%$rui/bullet_point%`0Novo mapa - Jogos de Guerra\n\n`2%$rui/bullet_point%`0Novo mapa de Queima-roupa - Tráfego\n\n`2%$rui/bullet_point%`0Nova execução de Piloto - Boxe Simulado\n\n`2%$rui/bullet_point%`03º espaço de arma\n\n`2%$rui/bullet_point%`0Configurações de partida privada"
- "KNB_SUBJECT_00_SUB_04_Q" "%$rui/hud/scoreboard/status_titan% 27/06 - Jogos de Guerra"
- "KNB_SUBJECT_00_SUB_05_A" "`2%$rui/bullet_point%`0Novo Titã - Monarch\n\n`2%$rui/bullet_point%`0Novo mapa - Relíquia\n\n`2%$rui/bullet_point%`0Nova execução de Piloto - Agora Você Me Vê\n\n`2%$rui/bullet_point%`0Novo conteúdo à venda na Loja"
- "KNB_SUBJECT_00_SUB_05_Q" "%$rui/hud/scoreboard/status_titan% 30/05 - Reino do Monarca"
- "KNB_SUBJECT_00_SUB_06_A" "`2%$rui/bullet_point%`0Novo mapa - Falha\n\n`2%$rui/bullet_point%`0Novo mapa de Queima-roupa - Convés\n\n`2%$rui/bullet_point%`0Nova facção - M.R.V.N.\n\n`2%$rui/bullet_point%`0Nova execução de Piloto - Direto ao Ponto\n\n`2%$rui/bullet_point%`0Geração máxima aumentada para 100"
- "KNB_SUBJECT_00_SUB_06_Q" "%$rui/hud/scoreboard/status_titan% 25/04 - Falha na Fronteira"
- "KNB_SUBJECT_00_SUB_07_A" "`2%$rui/bullet_point%`0Novo mapa - Colônia\n\n`2%$rui/bullet_point%`0Nova execução de Piloto - Esmaga-crânio\n\n`2%$rui/bullet_point%`0Nova arma - R-101\n\n`2%$rui/bullet_point%`0Novo conteúdo à venda na Loja"
- "KNB_SUBJECT_00_SUB_07_Q" "%$rui/hud/scoreboard/status_titan% 30/03 - Colônia Renascida"
- "KNB_SUBJECT_00_SUB_08_A" "`2%$rui/bullet_point%`0Queima-roupa - Um novo modo de eliminação entre Pilotos! As partidas são disputadas em rodadas de 6v6 sem reaparecimento. Você terá um minuto para eliminar a equipe inimiga e vencer a rodada. Também é possível vencer se sua equipe estiver em posse da bandeira neutra quando o tempo acabar. A primeira equipe a vencer 5 rodadas ganha a partida.\n\n`2%$rui/bullet_point%`0Novo mapa de Queima-roupa - Prado\n\n`2%$rui/bullet_point%`0Novo mapa de Queima-roupa - Pilhas\n\n`2%$rui/bullet_point%`0Nova execução de Piloto - Golpe Atrasado"
- "KNB_SUBJECT_00_SUB_08_Q" "%$rui/hud/scoreboard/status_titan% 23/02 - Queima-roupa"
- "KNB_SUBJECT_00_SUB_09_A" "`2%$rui/bullet_point%`0Novo mapa - Angel City\n\n`2%$rui/bullet_point%`0Nova arma - B3 Wingman de Elite\n\n`2%$rui/bullet_point%`0Nova execução de Piloto - De Dentro para Fora\n\n`2%$rui/bullet_point%`0Novos kits de Titã\n\n`2%$rui/bullet_point%`0Novo conteúdo à venda na Loja"
- "KNB_SUBJECT_00_SUB_09_Q" "%$rui/hud/scoreboard/status_titan% 30/11 - O Mais Procurado de Angel City"
- "MP_ANGEL_CITY_FD_WAVE_1" "Ligados aos Céus"
- "MP_ANGEL_CITY_FD_WAVE_2" "Sem Formas"
- "MP_ANGEL_CITY_FD_WAVE_3" "Insurgência"
- "MP_ANGEL_CITY_FD_WAVE_4" "Uma Turma Aguerrida"
- "MP_ANGEL_CITY_FD_WAVE_5" "Rolando os Dados"
- "MP_DRYDOCK_FD_WAVE_1" "Nadando Contra a Corrente"
- "MP_DRYDOCK_FD_WAVE_2" "Eles estão sem balas!"
- "MP_DRYDOCK_FD_WAVE_3" "Ofuscado pela ciência"
- "MP_DRYDOCK_FD_WAVE_4" "Sistema de Alta Pressão"
- "MP_DRYDOCK_FD_WAVE_5" "Olho do Furacão"
- "MP_THAW_FD_WAVE_1" "Consciência da Situação"
- "MP_THAW_FD_WAVE_2" "A União Faz a Força"
- "MP_THAW_FD_WAVE_3" "Capanga 21"
- "MP_THAW_FD_WAVE_4" "Brincando com Fogo"
- "MP_THAW_FD_WAVE_5" "Sirva Bem às Armas"
- "NO_PRICE" "Oferta expirada"
- "NO_PRICE_TWO_LINES" "Oferta\nexpirada"
- "PL_aegis_last_titan_standing" "SdT Égide"
- "PL_aegis_last_titan_standing_abbr" "SdTE"
- "PL_aegis_last_titan_standing_desc" "Melhorias Égide ativadas. Partida de eliminação por rodada. O primeiro a ganhar 3 rodadas vence.\n^FFC83200Jogadores: 5v5 *Começa como Titã\nLimite de tempo: 3 minutos por rodada *Sem reaparecimento\nTamanho máximo do grupo: 5"
- "PL_aegis_last_titan_standing_lobby" "PL_aegis_last_titan_standing_lobby"
- "PL_aegis_titan_brawl" "Disputa de Titãs Égide"
- "PL_aegis_titan_brawl_abbr" "DdTE"
- "PL_aegis_titan_brawl_desc" "Elimine Titãs inimigos. Melhorias Égide ativadas.\n^FFC83200Jogadores: 5v5\nLimite de tempo: 10 min.\nTamanho máximo do grupo: 5"
- "PL_aegis_titan_brawl_hint" "Elimine Titãs inimigos.\nSem ejeção"
- "PL_aegis_titan_brawl_lobby" "Sala de espera: Disputa de Titãs Égide"
- "PL_aitdm" "Exaustão"
- "PL_aitdm_abbr" "EXA"
- "PL_aitdm_desc" "Elimine todos os inimigos.\n^FFC83200Jogadores: 6v6 *IA\nLimite de tempo: 10 min\nTamanho máximo do grupo: 6"
- "PL_aitdm_lobby" "Sala de espera: Exaustão"
- "PL_all_grapple" "Ataque com Gancho"
- "PL_all_grapple_abbr" "EXA"
- "PL_all_grapple_desc" "Regras de Exaustão clássicas, exceto todas as habilidades Táticas, são substituídas com Gancho.\n^FFC83200Jogadores: 6v6 *IA\nLimite de tempo: 10 min.\nTamanho máximo do grupo: 6"
- "PL_all_grapple_lobby" "Sala de espera: Ataque com Gancho"
- "PL_all_holopilot" "A Grande Trapaça"
- "PL_all_holopilot_abbr" "QR"
- "PL_all_holopilot_desc" "Regras de Queima-roupa clássicas, exceto todas as habilidades Táticas, são substituídas com Holopiloto.\n^FFC83200Jogadores: 6v6 *Sem Titãs\nLimite de tempo: 60 seg.\nTamanho máximo do grupo: 6"
- "PL_all_holopilot_lobby" "Sala de espera: A Grande Trapaça"
- "PL_all_phase" "O Outrolado"
- "PL_all_phase_abbr" "EXA"
- "PL_all_phase_desc" "Regras de Exaustão clássicas, exceto todas as habilidades Táticas, são substituídas com Cronossalto.\n^FFC83200Jogadores: 6v6 *IA\nLimite de tempo: 10 min.\nTamanho máximo do grupo: 6"
- "PL_all_phase_lobby" "Sala de espera: O Outrolado"
- "PL_all_spicy" "Exaustão Apimentada"
- "PL_all_spicy_abbr" "EXA"
- "PL_all_spicy_desc" "Regras de Exaustão clássicas, exceto todas as habilidades Táticas, são substituídas com Pulgões.\n^FFC83200Jogadores: 6v6 *IA\nLimite de tempo: 10 min.\nTamanho máximo do grupo: 6"
- "PL_all_spicy_lobby" "Sala de espera: Exaustão Apimentada"
- "PL_amped_tacticals" "Táticas Melhoradas"
- "PL_amped_tacticals_abbr" "EXA"
- "PL_amped_tacticals_desc" "Regras de Exaustão clássicas, exceto que todas as habilidades Táticas são mais potentes.\n^FFC83200Jogadores: 6v6 *IA\nLimite de tempo: 10 min.\nTamanho máximo do grupo: 6"
- "PL_amped_tacticals_lobby" "Sala de espera: Táticas Melhoradas"
- "PL_ANGEL_CITY" "Angel City Permanente"
- "PL_angel_city_abbr" "AC"
- "PL_angel_city_desc" "Somente Angel City, o tempo todo.\n^FFC83200*Recompensa *Exaustão\n*PCA"
- "PL_angel_city_lobby" "Sala de espera: Angel City Permanente"
- "PL_at_coop" "Fuga (Coop)"
- "PL_at_coop_desc" "Você acaba de fugir da prisão só com uma pistola. Sobreviva até o transporte de evacuação chegar. Elimine inimigos para ganhar dinheiro e comprar armas. \n^FFC83200Jogadores: 6\nTamanho máximo do grupo: 6"
- "PL_at_coop_lobby" "Sala de espera de Fuga"
- "PL_attrition" "Recompensa"
- "PL_attrition_abbr" "REC"
- "PL_attrition_desc" "Elimine os inimigos para ganhar dinheiro. Deposite os bônus em locais específicos para receber ainda mais.\n^FFC83200Jogadores: 5v5 *IA\nLimite de tempo: 10 min\nTamanho máximo do grupo: 5"
- "PL_attrition_lobby" "Sala de espera: Recompensa"
- "PL_capture_the_flag" "Captura de Bandeira"
- "PL_capture_the_flag_abbr" "CDB"
- "PL_capture_the_flag_desc" "Roube a bandeira do inimigo e leve-a para a sua base. Não deixe os inimigos pegarem a sua bandeira!\n^FFC83200Jogadores: 5v5\nLimite de tempo: 12 min\nTamanho máximo do grupo: 5"
- "PL_capture_the_flag_lobby" "Sala de espera: CdB"
- "PL_coliseum" "Coliseu"
- "PL_coliseum_desc" "Duelo com mobilidade extra numa jaula. Elimine seu oponente para vencer a rodada. Melhor de 5 ganha um Presente do Colaborador.^FFC83200\nJogadores: 1v1 *Sem Titãs\nLimite de tempo: 3 min. *Sem reaparecimento\n**^FFFFFF00REQUER BILHETE DO COLISEU ou PAGAMENTO DA TAXA DE ENTRADA"
- "PL_coliseum_lobby" "Sala de espera: Coliseu"
- "PL_colony" "Colônia Permanente"
- "PL_colony_abbr" "COL"
- "PL_colony_desc" "Somente Colônia, o tempo todo. ^CCCCCC00Isto vai buscar partidas de ^FFC83200Exaustão^CCCCCC00, ^FFC83200Pilotos vs Pilotos^CCCCCC00 e ^FFC83200Sobrevivência de Titã^CCCCCC00."
- "PL_colony_lobby" "Sala de espera de Colônia Permanente"
- "PL_ctf_lf" "CdB (Nitro)"
- "PL_ctf_lf_abbr" "CdB-N"
- "PL_ctf_lf_desc" "Captura de Bandeira frenética em mapas selecionados.\n^FFC83200Jogadores: 5v5\nTamanho máximo do grupo: 5\n^F4D5A600Retorno Imediato de Bandeira"
- "PL_ctf_lf_lobby" "Sala de espera: CdB Nitro"
- "PL_default_description" "Descrição padrão"
- "PL_default_lobbytitle" "Título de sala padrão"
- "PL_default_name" "Nome padrão"
- "PL_don" "Dobro ou Nada"
- "PL_fd" "Defesa da Fronteira"
- "PL_fd_desc" "Defenda-se contra ondas da Frota Remanescente"
- "PL_fd_easy" "Defesa da Fronteira: Fácil"
- "PL_fd_easy_desc" "Destrua a oposição"
- "PL_fd_easy_lobby" "Defesa da Fronteira: Sala de espera (Fácil)"
- "PL_fd_hard" "Defesa da Fronteira: Difícil"
- "PL_fd_hard_desc" "Requer habilidade"
- "PL_fd_hard_lobby" "Defesa da Fronteira: Sala de espera (Difícil)"
- "PL_fd_insane" "Defesa da Fronteira: Insana"
- "PL_fd_insane_desc" "Você não vai sobreviver"
- "PL_fd_insane_lobby" "Sala de espera: Defesa da Fronteira (Insana)"
- "PL_fd_lobby" "Sala de espera Defesa da Fronteira"
- "PL_fd_master" "Defesa da Fronteira: Mestre"
- "PL_fd_master_desc" "Somente os melhores entre os melhores têm êxito"
- "PL_fd_master_lobby" "Sala de espera: Defesa da Fronteira (Mestre)"
- "PL_fd_normal" "Defesa da Fronteira: Normal"
- "PL_fd_normal_desc" "Recomendado para jogadores experientes"
- "PL_fd_normal_lobby" "Defesa da Fronteira: Sala de espera (Normal)"
- "PL_ffa" "Cada Um por Si"
- "PL_ffa_abbr" "CPS"
- "PL_ffa_desc" "Salve-se quem puder, elimine todos os inimigos.\n^FFC83200Jogadores: 1v11\nLimite de tempo: 10 min\nTamanho máximo do grupo: 1"
- "PL_ffa_lobby" "Sala de espera: CUPS"
- "PL_fra" "Contrato Livre"
- "PL_fra_abbr" "CL"
- "PL_fra_desc" "Você está por conta própria. Elimine inimigos para vencer. Junte 3 baterias para chamar um Titã.\n^FFC83200Jogadores: 1v11\nLimite de tempo: 15 min.\nTamanho máximo do grupo: 1"
- "PL_fra_lobby" "Sala de espera: CL"
- "PL_groud_war_lobby" "Sala de espera: Variedade 8v8"
- "PL_ground_war" "Variedade 8v8"
- "PL_ground_war_abbr" "8v8"
- "PL_ground_war_desc" "Inclui Duelos e Ponto de Controle Amplificado com mais jogadores em todos os mapas.\n^FFC83200Jogadores: 8v8"
- "PL_hardpoint" "PCA"
- "PL_hardpoint_abbr" "PCA"
- "PL_hardpoint_desc" "Capture e mantenha um ponto de controle para acumular pontos. Os Pontos de Controle Amplificados dão pontos em dobro.\n^FFC83200Jogadores: 6v6\nLimite de tempo: 10 min\nTamanho máximo do grupo: 6"
- "PL_hardpoint_lobby" "Sala de espera: PCA"
- "PL_hunted" "Caçada"
- "PL_iron_last_titan_standing" "SdT - Aço"
- "PL_iron_last_titan_standing_abbr" "SdTA"
- "PL_iron_last_titan_standing_desc" "Partida de rodadas eliminatórias, exclusiva para Titãs. Vence quem conquistar 3 rodadas primeiro.\n^FFC83200Jogadores: 5v5 *SEM PILOTOS\nLimite de tempo: 3 minutos por rodada *Sem reaparecimento\nTamanho máximo do grupo: 5"
- "PL_iron_last_titan_standing_lobby" "PL_iron_last_titan_standing_lobby"
- "PL_last_titan_standing" "Sobrevivência de Titã"
- "PL_last_titan_standing_abbr" "SdT"
- "PL_last_titan_standing_desc" "Todos os jogadores já começam com Titãs nessa partida de eliminação por rodada. O primeiro a ganhar 3 rodadas vence.\n^FFC83200Jogadores: 5v5 *Começa com Titã\nLimite de tempo: 3 min por rodada *Sem reaparecimento\nTamanho máximo do grupo: 5"
- "PL_last_titan_standing_lobby" "Sala de espera: SdT"
- "PL_limited_time_mode" "Por tempo limitado"
- "PL_live_fire" "Queima-roupa"
- "PL_live_fire_abbr" "QR"
- "PL_live_fire_desc" "Combate frenético em uma arena de Queima-roupa. Vença a rodada eliminando todos os Pilotos inimigos ou controlando a bandeira quando o tempo acabar.^FFC83200\nJogadores: 6v6 *Sem Titãs\nLimite de tempo: 60 seg. *Sem reaparecimentos\nTamanho máximo do grupo: 6"
- "PL_live_fire_lobby" "Sala de Espera: Queima-roupa"
- "PL_load_a_map_on_the_command_line" "Carregue um mapa na linha de comando -apenas desenvolvedores"
- "PL_marked_for_death" "Marcado para Morrer"
- "PL_marked_for_death_abbr" "MPM"
- "PL_marked_for_death_desc" "Elimine ou proteja os alvos marcados.\n^FFC83200Jogadores: 6v6 \nLimite de tempo: 12m\nTamanho máximo do grupo: 6"
- "PL_marked_for_death_lobby" "Sala de espera: Marcado para Morrer"
- "PL_nitro_ffa" "CPS (Nitro)"
- "PL_nitro_ffa_abbr" "CPS-N"
- "PL_nitro_ffa_desc" "Cada Um Por Si frenético nos mapas selecionados.\n^FFC83200Jogadores: 6\n^F4D5A600Sem Titãs\nSem reforços"
- "PL_nitro_ffa_lobby" "Sala de espera: CPS Nitro"
- "PL_nitro_mixtape" "Variedade (Nitro)"
- "PL_nitro_mixtape_abbr" "VAR-N"
- "PL_nitro_mixtape_desc" "CdB, MPM e JxJ frenéticos em mapas selecionados.\n^FFC83200Jogadores: 5v5\nTamanho máximo do grupo: 5\n^F4D5A600Retorno Imediato de Bandeira"
- "PL_nitro_mixtape_lobby" "Sala de espera: Variedade"
- "PL_pilot_hunter" "Duelos"
- "PL_pilot_hunter_abbr" "DUE"
- "PL_pilot_hunter_desc" "Elimine Pilotos e Titãs inimigos. \n^FFC83200Jogadores: 8v8\nLimite de tempo: 10 min\nTamanho máximo do grupo: 8"
- "PL_pilot_hunter_lobby" "Sala de espera: Duelos"
- "PL_pilot_skirmish" "Pilotos vs. Pilotos"
- "PL_pilot_skirmish_abbr" "PvP"
- "PL_pilot_skirmish_desc" "Elimine os Pilotos inimigos. Não há lançamentos de Titãs.\n^FFC83200Jogadores: 8v8 *Sem Titãs\nLimite de tempo: 10 min\nTamanho máximo do grupo: 8"
- "PL_pilot_skirmish_lobby" "Sala de espera: PvP"
- "PL_pl_rebuild_all_paths" "Reconstruir todos os caminhos"
- "PL_pl_run_with_ai_ainrebuildonmapstart_2" "Executar com ai_ainRebuildOnMapStart 2"
- "PL_private_match" "Partida Privada (Beta)"
- "PL_private_match_desc" "Jogue uma partida privada personalizada em um mapa ou modo de sua escolha.\n^FFC83200CONVIDE A REDE ou CONVIDE OS AMIGOS para jogar.\n^FFC83200Jogadores: 1 a 16\nSem progresso"
- "PL_private_match_lobby" "Sala de Espera Privada (Beta)"
- "PL_promo_coop" "Cooperação para 4 jogadores"
- "PL_raid" "Incursão"
- "PL_rise" "Elevação Permanente"
- "PL_rise_abbr" "ELE"
- "PL_rise_desc" "Somente Elevação, o tempo todo. ^CCCCCC00Isto vai buscar partidas de ^FFC83200CdB^CCCCCC00, ^FFC83200Ponto de Controle Amplificado^CCCCCC00, ^FFC83200Pilotos vs Pilotos^CCCCCC00, ^FFC83200Queima-roupa^CCCCCC00 e ^FFC83200Sobrevivência de Titã^CCCCCC00."
- "PL_rise_lobby" "Sala de espera: Elevação Permanente"
- "PL_rocket_arena" "Arena de Foguetes"
- "PL_rocket_arena_abbr" "QR"
- "PL_rocket_arena_desc" "Regras de Queima-roupa clássicas, com EPGs modificadas.^FFC83200Jogadores: 6v6 *Sem Titãs\nLimite de tempo: 90 seg.\nTamanho máximo do grupo: 6"
- "PL_rocket_arena_lobby" "Sala de espera: Arena de Foguetes"
- "PL_settings_for_when_someone_loads_a_map_on_the_command_line_do_not_edit_the_cmdlinemapload_1_below_-_this_makes_this_work" "Configurações para quando alguém carrega um mapa na linha de comando. Não edite cmdlineMapLoad 1 abaixo - isso faz isso funcionar."
- "PL_speedball" "Queima-roupa"
- "PL_speedball_desc" "Lute pela posse de uma bandeira neutra. Elimine a equipe inimiga ou esteja com a bandeira quando o tempo acabar para vencer a rodada. Vence a equipe que ganhar 5 rodadas primeiro.\n^FFC83200Jogadores: 6v6 *Sem Titãs\nLimite de tempo: 60 segundos por rodada *Sem reaparecimento\nTamanho máximo do grupo: 6"
- "PL_speedball_lobby" "Sala de Espera: Queima-roupa"
- "PL_tactikill" "Exaustão em Eliminação Tática"
- "PL_tactikill_abbr" "EXA"
- "PL_tactikill_desc" "Regras de Exaustão clássicas, exceto que todas as habilidades Táticas são totalmente reiniciadas com uma eliminação.\n^FFC83200Jogadores: 6v6 *IA\nLimite de tempo: 10 min.\nTamanho máximo do grupo: 6"
- "PL_tactikill_lobby" "Sala de espera: Exaustão em Eliminação Tática"
- "PL_titan_brawl" "Disputa de Titãs"
- "PL_titan_brawl_abbr" "DdT"
- "PL_titan_brawl_desc" "Elimine Titãs inimigos. Proibido Pilotos.\n^FFC83200Jogadores: 5v5\nLimite de tempo: 10 min.\nTamanho máximo do grupo: 5"
- "PL_titan_brawl_hint" "Elimine Titãs inimigos.\nSem ejeção"
- "PL_titan_brawl_lobby" "Sala de espera: Disputa de Titãs"
- "PL_titan_brawl_turbo" "Disputa de Titãs Turbo"
- "PL_titan_brawl_turbo_abbr" "DdT"
- "PL_titan_brawl_turbo_desc" "Regras de Disputa de Titãs clássicas com regeneração de Arrancada e geração de Núcleo mais rápidas.\n^FFC83200Jogadores: 5v5\nLimite de tempo: 10 min.\nTamanho máximo do grupo: 5"
- "PL_titan_brawl_turbo_hint" "Elimine Titãs inimigos.\nSem ejeção"
- "PL_titan_brawl_turbo_lobby" "Sala de espera: Disputa de Titãs Turbo"
- "PL_turbo_last_titan_standing" "SdT Turbo"
- "PL_turbo_last_titan_standing_abbr" "SdT"
- "PL_turbo_last_titan_standing_desc" "Regras de SdT clássicas com regeneração de Arrancada e geração de Núcleo mais rápidas.\n^FFC83200Jogadores: 5v5 *Inicia como Titã\nLimite de tempo: 3 min. por rodada *Sem reaparecimentos\nTamanho máximo do grupo: 5"
- "PL_turbo_last_titan_standing_lobby" "Sala de espera: SdT Turbo"
- "PL_variety_pack" "Variedade"
- "PL_variety_pack_desc" "Número variável de jogadores e inclui uma variedade de mapas nos seguintes modos:\n^FFC83200*Recompensa *Exaustão\n*Sobrevivência de Titã *Ponto de Controle Amplificado\n*Pilotos vs. Pilotos *Captura de Bandeira"
- "PL_variety_pack_lobby" "Sala de espera: Variedade"
- "PL_wargames" "Jogos de Guerra Permanente"
- "PL_wargames_abbr" "JDG"
- "PL_wargames_desc" "Somente Jogos de Guerra, o tempo todo. ^CCCCCC00Isto vai buscar partidas de ^FFC83200Exaustão^CCCCCC00, ^FFC83200Pilotos vs Pilotos^CCCCCC00, ^FFC83200Ponto de Controle Amplificado^CCCCCC00 e ^FFC83200Sobrevivência de Titã^CCCCCC00."
- "PL_wargames_lobby" "Sala de espera: Jogos de Guerra Permanente"
- "WATCH_TUTORIAL" "ASSISTA AO TUTORIAL"
- }
- }
- "lang"
- {
- "Language" "japanese"
- "Tokens"
- {
- "COMMUNITYUPDATE_00_A" "フロンティアの絶景を巡る冒険は、タイタンフォール 2の最新DLC、フロンティアからのポストカードの登場でさらに続きます。新スポットやお馴染みのスポットに加え、多彩な新しい武器用エリートウォーペイントが加わって、フロンティアの彩りがかつてなく豊かになりました。\n\n\n`2%[A_BUTTON|MOUSE1]% `0で視聴。"
- "COMMUNITYUPDATE_00_Q" "「フロンティアからのポストカード」トレーラー"
- "COMMUNITYUPDATE_01_A" "フロンティアからのポストカードのパッチで変更された点をすべてご紹介します。\n\n\n`2%[A_BUTTON|MOUSE1]% `0で表示。"
- "COMMUNITYUPDATE_01_Q" "フロンティアからのポストカード:パッチノート"
- "COMMUNITYUPDATE_02_A" "「タイタンフォール アサルト」がモバイルに近日登場。Particle Cityとの提携で生まれた、タイタンフォールの世界を舞台にした白熱のリアルタイム・ストラテジーゲームです。ゲーム動画はこちら!\n\n\n`2%[A_BUTTON|MOUSE1]% `0で視聴。"
- "COMMUNITYUPDATE_02_Q" "タイタンフォール アサルト「ローンチ」トレーラー"
- "COMMUNITYUPDATE_03_A" "Iniquity氏が「タイタンフォール アサルト」のチュートリアルをプレイしながら、基本的なアドバイスを紹介します。ゲームの初歩を覚えるのに最適です。\n\n\n`2%[A_BUTTON|MOUSE1]% `0で表示。"
- "COMMUNITYUPDATE_03_Q" "タイタンフォール アサルト:「入門」動画"
- "COMMUNITYUPDATE_04_A" "フロンティアディフェンスの主な製作スタッフが、モードの歴史と制作について語り、ラウンドをプレイします!\n\n\n`2%[A_BUTTON|MOUSE1]% `0で視聴"
- "COMMUNITYUPDATE_04_Q" "スタッフプレイ:フロンティアディフェンス"
- "COMMUNITYUPDATE_05_A" "Kevin Younger氏から、華麗にパルスブレードを操る様子を大量に収めた楽しいダイジェスト動画が届きました。\n\n\n`2%[A_BUTTON|MOUSE1]% `0で視聴"
- "COMMUNITYUPDATE_05_Q" "コミュニティー作品:敵はそこだ"
- "COMMUNITYUPDATE_06_A" "redditのConzeyG氏が、マーク・フォー・デスでノーススターが残酷なまでの効率でパイロットの息の根を止める様子を披露してくれました。\n\n\n`2%[A_BUTTON|MOUSE1]% `0で表示。"
- "COMMUNITYUPDATE_06_Q" "コミュニティー作品:ノーススターのハント"
- "COMMUNITYUPDATE_07_A" "好評配信中!フロンティアディフェンスとマップ「ライズ」が復活。さらに新ウォーペイントの販売が始まり、ライブファイアに新マップが登場。実際のプレイの様子をご覧ください。\n\n\n`2%[A_BUTTON|MOUSE1]% `0で視聴。"
- "COMMUNITYUPDATE_07_Q" "「フロンティアシールド作戦」GPトレーラー"
- "COMMUNITYUPDATE_08_A" "配信開始!シリーズを代表するマップ「ウォーゲームズ」が美しさを増してタイタンフォール 2に戻ってきました。また、新処刑攻撃とライブファイアの新マップ「交通」もご紹介します。\n\n\n`2%[A_BUTTON|MOUSE1]% `0で視聴。"
- "COMMUNITYUPDATE_08_Q" "「ウォーゲームズ」ゲームプレイトレーラー"
- "COMMUNITYUPDATE_09_A" "今回のDLCでは、7体目のマルチプレイヤー用新タイタン「モナーク」とリマスター版マップ「レリック」、新処刑攻撃の配信に加え、販売アイテムにローニン・トーン用のプライムタイタンと新しい迷彩、バナー、ノーズアートが登場します。動画はこちら。\n\n\n`2%[A_BUTTON|MOUSE1]% `0で視聴。"
- "COMMUNITYUPDATE_09_Q" "「モナークレイン」ゲームプレイトレーラー"
- "COMMUNITYUPDATE_10_A" "フロンティアでは目に映るものがすべてではない。新マップ「グリッチ」を収録したタイタンフォール 2用最新無料DLCパック、「フロンティアのグリッチ」の登場に備えよう。ラスティモーサ大尉の故郷、惑星ハーモニーをモチーフに作成された、垂直にそびえる壁と長く蛇行した道が大半を占めるマップで、長距離のウォールランを繋げ、マップ中を滑らかに疾走するのにぴったりの構成となっています。ライブファイア用新マップ、デッキも登場。タイトな内部空間と開けた中庭、上空を旋回する監視ドローンが特徴です。ピンチな時は、マービンたちが力を貸してくれます。そして、パルスブレードを使った、敵を刃で貫く新処刑攻撃がアンロック可能となりました。\n\n\n`2%[A_BUTTON|MOUSE1]%`0 で再生。"
- "COMMUNITYUPDATE_10_Q" "「フロンティアのグリッチ」 トレーラー"
- "COMMUNITYUPDATE_11_A" "ファンの間で人気の高い初代の伝説のマルチプレイヤーマップ「植民地」に戻りましょう。「タイタンフォール 2」から登場した新しい戦術アビリティとタイタンの知識を活かさなければ、裏通りや見通しの利かない曲がり角、むき出しの屋上エリアから成る密集度の高い牧歌的な村落で、パイロットとタイタンが生き延びることはできません。マップは3月30日より全プレイヤーに無料配信。DLCパック「コロニーリボーン」には他にも、新デザインのR-101アサルトライフルといった前作でお馴染みの武器に加え、グラップルを使った新しい処刑攻撃、街を最高に格好良く血に染める有料の新装飾アイテムを収録しています。\n\n\n`2%[A_BUTTON|MOUSE1]%`0 で再生。"
- "COMMUNITYUPDATE_11_Q" "「コロニーリボーン」ゲームプレイトレーラー"
- "COMMUNITYUPDATE_12_A" "`1ライブファイア`0登場:パイロット専用、超高速な6対6の接近戦です。ライブファイア専用の最新マップ2種、`1スタック`0と`1草原`0を収録しています。これら2種類の無料マップは、高速の激戦が展開するモード特性に合わせて制作された、タイトで密閉された死のリングです。\n\n\n`2%[A_BUTTON|MOUSE1]%`0で再生。"
- "COMMUNITYUPDATE_12_Q" "「ライブファイア」ゲームプレイトレーラー"
- "COMMUNITYUPDATE_13_A" "元祖タイタンフォールの人気マップ、`1エンジェルシティ`0のリマスター版を体験せよ!2016年12月1日より全プレイヤーへ配信される無料DLC第1弾、`1エンジェルシティ・モスト・ウォンテッド`0に向けてスタンバイしましょう。フロンティアを彩る新しい装飾オプションも収録しています。\n\n\n`2%[A_BUTTON|MOUSE1]%`0で再生。"
- "COMMUNITYUPDATE_13_Q" "「エンジェルシティ」ゲームプレイトレーラー"
- "COMMUNITYUPDATE_14_A" "お帰りなさい。\n\n\n`2%[A_BUTTON|MOUSE1]%`0で再生。"
- "COMMUNITYUPDATE_14_Q" "絶賛「アンコール」トレーラー"
- "COMMUNITYUPDATE_15_A" "2人の伝説、1つの物語。\n\n\n`2%[A_BUTTON|MOUSE1]%`0で再生。"
- "COMMUNITYUPDATE_15_Q" "「Become One」ゲームプレイトレーラー"
- "COMMUNITYUPDATE_16_A" "無限の可能性。\n\n\n`2%[A_BUTTON|MOUSE1]%`0で再生。"
- "COMMUNITYUPDATE_16_Q" "「パイロット」ゲームプレイトレーラー"
- "COMMUNITYUPDATE_DESC" "`3タイタンフォールコミュニティの最新情報`0\n\nオンラインから、情報をたっぷりとお届けします。\n\n詳細は、次の手順でご覧ください。\n`2%$rui/bullet_point%`0Twitterで`1@Respawn`0をフォロー\n`2%$rui/bullet_point%`0`1facebook.com/RespawnEntertainment`0で「いいね!」\n`2%$rui/bullet_point%`0 `1www.respawn.com`0をチェック"
- "COMMUNITYUPDATE_NAME" "コミュニティ"
- "KNB_SUBJECT_00_DESC" "`3タイタンフォール更新履歴`0\n\nこちらをチェックして、タイタンフォール 2の変更点を確認しましょう!"
- "KNB_SUBJECT_00_NAME" "アップデート一覧"
- "KNB_SUBJECT_00_SUB_00_A" "`2%$rui/bullet_point%`010 コミュニティー発の新コールサインとバナーが登場\n\n`2%$rui/bullet_point%`0支持者のギフトがすべてクレジットで購入可能に\n\n`2%$rui/bullet_point%`0ストアに販売アイテムを新入荷\n\n"
- "KNB_SUBJECT_00_SUB_00_Q" "%$rui/hud/scoreboard/status_titan% 11月28日 - ハーベストタイム"
- "KNB_SUBJECT_00_SUB_01_A" "`2%$rui/bullet_point%`0メインスロットのピストル装備\n\n`2%$rui/bullet_point%`0ハロウィン仕様バナー\n\n`2%$rui/bullet_point%`0各種バランス調整\n\n`2%$rui/bullet_point%`0ストアに販売アイテムを新入荷\n\n"
- "KNB_SUBJECT_00_SUB_01_Q" "%$rui/hud/scoreboard/status_titan% 10月31日 - トリック&トリート"
- "KNB_SUBJECT_00_SUB_02_A" "`2%$rui/bullet_point%`0フロンティアディフェンス - 対応マップにドライドック、エンジェルシティ、外惑星を追加。\n\n`2%$rui/bullet_point%`0ライブファイアの新マップ - UMA\n\n`2%$rui/bullet_point%`0パイロットの処刑攻撃 - ホール・イン・ザ・ウォール\n\n`2%$rui/bullet_point%`0ストアに新着商品が登場"
- "KNB_SUBJECT_00_SUB_02_Q" "%$rui/hud/scoreboard/status_titan% 8月29日 - フロンティアからのポストカード"
- "KNB_SUBJECT_00_SUB_03_A" "`2%$rui/bullet_point%`0フロンティアディフェンス - 自分を含め最大4人のプレイヤーでプレイできる協力プレイモード。ゴールは重要な防衛対象を、次第に激しさを増すAIユニットのウェーブから守り通すこと。緊密な連携と臨機応変の対応が勝利のカギになる。\n\n`2%$rui/bullet_point%`0新マップ - ライズ\n\n`2%$rui/bullet_point%`0新ライブファイアマップ - タウンシップ\n\n`2%$rui/bullet_point%`0ストアの新販売アイテム"
- "KNB_SUBJECT_00_SUB_03_Q" "%$rui/hud/scoreboard/status_titan% 7月25日 - フロンティアシールド作戦"
- "KNB_SUBJECT_00_SUB_04_A" "`2%$rui/bullet_point%`0新マップ - ウォーゲーム\n\n`2%$rui/bullet_point%`0ライブファイア用の新マップ - 交通\n\n`2%$rui/bullet_point%`0新パイロット処刑攻撃 - シャドウボクシング\n\n`2%$rui/bullet_point%`0第3の武器スロット\n\n`2%$rui/bullet_point%`0プライベートマッチ設定"
- "KNB_SUBJECT_00_SUB_04_Q" "%$rui/hud/scoreboard/status_titan% 6月27日 - ウォーゲーム"
- "KNB_SUBJECT_00_SUB_05_A" "`2%$rui/bullet_point% `0新型タイタン - モナーク\n\n`2%$rui/bullet_point% `0新マップ - レリック\n\n`2%$rui/bullet_point% `0パイロットの新処刑攻撃 - 俺が見えるな\n\n`2%$rui/bullet_point% `0ストアに新着商品を追加"
- "KNB_SUBJECT_00_SUB_05_Q" "%$rui/hud/scoreboard/status_titan% 5月30日 - モナークレイン"
- "KNB_SUBJECT_00_SUB_06_A" "`2%$rui/bullet_point% `0新マップ - グリッチ\n\n`2%$rui/bullet_point% `0ライブファイア用新マップ - デッキ\n\n`2%$rui/bullet_point% `0新勢力 - M.R.V.N.\n\n`2%$rui/bullet_point% `0パイロットの新処刑攻撃 - 敵はそこだ\n\n`2%$rui/bullet_point% `0世代上限を100に上昇"
- "KNB_SUBJECT_00_SUB_06_Q" "%$rui/hud/scoreboard/status_titan% 4月25日 - フロンティアのグリッチ"
- "KNB_SUBJECT_00_SUB_07_A" "`2%$rui/bullet_point% `0新マップ - 植民地\n\n`2%$rui/bullet_point% `0パイロットの新処刑攻撃 - ロードチェック\n\n`2%$rui/bullet_point% `0新兵器 - R-101\n\n`2%$rui/bullet_point% `0ストアに新着商品を追加"
- "KNB_SUBJECT_00_SUB_07_Q" "%$rui/hud/scoreboard/status_titan% 3月30日 - コロニーリボーン"
- "KNB_SUBJECT_00_SUB_08_A" "`2%$rui/bullet_point% `0ライブファイア - パイロット同士が、勝ち残りを賭けて戦います!リスポーンなし、6対6のラウンド制マッチで、1分以内に敵を全滅させるとラウンド勝利です。また、ラウンド終了時に自分のチームが中立のフラッグを所持していた場合も勝利となります。5ラウンド先取したチームがマッチの勝者となります。\n\n`2%$rui/bullet_point% `0ライブファイア用新マップ - 草原\n\n`2%$rui/bullet_point% `0ライブファイア用新マップ - スタック\n\n`2%$rui/bullet_point% `0パイロットの新処刑攻撃 - レイトアタック"
- "KNB_SUBJECT_00_SUB_08_Q" "%$rui/hud/scoreboard/status_titan% 2月23日 - ライブファイア"
- "KNB_SUBJECT_00_SUB_09_A" "`2%$rui/bullet_point% `0新マップ - エンジェルシティ\n\n`2%$rui/bullet_point% `0新兵器 - B3ウィングマン・エリート\n\n`2%$rui/bullet_point% `0パイロットの新処刑攻撃 - インナーピース\n\n`2%$rui/bullet_point% `0新タイタンキット\n\n`2%$rui/bullet_point% `0ストアに新着商品を追加"
- "KNB_SUBJECT_00_SUB_09_Q" "%$rui/hud/scoreboard/status_titan%11月30日 - エンジェルシティモストウォンテッド"
- "MP_ANGEL_CITY_FD_WAVE_1" "空に繋がれ"
- "MP_ANGEL_CITY_FD_WAVE_2" "不定形"
- "MP_ANGEL_CITY_FD_WAVE_3" "暴動"
- "MP_ANGEL_CITY_FD_WAVE_4" "頑強な一群"
- "MP_ANGEL_CITY_FD_WAVE_5" "危険な賭け"
- "MP_DRYDOCK_FD_WAVE_1" "知らぬ海を泳げ"
- "MP_DRYDOCK_FD_WAVE_2" "弾を持たぬ敵"
- "MP_DRYDOCK_FD_WAVE_3" "科学の目隠し"
- "MP_DRYDOCK_FD_WAVE_4" "高圧力システム"
- "MP_DRYDOCK_FD_WAVE_5" "台風の目"
- "MP_THAW_FD_WAVE_1" "状況把握"
- "MP_THAW_FD_WAVE_2" "数の脅威"
- "MP_THAW_FD_WAVE_3" "ヘンチマン21"
- "MP_THAW_FD_WAVE_4" "銃火器の喜び"
- "MP_THAW_FD_WAVE_5" "銃器を活かし切れ"
- "NO_PRICE" "オファー終了"
- "NO_PRICE_TWO_LINES" "オファー\n終了"
- "PL_aegis_last_titan_standing" "イージスLTS"
- "PL_aegis_last_titan_standing_abbr" "ALTS"
- "PL_aegis_last_titan_standing_desc" "イージスアップグレードが有効。ラウンド単位で勝ち残りを狙う。先に3ラウンド勝利したチームが勝者となる。\n^FFC83200プレイヤー数:5対5 *タイタンでスタート\n時間制限:1ラウンド3分 *リスポーンなし\n最大パーティー人数:5"
- "PL_aegis_last_titan_standing_lobby" "PL_aegis_last_titan_standing_lobby"
- "PL_aegis_titan_brawl" "イージスタイタンブロール"
- "PL_aegis_titan_brawl_abbr" "ATB"
- "PL_aegis_titan_brawl_desc" "敵のタイタンを倒せ。イージスアップグレードが有効。\n^FFC83200プレイヤー数:5対5\n時間制限:10分\n最大パーティー人数:5"
- "PL_aegis_titan_brawl_hint" "敵のタイタンを倒せ。\n脱出なし"
- "PL_aegis_titan_brawl_lobby" "イージスタイタンブロールのロビー"
- "PL_aitdm" "消耗戦"
- "PL_aitdm_abbr" "ATT"
- "PL_aitdm_desc" "敵をすべて片付けろ。\n^FFC83200プレイヤー数:6対6 *AI\n時間制限:10分\n最大パーティー人数:6"
- "PL_aitdm_lobby" "消耗戦ロビー"
- "PL_all_grapple" "アタック・オン・タイタンフォール"
- "PL_all_grapple_abbr" "ATT"
- "PL_all_grapple_desc" "戦術アビリティがすべてグラップルに置き換わる以外は、従来の消耗戦と同じルール。\n^FFC83200プレイヤー数:6対6 *AI\n時間制限:10分\n最大パーティー人数:6"
- "PL_all_grapple_lobby" "アタック・オン・タイタンフォールのロビー"
- "PL_all_holopilot" "華麗なる謀略"
- "PL_all_holopilot_abbr" "LF"
- "PL_all_holopilot_desc" "戦術アビリティがすべてホロパイロットに置き換わる以外は、従来のライブファイアと同じルール。^FFC83200\nプレイヤー数:6対6 *タイタンなし\n時間制限:60秒 *リスポーンなし\n最大パーティー人数:6"
- "PL_all_holopilot_lobby" "華麗なる謀略のロビー"
- "PL_all_phase" "異次元"
- "PL_all_phase_abbr" "ATT"
- "PL_all_phase_desc" "戦術アビリティがすべてフェーズに置き換わる以外は、従来の消耗戦と同じルール。\n^FFC83200プレイヤー数:6対6 *AI\n時間制限:10分\n最大パーティー人数:6"
- "PL_all_phase_lobby" "異次元のロビー"
- "PL_all_spicy" "辛口消耗戦"
- "PL_all_spicy_abbr" "ATT"
- "PL_all_spicy_desc" "戦術アビリティがすべてティックに置き換わる以外は、従来の消耗戦と同じルール。\n^FFC83200プレイヤー数:6対6 *AI\n時間制限:10分\n最大パーティー人数:6"
- "PL_all_spicy_lobby" "辛口消耗戦のロビー"
- "PL_amped_tacticals" "戦術強化"
- "PL_amped_tacticals_abbr" "ATT"
- "PL_amped_tacticals_desc" "戦術アビリティが強化される以外は、従来の消耗戦と同じルール。\n^FFC83200プレイヤー数:6対6 *AI\n時間制限:10分\n最大パーティー人数:6"
- "PL_amped_tacticals_lobby" "戦術強化のロビー"
- "PL_ANGEL_CITY" "エンジェルシティ24/7"
- "PL_angel_city_abbr" "AC"
- "PL_angel_city_desc" "エンジェルシティ\n^FFC83200*賞金稼ぎ *消耗戦\n*拠点増幅"
- "PL_angel_city_lobby" "エンジェルシティ24/7ロビー"
- "PL_at_coop" "脱出(協力プレイ)"
- "PL_at_coop_desc" "ピストルだけを手に監獄を脱出した。脱出艇が到着するまで生き残れ。敵を倒して金を稼ぎ、武器を購入しよう。\n^FFC83200プレイヤー数:6\n最大パーティー人数:6"
- "PL_at_coop_lobby" "脱出ロビー"
- "PL_attrition" "賞金稼ぎ"
- "PL_attrition_abbr" "BH"
- "PL_attrition_desc" "敵を倒して金を稼げ。稼いだボーナスを特定の地点で「アップロード」すればさらに獲得額が上昇。\n^FFC83200プレイヤー数:5対5 *AI\n時間制限:10分\n最大パーティー人数:5"
- "PL_attrition_lobby" "賞金稼ぎロビー"
- "PL_capture_the_flag" "キャプチャー・ザ・フラッグ"
- "PL_capture_the_flag_abbr" "CTF"
- "PL_capture_the_flag_desc" "敵のフラッグを奪って基地へ持ち帰れ。その間も敵チームにこちらのフラッグを奪わせるな!\n^FFC83200プレイヤー数:5対5\n時間制限:12分\n最大パーティー人数:5"
- "PL_capture_the_flag_lobby" "CTFロビー"
- "PL_coliseum" "コロシアム"
- "PL_coliseum_desc" "機動力を強化して、檻の中で1対1で戦う。敵を倒すとラウンド勝利となる。3本先取で支持者のギフトを獲得。^FFC83200\nプレイヤー数:1対1 *タイタンなし\n時間制限:3分 *リスポーンなし\n**^FFFFFF00コロシアムチケットまたは入場料の支払いが必要"
- "PL_coliseum_lobby" "コロシアムロビー"
- "PL_colony" "植民地24/7"
- "PL_colony_abbr" "植民地"
- "PL_colony_desc" "いつでも植民地だけを。^CCCCCC00このリストでは、^FFC83200消耗戦^CCCCCC00、^FFC83200パイロット対パイロット^CCCCCC00と^FFC83200ラスト・タイタン・スタンディング^CCCCCC00のマッチを検索します。"
- "PL_colony_lobby" "植民地24/7ロビー"
- "PL_ctf_lf" "CTF(ニトロ)"
- "PL_ctf_lf_abbr" "CTF-N"
- "PL_ctf_lf_desc" "選択したマップで繰り広げる高速のキャプチャー・ザ・フラッグ。\n^FFC83200プレイヤー数:5対5\n最大パーティー人数:5\n^F4D5A600フラッグを即時返還"
- "PL_ctf_lf_lobby" "CTFニトロのロビー"
- "PL_default_description" "デフォルトの説明"
- "PL_default_lobbytitle" "デフォルトのロビータイトル"
- "PL_default_name" "デフォルトの名前"
- "PL_don" "ダブル・オア・ナッシング"
- "PL_fd" "フロンティアディフェンス"
- "PL_fd_desc" "残留艦隊の波状攻撃を防ぎきれ"
- "PL_fd_easy" "フロンティアディフェンス:イージー"
- "PL_fd_easy_desc" "敵軍を打ち砕け"
- "PL_fd_easy_lobby" "フロンティアディフェンス:イージー用ロビー"
- "PL_fd_hard" "フロンティアディフェンス:ハード"
- "PL_fd_hard_desc" "巧みなプレイが必要"
- "PL_fd_hard_lobby" "フロンティアディフェンス:ハード用ロビー"
- "PL_fd_insane" "フロンティアディフェンス:マックス"
- "PL_fd_insane_desc" "生き残りは不可能"
- "PL_fd_insane_lobby" "フロンティアディフェンス:マックスのロビー"
- "PL_fd_lobby" "フロンティアディフェンスのロビー"
- "PL_fd_master" "フロンティアディフェンス:マスター"
- "PL_fd_master_desc" "真の実力者だけが成功をつかむ"
- "PL_fd_master_lobby" "フロンティアディフェンス:マスターのロビー"
- "PL_fd_normal" "フロンティアディフェンス:レギュラー"
- "PL_fd_normal_desc" "熟練プレイヤー向け"
- "PL_fd_normal_lobby" "フロンティアディフェンス:レギュラーのロビー"
- "PL_ffa" "フリー・フォー・オール"
- "PL_ffa_abbr" "FFA"
- "PL_ffa_desc" "全パイロットが自分のために戦う。敵をすべて始末しろ。\n^FFC83200プレイヤー数:1対11\n時間制限:10分\n最大パーティー人数:1"
- "PL_ffa_lobby" "フリー・フォー・オールロビー"
- "PL_fra" "フリー・エージェント"
- "PL_fra_abbr" "FRA"
- "PL_fra_desc" "1人きりの戦いに挑戦。敵を倒せば勝利だ。バッテリーを3個回収し、タイタンフォールを要請せよ。\n^FFC83200プレイヤー数:1対11\n時間制限:15分\n最大パーティー人数:1"
- "PL_fra_lobby" "フリー・エージェントロビー"
- "PL_groud_war_lobby" "8v8ミックステープロビー"
- "PL_ground_war" "8v8ミックステープ"
- "PL_ground_war_abbr" "8v8"
- "PL_ground_war_desc" "スカーミッシュと拠点増幅を全マップにおいて大人数でプレイできます。\n^FFC83200プレイヤー数:8対8"
- "PL_hardpoint" "拠点増幅"
- "PL_hardpoint_abbr" "AHP"
- "PL_hardpoint_desc" "拠点を制圧して守り切ればポイントを獲得。増幅した拠点は獲得ポイントが2倍になる。\n^FFC83200プレイヤー数:6対6\n時間制限:10分\n最大パーティー人数:6"
- "PL_hardpoint_lobby" "拠点増幅ロビー"
- "PL_hunted" "逃亡者"
- "PL_iron_last_titan_standing" "アイアンLTS"
- "PL_iron_last_titan_standing_abbr" "ILTS"
- "PL_iron_last_titan_standing_desc" "タイタンのみ、ラウンド制の勝ち抜き戦。3ラウンド先取で勝利。\n^FFC83200プレイヤー数:5対5 *パイロットなし\n時間制限:1ラウンド3分 *リスポーンなし\n最大パーティー人数:5"
- "PL_iron_last_titan_standing_lobby" "PL_iron_last_titan_standing_lobby"
- "PL_last_titan_standing" "ラスト・タイタン・スタンディング"
- "PL_last_titan_standing_abbr" "LTS"
- "PL_last_titan_standing_desc" "全員がタイタンに乗った状態で開始し、ラウンド単位で勝ち残りを狙う。先に3ラウンド勝利したチームが勝者となる。\n^FFC83200プレイヤー数:5対5 *タイタンでスタート\n時間制限:1ラウンド3分 *リスポーンなし\n最大パーティー人数:5"
- "PL_last_titan_standing_lobby" "LTSロビー"
- "PL_limited_time_mode" "期間限定モード"
- "PL_live_fire" "ライブファイア"
- "PL_live_fire_abbr" "LF"
- "PL_live_fire_desc" "高速の戦闘がライブファイア・アリーナで展開。敵パイロットを全滅させるか、タイムオーバー時にフラッグを所持しているとラウンド勝利。^FFC83200\nプレイヤー数:6対6 *タイタンなし\n時間制限:60秒 *リスポーンなし\n最大パーティー人数:6"
- "PL_live_fire_lobby" "ライブファイアロビー"
- "PL_load_a_map_on_the_command_line" "コマンド行でマップをロード -devonly"
- "PL_marked_for_death" "マーク・フォー・デス"
- "PL_marked_for_death_abbr" "MFD"
- "PL_marked_for_death_desc" "マークされた標的の命をめぐる攻防戦。\n^FFC83200プレイヤー数:6対6 \n時間制限:12分\n最大パーティー人数:6"
- "PL_marked_for_death_lobby" "マーク・フォー・デス・ロビー"
- "PL_nitro_ffa" "FFA(ニトロ)"
- "PL_nitro_ffa_abbr" "FFA-N"
- "PL_nitro_ffa_desc" "選択したマップで繰り広げる高速のフリー・フォー・オール。\n^FFC83200プレイヤー数:6\n^F4D5A600タイタンなし\nブーストなし"
- "PL_nitro_ffa_lobby" "FFAニトロのロビー"
- "PL_nitro_mixtape" "ミックステープ(ニトロ)"
- "PL_nitro_mixtape_abbr" "MXT-N"
- "PL_nitro_mixtape_desc" "選択したマップで繰り広げる高速のCTF、MFDおよびPvP。\n^FFC83200プレイヤー数:5対5\n最大パーティー人数:5\n^F4D5A600フラッグを即時返還"
- "PL_nitro_mixtape_lobby" "ミックステープロビー"
- "PL_pilot_hunter" "スカーミッシュ"
- "PL_pilot_hunter_abbr" "SKM"
- "PL_pilot_hunter_desc" "敵のパイロットやタイタンを倒せ。\n^FFC83200プレイヤー数:8対8\n時間制限:10分\n最大パーティー人数:8"
- "PL_pilot_hunter_lobby" "スカーミッシュのロビー"
- "PL_pilot_skirmish" "パイロット対パイロット"
- "PL_pilot_skirmish_abbr" "PvP"
- "PL_pilot_skirmish_desc" "敵パイロットを撃破せよ。タイタンフォール禁止。\n^FFC83200プレイヤー数:8対8 *タイタンなし\n時間制限:10分\n最大パーティー人数:8"
- "PL_pilot_skirmish_lobby" "PvPロビー"
- "PL_pl_rebuild_all_paths" "進路再建"
- "PL_pl_run_with_ai_ainrebuildonmapstart_2" "ai_ainRebuildOnMapStart 2 で実行"
- "PL_private_match" "プライベートマッチ(ベータ)"
- "PL_private_match_desc" "好きなマップとモードを選んで、カスタマイズしたプライベートマッチをプレイしよう。\n^FFC83200ネットワークかフレンドを招待してプレイ。\n^FFC83200プレイヤー数:1~16人\n進行なし"
- "PL_private_match_lobby" "プライベートマッチ・ベータロビー"
- "PL_promo_coop" "4人協力プレイ"
- "PL_raid" "レイド"
- "PL_rise" "ライズ24/7"
- "PL_rise_abbr" "RIS"
- "PL_rise_desc" "いつでもライズだけを。^CCCCCC00このリストでは^FFC83200CTF^CCCCCC00、^FFC83200拠点増幅^CCCCCC00、^FFC83200パイロット対パイロット^CCCCCC00、^FFC83200ライブファイア^CCCCCC00と^FFC83200ラスト・タイタン・スタンディング^CCCCCC00のマッチを検索します。"
- "PL_rise_lobby" "ライズ24/7のロビー"
- "PL_rocket_arena" "ロケットアリーナ"
- "PL_rocket_arena_abbr" "LF"
- "PL_rocket_arena_desc" "従来のライブファイアと同じルールで、改造したEPGを使用する。^FFC83200\nプレイヤー数:6対6 *タイタンなし\n時間制限:90秒 *リスポーンなし\n最大パーティー人数:6"
- "PL_rocket_arena_lobby" "ロケットアリーナのロビー"
- "PL_settings_for_when_someone_loads_a_map_on_the_command_line_do_not_edit_the_cmdlinemapload_1_below_-_this_makes_this_work" "コマンド行でマップをロードする際の設定。以下のcmdlineMapLoad 1は実行に必要なので編集しないでください。"
- "PL_speedball" "ライブファイア"
- "PL_speedball_desc" "中立のフラッグを奪い合う。敵チームを排除するか、制限時間終了時に自チームがフラッグを所有していればラウンドに勝利。5ラウンド先取制。\n^FFC83200プレイヤー数:6対6 *タイタンなし\n時間制限:1ラウンドにつき60秒 *リスポーンなし\n最大パーティー人数:6"
- "PL_speedball_lobby" "ライブファイアロビー"
- "PL_tactikill" "戦術キル消耗戦"
- "PL_tactikill_abbr" "ATT"
- "PL_tactikill_desc" "キル時に戦術アビリティが完全にリセットされる以外は、従来の消耗戦と同じルール。\n^FFC83200プレイヤー数:6対6 *AI\n時間制限:10分\n最大パーティー人数:6"
- "PL_tactikill_lobby" "戦術キル消耗戦のロビー"
- "PL_titan_brawl" "タイタンブロール"
- "PL_titan_brawl_abbr" "TB"
- "PL_titan_brawl_desc" "敵のタイタンを倒せ。パイロットは参戦禁止。\n^FFC83200プレイヤー数:5対5\n時間制限:10分\n最大パーティー人数:5"
- "PL_titan_brawl_hint" "敵のタイタンを倒せ。\n降機なし。"
- "PL_titan_brawl_lobby" "タイタンブロールのロビー"
- "PL_titan_brawl_turbo" "ターボタイタンブロール"
- "PL_titan_brawl_turbo_abbr" "TTDM"
- "PL_titan_brawl_turbo_desc" "ダッシュとコアの回復が早まった状態で、従来のタイタンブロールのルールで戦う。\n^FFC83200プレイヤー数:5対5\n時間制限:10分\n最大パーティー人数:5"
- "PL_titan_brawl_turbo_hint" "敵のタイタンを倒せ。\n脱出なし"
- "PL_titan_brawl_turbo_lobby" "ターボタイタンブロールのロビー"
- "PL_turbo_last_titan_standing" "ターボLTS"
- "PL_turbo_last_titan_standing_abbr" "LTS"
- "PL_turbo_last_titan_standing_desc" "ダッシュとコアの回復が早まった状態で、従来のLTSのルールで戦う。\n^FFC83200プレイヤー数:5対5 *タイタンでスタート\n時間制限:1ラウンド3分 *リスポーン\n最大パーティー人数:5"
- "PL_turbo_last_titan_standing_lobby" "ターボLTSのロビー"
- "PL_variety_pack" "ミックステープ"
- "PL_variety_pack_desc" "様々なプレイヤー数やマップで、次のモードをプレイできます。\n^FFC83200*賞金稼ぎ *消耗戦\n*ラスト・タイタン・スタンディング *拠点増幅\n*パイロット対パイロット *キャプチャー・ザ・フラッグ"
- "PL_variety_pack_lobby" "ミックステープロビー"
- "PL_wargames" "ウォーゲーム24/7"
- "PL_wargames_abbr" "WGM"
- "PL_wargames_desc" "いつでもウォーゲームだけを。^CCCCCC00このリストでは^FFC83200消耗戦^CCCCCC00、^FFC83200CTF^CCCCCC00、^FFC83200パイロット対パイロット^CCCCCC00、^FFC83200拠点増幅^CCCCCC00と^FFC83200ラスト・タイタン・スタンディング^CCCCCC00のマッチを検索します。"
- "PL_wargames_lobby" "ウォーゲーム24/7のロビー"
- "WATCH_TUTORIAL" "チュートリアルを見る"
- }
- }
- "lang"
- {
- "Language" "russian"
- "Tokens"
- {
- "COMMUNITYUPDATE_00_A" "Продолжите свое приключение на чарующем Фронтире в новом DLC для Titanfall 2 — «Открытки с Фронтира». В нем вас ждут новые и знакомые локации, а также свежая коллекция элитных раскрасок оружия — таким Фронтир вы еще не видели!\n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_00_Q" "Трейлер «Открыток с Фронтира»"
- "COMMUNITYUPDATE_01_A" "Узнайте, что ждет вас в обновлении «Открытки с Фронтира». \n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_01_Q" "Открытки с Фронтира: изменения"
- "COMMUNITYUPDATE_02_A" "Titanfall: Assault — это стратегия в реальном времени во вселенной Titanfall, которую мы разрабатываем для мобильных устройств совместно со студией Particle City. Посмотреть на ее игровой процесс можно здесь! \n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_02_Q" "Трейлер к выходу Titanfall: Assault"
- "COMMUNITYUPDATE_03_A" "На канале Iniquity Games разобрано обучение и даются советы по игре Titanfall Assault. Это самый лучший способ ознакомиться с игрой.\n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_03_Q" "Titanfall: Assault: видео «Основы игры»"
- "COMMUNITYUPDATE_04_A" "Узнайте историю разработки режима «Оборона Фронтира» от нескольких ведущих разработчков и посмотрите, как мы играем в него!\n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_04_Q" "Respawn играет в «Оборону Фронтира»"
- "COMMUNITYUPDATE_05_A" "Kevin Younger создал забавный ролик, в котором демонстрирует различные приемчики с пульсирующим клинком.\n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_05_Q" "Творчество сообщества: На острие"
- "COMMUNITYUPDATE_06_A" "ConzeyG с reddit демонстрирует жестокую эффективность «Нордстара», одного за другим уничтожая пилотов в режиме «Приговор — смерть».\n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_06_Q" "Сообщество: Охота на пилотов «Нордстара»"
- "COMMUNITYUPDATE_07_A" "Уже в игре! «Оборона Фронтира» возвращается вместе с картой «Восход», для покупки доступны новые боевые раскраски, а также появилась новая карта для режима «Перестрелка». Ознакомьтесь с нововведениями здесь. \n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_07_Q" "Трейлер \"Операция «Щит Фронтира»\""
- "COMMUNITYUPDATE_08_A" "Уже в игре! Знаменитая карта «Военные игры» возвращается — и такой вы ее еще не видели! А еще не пропустите новую казнь и карту для «Перестрелки» — «Траффик».\n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_08_Q" "Трейлер «Военные игры»"
- "COMMUNITYUPDATE_09_A" "Это DLC добавляет «Монарха» (седьмого Титана для сетевой игры), переделанную карту «Святыня», новую казнь, а также «Ронина Прайм», «Тона Прайм», камуфляжи, фоны и рисунки на корпус в магазин. Ознакомиться с игровым процессом можно здесь.\n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_09_Q" "Трейлер «Власть монарха»"
- "COMMUNITYUPDATE_10_A" "Новое в бесплатном DLC «Разлом на Фронтире»: nкарта для режима «Перестрелка»: «Палуба», nфракция: «Марвины», nказнь для пилота: «Пульсирующий клинок».\n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_10_Q" "Трейлер «Разлом на Фронтире»"
- "COMMUNITYUPDATE_11_A" "Ставшая культовой карта для сетевого режима оригинального Titanfall «Колония» теперь доступна и в сиквеле! Пилоты Titanfall 2 могут опробовать свои силы в боях на тихих узких улочках, крышах и закрытых двориках небольшой деревеньки. Переосмыслить старые тактики с новыми Титанами и оружием игроки смогут уже с 30 марта — и совершенно бесплатно! В наборе DLC «Новая колония» вы найдете и новые версии классического оружия (например, винтовку R-101), новую казнь с помощью крюка и улучшения внешнего вида — устраивать резню на улицах города нужно по последней моде!\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_11_Q" "Трейлер «Новая колония»"
- "COMMUNITYUPDATE_12_A" "«Перестрелка» — новый адреналиновый режим, в котором две команды из шести пилотов сражаются до последней капли крови. Для этого режима мы специально создали две новые бесплатные карты: «Луг» и «Склад». Это компактные закрытые арены, идеально подходящие для напряженных боев на близких дистанциях.\n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_12_Q" "Трейлер «Перестрелка»"
- "COMMUNITYUPDATE_13_A" "Всеми любимая карта `1Город Ангелов`0 из первой части Titanfall снова в строю. Первое бесплатное DLC для Titanfall 2 под названием `1Особо опасные в Городе Ангелов`0 доступно для всех игроков с 1 декабря. В обновлении также есть улучшения внешнего вида, которые немного изменят Фронтир. \n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_13_Q" "Трейлер «Город Ангелов»"
- "COMMUNITYUPDATE_14_A" "С возвращением!\n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_14_Q" "Трейлер «На бис»"
- "COMMUNITYUPDATE_15_A" "Две легенды. Одно наследие.\n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_15_Q" "Трейлер одиночной игры «Единое целое»"
- "COMMUNITYUPDATE_16_A" "Никаких ограничений.\n\n\nДля просмотра нажмите `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_16_Q" "Трейлер сетевой игры «Пилоты»"
- "COMMUNITYUPDATE_DESC" "`3Новости сообщества Titanfall`0\n\nНовости и ссылки со всего Интернета.\n\nХотите еще?\n`2%$rui/bullet_point%`0Подпишитесь на нас в Twitter: `1@Respawn`0\n`2%$rui/bullet_point%`0Поставьте «Нравится» на `1facebook.com/RespawnEntertainment`0\n`2%$rui/bullet_point%`0Заходите на `1www.respawn.com`0."
- "COMMUNITYUPDATE_NAME" "Сообщество"
- "KNB_SUBJECT_00_DESC" "`3Что нового в Titanfall?`0\n\nНовости обновлений Titanfall 2!"
- "KNB_SUBJECT_00_NAME" "Обновления игры"
- "KNB_SUBJECT_00_SUB_00_A" "`2%$rui/bullet_point%`010 Новые фоны эмблем от сообщества\n\n`2%$rui/bullet_point%`0Все подарки сторонника теперь доступны за кредиты\n\n`2%$rui/bullet_point%`0Новый платный контент в магазине\n\n"
- "KNB_SUBJECT_00_SUB_00_Q" "%$rui/hud/scoreboard/status_titan% 28 ноября — время жатвы"
- "KNB_SUBJECT_00_SUB_01_A" "`2%$rui/bullet_point%`0Главная ячейка для пистолета\n\n`2%$rui/bullet_point%`0Фоны на Хэллоуин\n\n`2%$rui/bullet_point%`0Изменения баланса\n\n`2%$rui/bullet_point%`0Новый доступный для покупки контент в магазине\n\n"
- "KNB_SUBJECT_00_SUB_01_Q" "%$rui/hud/scoreboard/status_titan% 31 октября: «Сласти и страсти»"
- "KNB_SUBJECT_00_SUB_02_A" "`2%$rui/bullet_point%`0«Оборона Фронтира» — добавлена поддержка 3 карт: Док, Город Ангелов и Экзопланета.\n\n`2%$rui/bullet_point%`0Новая карта для «Перестрелки» — UMA\n\n`2%$rui/bullet_point%`0Новая казнь пилота — Дырявая стена\n\n`2%$rui/bullet_point%`0Новый доступный для покупки контент в магазине"
- "KNB_SUBJECT_00_SUB_02_Q" "%$rui/hud/scoreboard/status_titan% 29 августа — Открытки с Фронтира"
- "KNB_SUBJECT_00_SUB_03_A" "`2%$rui/bullet_point%`0Оборона Фронтира — новый совместный режим, в котором вам придется вместе с другими игроками защищать важную цель от усиливающихся волн противников под управлением ИИ. Без общения и умения адаптироваться тут не победить.\n\n`2%$rui/bullet_point%`0Новая карта: «Восход»\n\n`2%$rui/bullet_point%`0Новая карта для «Перестрелки»: «Поселок»\n\n`2%$rui/bullet_point%`0Новый доступный для покупки контент в магазине"
- "KNB_SUBJECT_00_SUB_03_Q" "%$rui/hud/scoreboard/status_titan% 25 июля: операция «Щит Фронтира»"
- "KNB_SUBJECT_00_SUB_04_A" "`2%$rui/bullet_point%`0Новая карта — «Военные игры»\n\n`2%$rui/bullet_point%`0Новая карта для режима «Перестрелка» — «Траффик»\n\n`2%$rui/bullet_point%`0Новая казнь пилота — «Бой с тенью»\n\n`2%$rui/bullet_point%`03 ячейка для оружия\n\n`2%$rui/bullet_point%`0Настройки частных матчей"
- "KNB_SUBJECT_00_SUB_04_Q" "%$rui/hud/scoreboard/status_titan% 27 июня: «Военные игры»"
- "KNB_SUBJECT_00_SUB_05_A" "`2%$rui/bullet_point%`0Новый Титан: «Монарх»\n\n`2%$rui/bullet_point%`0Новая карта: «Святыня»\n\n`2%$rui/bullet_point%`0Новая казнь пилота: «Иллюзия обмана»\n\n`2%$rui/bullet_point%`0Новый контент в магазине"
- "KNB_SUBJECT_00_SUB_05_Q" "%$rui/hud/scoreboard/status_titan% 30 мая: Власть монарха"
- "KNB_SUBJECT_00_SUB_06_A" "`2%$rui/bullet_point%`0Новая карта: «Разлом»\n\n`2%$rui/bullet_point%`0Новая карта для «Перестрелки»: «Палуба»\n\n`2%$rui/bullet_point%`0Новая фракция: МРВН\n\n`2%$rui/bullet_point%`0Новая казнь пилота: «На острие»\n\n`2%$rui/bullet_point%`0Увеличение макс. поколения до 100"
- "KNB_SUBJECT_00_SUB_06_Q" "%$rui/hud/scoreboard/status_titan% 25 апреля: Разлом на Фронтире"
- "KNB_SUBJECT_00_SUB_07_A" "`2%$rui/bullet_point%`0Новая карта: «Колония»\n\n`2%$rui/bullet_point%`0Новая казнь пилота: «Череподав»\n\n`2%$rui/bullet_point%`0Новое оружие: R-101\n\n`2%$rui/bullet_point%`0Новый контент в магазине"
- "KNB_SUBJECT_00_SUB_07_Q" "%$rui/hud/scoreboard/status_titan% 30 марта: Новая колония"
- "KNB_SUBJECT_00_SUB_08_A" "`2%$rui/bullet_point%`0«Перестрелка» — новый режим на выбывание для пилотов! Вас ждут битвы 6 на 6 без возможности возрождения. Выигрывает та команда, которая уничтожит соперника за одну минуту или будет удерживать нейтральный флаг по окончании отсчета. Первая команда, выигравшая в пяти раундах, побеждает.\n\n`2%$rui/bullet_point%`0Новые карты для «Перестрелки»: «Луг» и «Склад»\n\n`2%$rui/bullet_point%`0Новая казнь пилота: «Поздний удар»"
- "KNB_SUBJECT_00_SUB_08_Q" "%$rui/hud/scoreboard/status_titan% 23 февраля: Перестрелка"
- "KNB_SUBJECT_00_SUB_09_A" "`2%$rui/bullet_point%`0Новая карта: «Город Ангелов»\n\n`2%$rui/bullet_point%`0Новое оружие: «Элитный ведомый B3»\n\n`2%$rui/bullet_point%`0Новая казнь пилота: «Внутренности»\n\n`2%$rui/bullet_point%`0Новые наборы для Титанов\n\n`2%$rui/bullet_point%`0Новый контент в магазине"
- "KNB_SUBJECT_00_SUB_09_Q" "%$rui/hud/scoreboard/status_titan% 30 ноября: Особо опасные в Городе Ангелов"
- "MP_ANGEL_CITY_FD_WAVE_1" "Пленники небес"
- "MP_ANGEL_CITY_FD_WAVE_2" "Бесформенность"
- "MP_ANGEL_CITY_FD_WAVE_3" "Мятеж"
- "MP_ANGEL_CITY_FD_WAVE_4" "Неумолимый жребий"
- "MP_ANGEL_CITY_FD_WAVE_5" "Пойти ва-банк"
- "MP_DRYDOCK_FD_WAVE_1" "Неизведанные воды"
- "MP_DRYDOCK_FD_WAVE_2" "У них кончились патроны!"
- "MP_DRYDOCK_FD_WAVE_3" "Ослепленные наукой"
- "MP_DRYDOCK_FD_WAVE_4" "Система высокого давления"
- "MP_DRYDOCK_FD_WAVE_5" "Око бури"
- "MP_THAW_FD_WAVE_1" "Действия по ситуации"
- "MP_THAW_FD_WAVE_2" "Сила в количестве"
- "MP_THAW_FD_WAVE_3" "Приспешник-21"
- "MP_THAW_FD_WAVE_4" "Игры с огнем"
- "MP_THAW_FD_WAVE_5" "Одним великанам под силу"
- "NO_PRICE" "Истекло"
- "NO_PRICE_TWO_LINES" "Истекло"
- "PL_aegis_last_titan_standing" "ПиТ «Эгида»"
- "PL_aegis_last_titan_standing_abbr" "ПиТЭ"
- "PL_aegis_last_titan_standing_desc" "Доступны улучшения Эгиды. Многораундовая игра до последнего выжившего. Побеждает команда, которая первой выиграет 3 раунда.\n^FFC83200Игроки: 5 на 5 *Сразу есть Титан\nЛимит времени: 3 минуты на раунд *Без возрождений\nРазмер команды: 5"
- "PL_aegis_last_titan_standing_lobby" "PL_aegis_last_titan_standing_lobby"
- "PL_aegis_titan_brawl" "Битва Титанов «Эгида»"
- "PL_aegis_titan_brawl_abbr" "ДТЭ"
- "PL_aegis_titan_brawl_desc" "Убивайте вражеских Титанов. Доступны улучшения Эгиды.\n^FFC83200Игроки: 5 на 5\nЛимит времени: 10 минут\nРазмер команды: 5"
- "PL_aegis_titan_brawl_hint" "Убивайте вражеских Титанов.\nКатапультирование запрещено"
- "PL_aegis_titan_brawl_lobby" "Лобби: Битва Титанов «Эгида»"
- "PL_aitdm" "Истребление"
- "PL_aitdm_abbr" "ИСТ"
- "PL_aitdm_desc" "Убить всех врагов.\n^FFC83200Игроки: 6 на 6 *ИИ\nВремя: 10 мин\nРазмер команды: 6"
- "PL_aitdm_lobby" "Лобби: Истребление"
- "PL_all_grapple" "Атака на Titanfall"
- "PL_all_grapple_abbr" "ИСТ"
- "PL_all_grapple_desc" "Классическое «Истребление», где все тактические умения заменены на крюк-кошку.\n^FFC83200Игроки: 6 на 6 * ИИ\nВремя: 10 мин\nРазмер команды: 6"
- "PL_all_grapple_lobby" "Лобби «Атака на Titanfall»"
- "PL_all_holopilot" "Великая разводка"
- "PL_all_holopilot_abbr" "ПС"
- "PL_all_holopilot_desc" "Классическая «Перестрелка», где все тактические умения заменены голопилотом.^FFC83200\nИгроки: 6 на 6 * Без Титанов\nВремя: 60 с * Без возрождений\nРазмер команды: 6"
- "PL_all_holopilot_lobby" "Лобби «Великая разводка»"
- "PL_all_phase" "Иная сторона"
- "PL_all_phase_abbr" "ИСТ"
- "PL_all_phase_desc" "Классическое «Истребление», где все тактические умения заменены на фазовый сдвиг.\n^FFC83200Игроки: 6 на 6 * ИИ\nВремя: 10 мин\nРазмер команды: 6"
- "PL_all_phase_lobby" "Лобби: Иная сторона"
- "PL_all_spicy" "Острое истребление"
- "PL_all_spicy_abbr" "ИСТ"
- "PL_all_spicy_desc" "Классическое «Истребление», где все тактические умения заменены на клещи.\n^FFC83200Игроки: 6 на 6 * ИИ\nВремя: 10 мин\nРазмер команды: 6"
- "PL_all_spicy_lobby" "Лобби: Острое истребление"
- "PL_amped_tacticals" "Усиленная тактика"
- "PL_amped_tacticals_abbr" "ИСТ"
- "PL_amped_tacticals_desc" "Классическое «Истребление», где все тактические умения значительно усилены.\n^FFC83200Игроки: 6 на 6 * ИИ\nВремя: 10 мин\nРазмер команды: 6"
- "PL_amped_tacticals_lobby" "Лобби «Усиленная тактика»"
- "PL_ANGEL_CITY" "Город Ангелов 24/7"
- "PL_angel_city_abbr" "ГА"
- "PL_angel_city_desc" "Город Ангелов в трех режимах.\n^FFC83200*Охота за наживой *Истребление\n*Усиленные опорные пункты"
- "PL_angel_city_lobby" "Лобби: Город Ангелов 24/7"
- "PL_at_coop" "Побег (совместно)"
- "PL_at_coop_desc" "Вы сбежали из тюрьмы с одним лишь пистолетом. Продержитесь до прибытия спасательного транспорта. Убивайте врагов, чтобы заработать деньги на оружие. \n^FFC83200Игроки: 6\nРазмер команды: 6"
- "PL_at_coop_lobby" "Лобби: Побег"
- "PL_attrition" "Охота за наживой"
- "PL_attrition_abbr" "ОН"
- "PL_attrition_desc" "Зарабатывайте деньги, убивая врагов. Заработайте больше, сдавая бонус в банк в указанных местах.\n^FFC83200Игроки: 5 на 5 *ИИ\nЛимит времени: 10 мин\nРазмер команды: 5"
- "PL_attrition_lobby" "Лобби: Охота за наживой"
- "PL_capture_the_flag" "Захват флага"
- "PL_capture_the_flag_abbr" "ЗФ"
- "PL_capture_the_flag_desc" "Захватите вражеский флаг и доставьте его на свою базу. Не дайте команде противника захватить ваш флаг!\n^FFC83200Игроки: 5 на 5\nЛимит времени: 12 мин\nРазмер команды: 5"
- "PL_capture_the_flag_lobby" "Лобби: Захват флага"
- "PL_coliseum" "Колизей"
- "PL_coliseum_desc" "Поединок в «клетке» с повышенной мобильностью. Чтобы выиграть раунд, убейте противника. Игрок, выигравший 3 из 5 раундов, получает подарок сторонника.^FFC83200\nИгроки: 1 на 1 *Без Титанов\nЛимит времени: 3 мин *Без возрождения\n**^FFFFFF00Требуется БИЛЕТ или ВНЕСЕНИЕ ПЛАТЫ"
- "PL_coliseum_lobby" "Лобби: Колизей"
- "PL_colony" "«Колония» 24/7"
- "PL_colony_abbr" "КОЛ"
- "PL_colony_desc" "«Колония» круглосуточно. ^CCCCCC00Поиск матчей в режимах ^FFC83200«Истребление»^CCCCCC00, ^FFC83200«Пилоты против пилотов»^CCCCCC00 и ^FFC83200«Последний из Титанов»^CCCCCC00."
- "PL_colony_lobby" "Лобби: «Колония» 24/7"
- "PL_ctf_lf" "ЗФ (Нитро)"
- "PL_ctf_lf_abbr" "ЗФ-Н"
- "PL_ctf_lf_desc" "Быстрая игра в режиме «Захват флага» на картах режима «Перестрелка».\n^FFC83200Игроки: 5 на 5\nРазмер команды: 5\n^F4D5A600Мгновенный возврат флага"
- "PL_ctf_lf_lobby" "Лобби: ЗФ Нитро"
- "PL_default_description" "Описание по умолчанию"
- "PL_default_lobbytitle" "Название лобби по умолчанию"
- "PL_default_name" "Название по умолчанию"
- "PL_don" "Все или ничего"
- "PL_fd" "Оборона Фронтира"
- "PL_fd_desc" "Обороняйтесь от волн наступающих врагов"
- "PL_fd_easy" "Оборона Фронтира: легко"
- "PL_fd_easy_desc" "Сокрушите противника"
- "PL_fd_easy_lobby" "Оборона Фронтира: лобби, легко"
- "PL_fd_hard" "Оборона Фронтира: сложно"
- "PL_fd_hard_desc" "Требуется хорошее умение игры"
- "PL_fd_hard_lobby" "Оборона Фронтира: лобби, тяжело"
- "PL_fd_insane" "Оборона Фронтира: безумие"
- "PL_fd_insane_desc" "Вам не выжить"
- "PL_fd_insane_lobby" "Лобби: Оборона Фронтира - безумие"
- "PL_fd_lobby" "Лобби: Оборона Фронтира"
- "PL_fd_master" "Оборона Фронтира: мастер"
- "PL_fd_master_desc" "Преуспеют только лучшие из лучших"
- "PL_fd_master_lobby" "Лобби: Оборона Фронтира - мастер"
- "PL_fd_normal" "Оборона Фронтира: нормально"
- "PL_fd_normal_desc" "Рекомендуется для опытных игроков"
- "PL_fd_normal_lobby" "Лобби: «Оборона Фронтира», нормально"
- "PL_ffa" "Все против всех"
- "PL_ffa_abbr" "ВПВ"
- "PL_ffa_desc" "Каждый сам за себя. Убейте всех пилотов.\n^FFC83200Игроки: 1 на 11\nЛимит времени: 10 мин\nРазмер команды: 1"
- "PL_ffa_lobby" "Лобби: Все против всех"
- "PL_fra" "Вольные пилоты"
- "PL_fra_abbr" "ВПЛ"
- "PL_fra_desc" "Каждый за себя. Убивайте врагов, чтобы победить. Соберите 3 батареи, чтобы вызвать Титана.\n^FFC83200Игроки: 1 на 11\nЛимит времени: 15 мин\nРазмер команды: 1"
- "PL_fra_lobby" "Лобби: Вольные пилоты"
- "PL_groud_war_lobby" "Смешанный набор 8 на 8: лобби"
- "PL_ground_war" "Смешанный набор 8 на 8"
- "PL_ground_war_abbr" "8 на 8"
- "PL_ground_war_desc" "В составе: «Схватка» и «Усиленные опорные пункты». Большое количество игроков на всех картах.\n^FFC83200Игроки: 8 на 8"
- "PL_hardpoint" "Усиленные опорные пункты"
- "PL_hardpoint_abbr" "УОП"
- "PL_hardpoint_desc" "Захватите и удерживайте опорные пункты, чтобы заработать очки. Усиленные опорные пункты приносят в 2 раза больше очков.\n^FFC83200Игроки: 6 на 6\nЛимит времени: 10 мин\nРазмер команды: 6"
- "PL_hardpoint_lobby" "Лобби: Усиленные опорные пункты"
- "PL_hunted" "Добыча"
- "PL_iron_last_titan_standing" "Железный ПИТ"
- "PL_iron_last_titan_standing_abbr" "ЖЛЗН"
- "PL_iron_last_titan_standing_desc" "Только Титаны, многораундовая игра до последнего выжившего. Побеждает игрок, который первым выиграет в 3 раундах.\n^FFC83200Игроки: 5 на 5 *БЕЗ ПИЛОТОВ\nЛимит времени: 3 мин на раунд *Без возрождений\nРазмер команды: 5"
- "PL_iron_last_titan_standing_lobby" "PL_iron_last_titan_standing_lobby"
- "PL_last_titan_standing" "Последний из Титанов"
- "PL_last_titan_standing_abbr" "ПИТ"
- "PL_last_titan_standing_desc" "В этой многораундовой игре на выбывание у каждого игрока сразу есть Титан. Побеждает команда, которая первой выиграет 3 раунда.\n^FFC83200Игроки: 5 на 5 *Сразу есть Титан\nЛимит времени: 3 минуты на раунд *Без возрождений\nРазмер команды: 5"
- "PL_last_titan_standing_lobby" "Лобби: Последний из Титанов"
- "PL_limited_time_mode" "(временно)"
- "PL_live_fire" "Перестрелка"
- "PL_live_fire_abbr" "ПЕР"
- "PL_live_fire_desc" "Динамичные бои на арене. Для победы необходимо перебить всех вражеских пилотов или удерживать флаг на момент истечения таймера.^FFC83200\nИгроки: 6 на 6 * Без Титанов\nВремя: 60 с * Без возрождений\nРазмер команды: 6"
- "PL_live_fire_lobby" "Лобби: Перестрелка"
- "PL_load_a_map_on_the_command_line" "Загрузка карты из командной строки -devonly"
- "PL_marked_for_death" "Приговор — смерть"
- "PL_marked_for_death_abbr" "П-С"
- "PL_marked_for_death_desc" "Убивайте или защищайте приговоренные цели.\n^FFC83200Игроки: 6 на 6\nВремя: 12 мин\nРазмер команды: 6"
- "PL_marked_for_death_lobby" "Лобби: Приговор — смерть"
- "PL_nitro_ffa" "ВПВ (Нитро)"
- "PL_nitro_ffa_abbr" "ВПВ-Н"
- "PL_nitro_ffa_desc" "Стремительные битвы «Все против всех» на избранных картах.\n^FFC83200Игроки: 6\n^F4D5A600Без Титанов\nБез усилений"
- "PL_nitro_ffa_lobby" "ВПВ (Нитро): лобби"
- "PL_nitro_mixtape" "Смешанный набор (Нитро)"
- "PL_nitro_mixtape_abbr" "СН-Н"
- "PL_nitro_mixtape_desc" "Стремительные битвы ЗФ, П-С и PvP на избранных картах.\n^FFC83200Игроки: 5 на 5\nРазмер команды: 5\n^F4D5A600Мгновенный возврат флага"
- "PL_nitro_mixtape_lobby" "Смешанный набор: лобби"
- "PL_pilot_hunter" "Схватка"
- "PL_pilot_hunter_abbr" "СХВ"
- "PL_pilot_hunter_desc" "Убивайте вражеских пилотов и Титанов. \n^FFC83200Игроки: 8 на 8\nЛимит времени: 10 мин\nРазмер команды: 8"
- "PL_pilot_hunter_lobby" "Лобби (Схватка)"
- "PL_pilot_skirmish" "Пилоты против пилотов"
- "PL_pilot_skirmish_abbr" "ППП"
- "PL_pilot_skirmish_desc" "Убивайте вражеских пилотов. Высадка Титана не разрешена.\n^FFC83200Игроки: 8 на 8 *Без Титанов\nЛимит времени: 10 мин\nРазмер команды: 8"
- "PL_pilot_skirmish_lobby" "Лобби: Пилоты против пилотов"
- "PL_pl_rebuild_all_paths" "Восстановить все пути"
- "PL_pl_run_with_ai_ainrebuildonmapstart_2" "Запуск с ai_ainRebuildOnMapStart 2"
- "PL_private_match" "Частный матч (бета)"
- "PL_private_match_desc" "Проведите частный матч на карте и в режиме по своему выбору.\n^FFC83200ПРИГЛАШАЙТЕ СЕТЬ или ПРИГЛАШАЙТЕ ДРУЗЕЙ на игру\n^FFC83200Игроки: 1-16\nБез прогресса"
- "PL_private_match_lobby" "Лобби частного матча (бета)"
- "PL_promo_coop" "Совместная игра на 4 игроков"
- "PL_raid" "Налет"
- "PL_rise" "«Восход» 24/7"
- "PL_rise_abbr" "ВСХ"
- "PL_rise_desc" "«Восход» 24/7. ^CCCCCC00Начинает поиск матчей в режимах ^FFC83200ЗФ^CCCCCC00, ^FFC83200«Усиленные опорные пункты»^CCCCCC00, ^FFC83200«Пилоты против пилотов»^CCCCCC00, ^FFC83200«Перестрелка»^CCCCCC00 и ^FFC83200«Последний из Титанов»^CCCCCC00."
- "PL_rise_lobby" "Лобби: «Восход» 24/7"
- "PL_rocket_arena" "Ракетная арена"
- "PL_rocket_arena_abbr" "ПС"
- "PL_rocket_arena_desc" "Классическая «Перестрелка» с модифицированными ЭПУ.^FFC83200\nИгроки: 6 на 6 * Без Титанов\nВремя: 90 с * Без возрождений\nРазмер команды: 6"
- "PL_rocket_arena_lobby" "Лобби: Ракетная арена"
- "PL_settings_for_when_someone_loads_a_map_on_the_command_line_do_not_edit_the_cmdlinemapload_1_below_-_this_makes_this_work" "Настройки на случай загрузки карты из командной строки. Не редактируйте cmdlineMapLoad 1 ниже (благодаря этому все и работает)."
- "PL_speedball" "Перестрелка"
- "PL_speedball_desc" "Сражение идет за владение нейтральным флагом. Для победы в раунде необходимо уничтожить всех вражеских игроков или захватить флаг до окончания отсчета. Побеждает команда, первой достигшая пяти побед.\n^FFC83200Игроков: 6 на 6 *Без Титанов\nОграничение по времени: 60 секунд на раунд *Без возрождений\nРазмер команды: 6"
- "PL_speedball_lobby" "Лобби: Перестрелка"
- "PL_tactikill" "Тактическое истребление"
- "PL_tactikill_abbr" "ИСТ"
- "PL_tactikill_desc" "Классическое «Истребление», где убийства полностью восстанавливают тактические способности.\n^FFC83200Игроки: 6 на 6 * ИИ\nВремя: 10 мин\nРазмер команды: 6"
- "PL_tactikill_lobby" "Лобби «Тактическое истребление»"
- "PL_titan_brawl" "Битва Титанов"
- "PL_titan_brawl_abbr" "БТ"
- "PL_titan_brawl_desc" "Убивайте вражеских Титанов. Пилоты в бою не участвуют.\n^FFC83200Игроки: 5 на 5\nЛимит времени: 10 мин\nРазмер команды: 5"
- "PL_titan_brawl_hint" "Убивайте вражеских Титанов.\nКатапультирование запрещено"
- "PL_titan_brawl_lobby" "Лобби: Битва Титанов"
- "PL_titan_brawl_turbo" "Турбодрака Титанов"
- "PL_titan_brawl_turbo_abbr" "КМНБ"
- "PL_titan_brawl_turbo_desc" "Классическая «Драка Титанов» с ускоренными перезарядкой рывка и зарядом ядра.\n^FFC83200Игроки: 5 на 5\nВремя: 10 мин.\nРазмер команды: 5"
- "PL_titan_brawl_turbo_hint" "Убивайте вражеских Титанов.\nКатапультирование запрещено"
- "PL_titan_brawl_turbo_lobby" "Лобби: Турбодрака Титанов"
- "PL_turbo_last_titan_standing" "Турбо-ПИТ"
- "PL_turbo_last_titan_standing_abbr" "ПИТ"
- "PL_turbo_last_titan_standing_desc" "Классический «Последний из Титанов» с ускоренными перезарядкой рывка и зарядом ядра.\n^FFC83200Игроки: 5 на 5 * Сразу есть Титан\nВремя: 3 минуты на раунд * Без возрождений\nРазмер команды: 5"
- "PL_turbo_last_titan_standing_lobby" "Лобби: Турбо-ПИТ"
- "PL_variety_pack" "Смешанный набор"
- "PL_variety_pack_desc" "Разное количество игроков и разнообразные карты. Режимы:\n^FFC83200*Охота за наживой *Истребление\n*Последний из Титанов *Усиленные опорные пункты\n*Пилоты против пилотов *Захват флага"
- "PL_variety_pack_lobby" "Смешанный набор: лобби"
- "PL_wargames" "«Военные игры» 24/7"
- "PL_wargames_abbr" "ВНИ"
- "PL_wargames_desc" "Круглосуточные «Военные игры». ^CCCCCC00Начинает поиск матчей в режимах ^FFC83200«Истребление»^CCCCCC00, ^FFC83200«ЗФ»^CCCCCC00, ^FFC83200«Пилоты против пилотов»^CCCCCC00, ^FFC83200«Усиленные опорные пункты»^CCCCCC00 и ^FFC83200«Последний из Титанов»^CCCCCC00."
- "PL_wargames_lobby" "Лобби: «Военные игры» 24/7"
- "WATCH_TUTORIAL" "СМОТРЕТЬ ОБУЧЕНИЕ"
- }
- }
- "lang"
- {
- "Language" "spanish"
- "Tokens"
- {
- "COMMUNITYUPDATE_00_A" "Tu aventura por los espectaculares paisajes de la Frontera continúa con el nuevo DLC de Titanfall 2: Postales de la Frontera. Con ubicaciones nuevas y familiares, así como una nueva colección de pinturas de guerra de armas de élite, la Frontera ahora es más espectacular que nunca.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para ver."
- "COMMUNITYUPDATE_00_Q" "Tráiler de juego de «Postales de la Frontera»"
- "COMMUNITYUPDATE_01_A" "Descubre todas las novedades del parche Postales de la Frontera.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para ver."
- "COMMUNITYUPDATE_01_Q" "Postales de la Frontera: notas de parche"
- "COMMUNITYUPDATE_02_A" "Disponible muy pronto para dispositivos móviles, Titanfall: Assault es un juego de ETR en el universo de Titanfall creado junto a Particle City. ¡Puedes verlo en acción aquí! \n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para ver."
- "COMMUNITYUPDATE_02_Q" "Tráiler «Lanzamiento» de Titanfall: Assault"
- "COMMUNITYUPDATE_03_A" "Iniquity nos guía por el tutorial y nos da consejos básicos para Titanfall Assault, la forma perfecta de iniciarse en este juego.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para ver."
- "COMMUNITYUPDATE_03_Q" "Titanfall Assault: vídeo «Fundamentos»"
- "COMMUNITYUPDATE_04_A" "¡Escucha a algunos de los desarrolladores claves de Defensa fronteriza hablar de la historia y creación del modo, mientras jugamos unas rondas. \n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para ver."
- "COMMUNITYUPDATE_04_Q" "Respawn Plays: Defensa fronteriza"
- "COMMUNITYUPDATE_05_A" "Kevin Younger ha creado un divertido montaje con muchas jugadas espectaculares con el filo de pulso. \n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para ver."
- "COMMUNITYUPDATE_05_Q" "Creaciones de la comunidad: Incisivo"
- "COMMUNITYUPDATE_06_A" "ConzeyG en reddit demuestra una eficacia brutal con el Northstar eliminando pilotos en Condenado. \n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para ver."
- "COMMUNITYUPDATE_06_Q" "Creaciones de la comunidad: Cazapilotos Northstar"
- "COMMUNITYUPDATE_07_A" "¡Ya disponible! Vuelve Defensa fronteriza junto con Ascenso, y nuevas pinturas a la venta y un nuevo mapa de Munición real. Puedes verlo en acción aquí.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para ver."
- "COMMUNITYUPDATE_07_Q" "Tráiler de juego de «Op. Escudo fronterizo»"
- "COMMUNITYUPDATE_08_A" "¡Ya disponible! El icónico mapa Juegos de guerra vuelve a Titanfall 2, con mejores gráficos que nunca. Echa también un vistazo a la nueva ejecución y al nuevo mapa de Munición real.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para ver."
- "COMMUNITYUPDATE_08_Q" "Tráiler de juego de «Juegos de guerra»"
- "COMMUNITYUPDATE_09_A" "Este DLC marca la llegada del 7.º titán de Multijugador, el Monarch; un mapa remasterizado, Reliquia, y una nueva ejecución, así como artículos adquiribles como los nuevos titanes prime Ronin y Tone, más camuflajes, indicativos y decoraciones. Disfruta de la acción aquí.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para ver."
- "COMMUNITYUPDATE_09_Q" "Tráiler de juego de «Reino del Monarch»"
- "COMMUNITYUPDATE_10_A" "En la Frontera no todo es lo que parece. Prepárate para el nuevo DLC gratuito de Titanfall 2, Un glitch en la Frontera, con el nuevo mapa «Glitch». Inspirado en el planeta natal del capitán Lastimosa, Armonía, aquí encontrarás un paisaje dominado por desniveles verticales y rutas largas y serpenteantes, ideal para encadenar carreras por muros y así cruzar ágilmente el mapa. Y, además, un nuevo mapa de Munición real, «Cubierta», con espacios constreñidos, patios expuestos y drones que acechan patrullando desde arriba. Y si te sientes abrumado(a), los siempre serviciales marvins han llegado como una nueva facción para echarte una mano (robótica). Finalmente, ya se puede desbloquear la nueva ejecución con el filo de pulso, para cuando quieras ponerte «incisivo(a)».\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_10_Q" "Tráiler de juego «Un glitch en la Frontera»"
- "COMMUNITYUPDATE_11_A" "Vuelve uno de los mapas multijugador favoritos del Titanfall original: el icónico Colonia. Añádele a esto las nuevas tácticas y titanes de Titanfall 2, y los pilotos y titanes tendrán que exprimir todas sus habilidades para sobrevivir en este asentamiento idílico y denso lleno de callejones, esquinas traicioneras y tejados expuestos. Disponible el 30 de marzo para todos los jugadores. El pack de DLC «Colony Reborn» incluye el retorno de armas clásicas como el rifle de asalto decorado R-101, una nueva ejecución con el garfio y nuevas opciones cosméticas a la venta para destacar en combate mientras arrasas a tus enemigos.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_11_Q" "Tráiler de juego «Colony Reborn»"
- "COMMUNITYUPDATE_12_A" "Presentamos Munición real, un frenético modo 6 contra 6 solo para pilotos centrado en combates competitivos a corta distancia. Con dos nuevos mapas diseñados específicamente para este modo: Chimeneas y Prado. Estos dos mapas gratuitos son zonas de combate letales y constreñidas creadas específicamente para este modo frenético e intenso.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_12_Q" "Tráiler de juego «Bienvenidos a Munición real»"
- "COMMUNITYUPDATE_13_A" "Disfruta de la versión remasterizada de uno de los mapas favoritos de los fans del Titanfall original: `1Angel City`0. Prepárate para el primer DLC gratis para Titanfall 2 con `1Más buscados de Angel City`0, disponible el 1 de diciembre de 2016 para todos los jugadores. Incluye nuevas opciones cosméticas para darle un toque fresco a la Frontera. \n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_13_Q" "Tráiler de juego «Bienvenidos a Angel City»"
- "COMMUNITYUPDATE_14_A" "Bienvenidos.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_14_Q" "Tráiler de premios «Bis»"
- "COMMUNITYUPDATE_15_A" "Dos leyendas, un legado.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_15_Q" "Tráiler Un jugador «Sed uno en combate»"
- "COMMUNITYUPDATE_16_A" "Sin límites.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_16_Q" "Tráiler de juego Multijugador «Pilotos»"
- "COMMUNITYUPDATE_DESC" "`3Noticias de comunidad de Titanfall`0\n\nInformación y enlaces en la red.\n\nPara más información:\n`2%$rui/bullet_point%`0Síguenos en Twitter `1@Respawn`0\n`2%$rui/bullet_point%`0Hazte fan en `1facebook.com/RespawnEntertainment`0\n`2%$rui/bullet_point%`0Únete en `1www.respawn.com`0"
- "COMMUNITYUPDATE_NAME" "Comunidad"
- "KNB_SUBJECT_00_DESC" "`3¿Qué novedades trae Titanfall?`0\n\n¡Consulta aquí qué ha cambiado en Titanfall 2!"
- "KNB_SUBJECT_00_NAME" "Actualizaciones"
- "KNB_SUBJECT_00_SUB_00_A" "`2%$rui/bullet_point%`010 nuevas banderas de indicativos creadas por la comunidad\n\n`2%$rui/bullet_point%`0Todos los regalos de partidario ahora pueden adquirirse con créditos\n\n`2%$rui/bullet_point%`0Nuevo contenido adquirible en la tienda\n\n"
- "KNB_SUBJECT_00_SUB_00_Q" "%$rui/hud/scoreboard/status_titan% 28 de noviembre: Cosecha"
- "KNB_SUBJECT_00_SUB_01_A" "`2%$rui/bullet_point%`0Espacio principal de pistola\n\n`2%$rui/bullet_point%`0Banderas de Halloween\n\n`2%$rui/bullet_point%`0Cambios de equilibrio\n\n`2%$rui/bullet_point%`0Nuevo contenido adquirible en la tienda\n\n"
- "KNB_SUBJECT_00_SUB_01_Q" "%$rui/hud/scoreboard/status_titan% 31 de octubre: Trucos o golosinas"
- "KNB_SUBJECT_00_SUB_02_A" "`2%$rui/bullet_point%`0Defensa fronteriza: - Compatibilidad para 3 mapas más - Dique seco, Angel City y Exoplaneta.\n\n`2%$rui/bullet_point%`0Nuevo mapa de Munición real - UMA\n\n`2%$rui/bullet_point%`0Nueva ejecución de piloto - Agujero en el muro\n\n`2%$rui/bullet_point%`0Nuevo contenido adquirible en la tienda"
- "KNB_SUBJECT_00_SUB_02_Q" "%$rui/hud/scoreboard/status_titan% 29 de agosto - Postales de la Frontera"
- "KNB_SUBJECT_00_SUB_03_A" "`2%$rui/bullet_point%`0Defensa fronteriza: un nuevo modo cooperativo donde unes fuerzas con hasta 3 jugadores más para defender un objetivo crucial de oleadas cada vez más intensas de combatientes de IA. La comunicación y la adaptabilidad son claves para sobrevivir.\n\n`2%$rui/bullet_point%`0Mapa nuevo: Ascenso\n\n`2%$rui/bullet_point%`0Mapa nuevo de Munición real: Municipio\n\n`2%$rui/bullet_point%`0Nuevo contenido adquirible en la tienda"
- "KNB_SUBJECT_00_SUB_03_Q" "%$rui/hud/scoreboard/status_titan% 25 de julio: operación Escudo fronterizo"
- "KNB_SUBJECT_00_SUB_04_A" "`2%$rui/bullet_point%`0Nuevo mapa: Juegos de guerra\n\n`2%$rui/bullet_point%`0Nuevo mapa de Munición real: Tráfico\n\n`2%$rui/bullet_point%`0Nueva ejecución de piloto: Lucha con tu sombra\n\n`2%$rui/bullet_point%`03.er espacio de arma\n\n`2%$rui/bullet_point%`0Ajustes de partida privada"
- "KNB_SUBJECT_00_SUB_04_Q" "%$rui/hud/scoreboard/status_titan% 27 de junio: Juegos de guerra"
- "KNB_SUBJECT_00_SUB_05_A" "`2%$rui/bullet_point%`0Nuevo titán: Monarch\n\n`2%$rui/bullet_point%`0Nuevo mapa: Reliquia\n\n`2%$rui/bullet_point%`0Nueva ejecución de piloto: Ahora me ves\n\n`2%$rui/bullet_point%`0Nuevo contenido adquirible en la tienda"
- "KNB_SUBJECT_00_SUB_05_Q" "%$rui/hud/scoreboard/status_titan% 30 de mayo: Reino del Monarch"
- "KNB_SUBJECT_00_SUB_06_A" "`2%$rui/bullet_point%`0Nuevo mapa: Glitch\n\n`2%$rui/bullet_point%`0Nuevo mapa de Munición real: Cubierta\n\n`2%$rui/bullet_point%`0Nueva facción: Marvins\n\n`2%$rui/bullet_point%`0Nueva ejecución de piloto: Incisivo\n\n`2%$rui/bullet_point%`0Generación máxima aumentada a 100"
- "KNB_SUBJECT_00_SUB_06_Q" "%$rui/hud/scoreboard/status_titan% 25 de abril: Un glitch en la Frontera"
- "KNB_SUBJECT_00_SUB_07_A" "`2%$rui/bullet_point%`0Nuevo mapa: Colonia\n\n`2%$rui/bullet_point%`0Nueva ejecución de piloto: Aplastacráneos\n\n`2%$rui/bullet_point%`0Nueva arma: R-101\n\n`2%$rui/bullet_point%`0Nuevo contenido adquirible en la tienda"
- "KNB_SUBJECT_00_SUB_07_Q" "%$rui/hud/scoreboard/status_titan% 30 de marzo: Colony Reborn"
- "KNB_SUBJECT_00_SUB_08_A" "`2%$rui/bullet_point%`0Munición real: un nuevo modo de juego de eliminación de pilotos contra pilotos. Modo 6 contra 6 sin reaparición, donde tienes un minuto para eliminar al equipo rival para ganar la ronda. También ganas la ronda si tu equipo conserva la bandera neutral cuando el tiempo se agote. Vence el primero en ganar 5 rondas.\n\n`2%$rui/bullet_point%`0Nuevo mapa de Munición real: Prado\n\n`2%$rui/bullet_point%`0Nuevo mapa de Munición real: Chimeneas\n\n`2%$rui/bullet_point%`0Nueva ejecución: Impacto tardío"
- "KNB_SUBJECT_00_SUB_08_Q" "%$rui/hud/scoreboard/status_titan% 23 de febrero: Munición real"
- "KNB_SUBJECT_00_SUB_09_A" "`2%$rui/bullet_point%`0Nuevo mapa: Angel City\n\n`2%$rui/bullet_point%`0Nueva arma: B3 Wingman de élite\n\n`2%$rui/bullet_point%`0Nueva ejecución de piloto: Destruido desde dentro\n\n`2%$rui/bullet_point%`0Nuevos kits de titán\n\n`2%$rui/bullet_point%`0Nuevo contenido adquirible en la tienda"
- "KNB_SUBJECT_00_SUB_09_Q" "%$rui/hud/scoreboard/status_titan% 30 de noviembre: Más buscados de Angel City"
- "MP_ANGEL_CITY_FD_WAVE_1" "Encadenado al cielo"
- "MP_ANGEL_CITY_FD_WAVE_2" "Amorfo"
- "MP_ANGEL_CITY_FD_WAVE_3" "Insurgencia"
- "MP_ANGEL_CITY_FD_WAVE_4" "Grupo obstinado"
- "MP_ANGEL_CITY_FD_WAVE_5" "Jugarse el cuello"
- "MP_DRYDOCK_FD_WAVE_1" "Nadar en aguas extrañas"
- "MP_DRYDOCK_FD_WAVE_2" "¡No tienen balas!"
- "MP_DRYDOCK_FD_WAVE_3" "Cegados por la ciencia"
- "MP_DRYDOCK_FD_WAVE_4" "Sistema de altas presiones"
- "MP_DRYDOCK_FD_WAVE_5" "Ojo de la tormenta"
- "MP_THAW_FD_WAVE_1" "Conciencia de situación"
- "MP_THAW_FD_WAVE_2" "Superioridad numérica"
- "MP_THAW_FD_WAVE_3" "Secuaz 21"
- "MP_THAW_FD_WAVE_4" "Diversión en el fuego"
- "MP_THAW_FD_WAVE_5" "Aprovecha las armas"
- "NO_PRICE" "Promoción expirada"
- "NO_PRICE_TWO_LINES" "Promoción\nexpirada"
- "PL_aegis_last_titan_standing" "UTEP Aegis"
- "PL_aegis_last_titan_standing_abbr" "UTEPA"
- "PL_aegis_last_titan_standing_desc" "Mejoras de Aegis activadas. Modo de eliminación por rondas. Vence el primero en ganar 3 rondas.\n^FFC83200Jugadores: 5 contra 5 *Empiezas como titán\nLímite de tiempo: 3 min por ronda *Sin reaparición\nTamaño máximo de grupo: 5"
- "PL_aegis_last_titan_standing_lobby" "PL_aegis_last_titan_standing_lobby"
- "PL_aegis_titan_brawl" "Batalla de titanes Aegis"
- "PL_aegis_titan_brawl_abbr" "BDTA"
- "PL_aegis_titan_brawl_desc" "Elimina titanes enemigos. Mejoras de Aegis activadas.\n^FFC83200Jugadores: 5 contra 5\nLímite de tiempo: 10 min\nTamaño máximo de grupo: 5"
- "PL_aegis_titan_brawl_hint" "Elimina titanes enemigos.\nSin eyección"
- "PL_aegis_titan_brawl_lobby" "Vestíbulo de Batalla de titanes Aegis"
- "PL_aitdm" "Desgaste"
- "PL_aitdm_abbr" "DGT"
- "PL_aitdm_desc" "Elimina a todos los enemigos.\n^FFC83200Jugadores: 6 contra 6 *IA\nLímite de tiempo: 10 min\nTamaño máximo de grupo: 6"
- "PL_aitdm_lobby" "Vestíbulo de Desgaste"
- "PL_all_grapple" "Ataque en Titanfall"
- "PL_all_grapple_abbr" "DGT"
- "PL_all_grapple_desc" "Reglas de Desgaste clásico, excepto que todas las funciones tácticas se reemplazan por el garfio.\n^FFC83200Jugadores: 6 contra 6 *IA\nLímite de tiempo: 10 min\nTamaño máximo de grupo: 6"
- "PL_all_grapple_lobby" "Vestíbulo de Ataque en Titanfall"
- "PL_all_holopilot" "El gran engaño"
- "PL_all_holopilot_abbr" "MR"
- "PL_all_holopilot_desc" "Reglas de Munición real clásico, excepto que todas las funciones tácticas se reemplazan por holopiloto.^FFC83200\nJugadores: 6 contra 6 *Sin titanes\nLímite de tiempo: 60 s *Sin reapariciones\nTamaño máximo de grupo: 6"
- "PL_all_holopilot_lobby" "Vestíbulo de El gran engaño"
- "PL_all_phase" "El otro lado"
- "PL_all_phase_abbr" "DGT"
- "PL_all_phase_desc" "Reglas de Desgaste clásico, excepto que todas las funciones tácticas se reemplazan por Fase.\n^FFC83200Jugadores: 6 contra 6 *IA\nLímite de tiempo: 10 min\nTamaño máximo de grupo: 6"
- "PL_all_phase_lobby" "Vestíbulo de El otro lado"
- "PL_all_spicy" "Desgaste animado"
- "PL_all_spicy_abbr" "DGT"
- "PL_all_spicy_desc" "Reglas de Desgaste clásico, excepto que todas las funciones tácticas se reemplazan con garrapatas.\n^FFC83200Jugadores: 6 contra 6 *IA\nLímite de tiempo: 10 min\nTamaño máximo de grupo: 6"
- "PL_all_spicy_lobby" "Vestíbulo de Desgaste animado"
- "PL_amped_tacticals" "Tácticas +"
- "PL_amped_tacticals_abbr" "DGT"
- "PL_amped_tacticals_desc" "Reglas de Desgaste clásico, excepto que las funciones tácticas son más potentes.\n^FFC83200Jugadores: 6 contra 6 *IA\nLímite de tiempo: 10 min\nTamaño máximo de grupo: 6"
- "PL_amped_tacticals_lobby" "Vestíbulo de Tácticas +"
- "PL_ANGEL_CITY" "Angel City 24/7"
- "PL_angel_city_abbr" "AC"
- "PL_angel_city_desc" "Solo Angel City, todo el tiempo.\n^FFC83200*Cazarrecompensas *Desgaste\n*Fortines Cargados"
- "PL_angel_city_lobby" "Vestíbulo de Angel City 24/7"
- "PL_at_coop" "Evasión (coop.)"
- "PL_at_coop_desc" "Acabas de escapar de una prisión con solo una pistola. Sobrevive hasta que llegue un transporte. Elimina enemigos para ganar dinero y comprar armas. \n^FFC83200Jugadores: 6\nTamaño máximo de grupo: 6"
- "PL_at_coop_lobby" "Vestíbulo de Evasión"
- "PL_attrition" "Cazarrecompensas"
- "PL_attrition_abbr" "CR"
- "PL_attrition_desc" "Elimina enemigos para ganar dinero. Consigue más ingresando tus bonificaciones en el banco, en los lugares designados.\n^FFC83200Jugadores: 5 contra 5 *IA\nLímite de tiempo: 10 min\nTamaño máximo de grupo: 5"
- "PL_attrition_lobby" "Vestíbulo de Cazarrecompensas"
- "PL_capture_the_flag" "Captura la bandera"
- "PL_capture_the_flag_abbr" "CLB"
- "PL_capture_the_flag_desc" "¡Hazte con la bandera enemiga y llévala hasta tu base, a la vez que evitas que el enemigo te robe la tuya!\n^FFC83200Jugadores: 5 contra 5\nLímite de tiempo: 12 min\nTamaño máximo de grupo: 5"
- "PL_capture_the_flag_lobby" "Vestíbulo de CLB"
- "PL_coliseum" "Coliseo"
- "PL_coliseum_desc" "Combate 1 contra 1 con movilidad mejorada en una jaula. Elimina a tu rival para ganar una ronda. El vencedor de 3 de 5 gana un regalo de partidario de recompensa.^FFC83200\nJugadores: 1 contra 1 *Sin titanes\nLímite de tiempo: 3 min *Sin reapariciones\n**^FFFFFF00REQUIERE TICKETS DE COLISEO o PAGAR ENTRADA"
- "PL_coliseum_lobby" "Vestíbulo de Coliseo"
- "PL_colony" "Colonia 24/7"
- "PL_colony_abbr" "COL"
- "PL_colony_desc" "Mapa Colonia, continuamente. ^CCCCCC00Buscará partidas de ^FFC83200Desgaste^CCCCCC00, ^FFC83200Pilotos contra pilotos^CCCCCC00 y ^FFC83200Último titán en pie^CCCCCC00."
- "PL_colony_lobby" "Vestíbulo de Colonia 24/7"
- "PL_ctf_lf" "CLB (Nitro)"
- "PL_ctf_lf_abbr" "CLB-N"
- "PL_ctf_lf_desc" "Frenético Captura la bandera en mapas seleccionados.\n^FFC83200Jugadores: 5 contra 5\nTamaño máximo de grupo: 5\n^F4D5A600Recuperación instantánea de banderas"
- "PL_ctf_lf_lobby" "Vestíbulo CLB Nitro"
- "PL_default_description" "Descripción predeterminada"
- "PL_default_lobbytitle" "Título de vestíbulo por defecto"
- "PL_default_name" "Nombre predeterminado"
- "PL_don" "Doble o nada"
- "PL_fd" "Defensa fronteriza"
- "PL_fd_desc" "Defiende contra las oleadas de las fuerzas de la Flota Remanente"
- "PL_fd_easy" "Defensa fronteriza: fácil"
- "PL_fd_easy_desc" "Aplasta a los rivales."
- "PL_fd_easy_lobby" "Defensa fronteriza: vestíbulo fácil"
- "PL_fd_hard" "Defensa fronteriza: difícil"
- "PL_fd_hard_desc" "Se requiere mucha habilidad"
- "PL_fd_hard_lobby" "Defensa fronteriza: vestíbulo difícil"
- "PL_fd_insane" "Defensa fronteriza: demencial"
- "PL_fd_insane_desc" "No sobrevivirás"
- "PL_fd_insane_lobby" "Vestíbulo de Defensa fronteriza: demencial"
- "PL_fd_lobby" "Vestíbulo de Defensa fronteriza"
- "PL_fd_master" "Defensa fronteriza: maestro"
- "PL_fd_master_desc" "Solo los mejores triunfarán"
- "PL_fd_master_lobby" "Vestíbulo de Defensa fronteriza: maestro"
- "PL_fd_normal" "Defensa fronteriza: normal"
- "PL_fd_normal_desc" "Recomendado para jugadores experimentados"
- "PL_fd_normal_lobby" "Vestíbulo de Defensa fronteriza: normal"
- "PL_ffa" "Batalla campal"
- "PL_ffa_abbr" "BC"
- "PL_ffa_desc" "Cada piloto por su cuenta; elimina a todos los enemigos.\n^FFC83200Jugadores: 1 contra 11\nLímite de tiempo: 10 min\nTamaño máximo de grupo: 1"
- "PL_ffa_lobby" "Vestíbulo de Batalla campal"
- "PL_fra" "Agentes libres"
- "PL_fra_abbr" "AL"
- "PL_fra_desc" "Cada piloto, por su cuenta. Elimina enemigos para ganar. Reúne 3 baterías para pedir un titán.\n^FFC83200Jugadores: 1 contra 11\nLímite de tiempo: 15 min\nTamaño máximo de grupo: 1"
- "PL_fra_lobby" "Vestíbulo de Agentes libres"
- "PL_groud_war_lobby" "Vestíbulo de Variado 8c8"
- "PL_ground_war" "Variado 8c8"
- "PL_ground_war_abbr" "8c8"
- "PL_ground_war_desc" "Incluye Escaramuza y Fortines cargados, con gran número de pilotos en todos los mapas.\n^FFC83200Jugadores: 8 contra 8"
- "PL_hardpoint" "Fortines cargados"
- "PL_hardpoint_abbr" "FC"
- "PL_hardpoint_desc" "Captura y conserva los fortines para ganar puntos. Los fortines cargados proporcionan el doble de puntos.\n^FFC83200Jugadores: 6 contra 6\nLímite de tiempo: 10 min\nTamaño máximo de grupo: 6"
- "PL_hardpoint_lobby" "Vestíbulo de Fortines cargados"
- "PL_hunted" "Cazado"
- "PL_iron_last_titan_standing" "UTEP de acero"
- "PL_iron_last_titan_standing_abbr" "UTEPA"
- "PL_iron_last_titan_standing_desc" "Modo de eliminación por rondas, solo titanes. Vence el primero en ganar 3 rondas.\n^FFC83200Jugadores: 5 contra 5 *SIN PILOTOS\nLímite de tiempo: 3 min por ronda *Sin reaparición\nTamaño máximo de grupo: 5"
- "PL_iron_last_titan_standing_lobby" "PL_iron_last_titan_standing_lobby"
- "PL_last_titan_standing" "Último titán en pie"
- "PL_last_titan_standing_abbr" "UTEP"
- "PL_last_titan_standing_desc" "En esta partida de eliminación por rondas, todos los jugadores empiezan en un titán. Gana el primero en vencer en 3 rondas.\n^FFC83200Jugadores: 5 contra 5 *Empiezas como titán\nLímite de tiempo: 3 min por ronda *Sin reapariciones\nTamaño máximo de grupo: 5"
- "PL_last_titan_standing_lobby" "Vestíbulo de UTEP"
- "PL_limited_time_mode" "Por tiempo limitado"
- "PL_live_fire" "Munición real"
- "PL_live_fire_abbr" "MR"
- "PL_live_fire_desc" "Combate frenético en una arena de munición real. Gana la ronda eliminando a todos los pilotos enemigos o conservando la bandera cuando se agote el tiempo.^FFC83200\nJugadores: 6 contra 6 *Sin titanes\nLímite de tiempo: 60 s *Sin reapariciones\nTamaño máximo de grupo: 6"
- "PL_live_fire_lobby" "Vestíbulo de Munición real"
- "PL_load_a_map_on_the_command_line" "Carga un mapa en la línea de comandos. Solo para desarrollo."
- "PL_marked_for_death" "Condenado"
- "PL_marked_for_death_abbr" "CON"
- "PL_marked_for_death_desc" "Elimina o protege los blancos marcados.\n^FFC83200Jugadores: 6 contra 6 \nLímite de tiempo: 12 min\nTamaño máximo de grupo: 6"
- "PL_marked_for_death_lobby" "Vestíbulo de Condenado"
- "PL_nitro_ffa" "BC (Nitro)"
- "PL_nitro_ffa_abbr" "BC-N"
- "PL_nitro_ffa_desc" "Frenética Batalla campal en mapas seleccionados.\n^FFC83200Jugadores: 6\n^F4D5A600Sin titanes\nSin potenciadores"
- "PL_nitro_ffa_lobby" "Vestíbulo de BC (Nitro)"
- "PL_nitro_mixtape" "Variado (Nitro)"
- "PL_nitro_mixtape_abbr" "VRD-N"
- "PL_nitro_mixtape_desc" "Frenéticos CLB, CON y JcJ en mapas seleccionados.\n^FFC83200Jugadores: 5 contra 5\nTamaño máximo de grupo: 5\n^F4D5A600Recuperación instantánea de banderas"
- "PL_nitro_mixtape_lobby" "Vestíbulo de Variado"
- "PL_pilot_hunter" "Escaramuza"
- "PL_pilot_hunter_abbr" "ECM"
- "PL_pilot_hunter_desc" "Elimina pilotos y titanes enemigos. \n^FFC83200Jugadores: 8 contra 8\nLímite de tiempo: 10 min\nTamaño máximo de grupo: 8"
- "PL_pilot_hunter_lobby" "Vestíbulo de Escaramuza"
- "PL_pilot_skirmish" "Pilotos contra pilotos"
- "PL_pilot_skirmish_abbr" "PcP"
- "PL_pilot_skirmish_desc" "Elimina pilotos enemigos. No se permiten titanes.\n^FFC83200Jugadores: 8 contra 8 *Sin titanes\nLímite de tiempo: 10 min\nTamaño máximo de grupo: 8"
- "PL_pilot_skirmish_lobby" "Vestíbulo de PcP"
- "PL_pl_rebuild_all_paths" "Reconstruir todas las rutas"
- "PL_pl_run_with_ai_ainrebuildonmapstart_2" "Ejecutar con ai_ainRebuildOnMapStart 2"
- "PL_private_match" "Partida privada (beta)"
- "PL_private_match_desc" "Juega una partida privada personalizada en el modo y mapa que prefieras.\n^FFC83200Invitar red o Invitar amigos para jugar\n^FFC83200Jugadores: 1-16\nSin progresión"
- "PL_private_match_lobby" "Vestíbulo de partida privada (beta)"
- "PL_promo_coop" "Coop. de 4 jugadores"
- "PL_raid" "Incursión"
- "PL_rise" "Ascenso 24/7"
- "PL_rise_abbr" "ASC"
- "PL_rise_desc" "Mapa Ascenso, continuamente. ^CCCCCC00Buscará partidas de ^FFC83200CLB^CCCCCC00, ^FFC83200Fortines cargados^CCCCCC00, ^FFC83200Pilotos contra pilotos^CCCCCC00, ^FFC83200Munición real^CCCCCC00 y ^FFC83200Último titán en pie^CCCCCC00."
- "PL_rise_lobby" "Vestíbulo de Ascenso 24/7"
- "PL_rocket_arena" "Arena balística"
- "PL_rocket_arena_abbr" "MR"
- "PL_rocket_arena_desc" "Reglas de Munición real clásico con EPG modificadas.^FFC83200\nJugadores: 6 contra 6 *Sin titanes\nLímite de tiempo: 90 s *Sin reapariciones\nTamaño máximo de grupo: 6"
- "PL_rocket_arena_lobby" "Vestíbulo de Arena balística"
- "PL_settings_for_when_someone_loads_a_map_on_the_command_line_do_not_edit_the_cmdlinemapload_1_below_-_this_makes_this_work" "Ajustes para cuando alguien carga un mapa desde la línea de comandos. No editar cmdlineMapLoad 1: eso hace que esto funcione."
- "PL_speedball" "Munición real"
- "PL_speedball_desc" "Lucha por la posesión de una bandera neutral. Elimina al equipo enemigo o mantén la posesión de la bandera cuando se agote el tiempo para vencer en la ronda. Gana el primero en imponerse en 5 rondas.\n^FFC83200Jugadores: 6 contra 6 *Sin titanes\nLímite de tiempo: 60 segundos por ronda *Sin reapariciones\nTamaño máximo de grupo: 6"
- "PL_speedball_lobby" "Vestíbulo de Munición real"
- "PL_tactikill" "Desgaste táctico"
- "PL_tactikill_abbr" "DGT"
- "PL_tactikill_desc" "Reglas de Desgaste clásico, excepto que las funciones tácticas se recuperan completamente al conseguir eliminaciones.\n^FFC83200Jugadores: 6 contra 6 *IA\nLímite de tiempo: 10 min\nTamaño máximo de grupo: 6"
- "PL_tactikill_lobby" "Vestíbulo de Desgaste táctico"
- "PL_titan_brawl" "Batalla de titanes"
- "PL_titan_brawl_abbr" "BDT"
- "PL_titan_brawl_desc" "Elimina titanes enemigos. Pilotos no permitidos.\n^FFC83200Jugadores: 5 contra 5\nLímite de tiempo: 10 min\nTamaño máximo de grupo: 5"
- "PL_titan_brawl_hint" "Elimina titanes enemigos.\nSin eyección."
- "PL_titan_brawl_lobby" "Vestíbulo de Batalla de titanes"
- "PL_titan_brawl_turbo" "Batalla de titanes turbo"
- "PL_titan_brawl_turbo_abbr" "BDT"
- "PL_titan_brawl_turbo_desc" "Reglas de Batalla de titanes clásico con regeneración de impulso y generación de núcleo más rápidas.\n^FFC83200Jugadores: 5 contra 5\nLímite de tiempo: 10 min\nTamaño máximo de grupo: 5"
- "PL_titan_brawl_turbo_hint" "Elimina titanes enemigos.\nSin eyección"
- "PL_titan_brawl_turbo_lobby" "Vestíbulo de Batalla de titanes turbo"
- "PL_turbo_last_titan_standing" "UTEP turbo"
- "PL_turbo_last_titan_standing_abbr" "UTEP"
- "PL_turbo_last_titan_standing_desc" "Reglas de UTEP clásico con regeneración de impulso y generación de núcleo más rápidas.\n^FFC83200Jugadores: 5 contra 5 *Empiezas como titán\nLímite de tiempo: 3 min por ronda *Sin reapariciones\nTamaño máximo de grupo: 5"
- "PL_turbo_last_titan_standing_lobby" "Vestíbulo de UTEP turbo"
- "PL_variety_pack" "Variado"
- "PL_variety_pack_desc" "Número de jugadores variables. Incluye diversos mapas de los siguientes modos:\n^FFC83200*Cazarrecompensas *Desgaste\n*Último titán en pie *Fortines cargados\n*Pilotos contra pilotos *Captura la bandera"
- "PL_variety_pack_lobby" "Vestíbulo de Variado"
- "PL_wargames" "Juegos de guerra 24/7"
- "PL_wargames_abbr" "JDG"
- "PL_wargames_desc" "Mapa Juegos de guerra, continuamente. ^CCCCCC00Buscará partidas de ^FFC83200Desgaste^CCCCCC00, ^FFC83200CLB^CCCCCC00, ^FFC83200Pilotos contra pilotos^CCCCCC00, ^FFC83200Fortines cargados^CCCCCC00 y ^FFC83200Último titán en pie^CCCCCC00."
- "PL_wargames_lobby" "Vestíbulo de Juegos de guerra 24/7"
- "WATCH_TUTORIAL" "VER TUTORIAL"
- }
- }
- "lang"
- {
- "Language" "tchinese"
- "Tokens"
- {
- "COMMUNITYUPDATE_00_A" "透過最新發佈的《Titanfall 2:邊境明信片》DLC,您將可以在邊境繼續您的驚奇冒險。內含全新和您熟悉的地點,以及全新的菁英武器戰鬥塗裝收集品,邊境將會有更美好的景觀。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_00_Q" "「邊境明信片」預告片"
- "COMMUNITYUPDATE_01_A" "瞭解邊境明信片修補檔的所有變更內容。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_01_Q" "邊境明信片:修補檔說明"
- "COMMUNITYUPDATE_02_A" "即將在行動裝置上推出的《Titanfall:突擊》是一款位於 Titanfall 世界中刺激的即時策略遊戲,它是與 Particle City 合作完成。到這裡觀看這些精彩內容!\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_02_Q" "《Titanfall:突擊》\發行\預告片"
- "COMMUNITYUPDATE_03_A" "Iniquity 帶領我們完成《Titanfall:突擊》的教學關卡並分享基本的游戲訣竅。這是瞭解這款游戲的絕佳途徑。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_03_Q" "《Titanfall:突擊》:\學習基本操作\影片"
- "COMMUNITYUPDATE_04_A" "聽聽邊境防禦幕後的一些重要人物談論關於這個模式的一些歷史和製作過程,並觀看幾回合的遊玩過程!\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_04_Q" "Respawn 一起玩邊境防禦"
- "COMMUNITYUPDATE_05_A" "Kevin Younger 製作了一些有趣的集錦,展現使用脈衝刀做出的大量美妙動作。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_05_Q" "社群創作:前往據點"
- "COMMUNITYUPDATE_06_A" "ConzeyG 透過 Reddit 展現在獵殺標記模式中使用北極星擊破鐵馭的驚人效率。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_06_Q" "社群創作:北極星獵殺鐵馭"
- "COMMUNITYUPDATE_07_A" "現已開放!邊境防禦與崛起地圖將一同返回,另外還有一系列全新戰鬥塗裝供你購買和一張新的烈火戰場地圖。到這裡觀看這些精彩內容。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_07_Q" "「邊境神盾任務」玩法預告片"
- "COMMUNITYUPDATE_08_A" "現已開放!經典的戰爭遊戲地圖以全新姿態重返《Titanfall 2》。更別錯過全新處決動畫與烈火戰場地圖 - 交通。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_08_Q" "「戰爭遊戲」玩法預告片"
- "COMMUNITYUPDATE_09_A" "此 DLC 內含第 7 具多人遊戲泰坦:「帝王」,為「遺跡」的重製地圖,並新增了可購買的至尊浪人以及至尊強力泰坦、更多迷彩、旗幟和機頭藝術。於此處觀看影像。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_09_Q" "「帝王的統治」遊戲玩法預告片"
- "COMMUNITYUPDATE_10_A" "邊境中暗藏危機 - 準備進入《Titanfall 2》最新的免費 DLC:邊境故障,其中將包含全新地圖「異常」。受拉斯提摩沙上尉的家鄉哈墨尼星所啟發的環境設計,其中大多為垂直空間與連綿曲折的道路,非常適合使用連鎖蹬壁來橫跨此地圖。另外還有一張全新烈火戰場地圖即將登場:甲板,其中包含狹窄的室內空間、空曠的廣場和在空中盤旋的機器人。如果本次更新讓您感到壓力太大,您最得力的助手馬文機器人現在將成為全新陣營並助您一臂之力。最後,全新的脈衝刀處決動畫已開放,並在您需要的時候隨時供您使用。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_10_Q" "「邊境故障」遊戲玩法預告片"
- "COMMUNITYUPDATE_11_A" "重返粉絲們最愛的初代《Titanfall》地圖:殖民地。混合了《Titanfall 2》中所有全新戰術技能與泰坦,泰坦與鐵馭們想在這張充滿狹窄巷弄、死角與開放屋頂的鄉村地圖中存活必須隨時保持警覺。於 3 月 30 日對所有玩家免費開放。「殖民地重生」DLC 組合包中含有酷炫的經典武器 R-101 步槍、全新勾爪處決動畫和全新外觀選項供您購買,讓您能夠在浴血奮戰的同時展現您獨有的魅力。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_11_Q" "「殖民地重生」遊戲玩法預告片"
- "COMMUNITYUPDATE_12_A" "「烈火戰場」簡介:超快節奏的 6 對 6 鐵馭對戰模式,讓您體驗邊境上刺激的近距離戰鬥。「烈火戰場」包含兩張全新的專屬地圖:「堆積地」和「草原」。這兩張免費地圖提供了封閉式的對戰空間,是專門為快節奏的近戰模式而設計。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_12_Q" "「歡迎來到烈火戰場」遊戲玩法預告片"
- "COMMUNITYUPDATE_13_A" "體驗經過重製的初代《Titanfall》玩家最愛的`1天使城`0地圖。為在 12 月 1 日與`1天使城通緝令`0一同向所有玩家發佈的首個免費《Titanfall 2》DLC 做好準備。此內容包含新的外觀選項,可讓您在邊境上更加英姿煥發。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_13_Q" "「歡迎來到天使城」遊戲玩法預告片"
- "COMMUNITYUPDATE_14_A" "歡迎回來。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_14_Q" "「Encore」讚譽影片"
- "COMMUNITYUPDATE_15_A" "兩位傳奇,一次遺贈。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_15_Q" "「合而為一」單人模式遊戲玩法預告片"
- "COMMUNITYUPDATE_16_A" "無限的可能。\n\n\n按 `2%[A_BUTTON|MOUSE1]%`0 觀看。"
- "COMMUNITYUPDATE_16_Q" "「鐵馭」多人模式遊戲玩法預告片"
- "COMMUNITYUPDATE_DESC" "`3Titanfall 社群更新`0\n\n來自網路的資訊和連結。\n\n更多內容:\n`2%$rui/bullet_point%`0在 Twitter 上關注我們 `1@Respawn`0\n`2%$rui/bullet_point%`0在 `1facebook.com/RespawnEntertainment`0 追蹤我們\n`2%$rui/bullet_point%`0造訪 `1www.respawn.com`0 加入我們"
- "COMMUNITYUPDATE_NAME" "社群"
- "KNB_SUBJECT_00_DESC" "`3《Titanfall》有什麼新內容?`0\n\n從此處瞭解《Titanfall 2》的改變!"
- "KNB_SUBJECT_00_NAME" "遊戲更新"
- "KNB_SUBJECT_00_SUB_00_A" "`2%$rui/bullet_point%`010 社群建立的全新呼叫代號旗幟\n\n`2%$rui/bullet_point%`0現在能夠使用點數購買所有擁護禮包\n\n`2%$rui/bullet_point%`0全新商城道具供你購買\n\n"
- "KNB_SUBJECT_00_SUB_00_Q" "%$rui/hud/scoreboard/status_titan% 11 月 28 日 - 收穫季節"
- "KNB_SUBJECT_00_SUB_01_A" "`2%$rui/bullet_point%`0主手槍欄\n\n`2%$rui/bullet_point%`0萬聖節旗幟\n\n`2%$rui/bullet_point%`0平衡性變更\n\n`2%$rui/bullet_point%`0全新商城道具供你購買\n\n"
- "KNB_SUBJECT_00_SUB_01_Q" "%$rui/hud/scoreboard/status_titan% 10 月 31 日 - 萬聖節活動"
- "KNB_SUBJECT_00_SUB_02_A" "`2%$rui/bullet_point%`0邊境防禦 - 支援 3 張額外的地圖:乾塢、天使城和系外行星。\n\n`2%$rui/bullet_point%`0全新烈火戰場地圖 - UMA\n\n`2%$rui/bullet_point%`0全新鐵馭處決動畫 - 穿透障壁\n\n`2%$rui/bullet_point%`0全新商城道具供你購買"
- "KNB_SUBJECT_00_SUB_02_Q" "%$rui/hud/scoreboard/status_titan% 8 月 29 日 - 邊境明信片"
- "KNB_SUBJECT_00_SUB_03_A" "`2%$rui/bullet_point%`0邊境防禦 - 全新合作模式讓你與其他三名玩家一同保護重要目標並擊退一波波逐漸增強的 AI 敵人。溝通與適應力將是生存的關鍵。\n\n`2%$rui/bullet_point%`0全新地圖 - 崛起\n\n`2%$rui/bullet_point%`0全新烈火戰場地圖 - 小鎮\n\n`2%$rui/bullet_point%`0全新商城道具供你購買"
- "KNB_SUBJECT_00_SUB_03_Q" "%$rui/hud/scoreboard/status_titan% 7 月 25 日 - 邊境神盾任務"
- "KNB_SUBJECT_00_SUB_04_A" "`2%$rui/bullet_point%`0新地圖 - 戰爭遊戲\n\n`2%$rui/bullet_point%`0新烈火戰場地圖 - 交通\n\n`2%$rui/bullet_point%`0新鐵馭處決動畫 - 幻影拳腳\n\n`2%$rui/bullet_point%`0第三武器欄\n\n`2%$rui/bullet_point%`0私人比賽設置"
- "KNB_SUBJECT_00_SUB_04_Q" "%$rui/hud/scoreboard/status_titan% 6 月 27 日 - 戰爭遊戲"
- "KNB_SUBJECT_00_SUB_05_A" "`2%$rui/bullet_point%`0全新泰坦 - 帝王\n\n`2%$rui/bullet_point%`0全新地圖 - 遺跡\n\n`2%$rui/bullet_point%`0全新鐵馭處決動畫 - 無影無蹤\n\n`2%$rui/bullet_point%`0全新商城道具供你購買"
- "KNB_SUBJECT_00_SUB_05_Q" "%$rui/hud/scoreboard/status_titan% 5 月 30 日 - 帝王的統治"
- "KNB_SUBJECT_00_SUB_06_A" "`2%$rui/bullet_point%`0全新地圖 - 異常\n\n`2%$rui/bullet_point%`0全新烈火戰場地圖 - 甲板\n\n`2%$rui/bullet_point%`0全新陣營 - 馬文機器人\n\n`2%$rui/bullet_point%`0全新鐵馭處決動畫 - 刀刀見骨\n\n`2%$rui/bullet_point%`0重生上限提升至 100"
- "KNB_SUBJECT_00_SUB_06_Q" "%$rui/hud/scoreboard/status_titan% 4 月 25 日 - 邊境故障"
- "KNB_SUBJECT_00_SUB_07_A" "`2%$rui/bullet_point%`0全新地圖 - 殖民地\n\n`2%$rui/bullet_point%`0全新鐵馭處決動畫 - 猛擊\n\n`2%$rui/bullet_point%`0全新武器 - R-101\n\n`2%$rui/bullet_point%`0全新商城道具供你購買"
- "KNB_SUBJECT_00_SUB_07_Q" "%$rui/hud/scoreboard/status_titan% 3 月 30 日 - 殖民地重生"
- "KNB_SUBJECT_00_SUB_08_A" "`2%$rui/bullet_point%`0烈火戰場 - 全新鐵馭對鐵馭殲滅模式!這是一場 6 對 6 回合模式且不能重生,你將有一分鐘時間殲滅敵隊來贏得此回合。你也能夠透過在計時結束時持有中立旗幟來取勝。先贏得 5 個回合的隊伍將贏得比賽。\n\n`2%$rui/bullet_point%`0全新烈火戰場地圖 - 草原\n\n`2%$rui/bullet_point%`0全新烈火戰場地圖 - 堆積地\n\n`2%$rui/bullet_point%`0全新鐵馭處決動畫 - 快速攻擊"
- "KNB_SUBJECT_00_SUB_08_Q" "%$rui/hud/scoreboard/status_titan% 2 月 23 日 - 烈火戰場"
- "KNB_SUBJECT_00_SUB_09_A" "`2%$rui/bullet_point%`0全新地圖 - 天使城\n\n`2%$rui/bullet_point%`0全新武器 - B3 幫手菁英\n\n`2%$rui/bullet_point%`0全新鐵馭處決動畫 - 瞬間爆炸\n\n`2%$rui/bullet_point%`0全新泰坦裝備\n\n`2%$rui/bullet_point%`0全新商城道具供你購買"
- "KNB_SUBJECT_00_SUB_09_Q" "%$rui/hud/scoreboard/status_titan% 11 月 30 日 - 天使城通緝令"
- "MP_ANGEL_CITY_FD_WAVE_1" "被縛於天際"
- "MP_ANGEL_CITY_FD_WAVE_2" "無形"
- "MP_ANGEL_CITY_FD_WAVE_3" "暴動"
- "MP_ANGEL_CITY_FD_WAVE_4" "一群固執的人"
- "MP_ANGEL_CITY_FD_WAVE_5" "手氣絕佳"
- "MP_DRYDOCK_FD_WAVE_1" "游入陌生水域"
- "MP_DRYDOCK_FD_WAVE_2" "他們沒子彈了!"
- "MP_DRYDOCK_FD_WAVE_3" "受科學誤導"
- "MP_DRYDOCK_FD_WAVE_4" "高壓系統"
- "MP_DRYDOCK_FD_WAVE_5" "風暴之眼"
- "MP_THAW_FD_WAVE_1" "狀態意識"
- "MP_THAW_FD_WAVE_2" "人多力量大"
- "MP_THAW_FD_WAVE_3" "追隨者 21"
- "MP_THAW_FD_WAVE_4" "火中作樂"
- "MP_THAW_FD_WAVE_5" "嗜槍如命"
- "NO_PRICE" "優惠已過期"
- "NO_PRICE_TWO_LINES" "優惠\n已過期"
- "PL_aegis_last_titan_standing" "神盾泰坦殊死戰"
- "PL_aegis_last_titan_standing_abbr" "ALTS"
- "PL_aegis_last_titan_standing_desc" "神盾升級啟用。回合制淘汰賽。先贏 3 場者勝。\n^FFC83200玩家:5 對 5 *開始時有泰坦\n時間限制:每場 3 分鐘 *無重生\n最大派對人數:5"
- "PL_aegis_last_titan_standing_lobby" "PL_aegis_last_titan_standing_lobby"
- "PL_aegis_titan_brawl" "神盾泰坦爭鬥"
- "PL_aegis_titan_brawl_abbr" "ATTDM"
- "PL_aegis_titan_brawl_desc" "擊殺敵方泰坦。神盾升級啟用。\n^FFC83200玩家:5 對 5\n時間限制:10 分鐘\n最大派對人數:5"
- "PL_aegis_titan_brawl_hint" "擊殺敵方泰坦。\n無彈射"
- "PL_aegis_titan_brawl_lobby" "神盾泰坦爭鬥大廳"
- "PL_aitdm" "消耗戰"
- "PL_aitdm_abbr" "ATT"
- "PL_aitdm_desc" "擊殺所有敵人。\n^FFC83200玩家:6v6 *AI\n時間限制:10 分鐘\n最大派對人數:6"
- "PL_aitdm_lobby" "消耗戰大廳"
- "PL_all_grapple" "進擊的泰坦"
- "PL_all_grapple_abbr" "消耗戰"
- "PL_all_grapple_desc" "傳統消耗戰規則,但是戰術技能被鉤爪取代。\n^FFC83200玩家:6v6 *電腦\n時間限制:10 分鐘\n最大隊伍人數:6"
- "PL_all_grapple_lobby" "進擊的泰坦大廳"
- "PL_all_holopilot" "大騙局"
- "PL_all_holopilot_abbr" "烈火戰場"
- "PL_all_holopilot_desc" "傳統烈火戰場規則,但是戰術技能被幻影鐵馭取代。\n^FFC83200玩家:6v6 *無泰坦\n時間限制:60 秒 *無重生\n最大隊伍人數:6"
- "PL_all_holopilot_lobby" "大騙局大廳"
- "PL_all_phase" "異次元"
- "PL_all_phase_abbr" "消耗戰"
- "PL_all_phase_desc" "傳統消耗戰規則,但是戰術技能被轉移取代。\n^FFC83200玩家:6v6 *電腦\n時間限制:10 分鐘\n最大隊伍人數:6"
- "PL_all_phase_lobby" "異次元大廳"
- "PL_all_spicy" "火熱消耗戰"
- "PL_all_spicy_abbr" "消耗戰"
- "PL_all_spicy_desc" "傳統消耗戰規則,但是戰術技能被炸蛛取代。\n^FFC83200玩家:6v6 *電腦\n時間限制:10 分鐘\n最大隊伍人數:6"
- "PL_all_spicy_lobby" "火熱消耗戰大廳"
- "PL_amped_tacticals" "強化戰術技能"
- "PL_amped_tacticals_abbr" "消耗戰"
- "PL_amped_tacticals_desc" "傳統消耗戰規則,但是戰術技能將更加強大。\n^FFC83200玩家:6v6 *電腦\n時間限制:10 分鐘\n最大隊伍人數:6"
- "PL_amped_tacticals_lobby" "強化戰術技能大廳"
- "PL_ANGEL_CITY" "天使城 24/7"
- "PL_angel_city_abbr" "AC"
- "PL_angel_city_desc" "天使城,永遠都在。\n^FFC83200*賞金追緝 *消耗戰\n*強化據點"
- "PL_angel_city_lobby" "天使城 24/7 大廳"
- "PL_at_coop" "逃脫(合作模式)"
- "PL_at_coop_desc" "您剛剛逃離了監獄且身上只有一把手槍。存活至撤離艦到來。擊殺敵人來獲得金錢並用其購買武器。\n^FFC83200玩家:6\n最大派對人數:6"
- "PL_at_coop_lobby" "逃脫大廳"
- "PL_attrition" "賞金追緝"
- "PL_attrition_abbr" "BH"
- "PL_attrition_desc" "擊殺敵人獲取金錢。透過在指定地點「儲存」紅利以獲得額外金錢。\n^FFC83200玩家:5 對 5 *AI\n 時間限制:10 分鐘\n最大派對人數:5"
- "PL_attrition_lobby" "賞金追緝大廳"
- "PL_capture_the_flag" "奪旗"
- "PL_capture_the_flag_abbr" "CTF"
- "PL_capture_the_flag_desc" "奪取敵方旗幟並將其帶回你的基地,同時阻止對方奪取你的旗幟!\n^FFC83200玩家:5 對 5\n時間限制:12 分鐘\n最大派對人數:5"
- "PL_capture_the_flag_lobby" "奪旗大廳"
- "PL_coliseum" "競技場"
- "PL_coliseum_desc" "在鐵籠裡以強化行動力進行一對一戰鬥。每次擊殺對手便贏一回合。5 戰 3 勝者可獲得擁護禮包獎勵。^FFC83200\n玩家:1 對 1 *無泰坦\n時間限制:3 分鐘 *無重生\n**^FFFFFF00需要競技場門票或支付入場費"
- "PL_coliseum_lobby" "競技場大廳"
- "PL_colony" "殖民地 24/7"
- "PL_colony_abbr" "COL"
- "PL_colony_desc" "所有殖民地,持續不斷。 ^CCCCCC00這將會搜尋^FFC83200消耗戰^CCCCCC00、^FFC83200鐵馭對鐵馭^CCCCCC00、及^FFC83200泰坦殊死戰^CCCCCC00的比賽。"
- "PL_colony_lobby" "殖民地 24/7 大廳"
- "PL_ctf_lf" "奪旗(氮氧)"
- "PL_ctf_lf_abbr" "氮氧奪旗"
- "PL_ctf_lf_desc" "在選擇的地圖中進行快節奏的奪旗比賽。\n^FFC83200玩家:5 對 5\n最大隊伍人數:5\n^F4D5A600立即歸還旗幟"
- "PL_ctf_lf_lobby" "氮氧奪旗大廳"
- "PL_default_description" "預設說明"
- "PL_default_lobbytitle" "預設大廳名稱"
- "PL_default_name" "預設名稱"
- "PL_don" "加注翻倍"
- "PL_fd" "邊境防禦"
- "PL_fd_desc" "抵抗數波的殘餘部隊勢力"
- "PL_fd_easy" "邊境防禦:簡單"
- "PL_fd_easy_desc" "粉碎對手"
- "PL_fd_easy_lobby" "邊境防禦:簡單大廳"
- "PL_fd_hard" "邊境防禦:困難"
- "PL_fd_hard_desc" "必備高超的技巧"
- "PL_fd_hard_lobby" "邊境防禦:困難大廳"
- "PL_fd_insane" "邊境防禦:瘋狂"
- "PL_fd_insane_desc" "你將無法生存"
- "PL_fd_insane_lobby" "邊境防禦:瘋狂大廳"
- "PL_fd_lobby" "邊境防禦大廳"
- "PL_fd_master" "邊境防禦:大師"
- "PL_fd_master_desc" "只有最頂尖的菁英能夠成功"
- "PL_fd_master_lobby" "邊境防禦:大師大廳"
- "PL_fd_normal" "邊境防守:普通"
- "PL_fd_normal_desc" "推薦給資深玩家"
- "PL_fd_normal_lobby" "邊境防守:普通大廳"
- "PL_ffa" "混戰"
- "PL_ffa_abbr" "FFA"
- "PL_ffa_desc" "所有鐵馭為自己而戰,擊殺所有敵人。\n^FFC83200玩家:1 對 11\n時間限制:10 分鐘\n最大派對人數:1"
- "PL_ffa_lobby" "混戰大廳"
- "PL_fra" "自由混戰"
- "PL_fra_abbr" "FRA"
- "PL_fra_desc" "你將孤身作戰。擊殺敵人來取勝。收集 3 枚電池後可呼叫泰坦。\n^FFC83200玩家:1 對 11\n時間限制:15 分鐘\n最大派對人數:1"
- "PL_fra_lobby" "自由混戰大廳"
- "PL_groud_war_lobby" "8 對 8 綜合大廳"
- "PL_ground_war" "8 對 8 綜合"
- "PL_ground_war_abbr" "8v8"
- "PL_ground_war_desc" "收錄了「小規模戰鬥」和「強化據點」,並在每張地圖上都有高玩家人數。\n^FFC83200玩家:8對8"
- "PL_hardpoint" "強化據點"
- "PL_hardpoint_abbr" "AHP"
- "PL_hardpoint_desc" "佔領並堅守重地來獲得分數。強化的重地提供雙倍分數。\n^FFC83200玩家:6 對 6\n時間限制:10 分鐘\n最大派對人數:6"
- "PL_hardpoint_lobby" "強化據點大廳"
- "PL_hunted" "遭獵殺"
- "PL_iron_last_titan_standing" "鐵血泰坦殊死戰"
- "PL_iron_last_titan_standing_abbr" "ILTS"
- "PL_iron_last_titan_standing_desc" "僅泰坦參加的回合制殲滅戰。先贏 3 回合者獲勝。\n^FFC83200玩家:5 對 5 *無鐵馭\n時間限制:每回合 3 分鐘 *無重生\n最大派對人數:5"
- "PL_iron_last_titan_standing_lobby" " "
- "PL_last_titan_standing" "泰坦殊死戰"
- "PL_last_titan_standing_abbr" "LTS"
- "PL_last_titan_standing_desc" "所有玩家開始此回合制淘汰賽時皆有泰坦。先贏 3 場者勝。\n^FFC83200玩家:5 對 5 *開始時有泰坦\n時間限制:每場 3 分鐘 *無重生\n最大派對人數:5"
- "PL_last_titan_standing_lobby" "殊死大廳"
- "PL_limited_time_mode" "限時模式"
- "PL_live_fire" "烈火戰場"
- "PL_live_fire_abbr" "LF"
- "PL_live_fire_desc" "在烈火競技場中進行快節奏的戰鬥。在回合內擊殺所有敵方鐵馭或是在時間結束時持有旗幟即可獲勝。^FFC83200\n玩家:6 對 6 *無泰坦\n時間限制:60 秒 *無重生\n最大派對人數:6"
- "PL_live_fire_lobby" "烈火戰場大廳"
- "PL_load_a_map_on_the_command_line" "在命令行載入地圖-devonly"
- "PL_marked_for_death" "獵殺標記"
- "PL_marked_for_death_abbr" "MFD"
- "PL_marked_for_death_desc" "擊殺或保護被標記的目標。\n^FFC83200玩家:6 對 6\n時間限制:12 分鐘\n最大派對人數:6"
- "PL_marked_for_death_lobby" "獵殺標記大廳"
- "PL_nitro_ffa" "混戰(氮氧)"
- "PL_nitro_ffa_abbr" "混戰-氮氧"
- "PL_nitro_ffa_desc" "在特定地圖上進行快節奏的混戰。\n^FFC83200玩家:6\n^F4D5A600無泰坦\n無強化"
- "PL_nitro_ffa_lobby" "混戰氮氧大廳"
- "PL_nitro_mixtape" "綜合(氮氧)"
- "PL_nitro_mixtape_abbr" "綜合-氮氧"
- "PL_nitro_mixtape_desc" "在特定地圖上進行快節奏的奪旗、獵殺標記與鐵馭對鐵馭。\n^FFC83200玩家:5 對 5\n最大隊伍人數:5\n^F4D5A600立即歸還旗幟"
- "PL_nitro_mixtape_lobby" "綜合大廳"
- "PL_pilot_hunter" "小規模戰鬥"
- "PL_pilot_hunter_abbr" "SKM"
- "PL_pilot_hunter_desc" "擊殺敵方鐵馭與泰坦。\n^FFC83200玩家:8 對 8\n時間限制:10 分鐘\n最大派對人數:8"
- "PL_pilot_hunter_lobby" "小規模戰鬥大廳"
- "PL_pilot_skirmish" "鐵馭對鐵馭"
- "PL_pilot_skirmish_abbr" "PvP"
- "PL_pilot_skirmish_desc" "擊殺敵方鐵馭。無法呼叫泰坦。\n^FFC83200玩家:8 對 8 *無泰坦\n時間限制:10 分鐘\n最大派對人數:8"
- "PL_pilot_skirmish_lobby" "鐵馭對鐵馭大廳"
- "PL_pl_rebuild_all_paths" "重建所有路線"
- "PL_pl_run_with_ai_ainrebuildonmapstart_2" "執行 ai_ainRebuildOnMapStart 2"
- "PL_private_match" "私人比賽 (Beta 測試)"
- "PL_private_match_desc" "使用您選擇的地圖和模式進行自訂的私人比賽。\n^FFC83200邀請網路或邀請好友加入\n^FFC83200玩家:1-16 人\n無進度"
- "PL_private_match_lobby" "私人比賽大廳 (Beta 測試)"
- "PL_promo_coop" "4 人合作模式"
- "PL_raid" "突襲"
- "PL_rise" "崛起 24/7"
- "PL_rise_abbr" "RIS"
- "PL_rise_desc" "僅限崛起,持續不斷。^CCCCCC00這將搜尋^FFC83200奪旗^CCCCCC00、^FFC83200強化據點^CCCCCC00、^FFC83200鐵馭對鐵馭^CCCCCC00、^FFC83200烈火戰場^CCCCCC00與^FFC83200泰坦殊死戰^CCCCCC00比賽。"
- "PL_rise_lobby" "崛起 24/7 大廳"
- "PL_rocket_arena" "火箭競技場"
- "PL_rocket_arena_abbr" "烈火戰場"
- "PL_rocket_arena_desc" "傳統烈火戰場規則,但是配有改裝版 EPG。^FFC83200\n玩家:6v6*無泰坦\n時間限制:90 秒*無重生\n最大隊伍人數:6"
- "PL_rocket_arena_lobby" "火箭競技場大廳"
- "PL_settings_for_when_someone_loads_a_map_on_the_command_line_do_not_edit_the_cmdlinemapload_1_below_-_this_makes_this_work" "有人在命令行載入地圖時的設定。請勿編輯下面 cmdlineMapLoad 1-有這個才能使用本功能。"
- "PL_speedball" "烈火戰場"
- "PL_speedball_desc" "搶奪中立旗幟。消滅敵隊或是在比賽結束時持有旗幟者贏得一局。先贏 5 局者勝。\n^FFC83200玩家:6 對 6 *無泰坦\n時間限制:每局 60 秒 *無重生\n最大派對人數:6"
- "PL_speedball_lobby" "烈火戰場大廳"
- "PL_tactikill" "戰術擊殺消耗戰"
- "PL_tactikill_abbr" "消耗戰"
- "PL_tactikill_desc" "傳統消耗戰規則,但是戰術技能在擊殺時將會刷新。\n^FFC83200玩家:6v6 *電腦\n時間限制:10 分鐘\n最大隊伍人數:6"
- "PL_tactikill_lobby" "戰術擊殺消耗戰大廳"
- "PL_titan_brawl" "泰坦爭鬥"
- "PL_titan_brawl_abbr" "TTDM"
- "PL_titan_brawl_desc" "擊殺敵方泰坦,不可使用鐵馭。\n^FFC83200玩家:5 對 5\n時間限制:10 分鐘\n最大派對人數:5"
- "PL_titan_brawl_hint" "擊殺敵方泰坦。\n無彈射"
- "PL_titan_brawl_lobby" "泰坦爭鬥大廳"
- "PL_titan_brawl_turbo" "渦輪泰坦爭鬥"
- "PL_titan_brawl_turbo_abbr" "泰坦爭鬥"
- "PL_titan_brawl_turbo_desc" "傳統泰坦爭鬥規則,但是擁有更快的衝刺恢復與核心提升率。\n^FFC83200玩家:5 對 5\n時間限制:10 分鐘\n最大隊伍人數:5"
- "PL_titan_brawl_turbo_hint" "擊殺敵方泰坦。\n無彈射"
- "PL_titan_brawl_turbo_lobby" "渦輪泰坦爭鬥大廳"
- "PL_turbo_last_titan_standing" "渦輪殊死戰"
- "PL_turbo_last_titan_standing_abbr" "泰坦殊死戰"
- "PL_turbo_last_titan_standing_desc" "傳統泰坦殊死戰規則,但是擁有更快的衝刺恢復與核心提升率。\n^FFC83200玩家:5 對 5 *開始時有泰坦\n時間限制:每回合 3 分鐘 *無重生\n最大隊伍人數:5"
- "PL_turbo_last_titan_standing_lobby" "渦輪泰坦殊死戰大廳"
- "PL_variety_pack" "綜合"
- "PL_variety_pack_desc" "綜合玩家包含下列模式中的各種地圖:\n^FFC83200*賞金追緝 *消耗戰\n*泰坦殊死戰 *強化據點\n*鐵馭對鐵馭 *奪旗"
- "PL_variety_pack_lobby" "綜合大廳"
- "PL_wargames" "戰爭遊戲 24/7"
- "PL_wargames_abbr" "WGM"
- "PL_wargames_desc" "戰爭遊戲全系列,持續上演。 ^CCCCCC00這將會搜尋^FFC83200消耗戰^CCCCCC00、^FFC83200奪旗^CCCCCC00、^FFC83200鐵馭對鐵馭^CCCCCC00、^FFC83200強化據點^CCCCCC00,及^FFC83200泰坦殊死戰^CCCCCC00等對戰。"
- "PL_wargames_lobby" "戰爭遊戲 24/7 大廳"
- "WATCH_TUTORIAL" "觀看教學"
- }
- }
- "lang"
- {
- "Language" "italian"
- "Tokens"
- {
- "COMMUNITYUPDATE_00_A" "La tua avventura nei panorami eccezionali della Frontiera continua con l'ultimo DLC di Titanfall 2: Cartoline dalla Frontiera. Con luoghi nuovi e familiari e una nuova collezione di colori da guerra per armi Elite, la Frontiera non è mai stata così bella.\n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_00_Q" "Trailer \"Cartoline dalla Frontiera\""
- "COMMUNITYUPDATE_01_A" "Leggi tutte le novità introdotte nella patch Cartoline dalla Frontiera.\n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_01_Q" "Cartoline dalla Frontiera: note sulla patch"
- "COMMUNITYUPDATE_02_A" "Presto disponibile su dispositivi mobili, Titanfall: Assault è un videogioco strategico in tempo reale ambientato nell’universo Titanfall e realizzato in collaborazione con Particle City. Guardalo in azione! \n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_02_Q" "Trailer di \"Lancio\" Titanfall: Assault"
- "COMMUNITYUPDATE_03_A" "Iniquity ci illustra il tutorial e ci fornisce suggerimenti di base per Titanfall: Assault. Questo è il modo perfetto per iniziare a conoscere il gioco.\n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_03_Q" "Video Titanfall Assault: \"Impara le basi\""
- "COMMUNITYUPDATE_04_A" "Ascolta alcune delle persone chiave che hanno lavorato a Difesa Frontiera parlare della storia e della creazione della modalità e giocare a qualche partita! \n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_04_Q" "Respawn gioca a Difesa Frontiera"
- "COMMUNITYUPDATE_05_A" "Kevin Younger ha creato un montaggio divertente mostrando innumerevoli mosse con Lama a impulsi. \n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_05_Q" "Creazioni community: Arriva al punto"
- "COMMUNITYUPDATE_06_A" "ConzeyG su reddit mostra una brutale efficienza: Northstar che elimina i piloti nella modalità Marchiato a morte. \n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_06_Q" "Creazioni : Cacciatore di piloti Northstar"
- "COMMUNITYUPDATE_07_A" "Disponibile ora! Difesa Frontiera torna con Ascesa, nuovi colori da guerra acquistabili e una nuova mappa Live Fire.\n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_07_Q" "Trailer gameplay \"Scudo frontiera operazioni\""
- "COMMUNITYUPDATE_08_A" "Disponibile ora! L’apprezzata mappa Giochi di guerra torna in Titanfall 2, più bella che mai. Scopri anche la nuova esecuzione e la nuova mappa Live Fire, Traffico in azione.\n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_08_Q" "Trailer gameplay “Giochi di guerra”"
- "COMMUNITYUPDATE_09_A" "In questo DLC presentiamo: Monarch, il settimo Titan per multigiocatore; una rivisitazione della mappa Relitto; una nuova esecuzione e i Titan Ronin Prime e Tone Prime acquistabili; altre mimetiche, bandiere e decorazioni. Non perderti l'azione qui.\n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_09_Q" "Trailer gameplay “Regno di Monarch”"
- "COMMUNITYUPDATE_10_A" "Nulla è come sembra nella Frontiera: preparati a entrare nel nuovo pack DLC gratuito per Titanfall 2: Un Glitch nella Frontiera, che contiene la nuova mappa “Glitch”. Ispirato dal pianeta Harmony del capitano Lastimosa, l’ambiente è dominato da cadute verticali e lunghi percorsi tortuosi, perfetti per concatenare lunghe corse sui muri, per poi planare in tutta la mappa. È inoltre inclusa una nuova mappa Live Fire: Ponte, che vanta spazi interni ristretti, cortili esposti e droni vigili che volteggiano sulla testa. Se dovessi sentirti sopraffatto, non preoccuparti: i M.R.V.N., sempre pronti a darti una mano robotica, si uniscono al gioco come una fazione completamente nuova. Infine, è possibile sbloccare l’esecuzione Lama a impulsi, perché possa essere utilizzata tutte le volte che desideri “far arrivare il messaggio”.\n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_10_Q" "Trailer gameplay “Un Glitch nella Frontiera”"
- "COMMUNITYUPDATE_11_A" "Torna una delle mappe multigiocatore più apprezzate del Titanfall originale: Colonia. Con tutte le nuove tattiche e i nuovi Titan di Titanfall 2, Piloti e Titan dovranno rimanere sempre all’erta per sopravvivere in questo villaggio idilliaco e molto popolato fatto di vicoli, angoli ciechi e tetti esposti; disponibile gratuitamente il 30 marzo per tutti i giocatori. Il pack DLC “Colonia Rinata” comprende il ritorno di armi classiche come il fucile d’assalto R-101 modificato, una nuova esecuzione rampino e nuove opzioni estetiche da acquistare per apparire sempre al meglio mentre dipingi di rosso la città.\n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_11_Q" "Trailer gameplay \"Colonia Rinata\""
- "COMMUNITYUPDATE_12_A" "Presentazione di Live Fire: una modalità ultra-rapida 6v6 per piloti che pone in prima linea il combattimento a distanza ravvicinata. Sono incluse due nuove mappe progettate specificamente per Live Fire: Cataste e Prateria. Queste due mappe gratuite sono aree di gioco strette e mortali progettate specificamente per la natura intensa e rapida di questa nuova modalità.\n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_12_Q" "Trailer gameplay “Benvenuti in Live Fire”"
- "COMMUNITYUPDATE_13_A" "Prova una versione rivisitata di una della mappe preferite del Titanfall originale, `1Angel City`0. Tieniti pronto per il primo DLC gratuito per Titanfall 2 con `1Ricercato di Angel City`0 disponibile il 1 dicembre. Questo contenuto comprende nuove opzioni estetiche per aggiungere un po’ di eleganza alla Frontiera. \n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_13_Q" "Trailer gameplay “Benvenuti in Angel City”"
- "COMMUNITYUPDATE_14_A" "Bentornato.\n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_14_Q" "Trailer \"Encore\""
- "COMMUNITYUPDATE_15_A" "Due leggende, una sola eredità.\n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_15_Q" "Trailer “Diventate una cosa sola”"
- "COMMUNITYUPDATE_16_A" "Senza limiti.\n\n\nPremi `2%[A_BUTTON|MOUSE1]%`0 per visualizzare."
- "COMMUNITYUPDATE_16_Q" "Trailer multigiocatore “Piloti”"
- "COMMUNITYUPDATE_DESC" "`3Aggiornamenti community Titanfall`0\n\nInfo e collegamenti da tutto il Web.\n\nPer altre informazioni:\n`2%$rui/bullet_point%`0Seguici su Twitter `1@Respawn`0\n`2%$rui/bullet_point%`0Metti un like su `1facebook.com/RespawnEntertainment`0\n`2%$rui/bullet_point%`0Unisciti a noi visitando l’indirizzo `1www.respawn.com`0"
- "COMMUNITYUPDATE_NAME" "Community"
- "KNB_SUBJECT_00_DESC" "`3Quali sono le novità di Titanfall?`0\n\nQui potrai vedere tutte le novità in Titanfall 2!"
- "KNB_SUBJECT_00_NAME" "Aggiornamenti"
- "KNB_SUBJECT_00_SUB_00_A" "`2%$rui/bullet_point%`010 Nuovi banner distintivo creati dalla community\n\n`2%$rui/bullet_point%`0Tutti i regali del difensore sono ora acquistabili con crediti\n\n`2%$rui/bullet_point%`0Nuovo contenuto negozio acquistabile\n\n"
- "KNB_SUBJECT_00_SUB_00_Q" "%$rui/hud/scoreboard/status_titan% 28 novembre - Momento della raccolta"
- "KNB_SUBJECT_00_SUB_01_A" "`2%$rui/bullet_point%`0Slot primario pistola\n\n`2%$rui/bullet_point%`0Banner Halloween\n\n`2%$rui/bullet_point%`0Modifiche al bilanciamento\n\n`2%$rui/bullet_point%`0Nuovi contenuti del negozio acquistabili\n\n"
- "KNB_SUBJECT_00_SUB_01_Q" "%$rui/hud/scoreboard/status_titan% 31 ottobre - Dolcetti e scherzetti"
- "KNB_SUBJECT_00_SUB_02_A" "`2%$rui/bullet_point%`0Difesa Frontiera - Supporto per tre mappe aggiuntive - Bacino di carenaggio, Angel City ed Esopianeta.\n\n`2%$rui/bullet_point%`0Nuova mappa Live Fire - UMA\n\n`2%$rui/bullet_point%`0Nuova esecuzione pilota - Buco nel muro\n\n`2%$rui/bullet_point%`0Nuovo contenuto acquistabile nello store"
- "KNB_SUBJECT_00_SUB_02_Q" "%$rui/hud/scoreboard/status_titan% 29 agosto - Cartoline dalla frontiera"
- "KNB_SUBJECT_00_SUB_03_A" "`2%$rui/bullet_point%`0Difesa Frontiera: una nuova modalità cooperativa in cui unisci le forze con un massimo di altri tre giocatori per difendere un obiettivo vitale da ondate sempre più intense di combattenti IA. La comunicazione e l'adattamento sono la chiave per la sopravvivenza.\n\n`2%$rui/bullet_point%`0Nuova mappa: Ascesa\n\n`2%$rui/bullet_point%`0Nuova mappa Live Fire: Cittadina\n\n`2%$rui/bullet_point%`0Nuovo contenuto acquistabile nel negozio"
- "KNB_SUBJECT_00_SUB_03_Q" "%$rui/hud/scoreboard/status_titan% 25 luglio - Operazione Scudo Frontiera "
- "KNB_SUBJECT_00_SUB_04_A" "`2%$rui/bullet_point%`0Nuova mappa - Giochi di guerra\n\n`2%$rui/bullet_point%`0Nuova mappa Live Fire - Traffico\n\n`2%$rui/bullet_point%`0Nuova esecuzione pilota - Scatola ombra\n\n`2%$rui/bullet_point%`03° slot arma\n\n`2%$rui/bullet_point%`0Impostazioni partita privata"
- "KNB_SUBJECT_00_SUB_04_Q" "%$rui/hud/scoreboard/status_titan% 27 giugno - Giochi di guerra"
- "KNB_SUBJECT_00_SUB_05_A" "`2%$rui/bullet_point%`0Nuovo Titan - Monarch\n\n`2%$rui/bullet_point%`0Nuova mappa - Relitto\n\n`2%$rui/bullet_point%`0Nuova esecuzione pilota - Ora mi vedi\n\n`2%$rui/bullet_point%`0Nuovo contenuto acquistabile nello store"
- "KNB_SUBJECT_00_SUB_05_Q" "%$rui/hud/scoreboard/status_titan% 30 maggio - Regno di Monarch"
- "KNB_SUBJECT_00_SUB_06_A" "`2%$rui/bullet_point%`0Nuova mappa - Glitch\n\n`2%$rui/bullet_point%`0Nuova mappa Live Fire - Ponte\n\n`2%$rui/bullet_point%`0Nuova fazione - M.R.V.N.\n\n`2%$rui/bullet_point%`0Nuova esecuzione pilota - Arriva al punto\n\n`2%$rui/bullet_point%`0Generazione max portata a 100"
- "KNB_SUBJECT_00_SUB_06_Q" "%$rui/hud/scoreboard/status_titan% 25 aprile - Glitch nella Frontiera"
- "KNB_SUBJECT_00_SUB_07_A" "`2%$rui/bullet_point%`0Nuova mappa - Colonia\n\n`2%$rui/bullet_point%`0Nuova esecuzione pilota - Spaccatesta\n\n`2%$rui/bullet_point%`0Nuova arma - R-101\n\n`2%$rui/bullet_point%`0Nuovo contenuto acquistabile nello store"
- "KNB_SUBJECT_00_SUB_07_Q" "%$rui/hud/scoreboard/status_titan% 30 marzo - Colonia Rinata"
- "KNB_SUBJECT_00_SUB_08_A" "`2%$rui/bullet_point%`0Live Fire - Una nuova modalità di gioco a eliminazione Pilota contro Pilota! 6v6 basata su round senza rientri, avrai un minuto per eliminare la squadra rivale per vincere il round. Puoi vincere il round anche se la tua squadra è in possesso della bandiera neutra allo scadere del tempo. Vince la partita la squadra che si aggiudica per prima 5 round.\n\n`2%$rui/bullet_point%`0Nuova mappa Live Fire - Prateria\n\n`2%$rui/bullet_point%`0Nuova mappa Live Fire - Cataste\n\n`2%$rui/bullet_point%`0Nuova esecuzione pilota - Colpo ritardato"
- "KNB_SUBJECT_00_SUB_08_Q" "%$rui/hud/scoreboard/status_titan% 23 febbraio - Live Fire"
- "KNB_SUBJECT_00_SUB_09_A" "`2%$rui/bullet_point%`0Nuova mappa - Angel City\n\n`2%$rui/bullet_point%`0Nuova arma - B3 Wingman Elite\n\n`2%$rui/bullet_point%`0Nuova esecuzione pilota - Dal di dentro\n\n`2%$rui/bullet_point%`0Nuovi kit Titan\n\n`2%$rui/bullet_point%`0Nuovo contenuto acquistabile nello store"
- "KNB_SUBJECT_00_SUB_09_Q" "%$rui/hud/scoreboard/status_titan% 30 novembre - Ricercato di Angel City"
- "MP_ANGEL_CITY_FD_WAVE_1" "Incatenato al cielo"
- "MP_ANGEL_CITY_FD_WAVE_2" "Informe"
- "MP_ANGEL_CITY_FD_WAVE_3" "Insurrezione"
- "MP_ANGEL_CITY_FD_WAVE_4" "Un gruppo testardo"
- "MP_ANGEL_CITY_FD_WAVE_5" "Sfida la sorte"
- "MP_DRYDOCK_FD_WAVE_1" "Nuotare in acque straniere"
- "MP_DRYDOCK_FD_WAVE_2" "Non hanno proiettili!"
- "MP_DRYDOCK_FD_WAVE_3" "Accecato dalla scienza"
- "MP_DRYDOCK_FD_WAVE_4" "Sistema ad alta pressione"
- "MP_DRYDOCK_FD_WAVE_5" "Occhio del ciclone"
- "MP_THAW_FD_WAVE_1" "Percezione della situazione"
- "MP_THAW_FD_WAVE_2" "La forza è nei numeri"
- "MP_THAW_FD_WAVE_3" "Scagnozzo 21"
- "MP_THAW_FD_WAVE_4" "Divertimento nel fuoco"
- "MP_THAW_FD_WAVE_5" "Rendere onore alle pistole"
- "NO_PRICE" "Offerta scaduta"
- "NO_PRICE_TWO_LINES" "Offerta\nscaduta"
- "PL_aegis_last_titan_standing" "Aegis ST"
- "PL_aegis_last_titan_standing_abbr" "AST"
- "PL_aegis_last_titan_standing_desc" "Aggiornamenti Aegis abilitati. Scontro organizzato in round a eliminazione. La vittoria va a chi vince per primo 3 round.\n^FFC83200Giocatori: 5v5 *Inizia come Titan\nTempo limite: 3 m per round *Nessun rientro\nDimensioni max gruppo: 5"
- "PL_aegis_last_titan_standing_lobby" "PL_aegis_last_titan_standing_lobby"
- "PL_aegis_titan_brawl" "Scontro tra Titan Aegis"
- "PL_aegis_titan_brawl_abbr" "ATTDM"
- "PL_aegis_titan_brawl_desc" "Uccidi Titan nemici. Aggiornamenti Aegis abilitati.\n^FFC83200Giocatori: 5v5\nTempo limite: 10m\nDimensioni max gruppo: 5"
- "PL_aegis_titan_brawl_hint" "Uccidi i Titan nemici.\nNessuna espulsione"
- "PL_aegis_titan_brawl_lobby" "Lobby scontro tra Titan Aegis"
- "PL_aitdm" "Logoramento"
- "PL_aitdm_abbr" "LOG"
- "PL_aitdm_desc" "Uccidi tutti i nemici.\n^FFC83200Giocatori: 6v6 *IA\nTempo limite: 10 min.\nDimensioni max gruppo: 6"
- "PL_aitdm_lobby" "Lobby Logoramento"
- "PL_all_grapple" "Attacco in Titanfall"
- "PL_all_grapple_abbr" "ATT"
- "PL_all_grapple_desc" "Regole di logoramento classiche, ad eccezione del fatto che tutte le abilità tattiche sono sostituite con Rampino.\n^FFC83200Giocatori: 6v6 *AI\nTempo limite: 10 m\nDimensioni max gruppo: 6"
- "PL_all_grapple_lobby" "Attacco alla Lobby Titanfall"
- "PL_all_holopilot" "Il grande inganno"
- "PL_all_holopilot_abbr" "LF"
- "PL_all_holopilot_desc" "Regole di Live Fire classiche, ad eccezione del fatto che tutte le abilità tattiche sono sostituite con Pilota olografico.^FFC83200\nGiocatori: 6v6 *No Titan\nTempo limite: 60 s *Nessun rientro\nDimensioni max gruppo: 6"
- "PL_all_holopilot_lobby" "Loggy Il grande inganno"
- "PL_all_phase" "L’Altra Parte"
- "PL_all_phase_abbr" "ATT"
- "PL_all_phase_desc" "Regole di logoramento classiche, ad eccezione del fatto che tutte le abilità tattiche sono sostituite con Fasico.\n^FFC83200Giocatori: 6v6 *AI\nTempo limite: 10 m\nDimensioni max gruppo: 6"
- "PL_all_phase_lobby" "Lobby L’Altra Parte"
- "PL_all_spicy" "Logoramento speziato"
- "PL_all_spicy_abbr" "ATT"
- "PL_all_spicy_desc" "Regole di logoramento classiche, ad eccezione del fatto che tutte le abilità tattiche sono sostituite con Tick.\n^FFC83200Giocatori: 6v6 *AI\nTempo limite: 10 m\nDimensioni max gruppo: 6"
- "PL_all_spicy_lobby" "Lobby Logoramento speziato"
- "PL_amped_tacticals" "Tattiche amplificate"
- "PL_amped_tacticals_abbr" "ATT"
- "PL_amped_tacticals_desc" "Regole di logoramento classiche, ad eccezione del fatto che le abilità tattiche sono più potenti.\n^FFC83200Giocatori: 6v6 *AI\nTempo limite: 10 m\nDimensioni max gruppo: 6"
- "PL_amped_tacticals_lobby" "Lobby Tattiche amplificate"
- "PL_ANGEL_CITY" "Angel City 24/7"
- "PL_angel_city_abbr" "AC"
- "PL_angel_city_desc" "Sempre e solo Angel City.\n^FFC83200*Caccia alle taglie *Logoramento\n*PCA"
- "PL_angel_city_lobby" "Lobby Angel City 24/7"
- "PL_at_coop" "Fuga (Co-op)"
- "PL_at_coop_desc" "Sei appena evaso di prigione e hai con te solo una pistola. Sopravvivi fino all'arrivo di una nave da evacuazione. Uccidi i nemici per guadagnare denaro e acquistare armi. \n^FFC83200Giocatori: 6\nDimensioni max gruppo: 6"
- "PL_at_coop_lobby" "Lobby Escape"
- "PL_attrition" "Caccia alle taglie"
- "PL_attrition_abbr" "CT"
- "PL_attrition_desc" "Uccidi i nemici per guadagnare soldi. Ottienine di più depositando i bonus nei luoghi designati.\n^FFC83200Giocatori: 5v5 *IA\nTempo limite: 10 min.\nDimensioni max gruppo: 5"
- "PL_attrition_lobby" "Lobby Caccia alle taglie"
- "PL_capture_the_flag" "Cattura bandiera"
- "PL_capture_the_flag_abbr" "CLB"
- "PL_capture_the_flag_desc" "Ruba la bandiera nemica e riportala alla tua base mentre impedisci alla squadra avversaria di prendere la tua!\n^FFC83200Giocatori: 5v5\nTempo limite: 12 min.\nDimensioni max gruppo: 5"
- "PL_capture_the_flag_lobby" "Lobby CB"
- "PL_coliseum" "Colosseo"
- "PL_coliseum_desc" "Uno-contro-uno in gabbia con mobilità incrementata. Vince il round chi uccide l'avversario. Chi si aggiudica 3 round su 5 vince un regalo del difensore.^FFC83200\nGiocatori: 1v1 *Niente Titan\nTempo limite: 3 min. *Nessun rientro\n**^FFFFFF00RICHIEDE BIGLIETTO COLOSSEO o PAGAMENTO DEL COSTO D'INGRESSO"
- "PL_coliseum_lobby" "Lobby Colosseo"
- "PL_colony" "Colonia 24/7"
- "PL_colony_abbr" "COL"
- "PL_colony_desc" "Sempre e soltanto Colonia. ^CCCCCC00Questa operazione effettuerà ricerche di corrispondenze di ^FFC83200Logoramento^CCCCCC00, ^FFC83200Piloti contro piloti^CCCCCC00 e ^FFC83200Sopravvivenza Titan^CCCCCC00."
- "PL_colony_lobby" "Lobby Colonia 24/7"
- "PL_ctf_lf" "CB (Nitro)"
- "PL_ctf_lf_abbr" "CB-N"
- "PL_ctf_lf_desc" "Un frenetico Cattura bandiera in mappe selezionate.\n^FFC83200Giocatori: 5v5\nDimensioni max gruppo: 5\n^F4D5A600Torna Bandiera istantanea"
- "PL_ctf_lf_lobby" "Lobby Nitro CB"
- "PL_default_description" "Descrizione predefinita"
- "PL_default_lobbytitle" "Titolo lobby predefinito"
- "PL_default_name" "Nome predefinito"
- "PL_don" "Lascia o raddoppia"
- "PL_fd" "Difesa Frontiera"
- "PL_fd_desc" "Difenditi contro le ondate delle forze della flotta Remnant"
- "PL_fd_easy" "Difesa Frontiera: facile"
- "PL_fd_easy_desc" "Sconfiggi l’opposizione"
- "PL_fd_easy_lobby" "Difesa Frontiera: Lobby facile"
- "PL_fd_hard" "Difesa Frontiera: difficile"
- "PL_fd_hard_desc" "Sono necessarie buone abilità di gioco"
- "PL_fd_hard_lobby" "Difesa Frontiera: Lobby difficile"
- "PL_fd_insane" "Difesa Frontiera: folle"
- "PL_fd_insane_desc" "Non sopravviverai"
- "PL_fd_insane_lobby" "Difesa Frontiera: Lobby folle"
- "PL_fd_lobby" "Lobby Difesa Frontiera"
- "PL_fd_master" "Difesa Frontiera: maestro"
- "PL_fd_master_desc" "Solo i migliori dei migliori sopravviveranno"
- "PL_fd_master_lobby" "Difesa Frontiera: Lobby maestro"
- "PL_fd_normal" "Difesa Frontiera: normale"
- "PL_fd_normal_desc" "Consigliato per giocatori esperti"
- "PL_fd_normal_lobby" "Difesa Frontiera: lobby normale"
- "PL_ffa" "Tutti contro tutti"
- "PL_ffa_abbr" "TCT"
- "PL_ffa_desc" "Ogni pilota è solo. Uccidi tutti i nemici.\n^FFC83200Giocatori: 1v11\nTempo limite: 10 min.\nDimensioni max gruppo: 1"
- "PL_ffa_lobby" "Lobby Tutti contro tutti"
- "PL_fra" "Azione libera"
- "PL_fra_abbr" "AL"
- "PL_fra_desc" "Ogni pilota lotta per sé. Uccidi i nemici per vincere. Taccogli 3 batterie per un Titanfall.\n^FFC83200Giocatori: 1v11\nLimite di tempo: 15m\nDimensioni max gruppo: 1"
- "PL_fra_lobby" "Lobby Azione libera"
- "PL_groud_war_lobby" "Lobby Remix 8v8"
- "PL_ground_war" "Remix 8v8"
- "PL_ground_war_abbr" "8v8"
- "PL_ground_war_desc" "Include Scontro e Punto di controllo amplificato, con elevato numero di giocatori su tutte le mappe.\n^FFC83200Giocatori: 8v8"
- "PL_hardpoint" "PCA"
- "PL_hardpoint_abbr" "PCA"
- "PL_hardpoint_desc" "Cattura e mantieni un punto di controllo per ottenere punti. I punti di controllo amplificati danno punti doppi.\n^FFC83200Giocatori: 6v6\nTempo limite: 10 min.\nDimensioni max gruppo: 6"
- "PL_hardpoint_lobby" "Lobby PCA"
- "PL_hunted" "Preda"
- "PL_iron_last_titan_standing" "ST d'acciaio"
- "PL_iron_last_titan_standing_abbr" "STA"
- "PL_iron_last_titan_standing_desc" "Solo Titan, scontro organizzato in round a eliminazione. La vittoria va a chi vince per primo 3 round.\n^FFC83200Giocatori: 5v5 *NO PILOTI\nTempo limite: 3 min per round *Nessun rientro\nDimensioni max gruppo: 5"
- "PL_iron_last_titan_standing_lobby" "PL_iron_last_titan_standing_lobby"
- "PL_last_titan_standing" "Sopravvivenza Titan"
- "PL_last_titan_standing_abbr" "ST"
- "PL_last_titan_standing_desc" "Tutti i giocatori iniziano a bordo dei Titan in questo scontro organizzato in round a eliminazione. La vittoria va a chi vince per primo 3 round.\n^FFC83200Giocatori: 5v5 *Inizi come Titan\nTempo limite: 3 min. per round *Nessun rientro\nDimensioni max gruppo: 5"
- "PL_last_titan_standing_lobby" "Lobby ST"
- "PL_limited_time_mode" "A tempo limitato"
- "PL_live_fire" "Live Fire"
- "PL_live_fire_abbr" "LF"
- "PL_live_fire_desc" "Combattimento rapido in un'arena Live Fire. Vinci il round uccidendo tutti i piloti nemici oppure tenendo la bandiera allo scadere del tempo.^FFC83200\nGiocatori: 6v6 *Niente Titan\nTempo limite: 60 s *Nessun rientro\nDimensioni max gruppo: 6"
- "PL_live_fire_lobby" "Lobby Live Fire"
- "PL_load_a_map_on_the_command_line" "Carica una mappa dalla linea di comando -solo sviluppatori"
- "PL_marked_for_death" "Marchiato a morte"
- "PL_marked_for_death_abbr" "MAM"
- "PL_marked_for_death_desc" "Uccidi o proteggi i bersagli marchiati.\n^FFC83200Giocatori: 6v6 \nTempo limite: 12 m\nDimensioni max gruppo: 6"
- "PL_marked_for_death_lobby" "Lobby Marchiato a morte"
- "PL_nitro_ffa" "FFA (Nitro)"
- "PL_nitro_ffa_abbr" "FFA-N"
- "PL_nitro_ffa_desc" "Un frenetico Tutti contro tutti su mappe selezionate.\n^FFC83200Giocatori: 6\n^F4D5A600No Titan\nNo potenziamenti"
- "PL_nitro_ffa_lobby" "Lobby Nitro FFA"
- "PL_nitro_mixtape" "Remix (Nitro)"
- "PL_nitro_mixtape_abbr" "MXT-N"
- "PL_nitro_mixtape_desc" "Un frenetico CB, MFD e PvP in mappe selezionate.\n^FFC83200Giocatori: 5v5\nDimensioni max gruppo: 5\n^F4D5A600Torna Bandiera istantanea"
- "PL_nitro_mixtape_lobby" "Lobby Remix"
- "PL_pilot_hunter" "Scontro"
- "PL_pilot_hunter_abbr" "SCN"
- "PL_pilot_hunter_desc" "Uccidi piloti e Titan nemici. \n^FFC83200Giocatori: 8v8\nTempo limite: 10 min.\nDimensioni max gruppo: 8"
- "PL_pilot_hunter_lobby" "Lobby Scontro"
- "PL_pilot_skirmish" "Piloti contro piloti"
- "PL_pilot_skirmish_abbr" "PvP"
- "PL_pilot_skirmish_desc" "Uccidi i piloti nemici. Titanfall non consentiti.\n^FFC83200Giocatori: 8v8 *Nessun Titan\nTempo limite: 10 min.\nDimensioni max gruppo: 8"
- "PL_pilot_skirmish_lobby" "Lobby PvP"
- "PL_pl_rebuild_all_paths" "Ricostruisci tutti i percorsi"
- "PL_pl_run_with_ai_ainrebuildonmapstart_2" "Esegui con ai_ainRebuildOnMapStart 2"
- "PL_private_match" "Partita privata Beta"
- "PL_private_match_desc" "Gioca una partita privata personalizzata in una mappa e modalità a scelta.\n^FFC83200INVITA NETWORK o INVITA AMICI per giocare\n^FFC83200Giocatori: 1-16\nNessun progresso"
- "PL_private_match_lobby" "Lobby Partita privata Beta"
- "PL_promo_coop" "CO-OP per 4 giocatori"
- "PL_raid" "Raid"
- "PL_rise" "Ascesa 24/7"
- "PL_rise_abbr" "ASC"
- "PL_rise_desc" "Sempre e soltanto Ascesa. ^CCCCCC00Questa operazione effettuerà una ricerca per corrispondenze di ^FFC83200Cattura Bandiera^CCCCCC00, ^FFC83200Punto di controllo amplificato^CCCCCC00, ^FFC83200Piloti contro piloti^CCCCCC00, ^FFC83200Live Fire^CCCCCC00 e ^FFC83200Sopravvivenza Titan^CCCCCC00."
- "PL_rise_lobby" "Lobby Ascesa 24/7"
- "PL_rocket_arena" "Arena razzi"
- "PL_rocket_arena_abbr" "LF"
- "PL_rocket_arena_desc" "Regole di Live Fire classiche con EPG modificati.^FFC83200\nGiocatori: 6v6 *No Titan\nTempo limite: 90 s *Nessun rientro\nDimensioni max gruppo: 6"
- "PL_rocket_arena_lobby" "Lobby Arena razzi"
- "PL_settings_for_when_someone_loads_a_map_on_the_command_line_do_not_edit_the_cmdlinemapload_1_below_-_this_makes_this_work" "Impostazioni per il caricamento di una mappa dalla linea di comando. Non modificare il comando sottostante cmdlineMapLoad 1 perché è essenziale per il funzionamento."
- "PL_speedball" "Live Fire"
- "PL_speedball_desc" "Combatti per il possesso di una bandiera neutrale. Elimina la squadra nemica o possiedi la bandiera allo scadere del tempo per vincere il round. Vince il primo ad aggiudicarsi 5 round.\n^FFC83200Giocatori: 6v6 *Niente Titan\nTempo limite: 60 secondi per round *Nessun rientro\nDimensioni max gruppo: 6"
- "PL_speedball_lobby" "Lobby Live Fire"
- "PL_tactikill" "Logoramento Uccisione tattica"
- "PL_tactikill_abbr" "ATT"
- "PL_tactikill_desc" "Regole di logoramento classiche, ad eccezione del fatto che le abilità tattiche sono ripristinate completamente al momento dell’uccisione.\n^FFC83200Giocatori: 6v6 *AI\nTempo limite: 10 m\nDimensioni max gruppo: 6"
- "PL_tactikill_lobby" "Lobby Logoramento Uccisione tattica"
- "PL_titan_brawl" "Scontro tra Titan"
- "PL_titan_brawl_abbr" "STT"
- "PL_titan_brawl_desc" "Uccidi i Titan nemici. Piloti non consentiti.\n^FFC83200Giocatori: 5v5\nTempo limite: 10m\nDimensioni max gruppo: 5"
- "PL_titan_brawl_hint" "Uccidi i Titan nemici.\nNessuna espulsione"
- "PL_titan_brawl_lobby" "Lobby Scontro tra Titan"
- "PL_titan_brawl_turbo" "Scontro tra Titan Turbo"
- "PL_titan_brawl_turbo_abbr" "TTDM"
- "PL_titan_brawl_turbo_desc" "Regole di Scontro tra Titan classiche con rigenerazione Scatto e generazione Nucleo più rapide.\n^FFC83200Giocatori: 5v5\nTempo limite: 10 m\nDimensioni max gruppo: 5"
- "PL_titan_brawl_turbo_hint" "Uccidi i Titan nemici.\nNessuna espulsione"
- "PL_titan_brawl_turbo_lobby" "Lobby Scontro tra Titan Turbo"
- "PL_turbo_last_titan_standing" "Turbo ST"
- "PL_turbo_last_titan_standing_abbr" "ST"
- "PL_turbo_last_titan_standing_desc" "Regole ST classiche con rigenerazione Scatto e generazione Nucleo più rapide.\n^FFC83200Giocatori: 5v5 *Inizia come Titan\nTempo limite: 3 m per round *Nessun rientro\nDimensioni max gruppo: 5"
- "PL_turbo_last_titan_standing_lobby" "Lobby ST Turbo"
- "PL_variety_pack" "Remix"
- "PL_variety_pack_desc" "Un numero di giocatori variabile e varie mappe in queste modalità:\n^FFC83200*Caccia alle taglie *Logoramento\n*Sopravvivenza Titan *Punto di controllo amplificato\n*Piloti contro piloti *Cattura bandiera"
- "PL_variety_pack_lobby" "Lobby Remix"
- "PL_wargames" "Giochi di guerra 24/7"
- "PL_wargames_abbr" "GDG"
- "PL_wargames_desc" "Sempre e soltanto Giochi di guerra. ^CCCCCC00Questa operazione effettuerà ricerche di corrispondenze di ^FFC83200Logoramento^CCCCCC00, ^FFC83200Cattura Bandiera^CCCCCC00, ^FFC83200Piloti contro piloti^CCCCCC00, ^FFC83200Punto di controllo amplificato^CCCCCC00 e ^FFC83200Sopravvivenza Titan^CCCCCC00."
- "PL_wargames_lobby" "Lobby Giochi di guerra 24/7"
- "WATCH_TUTORIAL" "GUARDA IL TUTORIAL"
- }
- }
- "lang"
- {
- "Language" "english"
- "Tokens"
- {
- "NO_PRICE" "Offer Expired"
- "NO_PRICE_TWO_LINES" "Offer\nExpired"
- "WATCH_TUTORIAL" "WATCH TUTORIAL"
- "PL_promo_coop" "4 Player CO-OP"
- "PL_limited_time_mode" "Limited Time Mode"
- "PL_speedball" "Live Fire"
- "PL_speedball_lobby" "Live Fire Lobby"
- "PL_speedball_desc" "Fight for possession of a netural flag. Eliminate the enemy team or possess the flag when the clock runs out to win the round. Winner is the first to 5 rounds won.\n^FFC83200Players: 6v6 *No Titans\nTime Limit: 60 seconds per round *No Respawns\nMax Party Size: 6"
- "PL_raid" "Raid"
- "PL_hunted" "Hunted"
- "PL_don" "Double or Nothing"
- "PL_fd" "Frontier Defense"
- "PL_fd_lobby" "Frontier Defense Lobby"
- "PL_fd_desc" "Defend against waves of Remnant Fleet forces"
- "PL_fd_easy" "Frontier Defense: Easy"
- "PL_fd_easy_lobby" "Frontier Defense: Easy Lobby"
- "PL_fd_easy_desc" "Crush the opposition"
- "PL_fd_normal" "Frontier Defense: Regular"
- "PL_fd_normal_lobby" "Frontier Defense: Regular Lobby"
- "PL_fd_normal_desc" "Recommended for experienced players"
- "PL_fd_hard" "Frontier Defense: Hard"
- "PL_fd_hard_lobby" "Frontier Defense: Hard Lobby"
- "PL_fd_hard_desc" "Skilled play is required"
- "PL_fd_master" "Frontier Defense: Master"
- "PL_fd_master_lobby" "Frontier Defense: Master Lobby"
- "PL_fd_master_desc" "Only the best of the best will succeed"
- "PL_fd_insane" "Frontier Defense: Insane"
- "PL_fd_insane_lobby" "Frontier Defense: Insane Lobby"
- "PL_fd_insane_desc" "You will not survive"
- "PL_angel_city" "Angel City 24/7"
- "PL_angel_city_lobby" "Angel City 24/7 Lobby"
- "PL_angel_city_desc" "All Angel City, all the time.\n^FFC83200*Bounty Hunt *Attrition\n*Amped Hardpoint"
- "PL_angel_city_abbr" "AC"
- "PL_colony" "Colony 24/7"
- "PL_colony_lobby" "Colony 24/7 Lobby"
- "PL_colony_desc" "All Colony, all the time. ^CCCCCC00This will search for matches of ^FFC83200Attrition^CCCCCC00, ^FFC83200Pilots vs Pilots^CCCCCC00, and ^FFC83200Last Titan Standing^CCCCCC00."
- "PL_colony_abbr" "COL"
- "PL_rise" "Rise 24/7"
- "PL_rise_lobby" "Rise 24/7 Lobby"
- "PL_rise_desc" "All Rise, all the time. ^CCCCCC00This will search for matches of ^FFC83200CTF^CCCCCC00, ^FFC83200Amped Hardpoint^CCCCCC00, ^FFC83200Pilots vs Pilots^CCCCCC00, ^FFC83200Live Fire^CCCCCC00, and ^FFC83200Last Titan Standing^CCCCCC00."
- "PL_rise_abbr" "RIS"
- "PL_wargames" "Wargames 24/7"
- "PL_wargames_lobby" "Wargames 24/7 Lobby"
- "PL_wargames_desc" "All Wargames, all the time. ^CCCCCC00This will search for matches of ^FFC83200Attrition^CCCCCC00, ^FFC83200CTF^CCCCCC00, ^FFC83200Pilots vs Pilots^CCCCCC00, ^FFC83200Amped Hardpoint^CCCCCC00, and ^FFC83200Last Titan Standing^CCCCCC00."
- "PL_wargames_abbr" "WGM"
- "PL_ctf_lf" "CTF (Nitro)"
- "PL_ctf_lf_lobby" "CTF Nitro Lobby"
- "PL_ctf_lf_desc" "Fast paced Capture the Flag in selected maps.\n^FFC83200Players: 5v5\nMax Party Size: 5\n^F4D5A600Instant Flag Returns // No Titans\nNo Boosts // Phase Shift Drops Flag"
- "PL_ctf_lf_abbr" "CTF-N"
-
- "PL_nitro_mixtape" "Mixtape (Nitro)"
- "PL_nitro_mixtape_lobby" "Mixtape Lobby"
- "PL_nitro_mixtape_desc" "Fast paced CTF, MFD and PvP on selected maps.\n^FFC83200Players: 5v5\nMax Party Size: 5\n^F4D5A600Instant Flag Returns // No Titans\nNo Boosts // Phase Shift Drops Flag"
- "PL_nitro_mixtape_abbr" "MXT-N"
-
- "PL_nitro_ffa" "FFA (Nitro)"
- "PL_nitro_ffa_lobby" "FFA Nitro Lobby"
- "PL_nitro_ffa_desc" "Fast paced Free for All on selected maps.\n^FFC83200Players: 6\n^F4D5A600No Titans\nNo Boosts"
- "PL_nitro_ffa_abbr" "FFA-N"
-
- "PL_aitdm" "Attrition"
- "PL_aitdm_lobby" "Attrition Lobby"
- "PL_aitdm_desc" "Kill all enemies.\n^FFC83200Players: 6v6 *AI\nTime Limit: 10m\nMax Party Size: 6"
- "PL_aitdm_abbr" "ATT"
- "PL_attrition" "Bounty Hunt"
- "PL_attrition_lobby" "Bounty Hunt Lobby"
- "PL_attrition_desc" "Kill enemies to earn money. Earn more by 'banking' your bonus at designated locations.\n^FFC83200Players: 5v5 *AI\nTime Limit: 10m\nMax Party Size: 5"
- "PL_attrition_abbr" "BH"
- "PL_at_coop" "Escape (Co-op)"
- "PL_at_coop_lobby" "Escape Lobby"
- "PL_at_coop_desc" "You've just escaped prison with nothing more than a pistol. Survive until an evac can arrive. Kill enemies to earn money and buy weapons. \n^FFC83200Players: 6\nMax Party Size: 6"
- "PL_pilot_skirmish" "Pilots vs. Pilots"
- "PL_pilot_skirmish_lobby" "PvP Lobby"
- "PL_pilot_skirmish_desc" "Kill enemy pilots. Titanfalls not permitted.\n^FFC83200Players: 8v8 *No Titans\nTime Limit: 10m\nMax Party Size: 8"
- "PL_pilot_skirmish_abbr" "PvP"
- "PL_hardpoint" "Amped Hardpoint"
- "PL_hardpoint_lobby" "Amped Hardpoint Lobby"
- "PL_hardpoint_desc" "Capture and hold a hardpoint to earn points. Amped Hardpoints give double points.\n^FFC83200Players: 6v6\nTime Limit: 10m\nMax Party Size: 6"
- "PL_hardpoint_abbr" "AHP"
- "PL_capture_the_flag" "Capture the Flag"
- "PL_capture_the_flag_lobby" "CTF Lobby"
- "PL_capture_the_flag_desc" "Steal the enemy flag and return it to your base while stopping the enemy team from taking your flag!\n^FFC83200Players: 5v5\nTime Limit: 12m\nMax Party Size: 5"
- "PL_capture_the_flag_abbr" "CTF"
- "PL_last_titan_standing" "Last Titan Standing"
- "PL_last_titan_standing_lobby" "LTS Lobby"
- "PL_last_titan_standing_desc" "All players start in Titans in this round-based elimination match-up. Winner is the first to 3 rounds won.\n^FFC83200Players: 5v5 *Start as Titan\nTime Limit: 3m per round *No Respawns\nMax Party Size: 5"
- "PL_last_titan_standing_abbr" "LTS"
- "PL_iron_last_titan_standing" "Iron LTS"
- "PL_iron_last_titan_standing_lobby" ""
- "PL_iron_last_titan_standing_desc" "Titans-only, round-based elimination match-up. Winner is the first to 3 rounds won.\n^FFC83200Players: 5v5 *NO PILOTS\nTime Limit: 3m per round *No Respawns\nMax Party Size: 5"
- "PL_iron_last_titan_standing_abbr" "ILTS"
- "PL_aegis_last_titan_standing" "Aegis LTS"
- "PL_aegis_last_titan_standing_lobby" ""
- "PL_aegis_last_titan_standing_desc" "Aegis Upgrades enabled. Round-based elimination match-up. Winner is the first to 3 rounds won.\n^FFC83200Players: 5v5 *Start as Titan\nTime Limit: 3m per round *No Respawns\nMax Party Size: 5"
- "PL_aegis_last_titan_standing_abbr" "ALTS"
- "PL_pilot_hunter" "Skirmish"
- "PL_pilot_hunter_lobby" "Skirmish Lobby"
- "PL_pilot_hunter_desc" "Kill enemy pilots and Titans. \n^FFC83200Players: 8v8\nTime Limit: 10m\nMax Party Size: 8"
- "PL_pilot_hunter_abbr" "SKM"
- "PL_titan_brawl" "Titan Brawl"
- "PL_titan_brawl_lobby" "Titan Brawl Lobby"
- "PL_titan_brawl_desc" "Kill enemy Titans. Pilots not permitted.\n^FFC83200Players: 5v5\nTime Limit: 10m\nMax Party Size: 5"
- "PL_titan_brawl_abbr" "TTDM"
- "PL_titan_brawl_hint" "Kill enemy Titans.\nNo Ejection // No Disembark"
- "PL_aegis_titan_brawl" "Aegis Titan Brawl"
- "PL_aegis_titan_brawl_lobby" "Aegis Titan Brawl Lobby"
- "PL_aegis_titan_brawl_desc" "Kill enemy Titans. Aegis Upgrades enabled.\n^FFC83200Players: 5v5\nTime Limit: 10m\nMax Party Size: 5"
- "PL_aegis_titan_brawl_abbr" "ATTDM"
- "PL_aegis_titan_brawl_hint" "Kill enemy Titans.\nNo Ejection // No Disembark"
- "PL_variety_pack" "Mixtape"
- "PL_variety_pack_lobby" "Mixtape Lobby"
- "PL_variety_pack_desc" "Varying player counts and including a variety of maps on these modes:\n^FFC83200*Bounty Hunt *Attrition\n*Last Titan Standing *Amped Hardpoint\n*Pilots vs. Pilots *Capture the Flag"
- "PL_coliseum" "Coliseum"
- "PL_coliseum_lobby" "Coliseum Lobby"
- "PL_coliseum_desc" "One on one combat with enhanced mobility in a cage. Kill your opponent, win a round. Best 3 out of 5 wins an Advocate Gift reward.^FFC83200\nPlayers: 1v1 *No Titans\nTime Limit: 3m *No Respawns\n**^FFFFFF00REQUIRES COLISEUM TICKET or PAID ENTRY FEE"
- "PL_ground_war" "8v8 Mixtape"
- "PL_groud_war_lobby" "8v8 Mixtape Lobby"
- "PL_ground_war_desc" "Includes Skirmish and Amped Hardpoint, with high player counts on all maps.\n^FFC83200Players: 8v8"
- "PL_ground_war_abbr" "8v8"
- "PL_ffa" "Free for All"
- "PL_ffa_lobby" "Free for All Lobby"
- "PL_ffa_desc" "Every pilot for themself, kill all enemies.\n^FFC83200Players: 1v11\nTime Limit: 10m\nMax Party Size: 1"
- "PL_ffa_abbr" "FFA"
- "PL_fra" "Free Agents"
- "PL_fra_lobby" "Free Agents Lobby"
- "PL_fra_desc" "You're running solo. Kill enemies to win. Collect 3 batteries for a Titanfall.\n^FFC83200Players: 1v11\nTime Limit: 15m\nMax Party Size: 1"
- "PL_fra_abbr" "FRA"
- "PL_default_name" "Default name"
- "PL_default_lobbytitle" "Default lobbytitle"
- "PL_default_description" "Default description"
- "PL_load_a_map_on_the_command_line" "Load a map on the command line -devonly"
- "PL_settings_for_when_someone_loads_a_map_on_the_command_line_do_not_edit_the_cmdlinemapload_1_below_-_this_makes_this_work" "Settings for when someone loads a map on the command line. Do not edit the cmdlineMapLoad 1 below - this makes this work."
- "PL_pl_rebuild_all_paths" "Rebuild all paths"
- "PL_pl_run_with_ai_ainrebuildonmapstart_2" "Run with ai_ainRebuildOnMapStart 2"
- "PL_private_match" "Private Match Beta"
- "PL_private_match_lobby" "Private Match Beta Lobby"
- "PL_private_match_desc" "Play a custom, private match on a map and mode of your choice.\n^FFC83200INVITE NETWORK or INVITE FRIENDS to play\n^FFC83200Players: 1-16\nNo Progression"
-
- "PL_live_fire" "Live Fire"
- "PL_live_fire_lobby" "Live Fire Lobby"
- "PL_live_fire_desc" "Fast-paced combat in a Live Fire Arena. Win the round by killing all enemy pilots or possessing the flag when the timer runs out.^FFC83200\nPlayers: 6v6 *No Titans\nTime Limit: 60s *No Respawns\nMax Party Size: 6"
- "PL_live_fire_abbr" "LF"
-
- "PL_marked_for_death" "Marked For Death"
- "PL_marked_for_death_lobby" "Marked For Death Lobby"
- "PL_marked_for_death_desc" "Kill or protect the marked targets.\n^FFC83200Players: 6v6 \nTime Limit: 12m\nMax Party Size: 6"
- "PL_marked_for_death_abbr" "MFD"
-
- "PL_amped_tacticals" "Amped Tacticals"
- "PL_amped_tacticals_lobby" "Amped Tacticals Lobby"
- "PL_amped_tacticals_desc" "Classic Attrition rules except Tactical abilities are more powerful.\n^FFC83200Players: 6v6 *AI\nTime Limit: 10m\nMax Party Size: 6"
- "PL_amped_tacticals_abbr" "ATT"
-
- "PL_tactikill" "Tactikill Attrition"
- "PL_tactikill_lobby" "Tactikill Attrition Lobby"
- "PL_tactikill_desc" "Classic Attrition rules except Tactical abilities are fully reset upon kill.\n^FFC83200Players: 6v6 *AI\nTime Limit: 10m\nMax Party Size: 6"
- "PL_tactikill_abbr" "ATT"
-
- "PL_all_grapple" "Attack on Titanfall"
- "PL_all_grapple_lobby" "Attack on Titanfall Lobby"
- "PL_all_grapple_desc" "Classic Attrition rules except all Tactical abilities are replaced with Grapple.\n^FFC83200Players: 6v6 *AI\nTime Limit: 10m\nMax Party Size: 6"
- "PL_all_grapple_abbr" "ATT"
-
- "PL_all_holopilot" "The Great Bamboozle"
- "PL_all_holopilot_lobby" "The Great Bamboozle Lobby"
- "PL_all_holopilot_desc" "Classic Live Fire rules except all Tactical abilities are replaced with Holopilot.^FFC83200\nPlayers: 6v6 *No Titans\nTime Limit: 60s *No Respawns\nMax Party Size: 6"
- "PL_all_holopilot_abbr" "LF"
-
- "PL_all_phase" "The Otherside"
- "PL_all_phase_lobby" "The Otherside Lobby"
- "PL_all_phase_desc" "Classic Attrition rules except all Tactical abilities are replaced with Phase.\n^FFC83200Players: 6v6 *AI\nTime Limit: 10m\nMax Party Size: 6"
- "PL_all_phase_abbr" "ATT"
-
- "PL_rocket_arena" "Rocket Arena"
- "PL_rocket_arena_lobby" "Rocket Arena Lobby"
- "PL_rocket_arena_desc" "Classic Live Fire rules with modified EPGs.^FFC83200\nPlayers: 6v6 *No Titans\nTime Limit: 90s *No Respawns\nMax Party Size: 6"
- "PL_rocket_arena_abbr" "LF"
-
- "PL_turbo_last_titan_standing" "Turbo LTS"
- "PL_turbo_last_titan_standing_lobby" "Turbo LTS Lobby"
- "PL_turbo_last_titan_standing_desc" "Classic LTS rules with faster Dash regen and Core generation.\n^FFC83200Players: 5v5 *Start as Titan\nTime Limit: 3m per round *No Respawns\nMax Party Size: 5"
- "PL_turbo_last_titan_standing_abbr" "LTS"
-
- "PL_all_spicy" "Spicy Attrition"
- "PL_all_spicy_lobby" "Spicy Attrition Lobby"
- "PL_all_spicy_desc" "Classic Attrition rules except all Tactical abilities are replaced with Ticks.\n^FFC83200Players: 6v6 *AI\nTime Limit: 10m\nMax Party Size: 6"
- "PL_all_spicy_abbr" "ATT"
-
- "PL_titan_brawl_turbo" "Turbo Titan Brawl"
- "PL_titan_brawl_turbo_lobby" "Turbo Titan Brawl Lobby"
- "PL_titan_brawl_turbo_desc" "Classic Titan Brawl rules with faster Dash regen and Core generation.\n^FFC83200Players: 5v5\nTime Limit: 10m\nMax Party Size: 5"
- "PL_titan_brawl_turbo_abbr" "TTDM"
- "PL_titan_brawl_turbo_hint" "Kill enemy Titans.\nNo Ejection // No Disembark"
-
- "PL_sbox" "Sandbox"
- "PL_sbox_lobby" "Sandbox Lobby"
- "PL_sbox_desc" "like gmod but worse"
- "PL_sbox_abbr" "SBOX"
- "GAMEMODE_SBOX" "Sandbox"
-
- "PL_gg" "Gun Game"
- "PL_gg_lobby" "Gun Game Lobby"
- "PL_gg_desc" "Get a kill with each gun to win."
- "PL_gg_abbr" "GG"
- "GAMEMODE_GG" "Gun Game"
-
- "PL_tt" "Titan Tag"
- "PL_tt_lobby" "Titan Tag Lobby"
- "PL_tt_desc" "Earn points while in your titan. Destroy a titan to get your own."
- "PL_tt_abbr" "TT"
- "GAMEMODE_TT" "Titan Tag"
-
- "PL_inf" "Infection"
- "PL_inf_lobby" "Infection Lobby"
- "PL_inf_desc" "Survivors are infected when killed."
- "PL_inf_abbr" "INF"
- "GAMEMODE_INF" "Infection"
- "INFECTION_YOU_ARE_INFECTED" "You've been Infected!"
- "INFECTION_KILL_SURVIVORS" "Infect All Remaining Survivors."
- "INFECTION_FIRST_INFECTED" "%s1 is the First Infected."
- "INFECTION_LAST_SURVIVOR" "%s1 is the Last Survivor!"
- "INFECTION_KILL_LAST_SURVIVOR" "Infect them before time runs out!"
- "INFECTION_YOU_ARE_LAST_SURVIVOR" "You are the Last Survivor!"
- "INFECTION_SURVIVE_LAST_SURVIVOR" "Survive."
-
- // these are defined in r1_english but titan war is a shit name so i'm changing it to another one that was referenced in development
- "GAMEMODE_fw" "Frontier War"
- "PL_fw" "Frontier War"
- "PL_fw_lobby" "Frontier War Lobby"
- "PL_fw_desc" "Destroy the enemy's harvester and protect your own"
- "PL_fw_abbr" "FW"
-
- "GAMEMODE_kr" "Amped Killrace"
- "PL_kr" "Amped Killrace"
- "PL_kr_lobby" "Amped Killrace Lobby"
- "PL_kr_desc" "Get kills to increase the length of your killrace. Collect the flag to start it. Set the record to win"
- "PL_kr_abbr" "KR"
- "SCOREBOARD_KR_RECORD" "Kill Record"
- "KR_NEW_RACER" "%s1 is the amped killracer"
- "KR_YOU_ARE_NEW_RACER" "You are the amped killracer"
- "KR_YOU_SET_NEW_RECORD" "Set a New Kill Record!"
- "KR_FLAG_INCOMING" "Flag incoming"
- "KR_COLLECT_FLAG" "Collect it to become the Killracer!"
- "KR_ENEMY_KILLRACE_OVER" "%s1's killrace is over"
- "KR_YOUR_KILLRACE_OVER" "Your killrace is over"
- "KR_YOUR_KILLRACE_SCORE" "You got %s1 kills."
-
- "GAMEMODE_fastball" "Fastball"
- "PL_fastball" "Fastball"
- "PL_fastball_lobby" "Fastball Lobby"
- "PL_fastball_desc" "Permadeath. Hack control panels to win rounds and respawn your teammates."
- "PL_fastball_abbr" "FB"
- "FASTBALL_PANEL_CAPTURED" "%s1 captured panel %s2"
- "SCOREBOARD_FASTBALL_HACKS" "Panels Captured"
-
- "GAMEMODE_ctf_comp" "Competitive CTF"
-
- // FAQ - Community
- //
-
- "COMMUNITYUPDATE_NAME" "Community"
- "COMMUNITYUPDATE_DESC" "`3Titanfall Community Updates`0\n\nGet latest info and see stuff we think is rad from around the web.\n\nFor more:\n`2%$rui/bullet_point%`0Follow us on Twitter `1@Respawn`0\n`2%$rui/bullet_point%`0Like us on `1facebook.com/RespawnEntertainment`0\n`2%$rui/bullet_point%`0Join us at `1www.respawn.com`0"
-
- "COMMUNITYUPDATE_00_Q" "\"Postcards from the Frontier\" Trailer"
- "COMMUNITYUPDATE_00_A" "Your adventure across the stunning vistas of the Frontier continues with the latest DLC drop for Titanfall 2: Postcards From the Frontier. Featuring new and familiar locations along with a new collection of Elite Weapon Warpaints, the Frontier has never looked better.\n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_01_Q" "Postcards from the Frontier: The Patch Notes"
- "COMMUNITYUPDATE_01_A" "Read all the changes that come with the Postcards from the Frontier patch.\n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_02_Q" "Titanfall: Assault \"Launch\" Trailer"
- "COMMUNITYUPDATE_02_A" "Coming soon to mobile devices, Titanfall: Assault is an exciting real time RTS set in the Titanfall universe in partnership with Particle City. Watch it in action here! \n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_03_Q" "Titanfall Assault: \"Learn the Basics\" video"
- "COMMUNITYUPDATE_03_A" "Iniquity walks us through the tutorial and gives basic tips for Titanfall Assault. This is the perfect way to get started learning about the game.\n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_04_Q" "Respawn Plays Frontier Defense"
- "COMMUNITYUPDATE_04_A" "Listen to some of the key folks behind Frontier Defense talk about the history and making of the mode and watch us play a few rounds! \n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_05_Q" "Community Creations: Get to the Point"
- "COMMUNITYUPDATE_05_A" "Kevin Younger created a fun montage showing off a plethora of sweet moves with the Pulse Blade. \n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_06_Q" "Community Creations: Northstar Pilot Hunt"
- "COMMUNITYUPDATE_06_A" "ConzeyG via reddit shows off brutal efficiency with Northstar picking off Pilots in Marked for Death mode. \n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_07_Q" "\"Operation Frontier Shield\" Gameplay Trailer"
- "COMMUNITYUPDATE_07_A" "Available now! Frontier Defense returns along with Rise as well as brand new warpaints to buy and new a new Live Fire map. Watch it all in action here.\n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_08_Q" "\"The War Games\" Gameplay Trailer"
- "COMMUNITYUPDATE_08_A" "Available now! The iconic War Games map returns to Titanfall 2 looking better than ever. Also check out the new execution and new live fire map, Traffic in action.\n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_09_Q" "\"Monarch's Reign\" Gameplay Trailer"
- "COMMUNITYUPDATE_09_A" "This DLC features the addition of the 7th multiplayer Titan: Monarch, a remaster of the map, Relic, a new execution as well as purchasable Ronin and Tone Prime Titans, more camos, banners, and nose art. Watch the action here.\n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_10_Q" "\"A Glitch in the Frontier\" Gameplay Trailer"
- "COMMUNITYUPDATE_10_A" "All is not as it appears on the Frontier - prepare to enter the newest free DLC pack for Titanfall 2: A Glitch in the Frontier - featuring the new map “Glitch”. Inspired by Captain Lastimosa’s home planet of Harmony, vertical drops and long, twisting paths dominate the environment, perfect for chaining together long wall runs to seamlessly glide across the map. A new Live Fire map also joins the fold: Deck, which features tight interior spaces, exposed courtyards, and watchful drones circling overhead. If you’re feeling overwhelmed, the ever-helpful M.R.V.N.s are now here as an all-new faction to lend a cheery robotic hand. Finally, the new Pulse Blade execution is available to unlock to use whenever you feel the need to get your point across.\n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_11_Q" "\"Colony Reborn\" Gameplay Trailer"
- "COMMUNITYUPDATE_11_A" "Return to an iconic fan favorite multiplayer map from the original Titanfall: Colony. Mix in all of the new tacticals & Titans from Titanfall 2, and Pilots & Titans will have to keep their wits about them to survive in this tightly-packed idyllic village of back alleys, blind corners and exposed rooftops; available for free on March 30th for all players. The “Colony Reborn” DLC pack includes the return of classic weapons like the tricked out R-101 assault rifle, a new grapple execution, and new cosmetic options for purchase to look your best while you paint the town red.\n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_12_Q" "\"Welcome to Live Fire\" Gameplay Trailer"
- "COMMUNITYUPDATE_12_A" "Introducing Live Fire: a lightning fast 6v6 Pilot only mode that brings competitive, close quarter combat to the forefront. Featuring two brand new maps designed specifically for Live Fire: Stacks and Meadow. These two free maps are tight, enclosed death boxes designed specifically for the fast-paced, intense nature of the mode.\n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_13_Q" "\"Welcome to Angel City\" Gameplay Trailer"
- "COMMUNITYUPDATE_13_A" "Experience a remastered version of the fan favorite map from the original Titanfall, `1Angel City`0. Stand by for the first free DLC for Titanfall 2 with `1Angel City's Most Wanted`0 available on December 1st for all players. This content includes new cosmetic options to add more flair to to the Frontier. \n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_14_Q" "\"Encore\" Accolades Trailer"
- "COMMUNITYUPDATE_14_A" "Welcome back.\n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_15_Q" "\"Become One\" Single Player Gameplay Trailer"
- "COMMUNITYUPDATE_15_A" "Two legends, one legacy.\n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- "COMMUNITYUPDATE_16_Q" "\"Pilots\" Multiplayer Gameplay Trailer"
- "COMMUNITYUPDATE_16_A" "Limitless.\n\n\nPress `2%[A_BUTTON|MOUSE1]%`0 to view."
-
- // faq_community_count = 17
-
- // FAQ - Patch Notes
- //
-
- "KNB_SUBJECT_00_NAME" "Game Updates"
- "KNB_SUBJECT_00_DESC" "`3What's New in Titanfall?`0\n\nCheck here to see what's changed in Titanfall 2!"
-
- "KNB_SUBJECT_00_SUB_00_A" "`2%$rui/bullet_point%`010 New community created callsign banners\n\n`2%$rui/bullet_point%`0All advocate gifts are now purchasable with credits\n\n`2%$rui/bullet_point%`0New Purchasable Store Content\n\n"
- "KNB_SUBJECT_00_SUB_00_Q" "%$rui/hud/scoreboard/status_titan% November 28 - Harvest Time"
-
- "KNB_SUBJECT_00_SUB_01_A" "`2%$rui/bullet_point%`0Pistol Primary Slot\n\n`2%$rui/bullet_point%`0Halloween Banners\n\n`2%$rui/bullet_point%`0Balance Changes\n\n`2%$rui/bullet_point%`0New Purchasable Store Content\n\n"
- "KNB_SUBJECT_00_SUB_01_Q" "%$rui/hud/scoreboard/status_titan% October 31 - Tricks and Treats"
-
- "KNB_SUBJECT_00_SUB_02_A" "`2%$rui/bullet_point%`0Frontier Defense - Support for 3 more maps - Drydock, Angel City and Exoplanet.\n\n`2%$rui/bullet_point%`0New Live Fire Map - UMA\n\n`2%$rui/bullet_point%`0New Pilot Execution - Hole In The Wall\n\n`2%$rui/bullet_point%`0New Purchasable Store Content"
- "KNB_SUBJECT_00_SUB_02_Q" "%$rui/hud/scoreboard/status_titan% August 29 - Postcards from the Frontier"
-
- "KNB_SUBJECT_00_SUB_03_A" "`2%$rui/bullet_point%`0Frontier Defense - A new cooperative mode where you join forces with up to three other players to defend a vital objective from increasingly intense waves of AI combatants. Communication and adaptation are key to surviving.\n\n`2%$rui/bullet_point%`0New Map - Rise\n\n`2%$rui/bullet_point%`0New Live Fire Map - Township\n\n`2%$rui/bullet_point%`0New Purchasable Store Content"
- "KNB_SUBJECT_00_SUB_03_Q" "%$rui/hud/scoreboard/status_titan% July 25 - Operation Frontier Shield"
-
- "KNB_SUBJECT_00_SUB_04_A" "`2%$rui/bullet_point%`0New Map - Wargames\n\n`2%$rui/bullet_point%`0New Live Fire Map - Traffic\n\n`2%$rui/bullet_point%`0New Pilot Execution - Shadow Boxing\n\n`2%$rui/bullet_point%`03rd Weapon Slot\n\n`2%$rui/bullet_point%`0Private Match Settings"
- "KNB_SUBJECT_00_SUB_04_Q" "%$rui/hud/scoreboard/status_titan% June 27 - The War Games"
-
- "KNB_SUBJECT_00_SUB_05_A" "`2%$rui/bullet_point%`0New Titan - Monarch\n\n`2%$rui/bullet_point%`0New Map - Relic\n\n`2%$rui/bullet_point%`0New Pilot Execution - Now You See Me\n\n`2%$rui/bullet_point%`0New Purchasable Store Content"
- "KNB_SUBJECT_00_SUB_05_Q" "%$rui/hud/scoreboard/status_titan% May 30 - Monarch's Reign"
-
- "KNB_SUBJECT_00_SUB_06_A" "`2%$rui/bullet_point%`0New Map - Glitch\n\n`2%$rui/bullet_point%`0New Live Fire Map - Deck\n\n`2%$rui/bullet_point%`0New Faction - M.R.V.N.\n\n`2%$rui/bullet_point%`0New Pilot Execution - Get to the Point\n\n`2%$rui/bullet_point%`0Max Gen increased to 100"
- "KNB_SUBJECT_00_SUB_06_Q" "%$rui/hud/scoreboard/status_titan% Apr 25 - A Glitch in the Frontier"
-
- "KNB_SUBJECT_00_SUB_07_A" "`2%$rui/bullet_point%`0New Map - Colony\n\n`2%$rui/bullet_point%`0New Pilot Execution - Curb Check\n\n`2%$rui/bullet_point%`0New Weapon - R-101\n\n`2%$rui/bullet_point%`0New Purchasable Store Content"
- "KNB_SUBJECT_00_SUB_07_Q" "%$rui/hud/scoreboard/status_titan% Mar 30 - Colony Reborn"
-
- "KNB_SUBJECT_00_SUB_08_A" "`2%$rui/bullet_point%`0Live Fire - A new Pilot vs Pilot elimination game mode! It’s a 6v6 round-based with no respawns, you will have one minute to eliminate the opposing team in order to win the round. You can also win the round if your team is holding the neutral flag when the round timer ends. The team to win 5 rounds first wins the match.\n\n`2%$rui/bullet_point%`0New Live Fire Map - Meadow\n\n`2%$rui/bullet_point%`0New Live Fire Map - Stacks\n\n`2%$rui/bullet_point%`0New Pilot Execution - Late Hit"
- "KNB_SUBJECT_00_SUB_08_Q" "%$rui/hud/scoreboard/status_titan% Feb 23 - Live Fire"
-
- "KNB_SUBJECT_00_SUB_09_A" "`2%$rui/bullet_point%`0New Map - Angel City\n\n`2%$rui/bullet_point%`0New Weapon - B3 Wingman Elite\n\n`2%$rui/bullet_point%`0New Pilot Execution - Inner Pieces\n\n`2%$rui/bullet_point%`0New Titan Kits\n\n`2%$rui/bullet_point%`0New Purchasable Store Content"
- "KNB_SUBJECT_00_SUB_09_Q" "%$rui/hud/scoreboard/status_titan% Nov 30 - Angel City's Most Wanted"
-
- "MP_ANGEL_CITY_FD_WAVE_1" "Chained to the Sky"
- "MP_ANGEL_CITY_FD_WAVE_2" "Formlessness"
- "MP_ANGEL_CITY_FD_WAVE_3" "Insurgency"
- "MP_ANGEL_CITY_FD_WAVE_4" "An Obstinate Lot"
- "MP_ANGEL_CITY_FD_WAVE_5" "Roll the Hard Six"
-
- "MP_DRYDOCK_FD_WAVE_1" "To Swim in Strange Water"
- "MP_DRYDOCK_FD_WAVE_2" "They've got no bullets!"
- "MP_DRYDOCK_FD_WAVE_3" "Blinded by Science"
- "MP_DRYDOCK_FD_WAVE_4" "High Pressure System"
- "MP_DRYDOCK_FD_WAVE_5" "Eye of the Storm"
-
- "MP_THAW_FD_WAVE_1" "Situational Awareness"
- "MP_THAW_FD_WAVE_2" "Strength in Numbers"
- "MP_THAW_FD_WAVE_3" "Henchman 21"
- "MP_THAW_FD_WAVE_4" "Fun in the Fire"
- "MP_THAW_FD_WAVE_5" "Serve Well the Guns"
- }
- }
- "lang"
- {
- "Language" "french"
- "Tokens"
- {
- "COMMUNITYUPDATE_00_A" "Vos aventures à travers les environnements de la Frontière continuent avec le nouveau DLC de Titanfall 2 : Cartes postales de la Frontière. Personnalisez votre arsenal avec des peintures de guerre d'élite et combattez dans des lieux nouveaux ou familiers. La Frontière n'aura jamais été aussi belle !\n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_00_Q" "Trailer \"Cartes postales de la Frontière\""
- "COMMUNITYUPDATE_01_A" "Consultez la liste de changements inclus au patch Cartes postales de la Frontière.\n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_01_Q" "Cartes postales de la Frontière : Notes "
- "COMMUNITYUPDATE_02_A" "Prochainement disponible sur appareils mobiles, Titanfall: Assault est un STR captivant dans l'univers Titanfall développé en collaboration avec Particle City. Regardez la vidéo ! \n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_02_Q" "Titanfall: Assault - Trailer de lancement"
- "COMMUNITYUPDATE_03_A" "Iniquity nous présente le didacticiel et les bases de Titanfall: Assault. Obtenez vite plus d'informations sur les mécaniques de ce nouveau jeu.\n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_03_Q" "Titanfall: Assault - \"Les bases du jeu\""
- "COMMUNITYUPDATE_04_A" "Regardez les créateurs de Défense frontalière évoquer l'histoire et la conception de ce mode de jeu manette en main ! \n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_04_Q" "Respawn Plays : Défense frontalière"
- "COMMUNITYUPDATE_05_A" "Kevin Younger a créé un montage de ses meilleures actions avec sa lame à impulsion. \n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_05_Q" "Créations communautaires : impulsion fatale"
- "COMMUNITYUPDATE_06_A" "ConzeyG (sur reddit) nous démontre de toute son efficacité avec le Titan Northstar dans le mode de jeu Condamnation. \n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_06_Q" "Créations : Northstar chasseur de pilotes "
- "COMMUNITYUPDATE_07_A" "Disponible ! Défense frontalière revient avec la carte Expansion, de nouvelles peintures de guerre payantes et une nouvelle carte Live Fire. Regardez vite le trailer !\n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0."
- "COMMUNITYUPDATE_07_Q" "Trailer gameplay \"Opération Frontier Shield\""
- "COMMUNITYUPDATE_08_A" "Disponible dès maintenant ! La carte à succès Jeux de guerre fait son grand retour dans Titanfall 2. Découvrez également une exécution inédite et Trafic, une toute nouvelle carte Live Fire.\n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0 pour voir la vidéo."
- "COMMUNITYUPDATE_08_Q" "Trailer gameplay \"Jeux de guerre\""
- "COMMUNITYUPDATE_09_A" "Notre nouveau DLC inclut le Monarch (7e Titan multijoueur du jeu), une version remasterisée de la carte Relique, une exécution inédite, ainsi que du contenu payant incluant les Titans Ronin Prime et Tone Prime avec des nouveaux camouflages, bannières et personnalisations de cockpit. Regardez vite le trailer !\n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0 pour voir la vidéo."
- "COMMUNITYUPDATE_09_Q" "Trailer gameplay \"Règne du Monarch\""
- "COMMUNITYUPDATE_10_A" "Les apparences sont parfois trompeuses à la Frontière ! Préparez-vous pour Glitch frontalier, le nouveau DLC gratuit de Titanfall 2 qui inclut la carte inédite \"Glitch\". Inspirée par Harmony, la planète natale du capitaine Lastimosa, cette carte regorge de voies verticales et de longs chemins tortueux qui vous permettront d'enchaîner les courses sur les murs. Découvrez également \"Pont\", une toute nouvelle carte Live Fire avec des sections intérieures étroites et des zones exposées survolées par des drones aériens. Vous ne serez pas seuls sur ces nouveaux champs de bataille : les serviables Marvins s'invitent au combat en tant que nouvelle faction pour vous prêter main forte ! Débloquez également la nouvelle exécution Impulsion fatale pour faire passer un message à tous vos ennemis.\n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0 pour voir la vidéo."
- "COMMUNITYUPDATE_10_Q" "Trailer gameplay \"Glitch frontalier\""
- "COMMUNITYUPDATE_11_A" "Découvrez la nouvelle version de Colonie, l'une des cartes multijoueurs favorites des fans du premier Titanfall ! Combinez les différentes capacités tactiques et les classes de Titan de Titanfall 2 à compter du 30 mars pour éliminer vos adversaires à travers les ruelles tortueuses, les recoins dangereux et les toitures exposées de ce village idyllique. Le DLC gratuit \"Nouvelle colonie\" inclut des armes mythiques comme la nouvelle version du fusil d'assaut R-101, une exécution au grappin inédite et de nouvelles options cosmétiques payantes pour combattre avec encore plus de style !\n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0 pour voir la vidéo."
- "COMMUNITYUPDATE_11_Q" "Trailer gameplay \"Nouvelle colonie\""
- "COMMUNITYUPDATE_12_A" "Découvrez Live Fire, un tout nouveau mode de jeu pour pilotes proposant des affrontements ultra-rapides à 6c6 en combat rapproché. Combattez sur deux nouvelles cartes spécialement conçues pour Live Fire : Empilements et Prairie. Ces deux cartes comportent des zones de jeu resserrées parfaitement adaptées au caractère intense et débridé de ce nouveau mode de jeu.\n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0 pour voir la vidéo."
- "COMMUNITYUPDATE_12_Q" "Trailer gameplay \"Live Fire\""
- "COMMUNITYUPDATE_13_A" "Découvrez la version remasterisée d'`1Angel City`0, la carte favorite des joueurs du premier Titanfall ! Préparez-vous pour le premier DLC gratuit de Titanfall 2, `1Liste noire d'Angel City`0, qui sera disponible le 1er décembre pour tous les joueurs. Ce nouveau contenu inclut également des optimisations cosmétiques qui vous aideront à vous démarquer sur les champs de bataille de la Frontière. \n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0 pour voir la vidéo."
- "COMMUNITYUPDATE_13_Q" "Trailer gameplay \"Angel City\""
- "COMMUNITYUPDATE_14_A" "Bon retour parmi nous !\n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0 pour voir la vidéo."
- "COMMUNITYUPDATE_14_Q" "Trailer - \"Encore\""
- "COMMUNITYUPDATE_15_A" "Deux légendes, un héritage.\n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0 pour voir la vidéo."
- "COMMUNITYUPDATE_15_Q" "Trailer Solo - \"Ne faites plus qu'un\""
- "COMMUNITYUPDATE_16_A" "Sans limite.\n\n\nAppuyez sur `2%[A_BUTTON|MOUSE1]%`0 pour voir la vidéo."
- "COMMUNITYUPDATE_16_Q" "Trailer multijoueur - \"Pilotes\""
- "COMMUNITYUPDATE_DESC" "`3Titanfall - Mises à jour de la communauté`0\n\nDes infos et des liens en provenance de tout le web.\n\nPour ne rien manquer :\n`2%$rui/bullet_point%`0Suivez-nous sur Twitter `1@Respawn`0\n`2%$rui/bullet_point%`0Rendez-vous sur `1facebook.com/RespawnEntertainment`0\n`2%$rui/bullet_point%`0Rejoignez-nous sur `1www.respawn.com`0"
- "COMMUNITYUPDATE_NAME" "Communauté"
- "KNB_SUBJECT_00_DESC" "`3Quoi de neuf dans Titanfall ?`0\n\nPrenez connaissance des nouvelles fonctionnalités de Titanfall 2 !"
- "KNB_SUBJECT_00_NAME" "Mises à jour du jeu"
- "KNB_SUBJECT_00_SUB_00_A" "`2%$rui/bullet_point%`010 Nouvelles bannières créées par la communauté\n\n`2%$rui/bullet_point%`0Tous les cadeaux sont désormais achetables avec des crédits\n\n`2%$rui/bullet_point%`0Nouveau contenu payant dans la Boutique\n\n"
- "KNB_SUBJECT_00_SUB_00_Q" "%$rui/hud/scoreboard/status_titan% 28 novembre - Récolte"
- "KNB_SUBJECT_00_SUB_01_A" "`2%$rui/bullet_point%`0Emplacement principal pour pistolet\n\n`2%$rui/bullet_point%`0Bannières Halloween\n\n`2%$rui/bullet_point%`0Optimisations de l'équilibre\n\n`2%$rui/bullet_point%`0Nouveau contenu payant dans la Boutique\n\n"
- "KNB_SUBJECT_00_SUB_01_Q" "%$rui/hud/scoreboard/status_titan% 31 octobre - Bundle Halloween"
- "KNB_SUBJECT_00_SUB_02_A" "`2%$rui/bullet_point%`0Défense frontalière - Prise en charge de 3 cartes supplémentaires : Cale sèche, Angel City et Exoplanète.\n\n`2%$rui/bullet_point%`0Nouvelle carte Live Fire - UMA\n\n`2%$rui/bullet_point%`0Nouvelle exécution de pilote - Trou dans le mur\n\n`2%$rui/bullet_point%`0Nouveau contenu payant dans la Boutique"
- "KNB_SUBJECT_00_SUB_02_Q" "%$rui/hud/scoreboard/status_titan% 29 août - Cartes postales de la Frontière"
- "KNB_SUBJECT_00_SUB_03_A" "`2%$rui/bullet_point%`0Défense frontalière - Nouveau mode coopératif, qui vous propose de vous allier à un maximum de trois autres joueurs pour défendre un objectif stratégique face à des vagues de combattants IA de plus en plus intenses. Votre survie dépendra de vos facultés de communication et d'adaptation !\n\n`2%$rui/bullet_point%`0Nouvelle carte - Expansion\n\n`2%$rui/bullet_point%`0Nouvelle carte Live Fire - Cité\n\n`2%$rui/bullet_point%`0Nouveau contenu payant dans la Boutique"
- "KNB_SUBJECT_00_SUB_03_Q" "%$rui/hud/scoreboard/status_titan% 25 juillet - Opération Frontier Shield"
- "KNB_SUBJECT_00_SUB_04_A" "`2%$rui/bullet_point%`0Nouvelle carte - Jeux de guerre\n\n`2%$rui/bullet_point%`0Nouvelle carte Live Fire - Trafic\n\n`2%$rui/bullet_point%`0Nouvelle exécution de pilote - Boxe furtive\n\n`2%$rui/bullet_point%`0Troisième emplacement d'armement\n\n`2%$rui/bullet_point%`0Paramètres de partie privée"
- "KNB_SUBJECT_00_SUB_04_Q" "%$rui/hud/scoreboard/status_titan% 27 juin - Jeux de guerre"
- "KNB_SUBJECT_00_SUB_05_A" "`2%$rui/bullet_point%`0Nouveau Titan - Monarch\n\n`2%$rui/bullet_point%`0Nouvelle carte - Relique\n\n`2%$rui/bullet_point%`0Nouvelle exécution - Vision mortelle\n\n`2%$rui/bullet_point%`0Nouveau contenu payant dans la Boutique"
- "KNB_SUBJECT_00_SUB_05_Q" "%$rui/hud/scoreboard/status_titan% 30 mai - Règne du Monarch"
- "KNB_SUBJECT_00_SUB_06_A" "`2%$rui/bullet_point%`0Nouvelle carte - Glitch\n\n`2%$rui/bullet_point%`0Nouvelle carte Live Fire - Pont\n\n`2%$rui/bullet_point%`0Nouvelle faction - Marvin\n\n`2%$rui/bullet_point%`0Nouvelle exécution de pilote - Impulsion fatale\n\n`2%$rui/bullet_point%`0Niveau de génération maximal augmenté à 100"
- "KNB_SUBJECT_00_SUB_06_Q" "%$rui/hud/scoreboard/status_titan% 25 avril - Glitch frontalier"
- "KNB_SUBJECT_00_SUB_07_A" "`2%$rui/bullet_point%`0Nouvelle carte - Colonie\n\n`2%$rui/bullet_point%`0Nouvelle exécution de pilote - Coup du grappin\n\n`2%$rui/bullet_point%`0Nouvelle arme - R-101\n\n`2%$rui/bullet_point%`0Nouveau contenu payant dans la Boutique"
- "KNB_SUBJECT_00_SUB_07_Q" "%$rui/hud/scoreboard/status_titan% 30 mars - Nouvelle colonie"
- "KNB_SUBJECT_00_SUB_08_A" "`2%$rui/bullet_point%`0Live Fire - Un nouveau mode Pilotes contre pilotes à élimination ! Dans ce mode à 6c6 en plusieurs manches, vous disposerez d'une minute pour éliminer l'équipe adverse et remporter la manche. Vous pourrez aussi gagner la manche si votre équipe est en possession du drapeau neutre à la fin du temps imparti. La première équipe à gagner 5 manches remporte la partie.\n\n`2%$rui/bullet_point%`0Nouvelle carte Live Fire - Prairie\n\n`2%$rui/bullet_point%`0Nouvelle carte Live Fire - Empilements\n\n`2%$rui/bullet_point%`0Nouvelle exécution de pilote - Frappe spéciale"
- "KNB_SUBJECT_00_SUB_08_Q" "%$rui/hud/scoreboard/status_titan% 23 février - Live Fire"
- "KNB_SUBJECT_00_SUB_09_A" "`2%$rui/bullet_point%`0Nouvelle carte - Angel City\n\n`2%$rui/bullet_point%`0Nouvelle arme - Wingman B3 Élite\n\n`2%$rui/bullet_point%`0Nouvelle exécution de pilote - Viscéral\n\n`2%$rui/bullet_point%`0Nouveaux kits pour Titan\n\n`2%$rui/bullet_point%`0Nouveau contenu payant dans la Boutique"
- "KNB_SUBJECT_00_SUB_09_Q" "%$rui/hud/scoreboard/status_titan% 30 novembre - Liste noire d'Angel City"
- "MP_ANGEL_CITY_FD_WAVE_1" "Enchaînement céleste"
- "MP_ANGEL_CITY_FD_WAVE_2" "Menace informe"
- "MP_ANGEL_CITY_FD_WAVE_3" "Insurrection"
- "MP_ANGEL_CITY_FD_WAVE_4" "Obstination"
- "MP_ANGEL_CITY_FD_WAVE_5" "Tout pour le tout"
- "MP_DRYDOCK_FD_WAVE_1" "En eaux troubles"
- "MP_DRYDOCK_FD_WAVE_2" "En manque de munitions"
- "MP_DRYDOCK_FD_WAVE_3" "Aveuglement scientifique"
- "MP_DRYDOCK_FD_WAVE_4" "Haute pression"
- "MP_DRYDOCK_FD_WAVE_5" "Oeil du cyclone"
- "MP_THAW_FD_WAVE_1" "Connaissance situationnelle"
- "MP_THAW_FD_WAVE_2" "La force par le nombre"
- "MP_THAW_FD_WAVE_3" "Hommes de main"
- "MP_THAW_FD_WAVE_4" "Divertissement ardent"
- "MP_THAW_FD_WAVE_5" "Pour l'honneur"
- "NO_PRICE" "Offre expirée"
- "NO_PRICE_TWO_LINES" "Offre\nexpirée"
- "PL_aegis_last_titan_standing" "DT Aegis"
- "PL_aegis_last_titan_standing_abbr" "DTA"
- "PL_aegis_last_titan_standing_desc" "Optimisations Aegis autorisées. Plusieurs manches à élimination. La première équipe à gagner 3 manches remporte la partie.\n^FFC83200Joueurs : 5c5 *Début en Titan\nLimite de temps : 3 min par manche *Aucune réapparition\nTaille max. du groupe : 5"
- "PL_aegis_last_titan_standing_lobby" "PL_aegis_last_titan_standing_lobby"
- "PL_aegis_titan_brawl" "Combat de Titan Aegis"
- "PL_aegis_titan_brawl_abbr" "CDTA"
- "PL_aegis_titan_brawl_desc" "Détruisez les Titans ennemis. Optimisations Aegis autorisées.\n^FFC83200Joueurs : 5c5\nLimite de temps : 10 min\nTaille max. du groupe : 5"
- "PL_aegis_titan_brawl_hint" "Détruisez les Titans ennemis.\nPas d'éjection"
- "PL_aegis_titan_brawl_lobby" "Salon Combat de Titan Aegis"
- "PL_aitdm" "Attrition"
- "PL_aitdm_abbr" "ATT"
- "PL_aitdm_desc" "Tuez tous vos ennemis.\n^FFC83200Joueurs : 6c6 *IA\nLimite de temps : 10 min\nTaille max. du groupe : 6"
- "PL_aitdm_lobby" "Salon Attrition"
- "PL_all_grapple" "Attaque sur Titanfall"
- "PL_all_grapple_abbr" "ATT"
- "PL_all_grapple_desc" "Règles Attrition classiques avec toutes les capacités tactiques remplacées par le grappin.\n^FFC83200Joueurs : 6c6 *IA\nLimite de temps : 10 min\nTaille max. du groupe : 6"
- "PL_all_grapple_lobby" "Salon Attaque sur Titanfall"
- "PL_all_holopilot" "Holo-bataille"
- "PL_all_holopilot_abbr" "LF"
- "PL_all_holopilot_desc" "Règles Live Fire classiques avec toutes les capacités tactiques remplacées par le module holo-pilote.^FFC83200\nJoueurs : 6c6 *Aucun Titan\nLimite de temps : 60 s *Aucune réapparition\nTaille max. du groupe : 6"
- "PL_all_holopilot_lobby" "Salon Holo-bataille"
- "PL_all_phase" "De l'autre côté"
- "PL_all_phase_abbr" "ATT"
- "PL_all_phase_desc" "Règles Attrition classiques avec toutes les capacités tactiques remplacées par la téléportation.\n^FFC83200Joueurs : 6c6 *IA\nLimite de temps : 10 min\nTaille max. du groupe : 6"
- "PL_all_phase_lobby" "Salon De l'autre côté"
- "PL_all_spicy" "Attritique"
- "PL_all_spicy_abbr" "ATT"
- "PL_all_spicy_desc" "Règles Attrition classiques avec toutes les capacités tactiques remplacées par des tiques.\n^FFC83200Joueurs : 6c6 *IA\nLimite de temps : 10 min\nTaille max. du groupe : 6"
- "PL_all_spicy_lobby" "Salon Attritique"
- "PL_amped_tacticals" "Tactiques amplifiées"
- "PL_amped_tacticals_abbr" "ATT"
- "PL_amped_tacticals_desc" "Règles Attrition classiques avec amplification de toutes les capacités tactiques.\n^FFC83200Joueurs : 6c6 *IA\nLimite de temps : 10 min\nTaille max. du groupe : 6"
- "PL_amped_tacticals_lobby" "Salon Tactiques amplifiées"
- "PL_ANGEL_CITY" "Angel City 24/7"
- "PL_angel_city_abbr" "AC"
- "PL_angel_city_desc" "Tout Angel City, tout le temps.\n^FFC83200*Chasse aux primes *Attrition\n*Point clé amplifié"
- "PL_angel_city_lobby" "Salon Angel City 24/7"
- "PL_at_coop" "Évasion (Coop)"
- "PL_at_coop_desc" "Vous venez de vous évader de prison avec un pistolet pour seule arme. Survivez jusqu’à l’arrivée du vaisseau d’évacuation. Abattez des ennemis pour gagner de l’argent et acheter des armes. \n^FFC83200Joueurs : 6\n^FFC83200Taille max. du groupe : 6"
- "PL_at_coop_lobby" "Salon Évasion"
- "PL_attrition" "Chasse aux primes"
- "PL_attrition_abbr" "CP"
- "PL_attrition_desc" "Abattez vos ennemis pour gagner de l'argent. Augmentez votre score en encaissant des bonus aux emplacements désignés.\n^FFC83200Joueurs : 5c5 *IA\nLimite de temps : 10 min\nTaille max. du groupe : 5"
- "PL_attrition_lobby" "Salon Chasse aux primes"
- "PL_capture_the_flag" "Capture de drapeau"
- "PL_capture_the_flag_abbr" "CDD"
- "PL_capture_the_flag_desc" "Emparez-vous du drapeau adverse et rapportez-le à votre base, tout en empêchant l’ennemi de prendre le vôtre.\n^FFC83200Joueurs : 5c5\nLimite de temps : 12 min\nTaille max. du groupe : 5"
- "PL_capture_the_flag_lobby" "Salon CDD"
- "PL_coliseum" "Colisée"
- "PL_coliseum_desc" "Duels rapides en cage à 3 manches gagnantes avec cadeau. Abattez votre adversaire pour remporter la manche.^FFC83200\nJoueurs : 1c1 *Aucun Titan\nLimite de temps : 3 min *Aucune réapparition\n**^FFFFFF00REQUIERT TICKET COLISÉE ou INSCRIPTION PAYANTE"
- "PL_coliseum_lobby" "Salon Colisée"
- "PL_colony" "Colonie 24/7"
- "PL_colony_abbr" "COL"
- "PL_colony_desc" "Affrontements exclusivement sur la carte Colonie. ^CCCCCC00Vous allez chercher des parties en modes ^FFC83200Attrition^CCCCCC00, ^FFC83200Pilotes contre pilotes^CCCCCC00 et ^FFC83200Dernier Titan^CCCCCC00."
- "PL_colony_lobby" "Salon Colonie 24/7"
- "PL_ctf_lf" "CDD (Nitro)"
- "PL_ctf_lf_abbr" "CDD-N"
- "PL_ctf_lf_desc" "Affrontements rapides en Capture de drapeau sur une sélection de cartes.\n^FFC83200Joueurs : 5c5\nTaille max. du groupe : 5\n^F4D5A600Retours instantanés du drapeau"
- "PL_ctf_lf_lobby" "Salon CDD Nitro"
- "PL_default_description" "Description par défaut"
- "PL_default_lobbytitle" "Nom salon par défaut"
- "PL_default_name" "Nom par défaut"
- "PL_don" "Quitte ou double"
- "PL_fd" "Défense frontalière"
- "PL_fd_desc" "Défendez-vous contre des vagues de forces ennemies."
- "PL_fd_easy" "Défense frontalière : Facile"
- "PL_fd_easy_desc" "Éliminez l'opposition !"
- "PL_fd_easy_lobby" "Salon Défense frontalière : Facile"
- "PL_fd_hard" "Défense frontalière : Difficile"
- "PL_fd_hard_desc" "Résistez en développant des stratégies avancées."
- "PL_fd_hard_lobby" "Défense frontalière : Salon difficile"
- "PL_fd_insane" "Défense frontalière : Extrême"
- "PL_fd_insane_desc" "Vous ne survivrez pas."
- "PL_fd_insane_lobby" "Défense frontalière : Salon extrême"
- "PL_fd_lobby" "Salon Défense frontalière"
- "PL_fd_master" "Défense frontalière : Élite"
- "PL_fd_master_desc" "Seuls les meilleurs pilotes gagneront."
- "PL_fd_master_lobby" "Défense frontalière : Salon élite"
- "PL_fd_normal" "Défense frontalière : Standard"
- "PL_fd_normal_desc" "Recommandé aux joueurs chevronnés"
- "PL_fd_normal_lobby" "Défense frontalière : salon Standard"
- "PL_ffa" "Chacun pour soi"
- "PL_ffa_abbr" "CPS"
- "PL_ffa_desc" "Chaque pilote joue seul et doit abattre tous ses ennemis.\n^FFC83200Joueurs : 1c11\nLimite de temps : 10 min\nTaille max. du groupe : 1"
- "PL_ffa_lobby" "Salon Chacun pour soi"
- "PL_fra" "Agent libre"
- "PL_fra_abbr" "AL"
- "PL_fra_desc" "Vous jouez pour vous. Abattez vos ennemis pour gagner. Collectez 3 batteries pour appeler votre Titan.\n^FFC83200Joueurs : 1c11\nLimite de temps : 15 min\nTaille max. du groupe : 1"
- "PL_fra_lobby" "Salon Agent libre"
- "PL_groud_war_lobby" "Salon Mixtape 8c8"
- "PL_ground_war" "Mixtape 8c8"
- "PL_ground_war_abbr" "8c8"
- "PL_ground_war_desc" "Inclut les modes Escarmouche et Point clé amplifié avec un nombre de joueurs élevé sur toutes les cartes.\n^FFC83200Joueurs : 8c8"
- "PL_hardpoint" "Point clé amplifié"
- "PL_hardpoint_abbr" "PCA"
- "PL_hardpoint_desc" "Capturez et contrôlez des points clés pour gagner des points (amplifier les points clés rapporte 2X plus).\n^FFC83200Joueurs : 6c6\nLimite de temps : 10 min\nTaille max. du groupe : 6"
- "PL_hardpoint_lobby" "Salon Point clé amplifié"
- "PL_hunted" "Traque"
- "PL_iron_last_titan_standing" "DT d'Acier"
- "PL_iron_last_titan_standing_abbr" "DTA"
- "PL_iron_last_titan_standing_desc" "Titans uniquement avec plusieurs manches à élimination. La première équipe à gagner 3 manches remporte la partie.\n^FFC83200Joueurs : 5c5 *PAS DE PILOTES\nLimite de temps : 3 min par manche *Aucune réapparition\nTaille max. du groupe : 5"
- "PL_iron_last_titan_standing_lobby" "PL_iron_last_titan_standing_lobby"
- "PL_last_titan_standing" "Dernier Titan"
- "PL_last_titan_standing_abbr" "DT"
- "PL_last_titan_standing_desc" "Chaque joueur commence à bord d'un Titan dans plusieurs manches à élimination. La première équipe à gagner 3 manches remporte la partie.\n^FFC83200Joueurs : 5c5 *Début en Titan\nLimite de temps : 3 min par manche *Aucune réapparition\nTaille max. du groupe : 5"
- "PL_last_titan_standing_lobby" "Salon DT"
- "PL_limited_time_mode" "Mode à durée limitée"
- "PL_live_fire" "Live Fire"
- "PL_live_fire_abbr" "LF"
- "PL_live_fire_desc" "Combats rapides dans une arène Live Fire. Abattez tous les pilotes ennemis ou détenez le drapeau à la fin du temps imparti pour remporter la manche.^FFC83200\nJoueurs : 6c6 *Aucun Titan\nLimite de temps : 60 s *Aucune réapparition\nTaille max. du groupe : 6"
- "PL_live_fire_lobby" "Salon Live Fire"
- "PL_load_a_map_on_the_command_line" "Charger carte par ligne de commande –dev uniquement"
- "PL_marked_for_death" "Condamnation"
- "PL_marked_for_death_abbr" "COND"
- "PL_marked_for_death_desc" "Abattez ou protégez les cibles désignées.\n^FFC83200Joueurs : 6c6 \nLimite de temps : 12 min\nTaille max. du groupe : 6"
- "PL_marked_for_death_lobby" "Salon Condamnation"
- "PL_nitro_ffa" "CPS (Nitro)"
- "PL_nitro_ffa_abbr" "CPS-N"
- "PL_nitro_ffa_desc" "Affrontements rapides en Chacun pour soi sur une sélection de cartes.\n^FFC83200Joueurs : 6\n^F4D5A600Pas de Titans\nAucun Boost"
- "PL_nitro_ffa_lobby" "Salon CPS Nitro"
- "PL_nitro_mixtape" "Mixtape (Nitro)"
- "PL_nitro_mixtape_abbr" "MXT-N"
- "PL_nitro_mixtape_desc" "Affrontements rapides en CDD, COND et PcP sur une sélection de cartes.\n^FFC83200Joueurs : 5c5\nTaille max. du groupe : 5\n^F4D5A600Retours instantanés du drapeau"
- "PL_nitro_mixtape_lobby" "Salon Mixtape"
- "PL_pilot_hunter" "Escarmouche"
- "PL_pilot_hunter_abbr" "ESC"
- "PL_pilot_hunter_desc" "Éliminez les pilotes et Titans ennemis. \n^FFC83200Joueurs : 8c8\nLimite de temps : 10 min\nTaille max. du groupe : 8"
- "PL_pilot_hunter_lobby" "Salon Escarmouche"
- "PL_pilot_skirmish" "Pilotes contre pilotes"
- "PL_pilot_skirmish_abbr" "PcP"
- "PL_pilot_skirmish_desc" "Tuez les pilotes ennemis. Aucun largage de Titan n’est autorisé.\n^FFC83200Joueurs : 8c8 *Aucun Titan\nLimite de temps : 10 min\nTaille max. du groupe : 8"
- "PL_pilot_skirmish_lobby" "Salon PcP"
- "PL_pl_rebuild_all_paths" "Tout reconstruire"
- "PL_pl_run_with_ai_ainrebuildonmapstart_2" "Exécuter avec ai_ainRebuildOnMapStart 2"
- "PL_private_match" "Partie privée bêta"
- "PL_private_match_desc" "Jouez une partie privée personnalisée sur le mode et la carte de votre choix.\n^FFC83200Choisissez INVITER RÉSEAU ou INVITER AMIS pour jouer.\n^FFC83200Joueurs : 1-16\nAucune progression"
- "PL_private_match_lobby" "Salon Partie privée bêta"
- "PL_promo_coop" "COOP 4 joueurs"
- "PL_raid" "Raid"
- "PL_rise" "Expansion 24/7"
- "PL_rise_abbr" "EXP"
- "PL_rise_desc" "Affrontements exclusivement sur la carte Expansion. ^CCCCCC00Vous allez chercher des parties en modes ^FFC83200CDD^CCCCCC00, ^FFC83200Point clé amplifié^CCCCCC00, ^FFC83200Pilotes contre pilotes^CCCCCC00, ^FFC83200Live Fire^CCCCCC00 et ^FFC83200Dernier Titan^CCCCCC00."
- "PL_rise_lobby" "Salon Expansion 24/7"
- "PL_rocket_arena" "Arène à roquettes"
- "PL_rocket_arena_abbr" "LF"
- "PL_rocket_arena_desc" "Règles Live Fire classiques avec EPG modifiés.^FFC83200\nJoueurs : 6c6 *Aucun Titan\nLimite de temps : 90 s *Aucune réapparition\nTaille max. du groupe : 6"
- "PL_rocket_arena_lobby" "Salon Arène à roquettes"
- "PL_settings_for_when_someone_loads_a_map_on_the_command_line_do_not_edit_the_cmdlinemapload_1_below_-_this_makes_this_work" "Paramètres pour le chargement utilisateur d’une carte par ligne de commande. Ne pas éditer la commande \"cmdlineMapLoad 1\" ci-dessous, elle est requise pour le chargement."
- "PL_speedball" "Live Fire"
- "PL_speedball_desc" "Disputez-vous la possession d'un drapeau neutre. Éliminez l'équipe ennemie ou détenez le drapeau à la fin de la manche. La première équipe à gagner 5 manches remporte la partie.\n^FFC83200Joueurs : 6c6 *Aucun Titan\nLimite de temps : 60 s par manche *Aucune réapparition\nTaille max. du groupe : 6"
- "PL_speedball_lobby" "Salon Live Fire"
- "PL_tactikill" "Attrition Frag tactique"
- "PL_tactikill_abbr" "ATT"
- "PL_tactikill_desc" "Règles Attrition classiques avec réinitialisation des capacités tactiques après un frag.\n^FFC83200Joueurs : 6c6 *IA\nLimite de temps : 10 min\nTaille max. du groupe : 6"
- "PL_tactikill_lobby" "Salon Attrition Frag tactique"
- "PL_titan_brawl" "Combat de Titan"
- "PL_titan_brawl_abbr" "CDT"
- "PL_titan_brawl_desc" "Détruisez les Titans ennemis. Les pilotes ne sont pas autorisés.\n^FFC83200Joueurs : 5c5\nLimite de temps : 10 min\nTaille max. du groupe : 5"
- "PL_titan_brawl_hint" "Détruisez les Titans ennemis.\nPas d'éjection"
- "PL_titan_brawl_lobby" "Salon Combat de Titan"
- "PL_titan_brawl_turbo" "Combat de Titan Turbo"
- "PL_titan_brawl_turbo_abbr" "CDT"
- "PL_titan_brawl_turbo_desc" "Règles Combat de Titan classiques avec régénération de propulsion et génération de noyau plus rapides.\n^FFC83200Joueurs : 5c5\nLimite de temps : 10 min\nTaille max. du groupe : 5"
- "PL_titan_brawl_turbo_hint" "Détruisez les Titans ennemis.\nPas d'éjection"
- "PL_titan_brawl_turbo_lobby" "Salon Combat de Titan Turbo"
- "PL_turbo_last_titan_standing" "DT Turbo"
- "PL_turbo_last_titan_standing_abbr" "DT"
- "PL_turbo_last_titan_standing_desc" "Règles DT classiques avec régénération de propulsion et génération de noyau plus rapides.\n^FFC83200Joueurs : 5c5 *Début en Titan\nLimite de temps : 3 min par manche *Aucune réapparition\nTaille max. du groupe : 5"
- "PL_turbo_last_titan_standing_lobby" "Salon DT Turbo"
- "PL_variety_pack" "Mixtape"
- "PL_variety_pack_desc" "Jouez avec différents nombres de joueurs et cartes dans plusieurs modes de jeu :\n^FFC83200*Chasse aux primes *Attrition\n*Dernier Titan *Point clé amplifié\n*Pilotes contre pilotes *Capture de drapeau"
- "PL_variety_pack_lobby" "Salon Mixtape"
- "PL_wargames" "Jeux de guerre 24/7"
- "PL_wargames_abbr" "JDG"
- "PL_wargames_desc" "Affrontements exclusivement sur la carte Jeux de guerre. ^CCCCCC00Vous allez chercher des parties en modes ^FFC83200Attrition^CCCCCC00, ^FFC83200CDD^CCCCCC00, ^FFC83200Pilotes contre pilotes^CCCCCC00, ^FFC83200Point clé amplifié^CCCCCC00 et ^FFC83200Dernier Titan^CCCCCC00."
- "PL_wargames_lobby" "Salon Jeux de guerre 24/7"
- "WATCH_TUTORIAL" "VOIR DIDACTICIEL"
- }
- }
- "lang"
- {
- "Language" "polish"
- "Tokens"
- {
- "COMMUNITYUPDATE_00_A" "Kontynuuj swoją przygodę na zapierających dech w piersi Kresach dzięki „Pocztówkom z Kresów”, najnowszemu DLC do Titanfall 2. Wzbogaciliśmy grę o nowe obszary i szeroki wachlarz elitarnych barw wojennych broni. Kresy jeszcze nigdy nie wyglądały tak dobrze!\n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_00_Q" "Zwiastun „Pocztówek z Kresów”!"
- "COMMUNITYUPDATE_01_A" "Zapoznaj się ze wszystkimi zmianami, które wprowadziliśmy w aktualizacji „Pocztówki z Kresów”.\n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_01_Q" "„Pocztówki z Kresów”: informacje o aktualizacji"
- "COMMUNITYUPDATE_02_A" "Wkrótce na urządzeniach mobilnych dostępna będzie gra Titanfall: Assault. To strategia czasu rzeczywistego rozgrywająca się w świecie Titanfall, która powstała we współpracy z Particle City. Zobacz ją w akcji!\n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_02_Q" "Titanfall: Assault – zwiastun premierowy"
- "COMMUNITYUPDATE_03_A" "Iniquity pokazuje nam samouczek i udziela podstawowych porad do Titanfall: Assault. To idealny sposób na zaznajomienie się z grą.\n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_03_Q" "Titanfall: Assault – poznaj podstawy rozgrywki"
- "COMMUNITYUPDATE_04_A" "Posłuchaj twórców „Obrony Kresów”, którzy opowiadają o kulisach powstania tego trybu i zobacz, jak rozgrywamy kilka gier! \n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_04_Q" "Respawn w akcji: Obrona Kresów"
- "COMMUNITYUPDATE_05_A" "Kevin Younger przygotował film prezentujący szeroki wachlarz zagrań z użyciem ostrza pulsacyjnego. \n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_05_Q" "Prace społeczności – Przejdźmy do rzeczy"
- "COMMUNITYUPDATE_06_A" "ConzeyG prezentuje w serwisie reddit zabójczą skuteczność Polaris w trybie „Na celowniku”. \n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_06_Q" "Filmy fanów – Polaris na polowaniu"
- "COMMUNITYUPDATE_07_A" "Już jest! „Obrona Kresów” powraca wraz z mapą „Powstanie”, a także nowymi barwami wojennymi do kupienia oraz mapą do trybu „Szybki szturm”. Zobacz całość w akcji.\n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_07_Q" "Operacja „Tarcza Kresów” – zwiastun z rozgrywką"
- "COMMUNITYUPDATE_08_A" "Już dostępne! Słynna mapa „Gry wojenne” powraca do Titanfall 2 w odświeżonej postaci. Oprócz tego gracze będą mogli cieszyć się nową egzekucją i „Ruchem ulicznym”, czyli nową mapą do Szybkiego szturmu.\n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_08_Q" "„Gry wojenne” – zwiastun z rozgrywką"
- "COMMUNITYUPDATE_09_A" "Ten dodatek obejmuje Monarchę, czyli siódmego Tytana dostępnego w trybie wieloosobowym, odświeżoną mapę „Relikt”, nową egzekucję, a także Tytany Prime: Ronina i Tona oraz więcej kamuflaży, sztandarów i grafik dziobowych do kupienia. Śledź akcję tutaj.\n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_09_Q" "Zwiastun - rozgrywka w „Rządach Monarchy”"
- "COMMUNITYUPDATE_10_A" "Nie wszystko jest takie, jak się wydaje na Kresach – przygotujcie się na „Błąd na Kresach”, najnowsze darmowe DLC do Titanfall 2, zawierające nową mapę „Błąd”. Inspiracją dla jej stworzenia była ojczysta planeta kapitana Lastimosy, Harmonia. Mapa obfituje w wysokie urwiska i długie, kręte ścieżki. To idealna przestrzeń dla długich sekwencji skoków po ścianach, które pozwolą błyskawicznie przemieszczać się po mapie. Gra zostanie również wzbogacona o nową mapę do trybu „Szybki szturm”, „Pokład”, pełną ciasnych pomieszczeń i otwartych dziedzińców. Nie zabraknie tam również dronów, pilnie śledzących potyczki z góry. Jeśli czujesz, że wróg cię przytłacza, skorzystaj z pomocy nowej frakcji Marvinów, która chętnie wyciągnie do ciebie pomocną, mechaniczną dłoń. Ponadto, piloci, którzy chcą przekazać wrogowi jasny komunikat, mogą odblokować egzekucję „Ostrze pulsacyjne”\n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_10_Q" "Zwiastun - prezentacja „Błędu na Kresach”"
- "COMMUNITYUPDATE_11_A" "Powróć na uwielbianą przez fanów mapę z oryginalnego Titanfall: Kolonia. Dodajmy do niej nowe zdolności taktyczne i Tytany z Titanfall 2, a piloci i Tytany będą musieli mieć oczy dookoła głowy, aby przeżyć w tej wiosce pełnej wąskich uliczek, ślepych zaułków i odkrytych dachów. Mapa będzie dostępna za darmo dla wszystkich graczy 30 marca. Pakiet DLC „Nowa Kolonia” zawiera także klasyczną broń, karabin R-101, nową egzekucję oraz opcje kosmetyczne do kupienia, dzięki którym będziesz wyglądać bardzo stylowo podczas siania zniszczenia.\n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_11_Q" "Zwiastun - rozgrywka w „Nowej Kolonii”"
- "COMMUNITYUPDATE_12_A" "Poznajcie „Szybki szturm” – niezwykle szybki tryb 6 na 6 dla pilotów, w którym nie zabraknie zaciętych potyczek na krótkich dystansach. Specjalnie na potrzeby tego trybu przygotowaliśmy dwie nowe mapy: „Stosy” i „Polana”. Są to ciasne przestrzenie, na których toczyć się będzie dynamiczna i zażarta rywalizacja.\n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_12_Q" "Zwiastun – rozgrywka w tr. „Szybki szturm”"
- "COMMUNITYUPDATE_13_A" "Poznaj odświeżoną wersję `1Miasta Aniołów`0, ulubionej mapy graczy z pierwszej części Titanfall. Przygotuj się na nadejście pierwszego darmowego pakietu DLC do Titanfall 2 – zestawu `1„Renegat z Miasta Aniołów”`0, który udostępnimy wszystkim graczom już 1 grudnia. Zestaw zawiera nowe opcje kosmetyczne, dzięki którym wyróżnisz się podczas walk na Kresach. \n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_13_Q" "Zwiastun - rozgrywka w Mieście Aniołów"
- "COMMUNITYUPDATE_14_A" "Witaj z powrotem.\n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_14_Q" "Zwiastun – „Bis”"
- "COMMUNITYUPDATE_15_A" "Dwie legendy, jedna historia.\n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_15_Q" "Zwiastun – rozgrywka w trybie fabularnym"
- "COMMUNITYUPDATE_16_A" "Bez ograniczeń.\n\n\nWciśnij `2%[A_BUTTON|MOUSE1]%`0, aby zobaczyć."
- "COMMUNITYUPDATE_16_Q" "Zwiastun – rozgrywka pilotów w trybie online"
- "COMMUNITYUPDATE_DESC" "`3Co nowego u społeczności Titanfall?`0\n\nInformacje i linki z całego świata.\n\nAby dowiedzieć się więcej:\n`2%$rui/bullet_point%`0śledź nas na Twitterze `1@Respawn`0\n`2%$rui/bullet_point%`0polub nasz profil na `1facebook.com/RespawnEntertainment`0\n`2%$rui/bullet_point%`0dołącz do nas na stronie `1www.respawn.com`0"
- "COMMUNITYUPDATE_NAME" "Społeczność"
- "KNB_SUBJECT_00_DESC" "`3Co nowego w Titanfall?`0\n\nZajrzyj tutaj, by zobaczyć zmiany w Titanfall 2!"
- "KNB_SUBJECT_00_NAME" "Aktualizacje gry"
- "KNB_SUBJECT_00_SUB_00_A" "`2%$rui/bullet_point%`010 Nowe, zaprojektowane przez społeczność identyfikatory.\n\n`2%$rui/bullet_point%`0Wszystkie prezenty patrona można teraz kupić za pomocą kredytów.\n\n`2%$rui/bullet_point%`0Nowa zawartość do kupienia w sklepie.\n\n"
- "KNB_SUBJECT_00_SUB_00_Q" "%$rui/hud/scoreboard/status_titan% 28 listopada – Pora żniw"
- "KNB_SUBJECT_00_SUB_01_A" "`2%$rui/bullet_point%`0Pistolet w głównym miejscu na broń\n\n`2%$rui/bullet_point%`0Halloweenowe identyfikatory\n\n`2%$rui/bullet_point%`0Zmiany w wyważaniu\n\n`2%$rui/bullet_point%`0Nowa zawartość do kupienia w sklepie\n\n"
- "KNB_SUBJECT_00_SUB_01_Q" "%$rui/hud/scoreboard/status_titan% 31 października – Cukierki i psikusy"
- "KNB_SUBJECT_00_SUB_02_A" "`2%$rui/bullet_point%`0Obrona Kresów – Obsługa 3 dodatkowych map: Suchy Dok, Miasto Aniołów i Egzoplaneta.\n\n`2%$rui/bullet_point%`0Nowa mapa do \"Szybkiego szturmu\" - UMA\n\n`2%$rui/bullet_point%`0Nowa egzekucja pilota – \"Dziura w ścianie\"\n\n`2%$rui/bullet_point%`0Nowa zawartość dostępna w sklepie"
- "KNB_SUBJECT_00_SUB_02_Q" "%$rui/hud/scoreboard/status_titan% 29 sierpnia – Pocztówki z Kresów"
- "KNB_SUBJECT_00_SUB_03_A" "`2%$rui/bullet_point%`0Obrona Kresów – nowy tryb współpracy, w którym łączysz siły z maksymalnie trzema innymi graczami, aby chronić ważny cel przed coraz silniejszymi falami przeciwników sterowanych przez SI. Komunikacja i przystosowanie się do sytuacji są kluczem do przetrwania.\n\n`2%$rui/bullet_point%`0Nowa mapa – Powstanie\n\n`2%$rui/bullet_point%`0Nowa mapa do trybu „Szybki szturm” – Miasto\n\n`2%$rui/bullet_point%`0Nowa zawartość do kupienia w sklepie"
- "KNB_SUBJECT_00_SUB_03_Q" "%$rui/hud/scoreboard/status_titan% 25 lipca – operacja „Tarcza Kresów”"
- "KNB_SUBJECT_00_SUB_04_A" "`2%$rui/bullet_point%`0Nowa mapa – „Gry wojenne”\n\n`2%$rui/bullet_point%`0Nowa mapa do Szybkiego szturmu – „Ruch uliczny”\n\n`2%$rui/bullet_point%`0Nowa egzekucja pilota – Walka z cieniem\n\n`2%$rui/bullet_point%`0Trzecie miejsce na broń\n\n`2%$rui/bullet_point%`0Ustawienia gier prywatnych"
- "KNB_SUBJECT_00_SUB_04_Q" "%$rui/hud/scoreboard/status_titan% 27 czerwca – Gry wojenne"
- "KNB_SUBJECT_00_SUB_05_A" "`2%$rui/bullet_point%`0Nowy Tytan – Monarcha\n\n`2%$rui/bullet_point%`0Nowa mapa – Relikt\n\n`2%$rui/bullet_point%`0Nowa egzekucja pilota – A kuku\n\n`2%$rui/bullet_point%`0Nowa zawartość dostępna w sklepie"
- "KNB_SUBJECT_00_SUB_05_Q" "%$rui/hud/scoreboard/status_titan% 30 maja: Rządy Monarchy"
- "KNB_SUBJECT_00_SUB_06_A" "`2%$rui/bullet_point%`0Nowa mapa – Błąd\n\n`2%$rui/bullet_point%`0Nowa mapa do szybkiego szturmu – Pokład\n\n`2%$rui/bullet_point%`0Nowa frakcja – MARVIN\n\n`2%$rui/bullet_point%`0Nowa egzekucja pilota – Na ostrzu noża\n\n`2%$rui/bullet_point%`0Zwiększenie maksymalnej generacji do 100"
- "KNB_SUBJECT_00_SUB_06_Q" "%$rui/hud/scoreboard/status_titan% 25 kwietnia: Błąd na Kresach"
- "KNB_SUBJECT_00_SUB_07_A" "`2%$rui/bullet_point%`0Nowa mapa – Kolonia\n\n`2%$rui/bullet_point%`0Nowa egzekucja pilota – Uziemienie\n\n`2%$rui/bullet_point%`0Nowa broń – R-101\n\n`2%$rui/bullet_point%`0Nowa zawartość dostępna w sklepie"
- "KNB_SUBJECT_00_SUB_07_Q" "%$rui/hud/scoreboard/status_titan% 30 marca – Nowa Kolonia"
- "KNB_SUBJECT_00_SUB_08_A" "`2%$rui/bullet_point%`0Szybki szturm – nowy tryb eliminacyjny, w którym zmagają się wyłącznie piloci! To oparty na rundach tryb 6 na 6, w którym nie można się odradzać. Gracze mają minutę na wyeliminowanie drużyny przeciwnej. Możliwe jest także wygranie rundy poprzez kontrolowanie neutralnej flagi, gdy upłynie czas. O wygranej decyduje zwycięstwo w pięciu rundach.\n\n`2%$rui/bullet_point%`0Nowa mapa do szybkiego szturmu – Polana\n\n`2%$rui/bullet_point%`0Nowa mapa do szybkiego szturmu – Stosy\n\n`2%$rui/bullet_point%`0Nowa egzekucja pilota – Późne uderzenie"
- "KNB_SUBJECT_00_SUB_08_Q" "%$rui/hud/scoreboard/status_titan% 23 lutego: Szybki szturm"
- "KNB_SUBJECT_00_SUB_09_A" "`2%$rui/bullet_point%`0Nowa mapa – Miasto aniołów\n\n`2%$rui/bullet_point%`0Nowa broń – Elitarny skrzydłowy B3\n\n`2%$rui/bullet_point%`0Nowa egzekucja pilota – Rozrywacz\n\n`2%$rui/bullet_point%`0Nowe zestawy Tytana\n\n`2%$rui/bullet_point%`0Nowa zawartość dostępna w sklepie"
- "KNB_SUBJECT_00_SUB_09_Q" "%$rui/hud/scoreboard/status_titan% 30 listopada: Renegat z Miasta Aniołów"
- "MP_ANGEL_CITY_FD_WAVE_1" "Przykuty do nieba"
- "MP_ANGEL_CITY_FD_WAVE_2" "Bezkształtność"
- "MP_ANGEL_CITY_FD_WAVE_3" "Rewolta"
- "MP_ANGEL_CITY_FD_WAVE_4" "Uparta zgraja"
- "MP_ANGEL_CITY_FD_WAVE_5" "Twarda szóstka"
- "MP_DRYDOCK_FD_WAVE_1" "Na nieznanych wodach"
- "MP_DRYDOCK_FD_WAVE_2" "Wystrzelali się!"
- "MP_DRYDOCK_FD_WAVE_3" "Oślepieni blaskiem nauki"
- "MP_DRYDOCK_FD_WAVE_4" "System wywierania nacisku"
- "MP_DRYDOCK_FD_WAVE_5" "Oko cyklonu"
- "MP_THAW_FD_WAVE_1" "Świadomość sytuacji"
- "MP_THAW_FD_WAVE_2" "Liczy się liczebność"
- "MP_THAW_FD_WAVE_3" "Siepacz 21"
- "MP_THAW_FD_WAVE_4" "Zabawa z ogniem"
- "MP_THAW_FD_WAVE_5" "Obsada dział"
- "NO_PRICE" "Oferta wygasła"
- "NO_PRICE_TWO_LINES" "Oferta\nwygasła"
- "PL_aegis_last_titan_standing" "DoT z Egidą"
- "PL_aegis_last_titan_standing_abbr" "DoTE"
- "PL_aegis_last_titan_standing_desc" "Ulepszenia Egidy dostępne. Tryb eliminacyjny, wygrywa drużyna, która jako pierwsza wygra 3 rundy.\n^FFC83200Gracze: 5 na 5 *Rozpoczynasz grę w Tytanie\nLimit czasu: 3 min na rundę *Bez odrodzeń\nMaksymalny rozmiar grupy: 5"
- "PL_aegis_last_titan_standing_lobby" "PL_aegis_last_titan_standing_lobby"
- "PL_aegis_titan_brawl" "Starcie Tytanów z Egidą"
- "PL_aegis_titan_brawl_abbr" "STE"
- "PL_aegis_titan_brawl_desc" "Zniszcz wrogie Tytany. Ulepszenia Egidy dostępne.\n^FFC83200Gracze: 5 na 5\nLimit czasu: 10 min\nMaksymalny rozmiar grupy: 5"
- "PL_aegis_titan_brawl_hint" "Zniszcz wrogie Tytany.\nBrak katapultowania"
- "PL_aegis_titan_brawl_lobby" "Lobby: Starcie Tytanów z Egidą"
- "PL_aitdm" "Wyniszczenie"
- "PL_aitdm_abbr" "WYN"
- "PL_aitdm_desc" "Zabij wszystkich wrogów.\n^FFC83200Gracze: 6 na 6 *AI\nLimit czasowy: 10m\nMaksymalny rozmiar grupy: 6"
- "PL_aitdm_lobby" "Wyniszczenie – lobby"
- "PL_all_grapple" "Atak na Tytany"
- "PL_all_grapple_abbr" "W"
- "PL_all_grapple_desc" "Klasyczne zasady wyniszczenia, poza tym, że wszystkie zdolności taktyczne zostają zastąpione liną z hakiem.\n^FFC83200Gracze: 6 na 6 *SI\nLimit czasowy: 10 min\nMaksymalna wielkość grupy: 6"
- "PL_all_grapple_lobby" "Lobby: Atak na Tytany"
- "PL_all_holopilot" "Wielka ściema"
- "PL_all_holopilot_abbr" "SS"
- "PL_all_holopilot_desc" "Klasyczne zasady szybkiego szturmu, poza tym, że wszystkie zdolności taktyczne zostają zastąpione holopilotem.\n^FFC83200Gracze: 6 na 6 *Bez Tytanów\nLimit czasowy: 60 s *Bez odrodzeń\nMaksymalna wielkość grupy: 6"
- "PL_all_holopilot_lobby" "Lobby: Wielka ściema"
- "PL_all_phase" "Druga strona"
- "PL_all_phase_abbr" "W"
- "PL_all_phase_desc" "Klasyczne zasady wyniszczenia, poza tym, że wszystkie zdolności taktyczne zostają zastąpione przeskokiem fazowym.\n^FFC83200Gracze: 6 na 6 *SI\nLimit czasowy: 10 min\nMaksymalna wielkość grupy: 6"
- "PL_all_phase_lobby" "Lobby: Druga strona"
- "PL_all_spicy" "Pikantne wyniszczenie"
- "PL_all_spicy_abbr" "W"
- "PL_all_spicy_desc" "Klasyczne zasady wyniszczenia, poza tym, że wszystkie zdolności taktyczne zostają zastąpione kleszczami.\n^FFC83200Gracze: 6 na 6 *SI\nLimit czasowy: 10 min\nMaksymalna wielkość grupy: 6"
- "PL_all_spicy_lobby" "Lobby: Pikantne wyniszczenie"
- "PL_amped_tacticals" "Wzmocnione zdolności taktyczne"
- "PL_amped_tacticals_abbr" "W"
- "PL_amped_tacticals_desc" "Klasyczne zasady wyniszczenia, poza tym, że wszystkie zdolności taktyczne są potężniejsze.\n^FFC83200Gracze: 6 na 6 *SI\nLimit czasowy: 10 min\nMaksymalna wielkość grupy: 6"
- "PL_amped_tacticals_lobby" "Lobby: Wzmocnione zdolności taktyczne"
- "PL_ANGEL_CITY" "Miasto Aniołów 24/7"
- "PL_angel_city_abbr" "MA"
- "PL_angel_city_desc" "Nieustające walki w Mieście Aniołów.\n^FFC83200*Łowy *Wyniszczenie\n*Obrona Umocnień"
- "PL_angel_city_lobby" "Miasto Aniołów 24/7 – lobby"
- "PL_at_coop" "Ucieczka (współpraca)"
- "PL_at_coop_desc" "Właśnie uciekłeś z więzienia. Masz przy sobie jedynie pistolet. Musisz przeżyć do czasu ewakuacji. Eliminuj przeciwników, żeby zdobyć pieniądze na zakup broni. \n^FFC83200Gracze: 6\nMaksymalny rozmiar grupy: 6"
- "PL_at_coop_lobby" "Lobby: Ucieczka"
- "PL_attrition" "Łowy"
- "PL_attrition_abbr" "ŁN"
- "PL_attrition_desc" "Zabijaj wrogów, aby zdobywać punkty. Zyskaj jeszcze więcej, deponując punkty w wyznaczonych miejscach.\n^FFC83200Gracze: 5 na 5 *SI\nLimit czasu: 10 min.\nMaksymalny rozmiar grupy: 5"
- "PL_attrition_lobby" "Lobby: Łowy"
- "PL_capture_the_flag" "Walka o flagę"
- "PL_capture_the_flag_abbr" "WOF"
- "PL_capture_the_flag_desc" "Odbierz wrogom flagę i zanieś ją do swojej bazy, jednocześnie chroniąc własną flagę przed atakami przeciwnej drużyny!\n^FFC83200Gracze: 5 na 5\nLimit czasu: 12 min.\nMaksymalny rozmiar grupy: 5"
- "PL_capture_the_flag_lobby" "Lobby: Walka o flagę"
- "PL_coliseum" "Koloseum"
- "PL_coliseum_desc" "Potyczka w klatce jeden na jednego z usprawnionymi zdolnościami poruszania się. Gracz, który wygra 3 z 5 rund, otrzyma w nagrodę prezent patrona.^FFC83200\nGracze: 1 na 1 *Bez Tytanów\nLimit czasu: 3 min. *Bez odrodzeń\n**^FFFFFF00WYMAGA BILETU DO KOLOSEUM lub UISZCZENIA OPŁATY WPISOWEJ"
- "PL_coliseum_lobby" "Lobby: Koloseum"
- "PL_colony" "Kolonia 24/7"
- "PL_colony_abbr" "KOL"
- "PL_colony_desc" "Nieustające walki w Kolonii. ^CCCCCC00Spowoduje wyszukiwanie gier w trybach ^FFC83200Wyniszczenia^CCCCCC00, ^FFC83200Piloci kontra piloci^CCCCCC00 i ^FFC83200Do ostatniego Tytana^CCCCCC00."
- "PL_colony_lobby" "Kolonia 24/7 – lobby"
- "PL_ctf_lf" "WoF (Nitro)"
- "PL_ctf_lf_abbr" "WoF-N"
- "PL_ctf_lf_desc" "Dynamiczna rozgrywka w trybie „Walka o flagę” na wybranych mapach.\n^FFC83200Gracze: 5 na 5\nMaksymalny rozmiar grupy: 5\n^F4D5A600Natychmiastowe odniesienie flagi"
- "PL_ctf_lf_lobby" "Lobby: WoF (Nitro)"
- "PL_default_description" "Domyślny opis"
- "PL_default_lobbytitle" "Domyślny tytuł lobby"
- "PL_default_name" "Domyślna nazwa"
- "PL_don" "Podwójne ryzyko"
- "PL_fd" "Obrona Kresów"
- "PL_fd_desc" "Broń się przed falami sił floty Ocalałych"
- "PL_fd_easy" "Obrona Kresów: niski"
- "PL_fd_easy_desc" "Zmiażdż opozycję"
- "PL_fd_easy_lobby" "Obrona Kresów: niski (lobby)"
- "PL_fd_hard" "Obrona Kresów: wysoki"
- "PL_fd_hard_desc" "W tym starciu liczą się umiejętności"
- "PL_fd_hard_lobby" "Obrona Kresów: wysoki (lobby)"
- "PL_fd_insane" "Obrona Kresów: szalony"
- "PL_fd_insane_desc" "Nie przeżyjesz"
- "PL_fd_insane_lobby" "Obrona Kresów: szalony (lobby)"
- "PL_fd_lobby" "Lobby: Obrona Kresów"
- "PL_fd_master" "Obrona Kresów: mistrzowski"
- "PL_fd_master_desc" "Przetrwają tylko najlepsi z najlepszych"
- "PL_fd_master_lobby" "Obrona Kresów: mistrzowski (lobby)"
- "PL_fd_normal" "Obrona Kresów: normalny"
- "PL_fd_normal_desc" "Zalecane dla doświadczonych graczy"
- "PL_fd_normal_lobby" "Obrona Kresów: normalny (lobby)"
- "PL_ffa" "Każdy na każdego"
- "PL_ffa_abbr" "KNK"
- "PL_ffa_desc" "Każdy na każdego, musisz wyeliminować wszystkich przeciwników.\n^FFC83200Gracze: 1 na 11\nLimit czasu: 10 min.\nMaksymalny rozmiar grupy: 1"
- "PL_ffa_lobby" "Lobby: Każdy na każdego"
- "PL_fra" "Wolni strzelcy"
- "PL_fra_abbr" "WS"
- "PL_fra_desc" "Każdy pilot działa sam. Eliminuj przeciwników i zbierz 3 baterie, aby wezwać Tytana.\n^FFC83200Gracze: 1 na 11\nLimit czasu: 15 min\nMaksymalny rozmiar grupy: 1"
- "PL_fra_lobby" "Lobby: Wolni strzelcy"
- "PL_groud_war_lobby" "8 na 8 Remix – lobby"
- "PL_ground_war" "8 na 8 Remix"
- "PL_ground_war_abbr" "8 na 8"
- "PL_ground_war_desc" "Zawiera tryby „Starcie pilotów” i „Obrona umocnień” z dużą liczbą graczy na każdej z map.\n^FFC83200Gracze: 8 na 8"
- "PL_hardpoint" "Obrona umocnień"
- "PL_hardpoint_abbr" "OU"
- "PL_hardpoint_desc" "Przejmij i utrzymaj umocnienie, aby zdobyć punkty. Wzmocnione umocnienia są warte dwa razy więcej punktów.\n^FFC83200Gracze: 6 na 6\nLimit czasu: 10 min.\nMaksymalny rozmiar grupy: 6"
- "PL_hardpoint_lobby" "Lobby: Obrona umocnień"
- "PL_hunted" "Ścigany"
- "PL_iron_last_titan_standing" "Żelazne DoT"
- "PL_iron_last_titan_standing_abbr" "ŻDoT"
- "PL_iron_last_titan_standing_desc" "Tylko Tytany, tryb eliminacyjny, walka toczy się do 3 wygranych rund.\n^FFC83200Gracze: 5 na 5 *BEZ PILOTÓW\nLimit czasu: 3 min na rundę *Bez odrodzeń\nMaksymalny rozmiar grupy: 5"
- "PL_iron_last_titan_standing_lobby" "PL_iron_last_titan_standing_lobby"
- "PL_last_titan_standing" "Do ostatniego Tytana"
- "PL_last_titan_standing_abbr" "DOT"
- "PL_last_titan_standing_desc" "Wszyscy gracze rozpoczynają eliminacje w trybie rundowym, siedząc w swoich Tytanach. Wygrywa drużyna, która jako pierwsza wygra 3 rundy.\n^FFC83200Gracze: 5 na 5 *Rozpoczynasz grę w Tytanie\nLimit czasu: 3 min na rundę *Bez odrodzeń\nMaksymalny rozmiar grupy: 5"
- "PL_last_titan_standing_lobby" "Lobby: DoT"
- "PL_limited_time_mode" "(Tymczasowo)"
- "PL_live_fire" "Szybki szturm"
- "PL_live_fire_abbr" "SS"
- "PL_live_fire_desc" "Dynamiczna potyczka na arenie do trybu Szybki szturm. Aby wygrać rundę, musisz wyeliminować wszystkich pilotów z przeciwnej drużyny lub być w posiadaniu flagi, gdy czas dobiegnie końca.^FFC83200\nGracze: 6 na 6 *Bez Tytanów\nLimit czasu: 60 s *Bez odrodzeń\nMaksymalny rozmiar grupy: 6"
- "PL_live_fire_lobby" "Lobby: Szybki szturm"
- "PL_load_a_map_on_the_command_line" "Wczytaj mapę w wierszu poleceń – tylko dla deva."
- "PL_marked_for_death" "Na celowniku"
- "PL_marked_for_death_abbr" "NC"
- "PL_marked_for_death_desc" "Zabijaj lub chroń oznaczone cele.\n^FFC83200Gracze: 6 na 6 \nLimit czasu: 12 min\nMaksymalny rozmiar grupy: 6"
- "PL_marked_for_death_lobby" "Lobby: Na celowniku"
- "PL_nitro_ffa" "KNK (Nitro)"
- "PL_nitro_ffa_abbr" "KNK-N"
- "PL_nitro_ffa_desc" "Dynamiczne starcia w trybie Każdy na każdego na wybranych mapach.\n^FFC83200Gracze: 6\n^F4D5A600Brak Tytanów\nBrak wzmocnień"
- "PL_nitro_ffa_lobby" "Lobby: KNK Nitro "
- "PL_nitro_mixtape" "Remix (Nitro)"
- "PL_nitro_mixtape_abbr" "RMX-N"
- "PL_nitro_mixtape_desc" "Dynamiczna rozgrywka w trybach „Walka o flagę”, „Na celowniku” i PvP na wybranych mapach.\n^FFC83200Gracze: 5 na 5\nMaksymalny rozmiar grupy: 5\n^F4D5A600Natychmiastowe odniesienie flagi"
- "PL_nitro_mixtape_lobby" "Lobby: Remix"
- "PL_pilot_hunter" "Starcie pilotów"
- "PL_pilot_hunter_abbr" "SP"
- "PL_pilot_hunter_desc" "Zabij wrogich pilotów i ich Tytany. \n^FFC83200Gracze: 8 na 8\nLimit czasu: 10 min.\nMaksymalny rozmiar grupy: 8"
- "PL_pilot_hunter_lobby" "Lobby: Starcie pilotów"
- "PL_pilot_skirmish" "Piloci kontra piloci"
- "PL_pilot_skirmish_abbr" "PvP"
- "PL_pilot_skirmish_desc" "Zabij wrogich pilotów. Zrzuty Tytanów niedozwolone.\n^FFC83200Gracze: 8 na 8 *Bez Tytanów\nLimit czasu: 10 min.\nMaksymalny rozmiar grupy: 8"
- "PL_pilot_skirmish_lobby" "Lobby: PvP"
- "PL_pl_rebuild_all_paths" "Odnów wszystkie ścieżki"
- "PL_pl_run_with_ai_ainrebuildonmapstart_2" "Uruchamianie z: ai_ainRebuildOnMapStart 2"
- "PL_private_match" "Gra prywatna (beta)"
- "PL_private_match_desc" "Rozegraj własną grę prywatną i samodzielnie wybierz tryb i mapę.\n^FFC83200ZAPROŚ SIEĆ lub ZAPROŚ ZNAJOMYCH do gry\n^FFC83200Gracze: 1-16\nBez postępów"
- "PL_private_match_lobby" "Lobby: Gra prywatna (beta)"
- "PL_promo_coop" "4-OS. TRYB KOOPERACJI"
- "PL_raid" "Rajd"
- "PL_rise" "Powstanie 24/7"
- "PL_rise_abbr" "POW"
- "PL_rise_desc" "Powstanie non-stop. ^CCCCCC00Wyszukiwane będą gry w trybach: ^FFC83200WoF^CCCCCC00, ^FFC83200Obrona umocnień^CCCCCC00, ^FFC83200Piloci kontra piloci^CCCCCC00, ^FFC83200Szybki szturm^CCCCCC00 i ^FFC83200Do ostatniego Tytana^CCCCCC00."
- "PL_rise_lobby" "Powstanie 24/7 – lobby"
- "PL_rocket_arena" "Rakietowa arena"
- "PL_rocket_arena_abbr" "SS"
- "PL_rocket_arena_desc" "Klasyczne zasady szybkiego szturmu ze zmodyfikowanymi EPG.^FFC83200\nGracze: 6 na 6 *Bez Tytanów\nLimit czasowy: 90s *Bez odrodzeń\nMaksymalny rozmiar grupy: 6"
- "PL_rocket_arena_lobby" "Lobby: Rakietowa arena"
- "PL_settings_for_when_someone_loads_a_map_on_the_command_line_do_not_edit_the_cmdlinemapload_1_below_-_this_makes_this_work" "Ustawienia w przypadku wczytania mapy poprzez wiersz poleceń. Nie edytować cmdlineMapLoad 1 – wszystko będzie działać."
- "PL_speedball" "Szybki szturm"
- "PL_speedball_desc" "Walcz o przejęcie neutralnej flagi. Wyeliminuj drużynę przeciwną lub bądź w posiadaniu flagi, gdy runda dobiegnie końca. Gra toczy się do 5 zwycięstw.\n^FFC83200Gracze: 6 na 6 *Bez Tytanów\nLimit czasu: 60 s/tura * Bez odrodzeń\nMaksymalny rozmiar grupy: 6"
- "PL_speedball_lobby" "Szybki szturm – lobby"
- "PL_tactikill" "Taktyczne wyniszczenie"
- "PL_tactikill_abbr" "W"
- "PL_tactikill_desc" "Klasyczne zasady wyniszczenia, poza tym, że wszystkie zdolności taktyczne zostają zresetowane przy zabójstwie.\n^FFC83200Gracze: 6 na 6 *SI\nLimit czasowy: 10 min\nMaksymalna wielkość grupy: 6"
- "PL_tactikill_lobby" "Lobby: Taktyczne wyniszczenie"
- "PL_titan_brawl" "Starcie Tytanów"
- "PL_titan_brawl_abbr" "ST"
- "PL_titan_brawl_desc" "Zniszcz wrogie Tytany. Bez pilotów.\n^FFC83200Gracze: 5 na 5\nLimit czasu: 10 min\nMaksymalny rozmiar grupy: 5"
- "PL_titan_brawl_hint" "Zniszcz wrogie Tytany.\nBrak katapultowania"
- "PL_titan_brawl_lobby" "Lobby: Starcie Tytanów"
- "PL_titan_brawl_turbo" "Turbo starcie Tytanów"
- "PL_titan_brawl_turbo_abbr" "ST"
- "PL_titan_brawl_turbo_desc" "Klasyczne zasady starcia Tytanów z szybszym odnawianiem zrywów oraz ładowaniem rdzenia.\n^FFC83200Gracze: 5 na 5\nLimit czasowy: 10 min\nMaksymalny rozmiar grupy: 5"
- "PL_titan_brawl_turbo_hint" "Zniszcz wrogie Tytany.\nBrak katapultowania"
- "PL_titan_brawl_turbo_lobby" "Lobby: Turbo starcie Tytanów"
- "PL_turbo_last_titan_standing" "Turbo DoT"
- "PL_turbo_last_titan_standing_abbr" "DOT"
- "PL_turbo_last_titan_standing_desc" "Klasyczne zasady DoT z szybszym odnawianiem zrywów oraz ładowaniem rdzenia.\n^FFC83200Gracze: 5v5 *Rozpoczynasz grę w Tytanie\nLimit czasowy: 3 min na każdą rundę *Bez odrodzeń\nMaksymalny rozmiar grupy: 5"
- "PL_turbo_last_titan_standing_lobby" "Lobby: Turbo DoT"
- "PL_variety_pack" "Remix"
- "PL_variety_pack_desc" "Zmienna liczba graczy i wybór różnych map; rozgrywka w trybach takich jak:\n^FFC83200*Łowy *Wyniszczenie\n*Do ostatniego Tytana *Obrona umocnień\n*Piloci kontra piloci *Walka o flagę"
- "PL_variety_pack_lobby" "Remix – lobby"
- "PL_wargames" "Gry wojenne 24/7"
- "PL_wargames_abbr" "GW"
- "PL_wargames_desc" "Gry wojenne non-stop. ^CCCCCC00Wyszukiwanie gier w trybach^FFC83200Wyniszczenia^CCCCCC00, ^FFC83200WOF^CCCCCC00, ^FFC83200Piloci kontra piloci^CCCCCC00, ^FFC83200Obrona umocnień^CCCCCC00, i ^FFC83200Do ostatniego Tytana^CCCCCC00."
- "PL_wargames_lobby" "Gry wojenne 24/7 – lobby"
- "WATCH_TUTORIAL" "OBEJRZYJ SAMOUCZEK"
- }
- }
- "lang"
- {
- "Language" "mspanish"
- "Tokens"
- {
- "COMMUNITYUPDATE_00_A" "Tu aventura por los asombrosos paisajes de la Frontera continúa con el último DLC de Titanfall 2: Postales de la Frontera. La Frontera se ve mejor que nunca con ubicaciones nuevas y conocidas, además de la nueva colección de pinturas de guerra de arma élite.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_00_Q" "Tráiler de \"Postales de la Frontera\""
- "COMMUNITYUPDATE_01_A" "Lee todos los cambios que llegan con el parche de Postales de la Frontera.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_01_Q" "Notas sobre parches de Postales de la Frontera"
- "COMMUNITYUPDATE_02_A" "Próximamente disponible para celulares, Titanfall: Assault es un juego de disparos en tiempo real ambientado en el universo de Titanfall con la colaboración de Particle City. Míralo en acción aquí. \n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_02_Q" "Tráiler de \"lanzamiento\" de Titanfall: Assault"
- "COMMUNITYUPDATE_03_A" "Iniquity nos muestra el tutorial y nos da consejos básicos para Titanfall: Assault. Esta es la forma perfecta de iniciarse en el juego.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_03_Q" "Video \"aprende lo básico\" de Titanfall: Assault"
- "COMMUNITYUPDATE_04_A" "Conoce la historia y la creación del modo a través de algunas de las personas clave que se encuentran tras Defensa fronteriza y mira cómo jugamos unas rondas. \n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_04_Q" "Partidas de Respawn: Defensa fronteriza"
- "COMMUNITYUPDATE_05_A" "Kevin Younger creó un montaje divertido en el que presume de grandes movimientos con la cuchilla de pulso. \n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_05_Q" "Creaciones de la comunidad: dale en el centro"
- "COMMUNITYUPDATE_06_A" "ConzeyG presume a través de reddit de manejar a Northstar de forma asombrosa mientras recoge pilotos en el modo Marcado para morir. \n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_06_Q" "Creaciones : cacería de pilotos con Northstar"
- "COMMUNITYUPDATE_07_A" "¡Ya disponible! Defensa fronteriza regresa junto con Ascenso y nuevas pinturas de guerra que podrás comprar y un nuevo mapa de Fuego vivo. Mira todo esto en acción aquí.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_07_Q" "Tráiler de juego \"Operación Escudo fronterizo\""
- "COMMUNITYUPDATE_08_A" "¡Ya disponible! El icónico mapa Juegos bélicos regresa a Titanfall 2 y se ve mejor que nunca. No te olvides de checar la nueva ejecución y el nuevo mapa Tráfico de Fuego vivo en acción.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_08_Q" "Tráiler de juego de \"Juegos bélicos\""
- "COMMUNITYUPDATE_09_A" "Este DLC incluye al séptimo titán del multijugador: Monarch, el mapa Reliquia remasterizado y una nueva ejecución. Además podrás comprar los titanes Ronin y Tone Prime, más camuflajes, banderas y decoraciones para el fuselaje. Mira la acción aquí.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_09_Q" "Tráiler de juego de \"Reino de Monarch\""
- "COMMUNITYUPDATE_10_A" "No todo es lo que parece en la Frontera. Prepárate para el nuevo pack de DLC de Titanfall 2: Un Fallo en la Frontera, que incluye el nuevo mapa “Fallo”. Está inspirado en Harmony, el planeta en el que se crió el capitán Lastimosa, repleto de caídas verticales y senderos eternos y serpenteantes, perfectos para encadenar carreras por las paredes y recorrer todo el mapa sin interrupciones. También se une al pack un nuevo mapa de Fuego vivo: Muelle, que cuenta con espacios internos estrechos, patios desprotegidos y drones de vigilancia que te observan desde las alturas. Si crees que esto te supera, los M.R.V.N. ya están aquí dispuestos a echarte una mano robótica. Por último, puedes desbloquear la ejecución cuchilla de pulso y usarla cuando más la necesites.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_10_Q" "Tráiler de juego de \"Un Fallo en la Frontera\""
- "COMMUNITYUPDATE_11_A" "Regresa el icónico mapa favorito de los aficionados del multijugador del Titanfall original: Colonia, con las nuevas tácticas y titanes de Titanfall 2, en el que los pilotos y los titanes tendrán que ingeniárselas para sobrevivir a esta ciudad idílica repleta de callejones sin salida, esquinas con poca visibilidad y azoteas expuestas. Este mapa estará disponible el 30 de marzo para todos los jugadores. El pack de DLC “Colonia Renacida” incluye armas clásicas como el rifle de asalto R-101, una nueva ejecución de arpeo y nuevas opciones estéticas que podrás comprar para verte lo mejor posible mientras bañas la ciudad de sangre enemiga.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_11_Q" "Tráiler de juego de \"Colonia Renacida\""
- "COMMUNITYUPDATE_12_A" "Presentamos Fuego vivo: un modo vertiginoso de 6vs6 exclusivo para pilotos que se centra en el combate competitivo y de corto alcance. Incluye dos mapas nuevos diseñados específicamente para Fuego vivo: Aglomeración y Pradera. Estos mapas gratuitos, diseñados específicamente para este modo intenso y frenético, son cajas letales estrechas y cerradas.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_12_Q" "Tráiler de juego \"Bienvenidos a Fuego vivo\""
- "COMMUNITYUPDATE_13_A" "Disfruta la versión remasterizada del mapa favorito de los aficionados del Titanfall original, `1Ciudad Ángel`0. Permanece atento al primer DLC gratis de Titanfall 2 con `1El más deseado de Ciudad Ángel`0 disponible el 1 de diciembre para todos los jugadores. Este contenido incluye nuevas opciones estéticas para darle más estilo a la Frontera. \n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_13_Q" "Tráiler de juego \"Bienvenidos a Ciudad Ángel\""
- "COMMUNITYUPDATE_14_A" "Bienvenido de nuevo.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_14_Q" "Tráiler de comentarios \"Encore\""
- "COMMUNITYUPDATE_15_A" "Dos leyendas, un legado.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_15_Q" "Tráiler de juego de un jugador \"Sean uno\""
- "COMMUNITYUPDATE_16_A" "Sin límites.\n\n\nPulsa `2%[A_BUTTON|MOUSE1]%`0 para verlo."
- "COMMUNITYUPDATE_16_Q" "Tráiler de juego de multijugador \"Pilotos\""
- "COMMUNITYUPDATE_DESC" "`3Actualizaciones en la comunidad de Titanfall`0\n\nInformación y enlaces de la web.\n\nPara más información:\n`2%$rui/bullet_point%`0Síguenos en Twitter `1@Respawn`0\n`2%$rui/bullet_point%`0Danos me gusta en `1facebook.com/RespawnEntertainment`0\n`2%$rui/bullet_point%`0Únete a nosotros en `1www.respawn.com`0"
- "COMMUNITYUPDATE_NAME" "Comunidad"
- "KNB_SUBJECT_00_DESC" "`3¿Qué es nuevo en Titanfall?`0\n\n¡Chécalo aquí para ver qué ha cambiado en Titanfall 2!"
- "KNB_SUBJECT_00_NAME" "Actualizaciones"
- "KNB_SUBJECT_00_SUB_00_A" "`2%$rui/bullet_point%`010 nuevas banderas creadas por la comunidad\n\n`2%$rui/bullet_point%`0Todos los regalos del defensor se pueden comprar ahora con créditos\n\n`2%$rui/bullet_point%`0Nuevo contenido en la tienda para comprar\n\n"
- "KNB_SUBJECT_00_SUB_00_Q" "%$rui/hud/scoreboard/status_titan% 28 de noviembre: Recolector de tiempo"
- "KNB_SUBJECT_00_SUB_01_A" "`2%$rui/bullet_point%`0Espacio principal de la pistola\n\n`2%$rui/bullet_point%`0Banderas de Halloween\n\n`2%$rui/bullet_point%`0Cambios de equilibrio\n\n`2%$rui/bullet_point%`0Nuevo contenido en la tienda para comprar\n\n"
- "KNB_SUBJECT_00_SUB_01_Q" "%$rui/hud/scoreboard/status_titan% 31 de octubre: Trucos y tratos"
- "KNB_SUBJECT_00_SUB_02_A" "`2%$rui/bullet_point%`0Defensa fronteriza compatible con 3 mapas más: Dique seco, Ciudad Ángel y Exoplaneta.\n\n`2%$rui/bullet_point%`0Nuevo mapa de Fuego vivo: UMA\n\n`2%$rui/bullet_point%`0Nueva ejecución de piloto: Agujero en el muro\n\n`2%$rui/bullet_point%`0Nuevo contenido en la tienda para comprar"
- "KNB_SUBJECT_00_SUB_02_Q" "%$rui/hud/scoreboard/status_titan% 29 de agosto: Postales de la Frontera"
- "KNB_SUBJECT_00_SUB_03_A" "`2%$rui/bullet_point%`0Defensa fronteriza: un nuevo modo cooperativo en el que unes tus fuerzas con hasta 3 otros jugadores para defender un objetivo vital de las oleadas de combatientes de la IA que van aumentando de intensidad. La comunicación y la adaptación son claves para la sobrevivencia.\n\n`2%$rui/bullet_point%`0Nuevo mapa: Ascenso\n\n`2%$rui/bullet_point%`0Nuevo mapa de Fuego vivo: Municipio\n\n`2%$rui/bullet_point%`0Nuevo contenido en la tienda para comprar"
- "KNB_SUBJECT_00_SUB_03_Q" "%$rui/hud/scoreboard/status_titan% 25 de julio: Operación Escudo fronterizo"
- "KNB_SUBJECT_00_SUB_04_A" "`2%$rui/bullet_point%`0Nuevo mapa: Juegos bélicos\n\n`2%$rui/bullet_point%`0Nuevo mapa de Fuego vivo: Tráfico\n\n`2%$rui/bullet_point%`0Nueva ejecución de piloto: Golpe fantasma\n\n`2%$rui/bullet_point%`0Tercer espacio de arma\n\n`2%$rui/bullet_point%`0Configuración de la partida privada"
- "KNB_SUBJECT_00_SUB_04_Q" "%$rui/hud/scoreboard/status_titan% 27 de junio: Juegos bélicos"
- "KNB_SUBJECT_00_SUB_05_A" "`2%$rui/bullet_point%`0Nuevo titán: Monarch\n\n`2%$rui/bullet_point%`0Nuevo mapa: Reliquia\n\n`2%$rui/bullet_point%`0Nueva ejecución de piloto: Ahora me ves\n\n`2%$rui/bullet_point%`0Nuevo contenido en la tienda para comprar"
- "KNB_SUBJECT_00_SUB_05_Q" "%$rui/hud/scoreboard/status_titan% 30 de mayo: Reino de Monarch"
- "KNB_SUBJECT_00_SUB_06_A" "`2%$rui/bullet_point%`0Nuevo mapa: Fallo\n\n`2%$rui/bullet_point%`0Nuevo mapa de Fuego vivo: Muelle\n\n`2%$rui/bullet_point%`0Nueva facción: M.R.V.N.\n\n`2%$rui/bullet_point%`0Nueva ejecución de piloto: Dale en el centro\n\n`2%$rui/bullet_point%`0Generación máxima aumentada a 100"
- "KNB_SUBJECT_00_SUB_06_Q" "%$rui/hud/scoreboard/status_titan% 25 de abril: Un Fallo en la Frontera"
- "KNB_SUBJECT_00_SUB_07_A" "`2%$rui/bullet_point%`0Nuevo mapa: Colonia\n\n`2%$rui/bullet_point%`0Nueva ejecución de piloto: Rompecráneos\n\n`2%$rui/bullet_point%`0Nueva arma: R-101\n\n`2%$rui/bullet_point%`0Nuevo contenido en la tienda para comprar"
- "KNB_SUBJECT_00_SUB_07_Q" "%$rui/hud/scoreboard/status_titan% 30 de marzo: Colonia Renacida"
- "KNB_SUBJECT_00_SUB_08_A" "`2%$rui/bullet_point%`0Fuego vivo: un nuevo modo de eliminaciones de Batalla de pilotos. Una partida de rondas de 6vs6 sin regeneraciones en la que tendrás un minuto para eliminar al equipo contrario y ganar la ronda. También podrás ganar la ronda si tu equipo tiene la bandera neutral cuando el temporizador llegue a cero. El primer equipo que gane 5 rondas ganará la partida.\n\n`2%$rui/bullet_point%`0Nuevo mapa de Fuego vivo: Pradera\n\n`2%$rui/bullet_point%`0Nuevo mapa de Fuego vivo: Aglomeración\n\n`2%$rui/bullet_point%`0Nueva ejecución de piloto: Último disparo"
- "KNB_SUBJECT_00_SUB_08_Q" "%$rui/hud/scoreboard/status_titan% 23 de febrero: Fuego vivo"
- "KNB_SUBJECT_00_SUB_09_A" "`2%$rui/bullet_point%`0Nuevo mapa: Ciudad Ángel\n\n`2%$rui/bullet_point%`0Nueva arma: B3 Wingman Élite\n\n`2%$rui/bullet_point%`0Nueva ejecución de piloto: Piezas internas\n\n`2%$rui/bullet_point%`0Nuevs kits de titán\n\n`2%$rui/bullet_point%`0Nuevo contenido en la tienda para comprar"
- "KNB_SUBJECT_00_SUB_09_Q" "%$rui/hud/scoreboard/status_titan% 30 de nov.: El más deseado de Ciudad Ángel"
- "MP_ANGEL_CITY_FD_WAVE_1" "Encadenado al cielo"
- "MP_ANGEL_CITY_FD_WAVE_2" "Sin forma"
- "MP_ANGEL_CITY_FD_WAVE_3" "Levantamiento"
- "MP_ANGEL_CITY_FD_WAVE_4" "Un grupo tenaz"
- "MP_ANGEL_CITY_FD_WAVE_5" "Arriésgate"
- "MP_DRYDOCK_FD_WAVE_1" "Nadando en aguas turbias"
- "MP_DRYDOCK_FD_WAVE_2" "¡No tienen balas!"
- "MP_DRYDOCK_FD_WAVE_3" "Cegados por la ciencia"
- "MP_DRYDOCK_FD_WAVE_4" "Sistema de alta presión"
- "MP_DRYDOCK_FD_WAVE_5" "Ojo de la tormenta"
- "MP_THAW_FD_WAVE_1" "Atención a los alrededores"
- "MP_THAW_FD_WAVE_2" "La unión nos hace más fuertes"
- "MP_THAW_FD_WAVE_3" "Secuaz 21"
- "MP_THAW_FD_WAVE_4" "Diversión en el fuego"
- "MP_THAW_FD_WAVE_5" "Escoge las armas adecuadas"
- "NO_PRICE" "Oferta caducada"
- "NO_PRICE_TWO_LINES" "Oferta\ncaducada"
- "PL_aegis_last_titan_standing" "UTEP Aegis"
- "PL_aegis_last_titan_standing_abbr" "UTEPA"
- "PL_aegis_last_titan_standing_desc" "Mejoras Aegis activadas. Eliminación por rondas. Gana el primero que gane 3 rondas.\n^FFC83200Jugadores: 5vs5 *Comienza como titán\nLímite de tiempo: 3 min. por ronda *Sin regeneraciones\nTamaño máximo del grupo: 5"
- "PL_aegis_last_titan_standing_lobby" "PL_aegis_last_titan_standing_lobby"
- "PL_aegis_titan_brawl" "Pelea de titanes Aegis"
- "PL_aegis_titan_brawl_abbr" "PdTA"
- "PL_aegis_titan_brawl_desc" "Elimina a los titanes enemigos. Mejoras Aegis activadas.\n^FFC83200Jugadores: 5vs5\nLímite de tiempo: 10 min.\nTamaño máximo del grupo: 5"
- "PL_aegis_titan_brawl_hint" "Elimina a los titanes enemigos.\nSin eyección"
- "PL_aegis_titan_brawl_lobby" "Lobby de Pelea de titanes Aegis"
- "PL_aitdm" "Deterioro"
- "PL_aitdm_abbr" "DET"
- "PL_aitdm_desc" "Elimina a todos los enemigos.\n^FFC83200Jugadores: 6vs6 *IA\nLímite de tiempo: 10 min.\nTamaño máximo del grupo: 6"
- "PL_aitdm_lobby" "Lobby de Deterioro"
- "PL_all_grapple" "Ataque a los titanes"
- "PL_all_grapple_abbr" "DET"
- "PL_all_grapple_desc" "Las reglas clásicas de Deterioro, pero todas las habilidades tácticas se reemplazan por el arpeo.\n^FFC83200Jugadores: 6vs6 *IA\nLímite de tiempo: 10 min.\nTamaño máximo del grupo: 6"
- "PL_all_grapple_lobby" "Lobby de Ataque a los titanes"
- "PL_all_holopilot" "El gran engaño"
- "PL_all_holopilot_abbr" "FV"
- "PL_all_holopilot_desc" "Las reglas clásicas de Fuego vivo, pero todas las habilidades tácticas se reemplazan por el holopiloto.^FFC83200\nJugadores: 6vs6 *Sin titanes\nLímite de tiempo: 60 s *Sin regeneraciones\nNúmero máximo de miembros del grupo: 6"
- "PL_all_holopilot_lobby" "Lobby de El gran engaño"
- "PL_all_phase" "El otro lado"
- "PL_all_phase_abbr" "DET"
- "PL_all_phase_desc" "Las reglas clásicas de Deterioro, pero todas las habilidades tácticas se reemplazan por la fase.\n^FFC83200Jugadores: 6vs6 *IA\nLímite de tiempo: 10 min.\nTamaño máximo del grupo: 6"
- "PL_all_phase_lobby" "Lobby de El otro lado"
- "PL_all_spicy" "Deterioro picante"
- "PL_all_spicy_abbr" "DET"
- "PL_all_spicy_desc" "Las reglas clásicas de Deterioro, pero todas las habilidades tácticas se reemplazan por garrapatas.\n^FFC83200Jugadores: 6vs6 *IA\nLímite de tiempo: 10 min.\nTamaño máximo del grupo: 6"
- "PL_all_spicy_lobby" "Lobby de Deterioro picante"
- "PL_amped_tacticals" "Tácticas +"
- "PL_amped_tacticals_abbr" "DET"
- "PL_amped_tacticals_desc" "Las reglas clásicas de Deterioro, pero todas las habilidades tácticas son más potentes.\n^FFC83200Jugadores: 6vs6 *IA\nLímite de tiempo: 10 min.\nTamaño máximo del grupo: 6"
- "PL_amped_tacticals_lobby" "Lobby de Tácticas +"
- "PL_ANGEL_CITY" "Ciudad Ángel 24/7"
- "PL_angel_city_abbr" "CA"
- "PL_angel_city_desc" "Toda Ciudad Ángel, todo el tiempo.\n^FFC83200*Cazarrecompensas *Deterioro\n*Pto. Clave Amplificado"
- "PL_angel_city_lobby" "Lobby de Ciudad Ángel 24/7"
- "PL_at_coop" "Escape (cooperativo)"
- "PL_at_coop_desc" "Recién escapaste de la cárcel y solo tienes una pistola. Sobrevive hasta que puedas evacuar. Elimina enemigos para ganar dinero y comprar armas. \n^FFC83200Jugadores: 6\nNúmero máximo de miembros del grupo: 6"
- "PL_at_coop_lobby" "Lobby de Escape"
- "PL_attrition" "Cazarrecompensas"
- "PL_attrition_abbr" "CAZ"
- "PL_attrition_desc" "Elimina enemigos para ganar dinero. Obtén más depositando tus bonificaciones en el banco.\n^FFC83200Jugadores: 5vs5 *IA\nLímite de tiempo: 10 min.\nTamaño máximo del grupo: 5"
- "PL_attrition_lobby" "Lobby de Cazarrecompensas"
- "PL_capture_the_flag" "Captura la bandera"
- "PL_capture_the_flag_abbr" "CLB"
- "PL_capture_the_flag_desc" "¡Roba la bandera enemiga y regrésala a tu base mientras evitas que el equipo enemigo tome la tuya!\n^FFC83200Jugadores: 5vs5\nLímite de tiempo: 12 min.\nTamaño máximo del grupo: 5"
- "PL_capture_the_flag_lobby" "Lobby de CLB"
- "PL_coliseum" "Coliseo"
- "PL_coliseum_desc" "Combate individual con movilidad mejorada en una jaula. Elimina a tu oponente y gana una ronda. El mejor en 3 de 5 rondas gana un regalo del defensor.^FFC83200\nJugadores: 1vs1 *Sin titanes\nLímite de tiempo: 3 min *Sin regeneraciones\n**^FFFFFF00REQUIERE BOLETO DE COLISEO o CUOTA DE ENTRADA PAGADA"
- "PL_coliseum_lobby" "Lobby de Coliseo"
- "PL_colony" "Colonia 24/7"
- "PL_colony_abbr" "COL"
- "PL_colony_desc" "Colonia, sin interrupciones. ^CCCCCC00Buscará partidas de^FFC83200Deterioro^CCCCCC00, ^FFC83200Batalla de pilotos^CCCCCC00 y ^FFC83200Último titán en pie^CCCCCC00."
- "PL_colony_lobby" "Lobby de Colonia 24/7"
- "PL_ctf_lf" "CLB (Nitro)"
- "PL_ctf_lf_abbr" "CLB-N"
- "PL_ctf_lf_desc" "El frenético Captura la bandera en mapas seleccionados.\n^FFC83200Jugadores: 5vs5\nTamaño máximo del grupo: 5\n^F4D5A600Regresos de bandera al instante"
- "PL_ctf_lf_lobby" "Lobby de Nitro de CLB"
- "PL_default_description" "Descripción predeterminada"
- "PL_default_lobbytitle" "Título de lobby predeterminado"
- "PL_default_name" "Nombre predeterminado"
- "PL_don" "Doble o nada"
- "PL_fd" "Defensa fronteriza"
- "PL_fd_desc" "Defiéndete contra las oleadas de las fuerzas restantes de la Flota."
- "PL_fd_easy" "Defensa fronteriza: Fácil"
- "PL_fd_easy_desc" "Aplasta a la oposición"
- "PL_fd_easy_lobby" "Defensa fronteriza: Lobby de dificultad fácil"
- "PL_fd_hard" "Defensa fronteriza: Difícil"
- "PL_fd_hard_desc" "Se requieren jugadas hábiles."
- "PL_fd_hard_lobby" "Defensa fronteriza: Lobby de dificultad difícil"
- "PL_fd_insane" "Defensa fronteriza: demencial"
- "PL_fd_insane_desc" "No sobrevivirás"
- "PL_fd_insane_lobby" "Lobby de Defensa fronteriza: demencial"
- "PL_fd_lobby" "Lobby de Defensa fronteriza"
- "PL_fd_master" "Defensa fronteriza: maestro"
- "PL_fd_master_desc" "Solo los mejores saldrán con vida"
- "PL_fd_master_lobby" "Lobby de Defensa fronteriza: maestro"
- "PL_fd_normal" "Defensa fronteriza: normal"
- "PL_fd_normal_desc" "Recomendado para jugadores con experiencia"
- "PL_fd_normal_lobby" "Defensa fronteriza: Lobby de dificultad normal"
- "PL_ffa" "Todos contra todos"
- "PL_ffa_abbr" "TCT"
- "PL_ffa_desc" "Cada piloto por su cuenta; elimina a todos los enemigos.\n^FFC83200Jugadores: 1vs11\nLímite de tiempo: 10 min.\nTamaño máximo de grupo: 1"
- "PL_ffa_lobby" "Lobby de Todos contra todos"
- "PL_fra" "Agentes Libres"
- "PL_fra_abbr" "AGL"
- "PL_fra_desc" "Estás por tu cuenta. Elimina enemigos para ganar. Recoge 3 baterías para un despliegue de titán.\n^FFC83200Jugadores: 1vs11\nLímite de tiempo: 15 min\nTamaño máximo del grupo: 1"
- "PL_fra_lobby" "Lobby de Agentes Libres"
- "PL_groud_war_lobby" "Lobby diverso 8vs8"
- "PL_ground_war" "Diverso 8vs8"
- "PL_ground_war_abbr" "8vs8"
- "PL_ground_war_desc" "Incluye Escaramuza y Punto clave amplificado con gran número de jugadores en todos los mapas.\n^FFC83200Jugadores: 8vs8"
- "PL_hardpoint" "Punto clave amplificado"
- "PL_hardpoint_abbr" "PCA"
- "PL_hardpoint_desc" "Captura y mantén un punto clave para ganar puntos. Los puntos clave amplificados dan el doble de puntos.\n^FFC83200Jugadores: 6vs6\nLímite de tiempo: 10 min.\nTamaño máximo del grupo: 6"
- "PL_hardpoint_lobby" "Lobby de Punto clave amplificado"
- "PL_hunted" "Cazado"
- "PL_iron_last_titan_standing" "UTEP de hierro"
- "PL_iron_last_titan_standing_abbr" "UTEPH"
- "PL_iron_last_titan_standing_desc" "Solo para titanes, partida de rondas por eliminación. Gana el primero con 3 rondas ganadas.\n^FFC83200Jugadores: 5vs5 *SIN PILOTOS\nLímite de tiempo: 3 min por ronda *Sin regeneraciones\nNúmero máximo de miembros del grupo: 5"
- "PL_iron_last_titan_standing_lobby" "PL_iron_last_titan_standing_lobby"
- "PL_last_titan_standing" "Último titán en pie"
- "PL_last_titan_standing_abbr" "UTEP"
- "PL_last_titan_standing_desc" "Todos los jugadores inician en titanes en esta partida de rondas por eliminación. Gana el primero con 3 rondas ganadas.\n^FFC83200Jugadores: 5vs5 *Comienza como titán\nLímite de tiempo: 3 min. por ronda *Sin regeneraciones\nTamaño máximo del grupo: 5"
- "PL_last_titan_standing_lobby" "Lobby de UTEP"
- "PL_limited_time_mode" "Por tiempo limitado"
- "PL_live_fire" "Fuego vivo"
- "PL_live_fire_abbr" "FV"
- "PL_live_fire_desc" "Combate frenético en un escenario de Fuego vivo. Elimina pilotos enemigos o ten la bandera cuando se acabe el tiempo para ganar la ronda.^FFC83200\nJugadores: 6vs6 *Sin titanes\nLímite de tiempo: 60 s *Sin regeneraciones\nNúmero máximo de miembros del grupo: 6"
- "PL_live_fire_lobby" "Looby de Fuego vivo"
- "PL_load_a_map_on_the_command_line" "Carga un mapa en la línea de comandos. Solo para desarrollo."
- "PL_marked_for_death" "Marcado para morir"
- "PL_marked_for_death_abbr" "MPM"
- "PL_marked_for_death_desc" "Elimina o protege los objetivos marcados.\n^FFC83200Jugadores: 6vs6 \nLímite de tiempo: 12 min\nNúmero máximo de miembros del grupo: 6"
- "PL_marked_for_death_lobby" "Lobby de Marcado para morir"
- "PL_nitro_ffa" "TCT (Nitro)"
- "PL_nitro_ffa_abbr" "TCT-N"
- "PL_nitro_ffa_desc" "Todos contra todos acelerado en mapas seleccionados.\n^FFC83200Jugadores: 6\n^F4D5A600Sin titanes\nSin potenciadores"
- "PL_nitro_ffa_lobby" "Lobby de TCT (Nitro)"
- "PL_nitro_mixtape" "Diverso (Nitro)"
- "PL_nitro_mixtape_abbr" "DVS-N"
- "PL_nitro_mixtape_desc" "CLB, MPM y BDP acelerados en mapas seleccionados.\n^FFC83200Jugadores: 5vs5\nTamaño máximo del grupo: 5\n^F4D5A600Regresos de bandera al instante"
- "PL_nitro_mixtape_lobby" "Lobby de Diverso"
- "PL_pilot_hunter" "Escaramuza"
- "PL_pilot_hunter_abbr" "ECM"
- "PL_pilot_hunter_desc" "Elimina a los pilotos y titanes enemigos. \n^FFC83200Jugadores: 8vs8\nLímite de tiempo: 10 min.\nTamaño máximo del grupo: 8"
- "PL_pilot_hunter_lobby" "Lobby de Escaramuza"
- "PL_pilot_skirmish" "Batalla de pilotos"
- "PL_pilot_skirmish_abbr" "BDP"
- "PL_pilot_skirmish_desc" "Elimina a los pilotos enemigos. No se permiten despliegues de titán.\n^FFC83200Jugadores: 8vs8 *Sin titanes\nLímite de tiempo: 10 min.\nTamaño máximo del grupo: 8"
- "PL_pilot_skirmish_lobby" "Lobby BDP"
- "PL_pl_rebuild_all_paths" "Reconstruir todos los caminos"
- "PL_pl_run_with_ai_ainrebuildonmapstart_2" "Ejecutar con ai_ainRebuildOnMapStart 2"
- "PL_private_match" "Partida privada (beta)"
- "PL_private_match_desc" "Juega una partida privada personalizada en el mapa y modo que quieras.\n^FFC83200INVITAR RED o INVITAR AMIGOS para jugar\n^FFC83200Jugadores: 1-16\nSin progresión"
- "PL_private_match_lobby" "Lobby de la Beta de partida privada"
- "PL_promo_coop" "COOPERATIVO de 4 jugadores"
- "PL_raid" "Incursión"
- "PL_rise" "Ascenso 24/7"
- "PL_rise_abbr" "ASC"
- "PL_rise_desc" "Ascenso, sin interrupciones. ^CCCCCC00Buscará partidas de ^FFC83200CLB^CCCCCC00, ^FFC83200Punto clave amplificado^CCCCCC00, ^FFC83200Batalla de pilotos^CCCCCC00, ^FFC83200Fuego vivo^CCCCCC00 y ^FFC83200Último titán en pie^CCCCCC00."
- "PL_rise_lobby" "Lobby de Ascenso 24/7"
- "PL_rocket_arena" "Zona de misiles"
- "PL_rocket_arena_abbr" "FV"
- "PL_rocket_arena_desc" "Las reglas clásicas de Fuego vivo con EPGs modificadas.^FFC83200\nJugadores: 6vs6 *Sin titanes\nLímite de tiempo: 90 s *Sin regeneraciones\nTamaño máximo del grupo: 6"
- "PL_rocket_arena_lobby" "Lobby de Zona de misiles"
- "PL_settings_for_when_someone_loads_a_map_on_the_command_line_do_not_edit_the_cmdlinemapload_1_below_-_this_makes_this_work" "Configuraciones para cuando alguien carga un mapa en la línea de comandos. No edites la cmdlineMapLoad 1 debajo porque se encarga de que esto funcione."
- "PL_speedball" "Fuego vivo"
- "PL_speedball_desc" "Lucha por la posesión de una bandera neutral. Elimina al equipo enemigo o ten la bandera cuando se acabe el tiempo para ganar la ronda. Gana el primero con 5 rondas ganadas.\n^FFC83200Jugadores: 6vs6 *Sin titanes\nLímite de tiempo: 60 segundos por ronda *Sin regeneraciones\nNúmero máximo de miembros del grupo: 6"
- "PL_speedball_lobby" "Looby de Fuego vivo"
- "PL_tactikill" "Eliminación táctica en Deterioro"
- "PL_tactikill_abbr" "DET"
- "PL_tactikill_desc" "Las reglas clásicas de Deterioro, pero todas las habilidades tácticas se reemplazan por completo con cada eliminación.\n^FFC83200Jugadores: 6vs6 *IA\nLímite de tiempo: 10 min.\nTamaño máximo del grupo: 6"
- "PL_tactikill_lobby" "Lobby de Eliminación táctica en Deterioro"
- "PL_titan_brawl" "Pelea de titanes"
- "PL_titan_brawl_abbr" "PdT"
- "PL_titan_brawl_desc" "Elimina a los titanes enemigos. No se permiten pilotos.\n^FFC83200Jugadores: 5vs5\nLímite de tiempo: 10 min.\nTamaño máximo del grupo: 5"
- "PL_titan_brawl_hint" "Elimina a los titanes enemigos.\nSin eyección"
- "PL_titan_brawl_lobby" "Lobby de Pelea de titanes"
- "PL_titan_brawl_turbo" "Pelea de titanes turbo"
- "PL_titan_brawl_turbo_abbr" "PdTT"
- "PL_titan_brawl_turbo_desc" "Las reglas clásicas de Pelea de titanes con regeneración de impulsos y generación de núcleo más rápidas.\n^FFC83200Jugadores: 5vs5\nLímite de tiempo: 10 min.\nTamaño máximo del grupo: 5"
- "PL_titan_brawl_turbo_hint" "Elimina a los titanes enemigos.\nSin eyección"
- "PL_titan_brawl_turbo_lobby" "Lobby de Pelea de titanes turbo"
- "PL_turbo_last_titan_standing" "UTEP turbo"
- "PL_turbo_last_titan_standing_abbr" "UTEP"
- "PL_turbo_last_titan_standing_desc" "Las reglas clásicas de UTEP con regeneración de impulsos y generación de núcleo más rápidas.\n^FFC83200Jugadores: 5vs5 *Comienza como titán\nLímite de tiempo: 3 min. por ronda *Sin regeneraciones\nTamaño máximo del grupo: 5"
- "PL_turbo_last_titan_standing_lobby" "Lobby de UTEP turbo"
- "PL_variety_pack" "Diverso"
- "PL_variety_pack_desc" "Número variado de jugadores con una gran variedad de mapas en estos modos:\n^FFC83200*Cazarrecompensas *Deterioro\n*Último titán en pie *Punto clave\n*Pilotos contra pilotos *Captura la bandera"
- "PL_variety_pack_lobby" "Lobby diverso"
- "PL_wargames" "Juegos de guerra 24/7"
- "PL_wargames_abbr" "JDG"
- "PL_wargames_desc" "Juegos de guerra, sin interrupciones. ^CCCCCC00Buscará partidas de ^FFC83200Deterioro^CCCCCC00, ^FFC83200CLB^CCCCCC00, ^FFC83200Batalla de pilotos^CCCCCC00, ^FFC83200Punto clave amplificado^CCCCCC00 y ^FFC83200Último titán en pie^CCCCCC00."
- "PL_wargames_lobby" "Lobby de Juegos de guerra 24/7"
- "WATCH_TUTORIAL" "VER TUTORIAL"
- }
- }
- }
-} \ No newline at end of file
diff --git a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_arena.gnut b/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_arena.gnut
deleted file mode 100644
index 4e6217e8..00000000
--- a/Northstar.Custom/scripts/vscripts/gamemodes/_gamemode_arena.gnut
+++ /dev/null
@@ -1,99 +0,0 @@
-global function GameModeArena_Init
-
-struct {
- entity imcBoostStore
- entity militiaBoostStore
-
- entity imcShield
- entity militiaShield
-} file
-
-void function GameModeArena_Init()
-{
- AddCallback_EntitiesDidLoad( CreateBoostStores )
- AddCallback_GameStateEnter( eGameState.Prematch, StartBuyPhase )
- AddCallback_GameStateEnter( eGameState.Playing, FinishBuyPhase )
-
- // todo: need a custom intro for this that allows players to move, buy etc in prematch
- // if that's actually possible lol not sure it is
-}
-
-void function CreateBoostStores()
-{
- array<entity> startspawns = GetEntArrayByClass_Expensive( "info_spawnpoint_human_start" ) // easier to do this than use a spawn callback imo
-
- vector imcAverageOrigin
- float imcAverageAngle
- int imcNumSpawns
-
- vector militiaAverageOrigin
- float militiaAverageAngle
- int militiaNumSpawns
-
- foreach ( entity startspawn in startspawns )
- {
- if ( startspawn.GetTeam() == TEAM_IMC )
- {
- imcAverageOrigin += startspawn.GetOrigin()
- imcAverageAngle += startspawn.GetAngles().y
- imcNumSpawns++
- }
- else
- {
- militiaAverageOrigin += startspawn.GetOrigin()
- militiaAverageAngle += startspawn.GetAngles().y
- militiaNumSpawns++
- }
- }
-
- // create imc boost store
- vector finalPositionImc = < imcAverageOrigin.x / imcNumSpawns, imcAverageOrigin.y / imcNumSpawns, imcAverageOrigin.z / imcNumSpawns >
- finalPositionImc += ( 200 * AnglesToForward( < 0, imcAverageAngle / imcNumSpawns, 0 > ) )
- CreateBoostStoreLocation( TEAM_IMC, finalPositionImc, < 0, 0, 0 >, true )
-
- vector finalPositionMilitia = < militiaAverageOrigin.x / militiaNumSpawns, militiaAverageOrigin.y / militiaNumSpawns, militiaAverageOrigin.z / militiaNumSpawns >
- finalPositionMilitia += ( 200 * AnglesToForward( < 0, militiaAverageAngle / militiaNumSpawns, 0 > ) )
- CreateBoostStoreLocation( TEAM_MILITIA, finalPositionMilitia, < 0, 0, 0 >, true )
-
- // createbooststorelocation is void so have to do this
- // also boost store code is just fully fucked lol, teams only get set on open so can't compare teams at this point
- // sorry if someone else makes their own boost stores lol this'll just break
- // if there's some way to get the invisible crates used for boost stores i will be very happy
-
- if ( GetBoostStores().len() != 2 )
- print( "_gamemode_arena.gnut: there are more than 2 boost stores, very bad no good" )
-
- file.imcBoostStore = GetBoostStores()[0]
- file.militiaBoostStore = GetBoostStores()[1]
-}
-
-void function StartBuyPhase()
-{
- //file.imcShield = CreateBubbleShieldWithSettings( TEAM_IMC, file.imcBoostStore.GetOrigin(), <0,0,0>, null, 15.0 )
- //file.militiaShield = CreateBubbleShieldWithSettings( TEAM_MILITIA, file.militiaBoostStore.GetOrigin(), <0,0,0>, null, 15.0 )
-
- entity bubbleShield = CreateEntity( "prop_dynamic" )
- bubbleShield.SetValueForModelKey( $"models/fx/xo_shield.mdl" )
- bubbleShield.kv.solid = 0
- bubbleShield.kv.rendercolor = "255 255 255" // white
- bubbleShield.kv.modelscale = 2.25
- bubbleShield.SetOrigin( file.imcBoostStore.GetOrigin() )
- DispatchSpawn( bubbleShield )
-
- file.imcShield = bubbleShield
-
- //SetTeam( bubbleShield, TEAM_IMC )
-
- // current problem, there is seemingly no way of getting a shield we can resize which actually resizes the collision
- // could probably just damage players that try to leave lol
-
- OpenBoostStores()
-}
-
-void function FinishBuyPhase()
-{
- file.imcShield.Destroy()
- //file.militiaShield.Destroy()
-
- CloseBoostStores()
-} \ No newline at end of file
diff --git a/Northstar.Custom/vpk/client_mp_northstar_common.bsp.pak000_000.vpk b/Northstar.Custom/vpk/client_mp_northstar_common.bsp.pak000_000.vpk
new file mode 100644
index 00000000..1b8ef396
--- /dev/null
+++ b/Northstar.Custom/vpk/client_mp_northstar_common.bsp.pak000_000.vpk
Binary files differ
diff --git a/Northstar.Custom/vpk/englishclient_mp_northstar_common.bsp.pak000_dir.vpk b/Northstar.Custom/vpk/englishclient_mp_northstar_common.bsp.pak000_dir.vpk
new file mode 100644
index 00000000..4d71f977
--- /dev/null
+++ b/Northstar.Custom/vpk/englishclient_mp_northstar_common.bsp.pak000_dir.vpk
Binary files differ
diff --git a/Northstar.CustomServers/mod.json b/Northstar.CustomServers/mod.json
index 6e4d2d58..547a1b8c 100644
--- a/Northstar.CustomServers/mod.json
+++ b/Northstar.CustomServers/mod.json
@@ -1,15 +1,19 @@
{
- "ApiId" : "Northstar.CustomServers",
- "Name" : "Northstar.CustomServers",
- "Description" : "Various script patches to fix and reimplement functionality for custom multiplayer servers",
- "Authors" : [
- "BobTheBob"
- ],
- "Contacts" : [
- "BobTheBob#1150"
+ "Name": "Northstar.CustomServers",
+
+ "ConVars": [
+ {
+ "Name": "ns_lobby_type",
+ "DefaultValue": "0"
+ },
+
+ {
+ "Name": "ns_should_return_to_lobby",
+ "DefaultValue": "1"
+ }
],
- "Version" : "0.1",
- "CustomScripts": [
+
+ "Scripts": [
{
"Path": "_misc.gnut",
"RunOn": "SERVER && MP",
@@ -44,12 +48,16 @@
{
"Path": "gamemodes/_gamemode_fra.nut",
"RunOn": "SERVER && MP",
- "ServerPreCallback": "GamemodeFRA_AddAdditionalInitCallback"
+ "ServerCallback": {
+ "Before": "GamemodeFRA_AddAdditionalInitCallback"
+ }
},
{
"Path": "gamemodes/_featured_mode_settings.gnut",
"RunOn": "SERVER && MP",
- "ServerCallback": "FeaturedModeSettings_Init"
+ "ServerCallback": {
+ "After": "FeaturedModeSettings_Init"
+ }
},
{
@@ -64,7 +72,9 @@
{
"Path": "_loadouts_mp.gnut",
"RunOn": "SERVER && MP",
- "ServerCallback": "SvLoadoutsMP_Init"
+ "ServerCallback": {
+ "After": "SvLoadoutsMP_Init"
+ }
},
{
diff --git a/Northstar.CustomServers/mod/cfg/autoexec_ns_server.cfg b/Northstar.CustomServers/mod/cfg/autoexec_ns_server.cfg
new file mode 100644
index 00000000..09d2d72c
--- /dev/null
+++ b/Northstar.CustomServers/mod/cfg/autoexec_ns_server.cfg
@@ -0,0 +1,8 @@
+//ns_auth_allow_insecure 1
+ns_server_name "boba server (very cool)"
+ns_server_desc "fucign badass dude "
+
+everything_unlocked 1
+cl_updaterate_mp 60
+sv_updaterate_mp 60
+sv_max_snapshots_multiplayer 1500 \ No newline at end of file
diff --git a/Northstar.CustomServers/cfg/server/persistent_player_data_version_231.pdef b/Northstar.CustomServers/mod/cfg/server/persistent_player_data_version_231.pdef
index c4af215a..c4af215a 100644
--- a/Northstar.CustomServers/cfg/server/persistent_player_data_version_231.pdef
+++ b/Northstar.CustomServers/mod/cfg/server/persistent_player_data_version_231.pdef
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_drone.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_drone.txt
index 64f151c7..64f151c7 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_drone.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_drone.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_dropship.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_dropship.txt
index a3a712e9..a3a712e9 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_dropship.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_dropship.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_flyer.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_flyer.txt
index a7a995f5..a7a995f5 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_flyer.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_flyer.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_frag_drone.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_frag_drone.txt
index c7459d71..c7459d71 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_frag_drone.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_frag_drone.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_goliath.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_goliath.txt
index c4dad6ab..c4dad6ab 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_goliath.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_goliath.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_gunship.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_gunship.txt
index b62c0793..b62c0793 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_gunship.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_gunship.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_marvin.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_marvin.txt
index 351b9ff7..351b9ff7 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_marvin.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_marvin.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_mp_auto_titan.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_mp_auto_titan.txt
index 74742e99..74742e99 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_mp_auto_titan.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_mp_auto_titan.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_mp_auto_titan_enhanced.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_mp_auto_titan_enhanced.txt
index 8e1bc7c1..8e1bc7c1 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_mp_auto_titan_enhanced.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_mp_auto_titan_enhanced.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_mp_auto_titan_enhanced_guard.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_mp_auto_titan_enhanced_guard.txt
index e68c6ab5..e68c6ab5 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_mp_auto_titan_enhanced_guard.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_mp_auto_titan_enhanced_guard.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_mp_auto_titan_guard.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_mp_auto_titan_guard.txt
index 07dacfaa..07dacfaa 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_mp_auto_titan_guard.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_mp_auto_titan_guard.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_pilot_elite.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_pilot_elite.txt
index e68f7ddb..e68f7ddb 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_pilot_elite.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_pilot_elite.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_pilot_elite_assassin.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_pilot_elite_assassin.txt
index 278d4873..278d4873 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_pilot_elite_assassin.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_pilot_elite_assassin.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_pilot_elite_assassin_cqb.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_pilot_elite_assassin_cqb.txt
index 282e9b9b..282e9b9b 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_pilot_elite_assassin_cqb.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_pilot_elite_assassin_cqb.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_pilot_elite_assassin_sniper.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_pilot_elite_assassin_sniper.txt
index 144654ab..144654ab 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_pilot_elite_assassin_sniper.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_pilot_elite_assassin_sniper.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_prowler.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_prowler.txt
index f5feb8c7..f5feb8c7 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_prowler.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_prowler.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_prowler_cqb.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_prowler_cqb.txt
index bff35f0b..bff35f0b 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_prowler_cqb.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_prowler_cqb.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_soldier.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_soldier.txt
index 106014c3..106014c3 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_soldier.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_soldier.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_sp_auto_titan.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_sp_auto_titan.txt
index be309949..be309949 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_sp_auto_titan.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_sp_auto_titan.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_sp_npc_titan_proto_stasisgun.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_sp_npc_titan_proto_stasisgun.txt
index b93d2249..b93d2249 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_sp_npc_titan_proto_stasisgun.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_sp_npc_titan_proto_stasisgun.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_sp_soldier.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_sp_soldier.txt
index 38ed82e5..38ed82e5 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_sp_soldier.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_sp_soldier.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_spectre.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_spectre.txt
index 66937c70..66937c70 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_spectre.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_spectre.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_stalker.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_stalker.txt
index 9bc1782a..9bc1782a 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_stalker.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_stalker.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_stalker_crawling.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_stalker_crawling.txt
index fac61cf5..fac61cf5 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_stalker_crawling.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_stalker_crawling.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_super_spectre.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_super_spectre.txt
index 341dd67a..341dd67a 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_super_spectre.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_super_spectre.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_titan.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan.txt
index 6070c68e..6070c68e 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_titan.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_buddy.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_buddy.txt
index 5636f267..5636f267 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_buddy.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_buddy.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_long_range.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_long_range.txt
index 0c378fe9..0c378fe9 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_long_range.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_long_range.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_melee.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_melee.txt
index d1f1b267..d1f1b267 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_melee.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_melee.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_melee_core.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_melee_core.txt
index 82193830..82193830 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_melee_core.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_melee_core.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_ogre_meteor.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_ogre_meteor.txt
index e189a512..e189a512 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_ogre_meteor.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_ogre_meteor.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_ogre_minigun.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_ogre_minigun.txt
index 8b13b689..8b13b689 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_ogre_minigun.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_ogre_minigun.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_ogre_minigun_nuke.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_ogre_minigun_nuke.txt
index 037f1505..037f1505 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_ogre_minigun_nuke.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_ogre_minigun_nuke.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_rocketeer.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_rocketeer.txt
index c9a25afe..c9a25afe 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_rocketeer.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_rocketeer.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_shotgun.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_shotgun.txt
index fe78babd..fe78babd 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_shotgun.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_shotgun.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_sniper.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_sniper.txt
index 87fa003f..87fa003f 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behavior_titan_sniper.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behavior_titan_sniper.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/behaviors.txt b/Northstar.CustomServers/mod/scripts/aibehavior/behaviors.txt
index 5fac7977..5fac7977 100644
--- a/Northstar.CustomServers/scripts/aibehavior/behaviors.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/behaviors.txt
diff --git a/Northstar.CustomServers/scripts/aibehavior/common_schedules.txt b/Northstar.CustomServers/mod/scripts/aibehavior/common_schedules.txt
index 8ef03ec4..8ef03ec4 100644
--- a/Northstar.CustomServers/scripts/aibehavior/common_schedules.txt
+++ b/Northstar.CustomServers/mod/scripts/aibehavior/common_schedules.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/base_vehicle.txt b/Northstar.CustomServers/mod/scripts/aisettings/base_vehicle.txt
index a13b3066..a13b3066 100644
--- a/Northstar.CustomServers/scripts/aisettings/base_vehicle.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/base_vehicle.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/classes.txt b/Northstar.CustomServers/mod/scripts/aisettings/classes.txt
index d250e2df..d250e2df 100644
--- a/Northstar.CustomServers/scripts/aisettings/classes.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/classes.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_bullseye.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_bullseye.txt
index 13a22de6..13a22de6 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_bullseye.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_bullseye.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_drone.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone.txt
index e2b65835..e2b65835 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_drone.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_drone_beam.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_beam.txt
index 388ee3d6..388ee3d6 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_drone_beam.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_beam.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_drone_cloaked.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_cloaked.txt
index 1f1fe079..1f1fe079 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_drone_cloaked.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_cloaked.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_drone_plasma.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_plasma.txt
index dd2665a4..dd2665a4 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_drone_plasma.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_plasma.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_drone_plasma_fast.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_plasma_fast.txt
index c05037c2..c05037c2 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_drone_plasma_fast.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_plasma_fast.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_drone_plasma_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_plasma_fd.txt
index 66140367..66140367 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_drone_plasma_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_plasma_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_drone_rocket.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_rocket.txt
index d330a3d2..d330a3d2 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_drone_rocket.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_rocket.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_drone_rocket_fast.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_rocket_fast.txt
index 7bd1a3e4..7bd1a3e4 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_drone_rocket_fast.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_rocket_fast.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_drone_shield.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_shield.txt
index e4e56d12..e4e56d12 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_drone_shield.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_shield.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_drone_worker.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_worker.txt
index f400d2c5..f400d2c5 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_drone_worker.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_worker.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_drone_worker_fast.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_worker_fast.txt
index e9e470bd..e9e470bd 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_drone_worker_fast.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_drone_worker_fast.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_dropship.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_dropship.txt
index 851b8f64..851b8f64 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_dropship.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_dropship.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_dropship_dogfighter.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_dropship_dogfighter.txt
index a2c6c88e..a2c6c88e 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_dropship_dogfighter.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_dropship_dogfighter.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_dropship_hero.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_dropship_hero.txt
index a7b9214c..a7b9214c 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_dropship_hero.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_dropship_hero.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_frag_drone.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_frag_drone.txt
index 9b435cdb..9b435cdb 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_frag_drone.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_frag_drone.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_frag_drone_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_frag_drone_fd.txt
index ce679d19..ce679d19 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_frag_drone_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_frag_drone_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_frag_drone_throwable.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_frag_drone_throwable.txt
index 53458c3c..53458c3c 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_frag_drone_throwable.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_frag_drone_throwable.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_gunship.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_gunship.txt
index e4df1fe1..e4df1fe1 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_gunship.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_gunship.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_gunship_scripted.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_gunship_scripted.txt
index e387551f..e387551f 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_gunship_scripted.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_gunship_scripted.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_marvin.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_marvin.txt
index 495f3cce..495f3cce 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_marvin.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_marvin.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_pilot_elite.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite.txt
index 8bd84029..8bd84029 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_pilot_elite.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_pilot_elite_assassin.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite_assassin.txt
index 144d4df1..144d4df1 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_pilot_elite_assassin.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite_assassin.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_pilot_elite_assassin_cqb.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite_assassin_cqb.txt
index 74bf638e..74bf638e 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_pilot_elite_assassin_cqb.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite_assassin_cqb.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_pilot_elite_assassin_sniper.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite_assassin_sniper.txt
index f9885b1d..f9885b1d 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_pilot_elite_assassin_sniper.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite_assassin_sniper.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_pilot_elite_s2s.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite_s2s.txt
index 2a497d2e..2a497d2e 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_pilot_elite_s2s.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_pilot_elite_s2s.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_prowler.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_prowler.txt
index 1df9538f..1df9538f 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_prowler.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_prowler.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier.txt
index e5dcfeb1..e5dcfeb1 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier_bish.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_bish.txt
index b4e6eee5..b4e6eee5 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier_bish.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_bish.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier_blisk.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_blisk.txt
index 82548c97..82548c97 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier_blisk.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_blisk.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier_drone_summoner.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_drone_summoner.txt
index 2ebedae2..2ebedae2 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier_drone_summoner.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_drone_summoner.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier_hero_bear.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_hero_bear.txt
index d10daea6..d10daea6 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier_hero_bear.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_hero_bear.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier_hero_sarah.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_hero_sarah.txt
index fcc3901b..fcc3901b 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier_hero_sarah.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_hero_sarah.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier_pve_eliteguard.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_pve_eliteguard.txt
index f09efada..f09efada 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier_pve_eliteguard.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_pve_eliteguard.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier_pve_sandbox.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_pve_sandbox.txt
index cb4e5784..cb4e5784 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier_pve_sandbox.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_pve_sandbox.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier_pve_specialist.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_pve_specialist.txt
index d3abdef2..d3abdef2 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier_pve_specialist.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_pve_specialist.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier_shield_captain.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_shield_captain.txt
index 96516c65..96516c65 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier_shield_captain.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_shield_captain.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier_sidearm.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_sidearm.txt
index e5062df0..e5062df0 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier_sidearm.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_sidearm.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier_specialist.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_specialist.txt
index fc7a77a0..fc7a77a0 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier_specialist.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_specialist.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier_specialist_militia.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_specialist_militia.txt
index f08a1346..f08a1346 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier_specialist_militia.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_specialist_militia.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier_spyglass.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_spyglass.txt
index 6fd6c86d..6fd6c86d 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier_spyglass.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_spyglass.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_soldier_training_sentry.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_training_sentry.txt
index 37634d9a..37634d9a 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_soldier_training_sentry.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_soldier_training_sentry.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_spectre.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_spectre.txt
index 27efebad..27efebad 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_spectre.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_spectre.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_spectre_mortar.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_spectre_mortar.txt
index 6c2151eb..6c2151eb 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_spectre_mortar.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_spectre_mortar.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_stalker.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_stalker.txt
index ae3347e9..ae3347e9 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_stalker.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_stalker.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_stalker_crawling.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_crawling.txt
index 3a251671..3a251671 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_stalker_crawling.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_crawling.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_stalker_crawling_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_crawling_fd.txt
index 62a9d7eb..62a9d7eb 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_stalker_crawling_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_crawling_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_stalker_crawling_mossy.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_crawling_mossy.txt
index 48fc894d..48fc894d 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_stalker_crawling_mossy.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_crawling_mossy.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_stalker_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_fd.txt
index cc21b441..cc21b441 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_stalker_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_stalker_zombie.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_zombie.txt
index fddee0fb..fddee0fb 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_stalker_zombie.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_zombie.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_stalker_zombie_mossy.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_zombie_mossy.txt
index 8dccbf6f..8dccbf6f 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_stalker_zombie_mossy.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_stalker_zombie_mossy.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_super_spectre.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre.txt
index f5d30aa5..f5d30aa5 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_super_spectre.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_super_spectre_aitdm.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre_aitdm.txt
index 1a9e1cf1..1a9e1cf1 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_super_spectre_aitdm.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre_aitdm.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_super_spectre_burnmeter.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre_burnmeter.txt
index fc52becd..fc52becd 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_super_spectre_burnmeter.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre_burnmeter.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_super_spectre_calmer.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre_calmer.txt
index 0acb249f..0acb249f 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_super_spectre_calmer.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre_calmer.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_super_spectre_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre_fd.txt
index 3a6a9da7..3a6a9da7 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_super_spectre_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_super_spectre_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan.txt
index b2d7f38f..b2d7f38f 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_arc.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_arc.txt
index 5cd5c2a3..5cd5c2a3 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_arc.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_arc.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas.txt
index 8ac0d2ea..8ac0d2ea 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_ion_prime_bounty.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_ion_prime_bounty.txt
index c042f71d..c042f71d 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_ion_prime_bounty.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_ion_prime_bounty.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_stickybomb.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_stickybomb.txt
index 0ce4acb3..0ce4acb3 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_stickybomb.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_stickybomb.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_stickybomb_boss_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_stickybomb_boss_fd.txt
index 0da91a35..0da91a35 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_stickybomb_boss_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_stickybomb_boss_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_stickybomb_bounty.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_stickybomb_bounty.txt
index 8fcda68e..8fcda68e 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_stickybomb_bounty.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_stickybomb_bounty.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker.txt
index 5a57b9ee..5a57b9ee 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker_boss_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker_boss_fd.txt
index 07a653c1..07a653c1 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker_boss_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker_boss_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker_bounty.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker_bounty.txt
index dc413e82..dc413e82 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker_bounty.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker_bounty.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker_fd_sniper.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker_fd_sniper.txt
index 1703dd9f..1703dd9f 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker_fd_sniper.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker_fd_sniper.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker_mortar.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker_mortar.txt
index 8dfc4baa..8dfc4baa 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_tracker_mortar.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_tracker_mortar.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_vanguard.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_vanguard.txt
index ec63b128..ec63b128 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_vanguard.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_vanguard.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_vanguard_boss_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_vanguard_boss_fd.txt
index 335eee59..335eee59 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_vanguard_boss_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_vanguard_boss_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_vanguard_bounty.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_vanguard_bounty.txt
index eebad86a..eebad86a 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_atlas_vanguard_bounty.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_atlas_vanguard_bounty.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto.txt
index 14f3c245..14f3c245 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas.txt
index 17a65f12..17a65f12 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_ion_prime.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_ion_prime.txt
index 5545e3d7..5545e3d7 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_ion_prime.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_ion_prime.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_rocketeer.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_rocketeer.txt
index 48fa9b99..48fa9b99 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_rocketeer.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_rocketeer.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_stickybomb.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_stickybomb.txt
index 72307ee8..72307ee8 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_stickybomb.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_stickybomb.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_tone_prime.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_tone_prime.txt
index a475466f..a475466f 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_tone_prime.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_tone_prime.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_tracker.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_tracker.txt
index 55bc4b0a..55bc4b0a 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_tracker.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_tracker.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_vanguard.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_vanguard.txt
index 9e002888..9e002888 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_atlas_vanguard.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_atlas_vanguard.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre.txt
index e291df60..e291df60 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_fighter.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_fighter.txt
index 921055c0..921055c0 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_fighter.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_fighter.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_legion_prime.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_legion_prime.txt
index 16afd226..16afd226 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_legion_prime.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_legion_prime.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_meteor.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_meteor.txt
index 385a401b..385a401b 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_meteor.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_meteor.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_minigun.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_minigun.txt
index 33e9b263..33e9b263 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_minigun.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_minigun.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_scorch_prime.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_scorch_prime.txt
index 8f0928b0..8f0928b0 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_ogre_scorch_prime.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_ogre_scorch_prime.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder.txt
index a1a6fbe9..a1a6fbe9 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_arc.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_arc.txt
index 82e384e8..82e384e8 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_arc.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_arc.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_leadwall.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_leadwall.txt
index 81896b86..81896b86 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_leadwall.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_leadwall.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_northstar_prime.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_northstar_prime.txt
index 0ce6d33e..0ce6d33e 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_northstar_prime.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_northstar_prime.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_ronin_prime.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_ronin_prime.txt
index 0d00942f..0d00942f 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_ronin_prime.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_ronin_prime.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_sniper.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_sniper.txt
index b43a5a0c..b43a5a0c 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_auto_stryder_sniper.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_auto_stryder_sniper.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_buddy.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_buddy.txt
index 453f0d2c..453f0d2c 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_buddy.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_buddy.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_buddy_s2s.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_buddy_s2s.txt
index 83b687ca..83b687ca 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_buddy_s2s.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_buddy_s2s.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_buddy_skyway.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_buddy_skyway.txt
index 12403bef..12403bef 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_buddy_skyway.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_buddy_skyway.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_mortar.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_mortar.txt
index 7f80721d..7f80721d 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_mortar.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_mortar.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_nuke.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_nuke.txt
index 3cd1eabb..3cd1eabb 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_nuke.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_nuke.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre.txt
index 7a284ae8..7a284ae8 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_fighter.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_fighter.txt
index d1f50477..d1f50477 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_fighter.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_fighter.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_fighter_berserker_core.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_fighter_berserker_core.txt
index c3058416..c3058416 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_fighter_berserker_core.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_fighter_berserker_core.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_legion_prime_bounty.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_legion_prime_bounty.txt
index 9c102839..9c102839 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_legion_prime_bounty.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_legion_prime_bounty.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_meteor.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_meteor.txt
index b935f34a..b935f34a 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_meteor.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_meteor.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_meteor_boss_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_meteor_boss_fd.txt
index ce863d29..ce863d29 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_meteor_boss_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_meteor_boss_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_meteor_bounty.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_meteor_bounty.txt
index 62a8afad..62a8afad 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_meteor_bounty.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_meteor_bounty.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_meteor_nuke.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_meteor_nuke.txt
index 5a73c6f0..5a73c6f0 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_meteor_nuke.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_meteor_nuke.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_minigun.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_minigun.txt
index 16055d80..16055d80 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_minigun.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_minigun.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_minigun_boss_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_minigun_boss_fd.txt
index 2587a331..2587a331 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_minigun_boss_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_minigun_boss_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_minigun_bounty.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_minigun_bounty.txt
index aa4ab86f..aa4ab86f 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_minigun_bounty.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_minigun_bounty.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_minigun_nuke.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_minigun_nuke.txt
index fba50cba..fba50cba 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_minigun_nuke.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_minigun_nuke.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_scorch_prime_bounty.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_scorch_prime_bounty.txt
index d8a8510d..d8a8510d 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_ogre_scorch_prime_bounty.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_ogre_scorch_prime_bounty.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_proto_stasisgun.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_proto_stasisgun.txt
index 57bd7864..57bd7864 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_proto_stasisgun.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_proto_stasisgun.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_sarah.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_sarah.txt
index 1030ad4e..1030ad4e 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_sarah.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_sarah.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_sniper.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_sniper.txt
index c4be82ae..c4be82ae 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_sniper.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_sniper.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder.txt
index 6257f377..6257f377 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_arc.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_arc.txt
index 37aec44e..37aec44e 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_arc.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_arc.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall.txt
index fc2111c1..fc2111c1 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall_arc.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall_arc.txt
index bdbfb50d..bdbfb50d 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall_arc.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall_arc.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall_boss_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall_boss_fd.txt
index 17f702ce..17f702ce 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall_boss_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall_boss_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall_bounty.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall_bounty.txt
index c5892a67..c5892a67 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall_bounty.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall_bounty.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall_shift_core.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall_shift_core.txt
index 9729cb7e..9729cb7e 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_leadwall_shift_core.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_leadwall_shift_core.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_northstar_prime_bounty.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_northstar_prime_bounty.txt
index 131a1085..131a1085 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_northstar_prime_bounty.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_northstar_prime_bounty.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_rocketeer.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_rocketeer.txt
index 2fa07fa7..2fa07fa7 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_rocketeer.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_rocketeer.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_rocketeer_dash_core.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_rocketeer_dash_core.txt
index b9691642..b9691642 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_rocketeer_dash_core.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_rocketeer_dash_core.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_sniper.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_sniper.txt
index b23e493e..b23e493e 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_sniper.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_sniper.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_sniper_boss_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_sniper_boss_fd.txt
index 90493d79..90493d79 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_sniper_boss_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_sniper_boss_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_sniper_bounty.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_sniper_bounty.txt
index 26c2ddc8..26c2ddc8 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_sniper_bounty.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_sniper_bounty.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_sniper_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_sniper_fd.txt
index 2a156b9a..2a156b9a 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_stryder_sniper_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_stryder_sniper_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_titan_vanguard.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_vanguard.txt
index 09daba77..09daba77 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_titan_vanguard.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_titan_vanguard.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_mega.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega.txt
index f44fa5c0..f44fa5c0 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_mega.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_mega_attrition.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_attrition.txt
index 8ea04829..8ea04829 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_mega_attrition.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_attrition.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_mega_fortwar.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_fortwar.txt
index 4c06f5d6..4c06f5d6 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_mega_fortwar.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_fortwar.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_mega_frontierdefense.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_frontierdefense.txt
index 1cb89fe6..1cb89fe6 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_mega_frontierdefense.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_frontierdefense.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_mega_nowindup.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_nowindup.txt
index 91fc60a6..91fc60a6 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_mega_nowindup.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_nowindup.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_mega_old.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_old.txt
index ba3cff00..ba3cff00 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_mega_old.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_old.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_mega_windup.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_windup.txt
index adbd3e88..adbd3e88 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_mega_windup.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_mega_windup.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry.txt
index f5dfa5f7..f5dfa5f7 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_burn_card_ap.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_burn_card_ap.txt
index 9ec58611..9ec58611 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_burn_card_ap.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_burn_card_ap.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_burn_card_ap_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_burn_card_ap_fd.txt
index 16cce927..16cce927 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_burn_card_ap_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_burn_card_ap_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_burn_card_at.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_burn_card_at.txt
index 58a5c49c..58a5c49c 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_burn_card_at.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_burn_card_at.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_burn_card_at_fd.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_burn_card_at_fd.txt
index f120c79b..f120c79b 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_burn_card_at_fd.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_burn_card_at_fd.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_plasma.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_plasma.txt
index bad53ace..bad53ace 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_plasma.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_plasma.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_plasma_skyway.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_plasma_skyway.txt
index 1244c353..1244c353 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_plasma_skyway.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_plasma_skyway.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_tactical_ability.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_tactical_ability.txt
index ad6a15c0..ad6a15c0 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_tactical_ability.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_tactical_ability.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_tday.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_tday.txt
index c94ada19..c94ada19 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_tday.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_tday.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_windup.txt b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_windup.txt
index 4d92d825..4d92d825 100644
--- a/Northstar.CustomServers/scripts/aisettings/npc_turret_sentry_windup.txt
+++ b/Northstar.CustomServers/mod/scripts/aisettings/npc_turret_sentry_windup.txt
diff --git a/Northstar.CustomServers/scripts/aisettings/synced_melee_data.rson b/Northstar.CustomServers/mod/scripts/aisettings/synced_melee_data.rson
index f07e21c4..f07e21c4 100644
--- a/Northstar.CustomServers/scripts/aisettings/synced_melee_data.rson
+++ b/Northstar.CustomServers/mod/scripts/aisettings/synced_melee_data.rson
diff --git a/Northstar.CustomServers/scripts/vscripts/_anim.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_anim.gnut
index 2ead1d30..2ead1d30 100644
--- a/Northstar.CustomServers/scripts/vscripts/_anim.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_anim.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_auto_precache.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_auto_precache.gnut
index 75c7873e..75c7873e 100644
--- a/Northstar.CustomServers/scripts/vscripts/_auto_precache.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_auto_precache.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_bubble_shield.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_bubble_shield.gnut
index 30758bec..30758bec 100644
--- a/Northstar.CustomServers/scripts/vscripts/_bubble_shield.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_bubble_shield.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_codecallbacks_common.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_codecallbacks_common.gnut
index b08fdcf1..b08fdcf1 100644
--- a/Northstar.CustomServers/scripts/vscripts/_codecallbacks_common.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_codecallbacks_common.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_codecallbacks_player_input.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_codecallbacks_player_input.gnut
index 12062056..12062056 100644
--- a/Northstar.CustomServers/scripts/vscripts/_codecallbacks_player_input.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_codecallbacks_player_input.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_control_panel.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_control_panel.gnut
index f9d7a4ff..f9d7a4ff 100644
--- a/Northstar.CustomServers/scripts/vscripts/_control_panel.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_control_panel.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_dogfighter.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_dogfighter.gnut
index db616173..db616173 100644
--- a/Northstar.CustomServers/scripts/vscripts/_dogfighter.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_dogfighter.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_entitystructs.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_entitystructs.gnut
index 378ceae3..378ceae3 100644
--- a/Northstar.CustomServers/scripts/vscripts/_entitystructs.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_entitystructs.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_global_entities.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_global_entities.gnut
index 767436d9..767436d9 100644
--- a/Northstar.CustomServers/scripts/vscripts/_global_entities.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_global_entities.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_harvester.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_harvester.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/_harvester.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_harvester.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_health_regen.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_health_regen.gnut
index ded25dc3..ded25dc3 100644
--- a/Northstar.CustomServers/scripts/vscripts/_health_regen.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_health_regen.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_init.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_init.gnut
index fc9fe2b9..fc9fe2b9 100644
--- a/Northstar.CustomServers/scripts/vscripts/_init.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_init.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_loadouts_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut
index 2b7b90b3..2b7b90b3 100644
--- a/Northstar.CustomServers/scripts/vscripts/_loadouts_mp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_loadouts_mp.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_mapspawn.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_mapspawn.gnut
index 3efee093..3efee093 100644
--- a/Northstar.CustomServers/scripts/vscripts/_mapspawn.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_mapspawn.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_menu_callbacks.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_menu_callbacks.gnut
index 5b2c2c53..c116ac33 100644
--- a/Northstar.CustomServers/scripts/vscripts/_menu_callbacks.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_menu_callbacks.gnut
@@ -7,8 +7,11 @@ void function MenuCallbacks_Init()
bool function ClientCommandCallback_LeaveMatch( entity player, array<string> args )
{
- SavePdataForEntityIndex( player.GetPlayerIndex() )
+ // todo: ideally, it'd be nice to get clients to return to lobby here, rather than just dcing them
+ // kind of a pain tho, since we'd have to get it to call script code without a remote func, since that'd break compatibility
+
ClientCommand( player, "disconnect" )
+ //ClientCommand( player, "setplaylist tdm; map mp_lobby" )
return true
} \ No newline at end of file
diff --git a/Northstar.CustomServers/scripts/vscripts/_misc.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_misc.gnut
index ef7e629f..20b53c50 100644
--- a/Northstar.CustomServers/scripts/vscripts/_misc.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_misc.gnut
@@ -1,4 +1,4 @@
-//todo figure out where these should be and move them to those places
+//todo figure out where these stub functions should be and move them to those places
global function Spotting_Init
global function FW_Border_GlobalInit
global function IsVDUTitan
@@ -12,7 +12,16 @@ void function Spotting_Init()
void function FW_Border_GlobalInit()
{
- AddSpawnCallbackEditorClass( "func_brush", "func_brush_fw_territory_border", void function( entity e ) { GameModeRemove( e ) } )
+ AddSpawnCallbackEditorClass( "func_brush", "func_brush_fw_territory_border", RemoveFWBorder )
+}
+
+void function RemoveFWBorder( entity border )
+{
+ if ( GameModeRemove( border ) )
+ return
+
+ if ( !border.HasKey( "gamemode_" + GAMETYPE ) )
+ border.Destroy()
}
bool function IsVDUTitan(entity titan)
diff --git a/Northstar.CustomServers/scripts/vscripts/_networkvars.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_networkvars.gnut
index 14990a15..14990a15 100644
--- a/Northstar.CustomServers/scripts/vscripts/_networkvars.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_networkvars.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_objective.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_objective.gnut
index 893861bf..893861bf 100644
--- a/Northstar.CustomServers/scripts/vscripts/_objective.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_objective.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_on_spawned.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_on_spawned.gnut
index d1935d62..d1935d62 100644
--- a/Northstar.CustomServers/scripts/vscripts/_on_spawned.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_on_spawned.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_pain_death_sounds.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_pain_death_sounds.gnut
index 10d2b616..10d2b616 100644
--- a/Northstar.CustomServers/scripts/vscripts/_pain_death_sounds.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_pain_death_sounds.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_passives.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_passives.gnut
index 1264686e..1264686e 100644
--- a/Northstar.CustomServers/scripts/vscripts/_passives.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_passives.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_ping.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_ping.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/_ping.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_ping.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_powerup.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_powerup.gnut
index 03b9fcfc..03b9fcfc 100644
--- a/Northstar.CustomServers/scripts/vscripts/_powerup.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_powerup.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_remote_functions_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_remote_functions_mp.gnut
index 567954b1..567954b1 100644
--- a/Northstar.CustomServers/scripts/vscripts/_remote_functions_mp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_remote_functions_mp.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_script_movers.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_script_movers.gnut
index ca7b839b..ca7b839b 100644
--- a/Northstar.CustomServers/scripts/vscripts/_script_movers.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_script_movers.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_script_movers_light.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_script_movers_light.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/_script_movers_light.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_script_movers_light.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_script_triggers.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_script_triggers.gnut
index c5e026b3..c5e026b3 100644
--- a/Northstar.CustomServers/scripts/vscripts/_script_triggers.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_script_triggers.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_side_notifications.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_side_notifications.gnut
index 2b3d3993..2b3d3993 100644
--- a/Northstar.CustomServers/scripts/vscripts/_side_notifications.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_side_notifications.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_store.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_store.gnut
index 5ebf090a..5ebf090a 100644
--- a/Northstar.CustomServers/scripts/vscripts/_store.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_store.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_trigger_functions.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_trigger_functions.gnut
index 0f82d9a6..0f82d9a6 100644
--- a/Northstar.CustomServers/scripts/vscripts/_trigger_functions.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_trigger_functions.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_utility.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_utility.gnut
index 50851dae..50851dae 100644
--- a/Northstar.CustomServers/scripts/vscripts/_utility.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_utility.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_utility_shared.nut b/Northstar.CustomServers/mod/scripts/vscripts/_utility_shared.nut
index e3cb0dbf..e3cb0dbf 100644
--- a/Northstar.CustomServers/scripts/vscripts/_utility_shared.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_utility_shared.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/_viewcone.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_viewcone.gnut
index 025c9dfd..025c9dfd 100644
--- a/Northstar.CustomServers/scripts/vscripts/_viewcone.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_viewcone.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_vscript.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_vscript.gnut
index 52b69c5d..52b69c5d 100644
--- a/Northstar.CustomServers/scripts/vscripts/_vscript.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_vscript.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/_xp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/_xp.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/_xp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/_xp.gnut
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_boss_titan.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_boss_titan.gnut
new file mode 100644
index 00000000..da3058d7
--- /dev/null
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_boss_titan.gnut
@@ -0,0 +1,794 @@
+global function PlayerParentTest
+
+global function AIBossTitan_Init
+global function OnBossTitanPrimaryFire
+global function IsVDUTitan
+global function IsBossTitan
+global function GetBossTitanCharacterModel
+
+global function BossTitanRetreat
+global function BossTitanAdvance
+global function IsMercTitan
+global function GetMercCharacterID
+global function BossTitanIntro
+global function BossTitanVDUEnabled
+global function BossTitanPlayerView
+
+global function MakeMidHealthTitan
+
+global const float SLAMZOOM_TIME = 1.0
+global const float BOSS_TITAN_CORE_DAMAGE_SCALER_LOW = 0.6
+global const float BOSS_TITAN_CORE_DAMAGE_SCALER = 0.5
+
+void function AIBossTitan_Init()
+{
+ if ( IsMultiplayer() )
+ return
+
+ FlagInit( "BossTitanViewFollow" )
+
+ AddSpawnCallback( "npc_titan", NPCTitanSpawned )
+ AddDeathCallback( "npc_titan", OnBossTitanDeath )
+ AddCallback_OnTitanDoomed( OnBossTitanDoomed )
+ AddCallback_OnTitanHealthSegmentLost( OnTitanLostSegment )
+
+ AddSyncedMeleeServerCallback( GetSyncedMeleeChooser( "titan", "titan" ), OnBossTitanExecuted )
+
+ PrecacheParticleSystem( $"P_VDU_mflash" )
+
+ RegisterSignal( "BossTitanStartAnim" )
+ RegisterSignal( "BossTitanIntroEnded" )
+}
+
+void function OnBossTitanExecuted( SyncedMeleeChooser actions, SyncedMelee action, entity attacker, entity victim )
+{
+ if ( victim.IsNPC() && IsVDUTitan( victim ) && BossTitanVDUEnabled( victim ) )
+ {
+ string name = victim.ai.bossCharacterName == "" ? "Generic1" : victim.ai.bossCharacterName
+ int bossID = GetBossTitanID( name )
+ foreach ( player in GetPlayerArray() )
+ {
+ if ( player == attacker || IsMercTitan( victim ) )
+ {
+ Remote_CallFunction_NonReplay( player, "ServerCallback_BossTitanDeath", victim.GetEncodedEHandle(), bossID )
+ }
+ }
+ }
+}
+
+void function OnBossTitanDeath( entity titan, var damageInfo )
+{
+ int damageSourceId = DamageInfo_GetDamageSourceIdentifier( damageInfo )
+ if ( damageSourceId == eDamageSourceId.titan_execution )
+ return
+
+ entity soul = titan.GetTitanSoul()
+ if ( soul.IsEjecting() )
+ return
+
+ entity attacker = DamageInfo_GetAttacker( damageInfo )
+
+ if ( IsVDUTitan( titan ) && BossTitanVDUEnabled( titan ) )
+ {
+ foreach ( player in GetPlayerArray() )
+ {
+ if ( player == attacker || IsMercTitan( titan ) )
+ {
+ string name = titan.ai.bossCharacterName == "" ? "Generic1" : titan.ai.bossCharacterName
+ Remote_CallFunction_NonReplay( player, "ServerCallback_BossTitanDeath", titan.GetEncodedEHandle(), GetBossTitanID( name ) )
+ }
+ }
+ }
+}
+
+void function OnBossTitanDoomed( entity titan, var damageInfo )
+{
+ entity attacker = DamageInfo_GetAttacker( damageInfo )
+
+ if ( IsVDUTitan( titan ) && BossTitanVDUEnabled( titan ) )
+ {
+ foreach ( player in GetPlayerArray() )
+ {
+ if ( player == attacker || IsMercTitan( titan ) )
+ Remote_CallFunction_NonReplay( player, "ServerCallback_BossTitanDoomed", titan.GetEncodedEHandle() )
+ }
+ }
+}
+
+void function OnBossTitanCoreMitigation( entity titan, var damageInfo )
+{
+ int damageSourceID = DamageInfo_GetDamageSourceIdentifier( damageInfo )
+ switch ( damageSourceID )
+ {
+ case eDamageSourceId.mp_titancore_salvo_core:
+ DamageInfo_ScaleDamage( damageInfo, BOSS_TITAN_CORE_DAMAGE_SCALER_LOW )
+ return
+
+ // case eDamageSourceId.mp_titancore_laser_cannon: laser core handles this in mp_titanweapon_lasercannon.nut
+ case eDamageSourceId.mp_titancore_flame_wave:
+ case eDamageSourceId.mp_titancore_flame_wave_secondary:
+ case eDamageSourceId.mp_titancore_shift_core:
+ case eDamageSourceId.mp_titanweapon_flightcore_rockets:
+ case eDamageSourceId.mp_titancore_amp_core:
+ case damagedef_nuclear_core:
+ DamageInfo_ScaleDamage( damageInfo, BOSS_TITAN_CORE_DAMAGE_SCALER )
+ return
+ }
+
+ // SMART CORE
+ array<string> weaponMods = GetWeaponModsFromDamageInfo( damageInfo )
+ if ( weaponMods.contains( "Smart_Core" ) )
+ {
+ DamageInfo_ScaleDamage( damageInfo, BOSS_TITAN_CORE_DAMAGE_SCALER )
+ // DamageInfo_ScaleDamage( damageInfo, BOSS_TITAN_CORE_DAMAGE_SCALER_LOW )
+ return
+ }
+}
+
+void function NPCTitanSpawned( entity titan )
+{
+ Assert( !IsMultiplayer() )
+
+ if ( titan.GetTeam() == TEAM_IMC )
+ {
+ switch ( titan.ai.bossTitanType )
+ {
+ case TITAN_WEAK:
+ case TITAN_HENCH:
+ MakeMidHealthTitan( titan )
+
+ case TITAN_BOSS:
+ RegisterBossTitan( titan )
+ ApplyTitanDamageState( titan )
+
+ if ( titan.ai.bossTitanType == TITAN_BOSS )
+ AddEntityCallback_OnDamaged( titan, OnBossTitanCoreMitigation )
+
+ if ( titan.HasKey( "skip_boss_intro" ) && titan.GetValueForKey( "skip_boss_intro" ) == "1" )
+ return
+ thread BossTitanNoIntro( titan )
+ break;
+
+
+ case TITAN_MERC:
+ // TODO: This SetSkin() call should move to RegisterBossTitan() when the above TITAN_BOSS stuff is cleaned up/removed.
+ titan.SetSkin( 1 ) // all titan models have a boss titan version of the skin at index 1
+ RegisterBossTitan( titan )
+ ApplyTitanDamageState( titan )
+
+ AddEntityCallback_OnDamaged( titan, OnBossTitanCoreMitigation )
+
+ if ( titan.HasKey( "skip_boss_intro" ) && titan.GetValueForKey( "skip_boss_intro" ) == "1" )
+ return
+
+ if ( !titan.ai.bossTitanPlayIntro )
+ return
+
+ foreach ( player in GetPlayerArray() )
+ {
+ thread BossTitanIntro( player, titan )
+ }
+ break
+
+ // case TITAN_WEAK:
+ // MakeLowHealthTitan( titan )
+ // break
+
+ case TITAN_AUTO:
+ if ( !IsMultiplayer() && GetMapName() == "sp_hub_timeshift" || GetMapName() == "sp_timeshift_spoke02" )
+ MakeLowHealthTitan( titan )
+ break
+ default:
+ return
+ }
+ }
+}
+
+void function BossTitanNoIntro( entity titan )
+{
+ FlagWait( "PlayerDidSpawn" )
+
+ entity player = GetPlayerArray()[0]
+
+ player.EndSignal( "OnDeath" )
+ titan.EndSignal( "OnDeath" )
+
+ // Wait until player sees the boss titan
+ waitthread WaitForHotdropToEnd( titan )
+
+ while ( 1 )
+ {
+ waitthread WaitTillLookingAt( player, titan, true, 60, 5100 )
+ if ( titan.GetEnemy() == null )
+ titan.WaitSignal( "OnSeeEnemy" )
+ else
+ break
+ }
+
+ if ( BossTitanVDUEnabled( titan ) )
+ Remote_CallFunction_NonReplay( player, "ServerCallback_BossTitanNoIntro", titan.GetEncodedEHandle() )
+ AddEntityCallback_OnDamaged( titan, OnBossTitanDamaged )
+ AddTitanCallback_OnHealthSegmentLost( titan, OnBossTitanLostSegment )
+}
+
+void function BossTitanIntro( entity player, entity titan, BossTitanIntroData ornull introdata = null )
+{
+ Assert( titan.IsNPC() )
+ Assert( titan.ai.bossCharacterName != "" )
+
+ if ( introdata == null )
+ {
+ BossTitanIntroData defaultData = GetBossTitanIntroData( titan.ai.bossCharacterName )
+ introdata = defaultData
+ }
+
+ expect BossTitanIntroData( introdata )
+
+ player.EndSignal( "OnDeath" )
+ titan.EndSignal( "OnDeath" )
+
+ HideCrit( titan )
+ titan.SetValidHealthBarTarget( false )
+ titan.SetInvulnerable()
+
+ // Wait until player sees the boss titan
+
+ while ( titan.e.isHotDropping )
+ {
+ WaitFrame()
+ }
+
+ HideName( titan )
+ titan.kv.allowshoot = 0
+
+ if ( introdata.waitToStartFlag != "" )
+ FlagWait( introdata.waitToStartFlag )
+
+ if ( introdata.waitForLookat )
+ waitthread WaitTillLookingAt( player, titan, introdata.lookatDoTrace, introdata.lookatDegrees, introdata.lookatMinDist )
+
+ while ( IsPlayerDisembarking( player ) || IsPlayerEmbarking( player ) )
+ {
+ WaitFrame()
+ }
+
+ BossTitanData bossTitanData = GetBossTitanData( titan.ai.bossCharacterName )
+
+ // Create a ref node to animate on
+ vector refPos
+ vector refAngles
+
+ if ( bossTitanData.introAnimTitanRef != "" )
+ {
+ entity titanAnimRef = GetEntByScriptName( bossTitanData.introAnimTitanRef )
+ refPos = titanAnimRef.GetOrigin()
+ refAngles = titanAnimRef.GetAngles()
+ }
+ else
+ {
+ refPos = titan.GetOrigin()
+
+ vector vecToPlayer = Normalize( player.GetOrigin() - titan.GetOrigin() )
+ refAngles = VectorToAngles( vecToPlayer )
+ refAngles = FlattenAngles( refAngles )
+ }
+
+ entity ref
+ if ( introdata.parentRef != null )
+ {
+ ref = introdata.parentRef
+ }
+ else
+ ref = CreateScriptRef( refPos, refAngles )
+
+ entity soul = titan.GetTitanSoul()
+ if ( IsValid( soul.soul.bubbleShield ) )
+ {
+ soul.soul.bubbleShield.Destroy()
+ }
+
+ // Freeze player and clear up the screen
+ StartBossIntro( player, titan, introdata )
+ player.Hide()
+ player.SetVelocity( <0,0,0> )
+ player.FreezeControlsOnServer()
+ player.SetNoTarget( true )
+ player.SetInvulnerable()
+
+ // Do special player view movement
+ FlagSet( "BossTitanViewFollow" )
+
+ // Animate the boss titan
+ entity pilot = CreatePropDynamic( GetBossTitanCharacterModel( titan ) )
+ if ( introdata.parentRef != null )
+ {
+ if ( introdata.parentAttach != "" )
+ {
+ pilot.SetParent( introdata.parentRef, introdata.parentAttach )
+ }
+ else
+ {
+ pilot.SetParent( introdata.parentRef )
+ }
+ }
+ SetTeam( pilot, TEAM_IMC )
+
+ string pilotAnimName = bossTitanData.introAnimPilot
+ string titanAnimName = bossTitanData.introAnimTitan
+
+ float introDuration = 6.0
+
+ Assert( titan.Anim_HasSequence( titanAnimName ), "Your boss titan does not have an intro animation set, or it is missing." )
+
+ introDuration = titan.GetSequenceDuration( titanAnimName )
+
+ svGlobal.levelEnt.Signal( "BossTitanStartAnim" )
+
+ if ( introdata.parentAttach != "" )
+ {
+ thread PlayAnim( pilot, pilotAnimName, ref, introdata.parentAttach, 0.0 )
+ thread PlayAnim( titan, titanAnimName, ref, introdata.parentAttach, 0.0 )
+ }
+ else
+ {
+ thread PlayAnim( pilot, pilotAnimName, ref, 0.0 )
+ thread PlayAnim( titan, titanAnimName, ref, 0.0 )
+ }
+
+ Objective_Hide( player )
+
+ thread BossTitanPlayerView( player, titan, ref, bossTitanData.titanCameraAttachment )
+
+ wait introDuration - SLAMZOOM_TIME
+
+ // Player view returns to normal
+ FlagClear( "BossTitanViewFollow" )
+ EndBossIntro( player, titan )
+
+ wait SLAMZOOM_TIME
+
+ // Return the player screen and movement back to normal
+ player.UnfreezeControlsOnServer()
+ player.SetNoTarget( false )
+ player.ClearInvulnerable()
+ player.Show()
+ pilot.Destroy()
+
+ if ( IsValid( titan ) )
+ {
+ titan.ClearInvulnerable()
+ titan.Solid()
+ AddEntityCallback_OnDamaged( titan, OnBossTitanDamaged )
+ AddTitanCallback_OnHealthSegmentLost( titan, OnBossTitanLostSegment )
+ ShowName( titan )
+ titan.SetValidHealthBarTarget( true )
+ ShowCrit( titan )
+ Signal( titan, "BossTitanIntroEnded" )
+ }
+
+ wait 0.5
+
+ if ( Flag( "AutomaticCheckpointsEnabled" ) )
+ {
+ if ( introdata.checkpointOnlyIfPlayerTitan )
+ {
+ if ( player.IsTitan() )
+ CheckPoint_Forced()
+ }
+ else
+ CheckPoint_Forced()
+ }
+
+ wait 1.0
+
+ titan.kv.allowshoot = 1
+ Remote_CallFunction_NonReplay( player, "ServerCallback_BossTitanPostIntro", titan.GetEncodedEHandle(), BossTitanVDUEnabled( titan ) )
+}
+
+void function PlayerParentTest()
+{
+ entity player = GetPlayerArray()[0]
+
+ vector moverStartPos = player.EyePosition()
+ vector moverStartAng = FlattenAngles( player.GetAngles() )
+ entity mover = CreateScriptMover( moverStartPos, moverStartAng )
+
+ player.SnapEyeAngles( moverStartAng )
+ player.SetParent( mover, "", true )
+}
+
+void function BossTitanPlayerView( entity player, entity titan, entity ref, string titanCameraAttachment )
+{
+ bool hasTitanCameraAttachment = titanCameraAttachment != ""
+
+ EndSignal( player, "OnDeath" )
+ EndSignal( titan, "OnDeath" )
+
+ vector moverStartPos = player.CameraPosition()
+
+ vector camFeetDiff = < 0,0,-185 >//player.GetOrigin() - player.CameraPosition()
+
+ vector moverStartAng = player.CameraAngles()
+ entity mover = CreateScriptMover( moverStartPos, moverStartAng )
+
+ // player.SnapEyeAngles( moverStartAng )
+ // player.SetParent( mover, "", true )
+ // ViewConeZero( player )
+
+ entity camera = CreateEntity( "point_viewcontrol" )
+ camera.kv.spawnflags = 56 // infinite hold time, snap to goal angles, make player non-solid
+
+ camera.SetOrigin( player.CameraPosition() )
+ camera.SetAngles( player.CameraAngles() )
+ DispatchSpawn( camera )
+
+ camera.SetParent( mover, "", false )
+
+ OnThreadEnd(
+ function() : ( player, titan, mover, camera )
+ {
+ if ( IsValid( camera ) )
+ {
+ camera.Destroy()
+ }
+
+ mover.Destroy()
+
+ if ( IsValid( player ) )
+ {
+ player.ClearParent()
+ player.ClearViewEntity()
+ RemoveCinematicFlag( player, CE_FLAG_HIDE_MAIN_HUD )
+ RemoveCinematicFlag( player, CE_FLAG_TITAN_3P_CAM )
+ }
+
+ if ( IsAlive( titan ) && titan.IsNPC() )
+ {
+ titan.SetNoTarget( false )
+ titan.DisableNPCFlag( NPC_IGNORE_ALL )
+ }
+ }
+ )
+
+ // Slam Zoom In
+ float slamZoomTime = SLAMZOOM_TIME
+ float slamZoomTimeAccel = 0.3
+ float slamZoomTimeDecel = 0.3
+ vector viewOffset = < 200, 100, 160 >
+
+ vector viewPos = ref.GetOrigin() + ( AnglesToForward( ref.GetAngles() ) * viewOffset.x ) + ( AnglesToRight( ref.GetAngles() ) * viewOffset.y ) + ( AnglesToUp( ref.GetAngles() ) * viewOffset.z )
+ vector viewAngles = ref.GetAngles() + <0,180,0>
+ if ( hasTitanCameraAttachment )
+ {
+ WaitFrame()
+ int titanCameraAttachmentID = titan.LookupAttachment( titanCameraAttachment )
+ viewPos = titan.GetAttachmentOrigin( titanCameraAttachmentID )
+ viewAngles = titan.GetAttachmentAngles( titanCameraAttachmentID )
+ }
+
+ float blendTime = 0.5
+ float waittime = 0.3
+ float moveTime = slamZoomTime - blendTime - waittime
+
+ float startTime = Time()
+
+ player.SetVelocity( < 0,0,0 > )
+ player.MakeInvisible()
+ HolsterAndDisableWeapons( player )
+
+ wait waittime // wait for the AI to blend into the anim
+
+ if ( titan.IsNPC() )
+ {
+ titan.SetNoTarget( true )
+ titan.EnableNPCFlag( NPC_IGNORE_ALL )
+ }
+
+ AddCinematicFlag( player, CE_FLAG_HIDE_MAIN_HUD )
+ AddCinematicFlag( player, CE_FLAG_TITAN_3P_CAM )
+
+ mover.SetOrigin( player.CameraPosition() )
+ mover.SetAngles( player.CameraAngles() )
+ player.SetViewEntity( camera, true )
+
+ player.SetPredictionEnabled( false )
+ OnThreadEnd(
+ function() : ( player )
+ {
+ if ( IsValid( player ) )
+ player.SetPredictionEnabled( true )
+ }
+ )
+
+ while ( Time() - startTime < moveTime )
+ {
+ if ( hasTitanCameraAttachment )
+ {
+ int titanCameraAttachmentID = titan.LookupAttachment( titanCameraAttachment )
+ viewPos = titan.GetAttachmentOrigin( titanCameraAttachmentID )
+ viewAngles = titan.GetAttachmentAngles( titanCameraAttachmentID )
+ }
+ mover.NonPhysicsMoveTo( viewPos, moveTime - (Time() - startTime), 0, 0 )
+ mover.NonPhysicsRotateTo( viewAngles, moveTime - (Time() - startTime), 0, 0 )
+ wait 0.1
+ }
+
+ if ( hasTitanCameraAttachment )
+ {
+ mover.SetParent( titan, titanCameraAttachment, false, blendTime )
+ }
+
+ wait 0.5
+
+ int tagID = titan.LookupAttachment( "CHESTFOCUS" )
+ while ( Flag( "BossTitanViewFollow" ) )
+ {
+ vector lookVec = Normalize( titan.GetAttachmentOrigin( tagID ) - mover.GetOrigin() )
+ vector angles = VectorToAngles( lookVec )
+ if ( !hasTitanCameraAttachment )
+ mover.NonPhysicsRotateTo( angles, 0.2, 0.0, 0.0 )
+ WaitFrame()
+ }
+
+ // Slam Zoom Out
+
+ mover.ClearParent()
+
+ startTime = Time()
+ while ( Time() - startTime < slamZoomTime )
+ {
+ moverStartPos = player.GetOrigin() - camFeetDiff
+ moverStartAng = FlattenAngles( player.GetAngles() )
+ mover.NonPhysicsMoveTo( moverStartPos, slamZoomTime - (Time() - startTime), 0, 0 )
+ mover.NonPhysicsRotateTo( moverStartAng, slamZoomTime - (Time() - startTime), 0, 0 )
+ wait 0.1
+ }
+
+ // mover.NonPhysicsMoveTo( moverStartPos, slamZoomTime, slamZoomTimeDecel, slamZoomTimeAccel )
+ // mover.NonPhysicsRotateTo( moverStartAng, slamZoomTime, slamZoomTimeDecel, slamZoomTimeAccel )
+ // wait slamZoomTime
+
+ ClearPlayerAnimViewEntity( player )
+ player.SnapEyeAngles( moverStartAng )
+ DeployAndEnableWeapons( player )
+ player.MakeVisible()
+
+ EmitSoundOnEntity( player, "UI_Lobby_RankChip_Disable" )
+}
+
+void function OnBossTitanDamaged( entity titan, var damageInfo )
+{
+}
+
+void function OnBossTitanLostSegment( entity titan, entity attacker )
+{
+ if ( !titan.IsNPC() || !BossTitanVDUEnabled( titan ) )
+ return
+
+ foreach ( player in GetPlayerArray() )
+ {
+ if ( player == attacker || IsMercTitan( titan ) )
+ Remote_CallFunction_NonReplay( player, "ServerCallback_BossTitanLostSegment", titan.GetEncodedEHandle(), GetTitanCurrentRegenTab( titan ) )
+ }
+}
+
+void function OnBossTitanPrimaryFire( entity titan )
+{
+}
+
+bool function IsVDUTitan( entity titan )
+{
+ Assert( IsSingleplayer() )
+
+ if ( titan.GetTeam() != TEAM_IMC )
+ return false
+
+ switch ( titan.ai.bossTitanType )
+ {
+ case TITAN_AUTO:
+ case TITAN_WEAK:
+ return false
+
+ case TITAN_HENCH:
+ case TITAN_MERC:
+ case TITAN_BOSS:
+ return true
+ }
+
+ Assert( 0, "Unknown boss titan type " + titan.ai.bossTitanType )
+ unreachable
+}
+
+bool function IsBossTitan( entity titan )
+{
+ Assert( IsSingleplayer() )
+
+ if ( titan.GetTeam() != TEAM_IMC )
+ return false
+
+ switch ( titan.ai.bossTitanType )
+ {
+ case TITAN_MERC:
+ case TITAN_BOSS:
+ return true
+ }
+
+ return false
+}
+
+int function GetMercCharacterID( entity titan )
+{
+ return titan.ai.mercCharacterID
+}
+
+asset function GetBossTitanCharacterModel( entity titan )
+{
+ int mercCharacterID = GetMercCharacterID( titan )
+ return GetMercCharacterModel( mercCharacterID )
+}
+
+void function OnTitanLostSegment( entity titan, entity attacker )
+{
+ entity player
+
+ if ( !titan.IsPlayer() )
+ player = titan.GetBossPlayer()
+ else
+ player = titan
+
+ if ( !IsValid( player ) )
+ return
+
+ if ( !IsValid( attacker ) )
+ return
+
+ if ( !attacker.IsNPC() || !IsVDUTitan( attacker ) || !BossTitanVDUEnabled( attacker ) )
+ return
+
+ Remote_CallFunction_NonReplay( player, "BossTitanPlayerLostHealthSegment", GetSegmentHealthForTitan( titan ) )
+}
+
+void function BossTitanRetreat( entity titan )
+{
+ if ( !IsVDUTitan( titan ) || !BossTitanVDUEnabled( titan ) )
+ return
+
+ foreach ( player in GetPlayerArray() )
+ {
+ Remote_CallFunction_NonReplay( player, "ServerCallback_BossTitanRetreat", titan.GetEncodedEHandle() )
+ }
+}
+
+void function BossTitanAdvance( entity titan )
+{
+ if ( !IsVDUTitan( titan ) || !BossTitanVDUEnabled( titan ) )
+ return
+
+ foreach ( player in GetPlayerArray() )
+ {
+ Remote_CallFunction_NonReplay( player, "ServerCallback_BossTitanAdvance", titan.GetEncodedEHandle() )
+ }
+}
+
+/*
+------------------------------------------------------------
+Low Health Titans
+------------------------------------------------------------
+*/
+
+void function MakeLowHealthTitan( entity ent )
+{
+ entity soul = ent.GetTitanSoul()
+ soul.soul.regensHealth = false
+ thread SetHealthValuesForLowHealth( soul )
+ //ent.SetValidHealthBarTarget( false )
+
+ ent.TakeOffhandWeapon( OFFHAND_ORDNANCE )
+ ent.TakeOffhandWeapon( OFFHAND_ANTIRODEO )
+ ent.TakeOffhandWeapon( OFFHAND_EQUIPMENT )
+ ent.TakeOffhandWeapon( OFFHAND_SPECIAL )
+}
+
+void function MakeMidHealthTitan( entity ent )
+{
+ entity soul = ent.GetTitanSoul()
+ soul.soul.regensHealth = false
+ thread SetHealthValuesForMidHealth( soul )
+}
+
+void function SetHealthValuesForMidHealth( entity soul )
+{
+ soul.EndSignal( "OnDestroy" )
+ WaitEndFrame() // wait for a bunch of variables to start up
+ soul.Signal( SIGNAL_TITAN_HEALTH_REGEN )
+ soul.Signal( "StopShieldRegen" )
+ soul.SetShieldHealth( 0 )
+
+ entity titan = soul.GetTitan()
+ int numSegments = ( titan.GetMaxHealth() / GetSegmentHealthForTitan( titan ) ) - 2
+ Assert( numSegments > 0 )
+ SetSoulBatteryCount( soul, numSegments )
+ if ( IsAlive( titan ) )
+ {
+ soul.soul.skipDoomState = true
+ int segmentHealth = GetSegmentHealthForTitan( titan ) * numSegments
+ titan.SetMaxHealth( segmentHealth )
+ titan.SetHealth( segmentHealth )
+ titan.kv.healthEvalMultiplier = 2
+ }
+
+ titan.Signal( "WeakTitanHealthInitialized" )
+
+ ApplyTitanDamageState( titan )
+}
+
+void function SetHealthValuesForLowHealth( entity soul )
+{
+ soul.EndSignal( "OnDestroy" )
+ WaitEndFrame() // wait for a bunch of variables to start up
+ soul.Signal( SIGNAL_TITAN_HEALTH_REGEN )
+ soul.Signal( "StopShieldRegen" )
+ soul.SetShieldHealth( 0 )
+
+ int numSegments = 2
+
+ SetSoulBatteryCount( soul, numSegments )
+ entity titan = soul.GetTitan()
+ if ( IsAlive( titan ) )
+ {
+ soul.soul.skipDoomState = true
+ int segmentHealth = GetSegmentHealthForTitan( titan ) * numSegments
+ titan.SetMaxHealth( segmentHealth )
+ titan.SetHealth( segmentHealth )
+ titan.kv.healthEvalMultiplier = 2
+ }
+
+ titan.Signal( "WeakTitanHealthInitialized" )
+
+ ApplyTitanDamageState( titan )
+}
+
+void function ApplyTitanDamageState( entity titan )
+{
+ array<float> healthScale = [
+ 1.0,
+ 0.6,
+ 0.3,
+ 0.1
+ ]
+
+ int state = 0
+
+ if ( titan.HasKey( "DamageState" ) )
+ {
+ state = int( titan.GetValueForKey( "DamageState" ) )
+ }
+
+ titan.SetHealth( titan.GetMaxHealth() * healthScale[state] )
+
+ if ( state >= 1 )
+ {
+ string part = [
+ "left_arm",
+ "right_arm"
+ ].getrandom()
+ GibBodyPart( titan, part )
+ }
+
+ if ( state >= 2 )
+ GibBodyPart( titan, "torso" )
+}
+
+bool function IsMercTitan( entity titan )
+{
+ if ( IsMultiplayer() )
+ return false
+ if ( titan.GetTeam() != TEAM_IMC )
+ return false
+ return titan.ai.bossTitanType == TITAN_MERC
+}
+
+bool function BossTitanVDUEnabled( entity titan )
+{
+ return titan.ai.bossTitanVDUEnabled
+} \ No newline at end of file
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_chatter.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_chatter.gnut
index 0429895b..0429895b 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_chatter.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_chatter.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_cloak_drone.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_cloak_drone.gnut
index e3addf81..e3addf81 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_cloak_drone.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_cloak_drone.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_drone.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_drone.gnut
index c0d56de7..c0d56de7 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_drone.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_drone.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_emp_titans.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_emp_titans.gnut
index 638166c8..638166c8 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_emp_titans.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_emp_titans.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_gunship.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_gunship.gnut
index 2f1fdc96..2f1fdc96 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_gunship.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_gunship.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_lethality.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_lethality.gnut
index 771fe6d9..771fe6d9 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_lethality.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_lethality.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_marvin_faces.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_marvin_faces.gnut
index e6d3bcf0..e6d3bcf0 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_marvin_faces.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_marvin_faces.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_marvin_jobs.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_marvin_jobs.gnut
index 588b4d75..588b4d75 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_marvin_jobs.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_marvin_jobs.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_marvins.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_marvins.gnut
index fc8b7d1e..fc8b7d1e 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_marvins.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_marvins.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_mortar_spectres.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_mortar_spectres.gnut
index 4aa3ac30..4aa3ac30 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_mortar_spectres.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_mortar_spectres.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_mortar_titans.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_mortar_titans.gnut
index 08598808..08598808 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_mortar_titans.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_mortar_titans.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_nuke_titans.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_nuke_titans.gnut
index 0d4b43c9..0d4b43c9 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_nuke_titans.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_nuke_titans.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_personal_shield.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_personal_shield.gnut
index f1fbdb80..f1fbdb80 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_personal_shield.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_personal_shield.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_pilots.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_pilots.gnut
index 3c2e36ce..3c2e36ce 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_pilots.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_pilots.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_sniper_titans.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_sniper_titans.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_sniper_titans.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_sniper_titans.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_soldiers.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_soldiers.gnut
index 9717c76d..9717c76d 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_soldiers.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_soldiers.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_soldiers_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_soldiers_mp.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_soldiers_mp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_soldiers_mp.gnut
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_soldiers_sp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_soldiers_sp.gnut
new file mode 100644
index 00000000..6faf6649
--- /dev/null
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_soldiers_sp.gnut
@@ -0,0 +1,17 @@
+global function IsAutoPopulateEnabled
+
+bool function IsAutoPopulateEnabled( var team = null )
+{
+ if ( IsNPCSpawningEnabled() == false )
+ return false
+
+ if ( Flag( "disable_npcs" ) )
+ return false
+
+ if ( team == TEAM_MILITIA && Flag( "Disable_MILITIA" ) )
+ return false
+ if ( team == TEAM_IMC && Flag( "Disable_IMC" ) )
+ return false
+
+ return true
+} \ No newline at end of file
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_spawn.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_spawn.gnut
index 7e4d2cdd..7e4d2cdd 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_spawn.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_spawn.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_spawn_content.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_spawn_content.gnut
index c6e7f9f4..c6e7f9f4 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_spawn_content.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_spawn_content.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_spectre.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_spectre.gnut
index 214aff96..214aff96 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_spectre.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_spectre.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_stalker.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_stalker.gnut
index f49560e0..f49560e0 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_stalker.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_stalker.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_stationary_firing_positions.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_stationary_firing_positions.gnut
index 50b6cc75..50b6cc75 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_stationary_firing_positions.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_stationary_firing_positions.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_suicide_spectres.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_suicide_spectres.gnut
index f8e0652c..f8e0652c 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_suicide_spectres.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_suicide_spectres.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_turret.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret.gnut
index eca5849b..eca5849b 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_turret.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret.gnut
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret_sentry.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret_sentry.gnut
new file mode 100644
index 00000000..e34b3082
--- /dev/null
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_turret_sentry.gnut
@@ -0,0 +1,72 @@
+global function AiTurretSentry_Init
+
+const DEAD_SENTRY_TURRET_FX = $"P_impact_exp_med_air"
+const DEAD_SENTRY_TURRET_SFX = "SentryTurret_DeathExplo"
+const SENTRY_TURRET_AIM_FX_RED = $"P_wpn_lasercannon_aim_short"
+const SENTRY_TURRET_AIM_FX_BLUE = $"P_wpn_lasercannon_aim_short_blue"
+
+void function AiTurretSentry_Init()
+{
+ PrecacheParticleSystem( DEAD_SENTRY_TURRET_FX )
+ //PrecacheParticleSystem( SENTRY_TURRET_AIM_FX_RED )
+ //PrecacheParticleSystem( SENTRY_TURRET_AIM_FX_BLUE )
+ //PrecacheParticleSystem( SENTRY_TURRET_AIM_FX2 )
+
+ AddSpawnCallback( "npc_turret_sentry", LightTurretSpawnFunction )
+ AddDeathCallback( "npc_turret_sentry", LightTurretDeathFX )
+
+ //RegisterSignal( "TurretDisabled" )
+ //RegisterSignal( "HandleTargetDeath" )
+ //RegisterSignal( "OnPlayerDisconnectResetTurret" )
+ //RegisterSignal( "Deactivate_Turret" )
+ //RegisterSignal( "TurretShieldWallRelease")
+ //RegisterSignal( "DestroyShieldFX")
+}
+
+void function LightTurretDeathFX( entity turret, var damageInfo )
+{
+ turret.SetBodygroup( 0, 1 )
+
+ int turretEHandle = turret.GetEncodedEHandle()
+ array<entity> players = GetPlayerArray()
+ foreach( player in players )
+ {
+ Remote_CallFunction_Replay( player, "ServerCallback_TurretRefresh", turretEHandle )
+ }
+
+ EmitSoundAtPosition( turret.GetTeam(), turret.GetOrigin(), DEAD_SENTRY_TURRET_SFX )
+ PlayFX( DEAD_SENTRY_TURRET_FX, turret.GetOrigin() + Vector( 0,0,38 ) ) // played with a slight offset as requested by BigRig
+}
+
+//////////////////////////////////////////////////////////
+void function LightTurretSpawnFunction( entity turret )
+{
+ turret.UnsetUsable()
+
+// float windupTime = TurretGetWindupTime( turret )
+// if ( windupTime > 0 )
+// thread HACK_TurretManagePreAttack( turret, OnWindupBegin_SentryTurret, OnWindupEnd_Turret )
+//
+ if ( turret.Dev_GetAISettingByKeyField( "aim_laser_disabled" ) )
+ return
+
+ thread SentryTurretAimLaser( turret )
+}
+
+void function SentryTurretAimLaser( entity turret )
+{
+ entity fx1 = PlayLoopFXOnEntity( SENTRY_TURRET_AIM_FX_RED, turret, "camera_glow", null, null, ENTITY_VISIBLE_TO_ENEMY )
+ entity fx2 = PlayLoopFXOnEntity( SENTRY_TURRET_AIM_FX_BLUE, turret, "camera_glow", null, null, ENTITY_VISIBLE_TO_FRIENDLY )
+
+ OnThreadEnd(
+ function() : ( fx1, fx2 )
+ {
+ if ( IsValid( fx1 ) )
+ EffectStop( fx1 )
+ if ( IsValid( fx2 ) )
+ EffectStop( fx2 )
+ }
+ )
+
+ WaitSignal( turret, "OnDeath" )
+}
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_utility.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_utility.gnut
index 67c68600..67c68600 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_utility.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_utility.gnut
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_droppod.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_droppod.gnut
new file mode 100644
index 00000000..40a7d932
--- /dev/null
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_droppod.gnut
@@ -0,0 +1,187 @@
+untyped
+
+global function DropPod_Init
+
+global function CreateDropPod
+global function LaunchAnimDropPod
+global function GetDropPodAnimDuration
+global function CreateDropPodSmokeTrail
+
+const DP_COLL_MODEL = $"models/vehicle/droppod_fireteam/droppod_fireteam_collision.mdl"
+const DROPPOD_MODEL = $"models/vehicle/droppod_fireteam/droppod_fireteam.mdl"
+
+function DropPod_Init()
+{
+ PrecacheModel( DROPPOD_MODEL )
+
+ RegisterSignal( "OnLaunch" )
+ RegisterSignal( "OnImpact" )
+
+ PrecacheModel( DP_COLL_MODEL )
+
+ PrecacheEffect( $"droppod_trail" )
+ PrecacheEffect( $"droppod_impact" )
+}
+
+
+function GetDropPodAnimDuration()
+{
+ // hack seems bad to spawn an ent to get this info
+ entity dropPod = CreateDropPod()
+
+ local animDuration = dropPod.GetSequenceDuration( "pod_testpath" )
+ dropPod.Destroy()
+
+ return animDuration
+}
+
+function LaunchAnimDropPod( entity dropPod, string anim, vector targetOrigin, vector targetAngles )
+{
+ dropPod.EndSignal( "OnDestroy" )
+ dropPod.EnableRenderAlways()
+
+ dropPod.s.launchAnim <- anim
+
+ int team = dropPod.GetTeam()
+
+ entity ref = CreateOwnedScriptMover( dropPod )
+ ref.SetOrigin( targetOrigin )
+ ref.SetAngles( targetAngles )
+
+ OnThreadEnd(
+ function () : ( dropPod, ref )
+ {
+ if ( IsValid( dropPod ) )
+ {
+ dropPod.ClearParent()
+ }
+
+ if ( IsValid( ref ) )
+ ref.Kill_Deprecated_UseDestroyInstead()
+ }
+ )
+
+ local e = {}
+ e.targetOrigin <- targetOrigin
+ e.targetAngles <- targetAngles
+
+ AddAnimEvent( dropPod, "OnImpact", DropPodOnImpactFXAndShake, e )
+ EmitSoundOnEntity( dropPod, "spectre_drop_pod" )
+
+ FirstPersonSequenceStruct sequence
+ sequence.thirdPersonAnim = anim
+
+ sequence.blendTime = 0.0
+ sequence.attachment = "ref"
+ sequence.useAnimatedRefAttachment = true
+ //DrawArrow( ref.GetOrigin(), ref.GetAngles(), 5, 100 )
+ waitthread FirstPersonSequence( sequence, dropPod, ref )
+ dropPod.DisableRenderAlways()
+// WaitFrame()
+}
+
+function CheckPlayersIntersectingPod( pod, targetOrigin )
+{
+ array<entity> playerList = GetPlayerArray()
+
+ // Multiplying the bounds by 1.42 to ensure this encloses the droppod when it's rotated 45 degrees
+ local mins = pod.GetBoundingMins() * 1.42 + targetOrigin
+ local maxs = pod.GetBoundingMaxs() * 1.42 + targetOrigin
+ local safeRadiusSqr = 250 * 250
+
+ foreach ( player in playerList )
+ {
+ local playerOrigin = player.GetOrigin()
+
+ if ( DistanceSqr( targetOrigin, playerOrigin ) > safeRadiusSqr )
+ continue
+
+ local playerMins = player.GetBoundingMins() + playerOrigin
+ local playerMaxs = player.GetBoundingMaxs() + playerOrigin
+
+ if ( BoxIntersectsBox( mins, maxs, playerMins, playerMaxs ) )
+ return true
+ }
+
+ return false
+}
+
+entity function CreateDropPod( vector ornull origin = null, vector ornull angles = null )
+{
+ entity prop_dynamic = CreateEntity( "prop_dynamic" )
+ prop_dynamic.SetValueForModelKey( DROPPOD_MODEL )
+ prop_dynamic.kv.contents = int( prop_dynamic.kv.contents ) & ~CONTENTS_TITANCLIP
+ prop_dynamic.kv.fadedist = -1
+ prop_dynamic.kv.renderamt = 255
+ prop_dynamic.kv.rendercolor = "255 255 255"
+ prop_dynamic.kv.solid = 6 // 0 = no collision, 2 = bounding box, 6 = use vPhysics, 8 = hitboxes only
+ if ( origin )
+ {
+ prop_dynamic.SetOrigin( expect vector( origin ) )
+ if ( angles )
+ prop_dynamic.SetAngles( expect vector( angles ) )
+ }
+ DispatchSpawn( prop_dynamic )
+
+ return prop_dynamic
+}
+
+void function PushPlayerAndCreateDropPodCollision( entity pod, vector targetOrigin )
+{
+ pod.EndSignal( "OnDestroy" )
+
+ entity point_push = CreateEntity( "point_push" )
+ point_push.kv.spawnflags = 8
+ point_push.kv.enabled = 1
+ point_push.kv.magnitude = 140.0 * 0.75 //Compensate for reduced player gravity to match R1
+ point_push.kv.radius = 192.0
+ point_push.SetOrigin( targetOrigin + Vector( 0.0, 0.0, 32.0 ) )
+ DispatchSpawn( point_push )
+
+ OnThreadEnd(
+ function() : ( point_push )
+ {
+ point_push.Fire( "Kill", "", 0.0 )
+ }
+ )
+
+ while ( CheckPlayersIntersectingPod( pod, targetOrigin ) )
+ wait( 0.1 )
+
+ pod.Solid()
+}
+
+function DropPodOnImpactFX( droppod, e )
+{
+ PlayImpactFXTable( expect vector( e.targetOrigin ), expect entity( droppod ), HOTDROP_IMPACT_FX_TABLE )
+}
+
+void function DropPodOnImpactFXAndShake( entity droppod )
+{
+ var e = GetOptionalAnimEventVar( droppod, "OnImpact" )
+ DropPodOnImpactFX( droppod, e )
+ CreateShake( expect vector( e.targetOrigin ), 7, 0.15, 1.75, 768 )
+
+ // 1 - No Damage - Only Force
+ // 2 - Push players
+ // 8 - Test LOS before pushing
+ local flags = 11
+ local impactOrigin = e.targetOrigin + Vector( 0,0,10 )
+ local impactRadius = 192
+ thread PushPlayerAndCreateDropPodCollision( droppod, expect vector( e.targetOrigin ) )
+}
+
+
+function CreateDropPodSmokeTrail( pod )
+{
+ entity smokeTrail = CreateEntity( "info_particle_system" )
+ smokeTrail.SetValueForEffectNameKey( $"droppod_trail" )
+ smokeTrail.kv.start_active = 0
+ DispatchSpawn( smokeTrail )
+
+ smokeTrail.SetOrigin( pod.GetOrigin() + Vector( 0, 0, 152 ) )
+ smokeTrail.SetParent( pod )
+
+ return smokeTrail
+}
+
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_droppod_fireteam.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_droppod_fireteam.gnut
index b93631ac..b93631ac 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_droppod_fireteam.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_droppod_fireteam.gnut
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/ai/_grunt_chatter.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_grunt_chatter.gnut
new file mode 100644
index 00000000..f5c0c84d
--- /dev/null
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_grunt_chatter.gnut
@@ -0,0 +1,1786 @@
+// _grunt_chatter.gnut
+
+global function GruntChatter_Init
+global function GruntChatter_AddCategory
+global function GruntChatter_AddEvent
+global function GruntChatter_TryCloakedPilotSpotted
+global function GruntChatter_TryThrowingGrenade
+global function GruntChatter_TryFriendlyEquipmentDeployed
+global function GruntChatter_TryPersonalShieldDamaged
+global function GruntChatter_TryDisplacingFromDangerousArea
+global function GruntChatter_TryEnemyTimeShifted
+global function GruntChatter_TryIncomingSpawn
+global function GruntChatter_TryPlayerPilotReloading
+global function GruntChatter_TryGruntFlankedByPlayer
+
+const float CHATTER_THINK_WAIT = 1.0
+const float CHATTER_SIGNAL_INTERRUPT_WAIT = 1.0 // how often the grunts will interrupt their signal waiting thread to check their kv timers
+const float CHATTER_EVENT_EXPIRE_TIME = 3.0 // chatter events get thrown away when they're at least this old
+
+const float CHATTER_PLAYER_COMBAT_STATE_CHANGE_DEBOUNCE = 1.5
+
+const float CHATTER_PILOT_LOST_NEARBY_TEAMMATE_DIST = 1024.0
+const float CHATTER_PLAYER_CLOSE_MIN_DIST = 370.0 // all squad members have to be at least this far away from enemy to say they lost visual
+
+const float CHATTER_PILOT_SPOTTED_CLOSE_DIST = 600.0
+const float CHATTER_PILOT_SPOTTED_MID_DIST = 1100.0
+const float CHATTER_PILOT_SPOTTED_NEARBY_TEAMMATE_DIST = 1024.0
+
+const float CHATTER_PILOT_SPOTTED_MID_DIST_MOVING_MIN_SPEED = 170.0
+
+const float CHATTER_PILOT_SPOTTED_RANGE_DIST_MIN = 600.0
+const float CHATTER_PILOT_SPOTTED_RANGE_DIST_MAX = 1400.0
+const float CHATTER_PILOT_SPOTTED_RANGE_DIST_20 = 787.0
+const float CHATTER_PILOT_SPOTTED_RANGE_DIST_25 = 984.0
+const float CHATTER_PILOT_SPOTTED_RANGE_DIST_30 = 1181.0
+const float CHATTER_PILOT_SPOTTED_RANGE_DIST_35 = 1378.0
+
+const float CHATTER_PILOT_DECOY_SPOTTED_DIST_MAX = 1500.0
+
+const float CHATTER_ENEMY_GRUNT_SPOTTED_DIST = 1250.0
+const float CHATTER_ENEMY_TITAN_SPOTTED_DIST = 3000.0
+const float CHATTER_ENEMY_TITAN_SPOTTED_DIST_CLOSE = 1024.0
+const float CHATTER_ENEMY_SPECTRE_SPOTTED_DIST = 1250.0
+const float CHATTER_ENEMY_SPECTRE_SPOTTED_DIST_CLOSE = 650.0
+const float CHATTER_ENEMY_TICK_SPOTTED_DIST = 1024.0
+
+const float CHATTER_PILOT_SPOTTED_ABOVE_DIST_MIN = 128.0
+const float CHATTER_PILOT_SPOTTED_ABOVE_DIST_MAX = 1024.0
+const float CHATTER_PILOT_SPOTTED_ABOVE_RADIUS = 450.0
+const float CHATTER_PILOT_SPOTTED_BELOW_DIST_MIN = 128.0
+const float CHATTER_PILOT_SPOTTED_BELOW_DIST_MAX = 1024.0
+const float CHATTER_PILOT_SPOTTED_BELOW_RADIUS = 512.0
+
+const float CHATTER_GRUNT_ENEMY_OUT_OF_SIGHT_TIME = 15.0
+
+const float CHATTER_FRIENDLY_EQUIPMENT_DEPLOYED_NEARBY_DIST = 900.0 // distance from the Specialist that a Grunt will chatter about him deploying things
+
+const bool CHATTER_DO_UNSUSPECTING_PILOT_CALLOUTS = false // couldn't get it working well enough in time just in script... next game maybe
+const float CHATTER_UNSUSPECTING_PILOT_TARGET_DIST_MAX = 512.0
+const float CHATTER_UNSUSPECTING_PILOT_TARGET_MIN_DOT_REAR = 0.65
+const float CHATTER_UNSUSPECTING_PILOT_MAX_SPEED = 170.0 // player has to be below this speed to trigger "unsuspecting pilot"
+const float CHATTER_UNSUSPECTING_PILOT_STATETIME_MIN = 2.0 // how long the player has to be in "unsuspecting state" before we try to chatter about it
+
+const float CHATTER_SEE_CLOAKED_PILOT_MIN_DOT_REAR = 0.65
+
+const float CHATTER_SUPPRESSION_EXPIRE_TIME = 0.2 // secs after kv.lastSuppressionTime that we will be ok with adding a chatter event about it
+const float CHATTER_MISS_FAST_TARGET_EXPIRE_TIME = 0.5 // secs after kv.lastMissFastPlayerTime that we will be ok with adding a chatter event about it
+const float CHATTER_MISS_FAST_TARGET_MIN_SPEED = 350.0 // min "speed" that player needs to be moving to trigger a missing fast player callout
+
+const float CHATTER_PILOT_LOW_HEALTH_FRAC = 0.35 // below this fraction of pilot maxhealth, enemies can chatter about pilot low health
+const float CHATTER_PILOT_LOW_HEALTH_RANGE = 1024.0 // beyond this distance, enemies won't chatter about pilot low health
+const float CHATTER_PLAYER_RELOADING_RANGE = 800.0
+
+const float CHATTER_NEARBY_GRUNT_TRACEFRAC_MIN = 0.95 // for when we need "LOS" trace
+
+const float CHATTER_ENEMY_PILOT_MULTIKILL_EXPIRETIME = 4.5 // max time between kills to trigger multikill callout
+const int CHATTER_PILOT_MULTIKILL_MIN_KILLS = 3
+
+const float CHATTER_FRIENDLY_GRUNT_DOWN_DIST_MAX = 1100.0
+const float CHATTER_FRIENDLY_TITAN_DOWN_DIST_MAX = 1500.0
+const float CHATTER_ENEMY_PILOT_DOWN_DIST_MAX = 600.0
+const float CHATTER_ENEMY_GRUNT_DOWN_DIST_MAX = 800.0
+const float CHATTER_ENEMY_TITAN_DOWN_DIST_MAX = 1500.0
+const float CHATTER_ENEMY_SPECTRE_DOWN_DIST_MAX = 800.0
+
+const float CHATTER_NEARBY_TITAN_DIST = 1024.0
+const float CHATTER_NEARBY_REAPER_DIST = 1024.0
+const float CHATTER_NEARBY_SPECTRE_DIST = 800.0
+
+const float CHATTER_ENEMY_TIME_SHIFT_NEARBY_DIST = 700.0
+
+const float CHATTER_SQUAD_DEPLETED_FRIENDLY_NEARBY_DIST = 650.0 // if any other friendly grunt is within this dist, squad deplete chatter won't play
+
+const float CHATTER_DANGEROUS_AREA_NEARBY_RANGE = 512.0
+
+struct ChatterCategory
+{
+ string alias
+ int priority = -1
+ string timer
+ string secondaryTimer
+ bool trackEventTarget
+ bool resetTargetKillChain
+}
+
+struct ChatterEvent
+{
+ ChatterCategory& category
+ entity npc = null
+ bool hasNPC = false
+ entity target = null
+ bool hasTarget = false
+ bool isValid = false
+ float time = -1
+}
+
+struct
+{
+ array<ChatterEvent> chatterEvents = []
+ table< string, ChatterCategory > chatterCategories
+ int usedEventTargetsArrayHandle
+
+ int pilotKillChainCounter = 0
+ float lastPilotKillTime = -1
+
+ int debugLevel = 0
+} file
+
+void function GruntChatter_Init()
+{
+ Assert( IsSingleplayer(), "Grunt chatter is only set up for SP." )
+
+ AddSpawnCallback( "player", GruntChatter_OnPlayerSpawned )
+ AddSpawnCallback( "npc_soldier", GruntChatter_OnGruntSpawned )
+ AddSpawnCallback( "npc_turret_sentry", GruntChatter_OnSentryTurretSpawned )
+
+ RegisterSignal( "GruntChatter_CombatStateChangeThread" )
+ RegisterSignal( "GruntChatter_Interrupt" )
+
+ file.usedEventTargetsArrayHandle = CreateScriptManagedEntArray()
+
+ AddCallback_OnPlayerKilled( GruntChatter_OnPlayerOrNPCKilled )
+ AddCallback_OnNPCKilled( GruntChatter_OnPlayerOrNPCKilled )
+ AddDeathCallback( "player_decoy", GruntChatter_OnPilotDecoyKilled )
+
+ GruntChatter_SharedInit()
+}
+
+void function GruntChatter_OnPlayerSpawned( entity player )
+{
+ thread GruntChatter_PlayerThink( player )
+ thread GruntChatter_TrackGruntCombatStateVsPlayer( player )
+
+ if ( CHATTER_DO_UNSUSPECTING_PILOT_CALLOUTS )
+ thread GruntChatter_DetectPlayerPilotUnsuspecting( player )
+}
+
+void function GruntChatter_OnGruntSpawned( entity grunt )
+{
+ if( IsMultiplayer() )
+ return
+
+ if ( !GruntChatter_IsGruntTypeEligibleForChatter( grunt ) )
+ return
+
+ AddEntityCallback_OnDamaged( grunt, GruntChatter_OnGruntDamaged )
+
+ thread GruntChatter_GruntSignalWait( grunt )
+}
+
+void function GruntChatter_OnSentryTurretSpawned( entity turret )
+{
+ if ( turret.GetTeam() != TEAM_IMC )
+ return
+
+ thread GruntChatter_TurretSignalWait( turret )
+}
+
+// ==== chatter mission control ====
+void function GruntChatter_AddCategory( string chatterAlias, int priority, string timerAlias, string secondaryTimerAlias, bool trackEventTarget, bool resetTargetKillChain )
+{
+ Assert( !( chatterAlias in file.chatterCategories ), "Chatter alias already set up: " + chatterAlias )
+ Assert( TimerExists( timerAlias ), "Grunt chatter timer not set up in grunt_chatter_timers.csv: " + timerAlias )
+
+ ChatterCategory newCategory
+ newCategory.alias = chatterAlias
+ newCategory.priority = priority
+ newCategory.timer = timerAlias
+ newCategory.trackEventTarget = trackEventTarget
+ newCategory.resetTargetKillChain = resetTargetKillChain
+
+ if ( secondaryTimerAlias != "" )
+ newCategory.secondaryTimer = secondaryTimerAlias
+
+ file.chatterCategories[ chatterAlias ] <- newCategory
+}
+
+// add a grunt to have him chatter specifically
+// target: must be alive or else event won't fire
+void function GruntChatter_AddEvent( string alias, entity ornull npc = null, entity ornull target = null )
+{
+ Assert( alias in file.chatterCategories, "Couldn't find chatter category alias " + alias + ", was it set up?" )
+
+ ChatterEvent newEvent
+ newEvent.category = file.chatterCategories[ alias ]
+ newEvent.isValid = true
+ newEvent.time = Time()
+
+ if ( npc != null )
+ {
+ newEvent.npc = expect entity( npc )
+ newEvent.hasNPC = true
+ }
+
+ if ( file.chatterCategories[ alias ].trackEventTarget )
+ Assert( target != null, "Category " + file.chatterCategories[ alias ].alias + " requires a target to track for its events." )
+
+ if ( file.chatterCategories[ alias ].resetTargetKillChain )
+ Assert( target != null, "Category " + file.chatterCategories[ alias ].alias + " requires a target on which to record kill chains." )
+
+ if ( target != null )
+ {
+ newEvent.target = expect entity( target )
+ newEvent.hasTarget = true
+ }
+
+ if ( file.debugLevel > 1 )
+ printt( "ADDING EVENT:", newEvent.category.alias )
+
+ file.chatterEvents.append( newEvent )
+}
+
+void function GruntChatter_AddToUsedEventTargets( entity ent )
+{
+ Assert( !GruntChatter_EventTargetAlreadyUsed( ent ), "Ent already added to event targets: " + ent )
+ AddToScriptManagedEntArray( file.usedEventTargetsArrayHandle, ent )
+}
+
+bool function GruntChatter_EventTargetAlreadyUsed( entity ent )
+{
+ return ScriptManagedEntArrayContains( file.usedEventTargetsArrayHandle, ent )
+}
+
+void function GruntChatter_PlayerThink( entity player )
+{
+ player.EndSignal( "OnDestroy" )
+
+ while ( 1 )
+ {
+ wait CHATTER_THINK_WAIT
+
+ // squad conversations don't play to dead players
+ if ( !IsAlive( player ) )
+ continue
+
+ if ( player.GetForcedDialogueOnly() )
+ continue
+
+ if ( !file.chatterEvents.len() )
+ continue
+
+ if ( !TimerCheck( "chatter_global" ) )
+ continue
+
+ // prune expired chatter events if necessary
+ GruntChatter_RemoveExpiredEventsFromQueue()
+
+ // process chatter events
+ array< ChatterEvent > currChatterEvents = file.chatterEvents
+
+ ChatterEvent eventToPlay
+
+ foreach ( chatterEvent in currChatterEvents )
+ {
+ // check timer
+ if ( !TimerCheck( chatterEvent.category.timer ) )
+ continue
+
+ // check priority vs currently selected
+ if ( chatterEvent.category.priority < eventToPlay.category.priority )
+ continue
+
+ // check ents are still legit
+ if ( chatterEvent.hasNPC )
+ {
+ if ( !GruntChatter_CanGruntChatterNow( chatterEvent.npc ) )
+ continue
+
+ if ( !GruntChatter_CanGruntChatterToPlayer( chatterEvent.npc, player ) )
+ continue
+ }
+
+ if ( chatterEvent.hasTarget && !GruntChatter_CanChatterEventUseEnemyTarget( chatterEvent ) )
+ continue
+
+ // check which event is more current
+ if ( eventToPlay.time > chatterEvent.time )
+ continue
+
+ eventToPlay = chatterEvent
+ }
+
+ if ( eventToPlay.isValid )
+ {
+ string alias = eventToPlay.category.alias
+ string timer = eventToPlay.category.timer
+
+ entity grunt = eventToPlay.npc
+ // if the event didn't include a grunt, use the closest grunt as the source
+ if ( !IsValid( grunt ) )
+ {
+ // only human grunts should talk
+ array<entity> nearbyGrunts = GetNearbyEnemyHumanGrunts( player.GetOrigin(), player.GetTeam() )
+
+ if ( !nearbyGrunts.len() )
+ {
+ if ( file.debugLevel > 0 )
+ printt( "GRUNT CHATTER: can't play chatter event because nobody is close enough:", alias )
+
+ continue
+ }
+
+ nearbyGrunts = ArrayClosest( nearbyGrunts, player.GetOrigin() )
+ grunt = nearbyGrunts[0]
+ }
+
+ Assert( IsAlive( grunt ), "Grunt chatter error: need a grunt to talk" )
+
+ if ( file.debugLevel > 0 )
+ printt( "GRUNT CHATTER:", alias )
+
+ if ( eventToPlay.category.trackEventTarget )
+ GruntChatter_AddToUsedEventTargets( eventToPlay.target )
+
+ if ( eventToPlay.category.resetTargetKillChain )
+ GruntChatter_ResetPilotKillChain( eventToPlay.target )
+
+ PlaySquadConversationToAll( alias, grunt )
+ ChatterTimerReset( eventToPlay )
+
+ // throw away all the old chatter events now that we processed one
+ GruntChatter_FlushEventQueue()
+ }
+ }
+}
+
+void function GruntChatter_FlushEventQueue()
+{
+ file.chatterEvents = []
+}
+
+void function GruntChatter_RemoveExpiredEventsFromQueue()
+{
+ array< ChatterEvent > recentEvents = []
+ foreach ( event in file.chatterEvents )
+ {
+ if ( Time() - event.time >= CHATTER_EVENT_EXPIRE_TIME )
+ {
+ if ( file.debugLevel > 1 )
+ printt( "expired event:", event.category.alias, "time:", Time() - event.time )
+
+ continue
+ }
+
+ recentEvents.append( event )
+ }
+
+ file.chatterEvents = recentEvents
+}
+
+void function ChatterTimerReset( ChatterEvent event )
+{
+ TimerReset( "chatter_global" )
+ TimerReset( event.category.timer )
+
+ if ( event.category.secondaryTimer != "" )
+ TimerReset( event.category.secondaryTimer )
+}
+
+
+// ==== combat state tracking ====
+void function GruntChatter_TrackGruntCombatStateVsPlayer( entity player )
+{
+ player.EndSignal( "OnDestroy" )
+
+ while ( 1 )
+ {
+ wait 1.0
+
+ if ( !IsAlive( player ) )
+ continue
+
+ int currState = GruntChatter_GetGruntCombatStateVsPlayer( player )
+
+ if ( currState == svGlobalSP.gruntCombatState )
+ continue
+
+ if ( file.debugLevel > 1 )
+ printt( "combat state change:", currState )
+
+ thread GruntChatter_TryPlayerPilotCombatStateChange( player, currState, svGlobalSP.gruntCombatState )
+
+ svGlobalSP.gruntCombatState = currState
+ }
+}
+
+int function GruntChatter_GetGruntCombatStateVsPlayer( entity player )
+{
+ array<entity> enemies = GetNPCArrayEx( "npc_soldier", TEAM_ANY, player.GetTeam(), Vector( 0, 0, 0 ), -1 )
+ ArrayRemoveDead( enemies )
+
+ int currState = eGruntCombatState.IDLE
+
+ foreach ( npc in enemies )
+ {
+ if ( !IsAlive( npc ) )
+ continue
+
+ if ( npc.GetNPCState() == "alert" && currState != eGruntCombatState.COMBAT )
+ currState = eGruntCombatState.ALERT
+ else if ( npc.GetNPCState() == "combat" && npc.GetEnemy() == player )
+ return eGruntCombatState.COMBAT
+ }
+
+ return currState
+}
+
+
+// ==== player event handling ====
+// not currently used - I can't make it work well enough in script. Maybe code next game.
+void function GruntChatter_DetectPlayerPilotUnsuspecting( entity player )
+{
+ player.EndSignal( "OnDestroy" )
+
+ bool resetUnsuspectingTime = true
+ float unsuspectingTime = -1
+ array<entity> nearbyGrunts
+
+ while ( 1 )
+ {
+ if ( resetUnsuspectingTime )
+ {
+ if ( Time() - unsuspectingTime >= CHATTER_UNSUSPECTING_PILOT_STATETIME_MIN )
+ if ( file.debugLevel > 2 )
+ printt( "========== RESET UNSUSPECTING!" )
+
+ unsuspectingTime = Time()
+ }
+
+ wait 1.0
+
+ if ( !IsAlive( player ) )
+ continue
+
+ if ( !IsPilot( player ) )
+ continue
+
+ if ( Length( player.GetVelocity() ) > CHATTER_UNSUSPECTING_PILOT_MAX_SPEED )
+ continue
+
+ array<entity> validGrunts
+
+ nearbyGrunts = GetNearbyEnemyHumanGrunts( player.GetOrigin(), player.GetTeam(), CHATTER_UNSUSPECTING_PILOT_TARGET_DIST_MAX )
+ if ( !nearbyGrunts.len() )
+ continue
+
+ foreach ( grunt in nearbyGrunts )
+ {
+ if ( grunt.GetEnemy() != player )
+ continue
+
+ // don't care about facing direction, just if he can trace to the player
+ if ( !GruntChatter_CanGruntTraceToLocation( grunt, player.EyePosition() ) )
+ continue
+
+ if ( !GruntChatter_IsTargetFacingAway( grunt, player, CHATTER_UNSUSPECTING_PILOT_TARGET_MIN_DOT_REAR ) )
+ continue
+
+ validGrunts.append( grunt )
+ }
+
+ if ( !validGrunts.len() )
+ continue
+
+ resetUnsuspectingTime = false
+
+ if ( file.debugLevel > 2 )
+ printt( "========== PLAYER IS UNSUSPECTING!" )
+
+ if ( unsuspectingTime < Time() && Time() - unsuspectingTime < CHATTER_UNSUSPECTING_PILOT_STATETIME_MIN )
+ continue
+
+ if ( !TimerCheck( "chatter_pilot_target_unsuspecting" ) )
+ {
+ if ( file.debugLevel > 2 )
+ printt( "waiting for UNSUSPECTING chatter timer...")
+
+ continue
+ }
+
+ entity closestGrunt = GetClosest( validGrunts, player.GetOrigin() )
+ GruntChatter_AddEvent( "gruntchatter_pilot_target_unsuspecting", closestGrunt, player )
+
+ resetUnsuspectingTime = true
+ }
+}
+
+
+// ==== grunt event handling ====
+void function GruntChatter_GruntSignalWait( entity grunt )
+{
+ grunt.EndSignal( "OnDeath" )
+ grunt.EndSignal( "OnDestroy" )
+
+ while ( 1 )
+ {
+ thread GruntChatter_InterruptSignal( grunt )
+ table result = WaitSignal( grunt, "OnFoundEnemy", "OnSeeEnemy", "OnLostEnemy", "GruntChatter_Interrupt" )
+
+ string signal = expect string( result.signal )
+
+ switch( signal )
+ {
+ // Sees target for the first time, or switches back to a target
+ case "OnFoundEnemy":
+ entity enemy = expect entity( result.value )
+ GruntChatter_TryOnFoundEnemy( grunt, enemy )
+ break
+
+ // Sees active target ent again
+ case "OnSeeEnemy":
+ entity enemy = expect entity( result.activator )
+ GruntChatter_TryPlayerPilotSpotted( grunt, enemy, signal )
+ break
+
+ // can no longer see active target ent
+ case "OnLostEnemy":
+ entity lostEnemy = expect entity( result.activator )
+ GruntChatter_TryPilotLost( grunt, lostEnemy )
+
+ // Grunt will send OnLost and OnFound at the same time if switching targets
+ entity newEnemy = grunt.GetEnemy()
+ if ( IsAlive( newEnemy ) )
+ GruntChatter_TryOnFoundEnemy( grunt, newEnemy )
+ break
+
+ case "GruntChatter_Interrupt":
+ GruntChatter_CheckGruntForEvents( grunt )
+ break
+ }
+ }
+}
+
+void function GruntChatter_TryOnFoundEnemy( entity grunt, entity enemy )
+{
+ GruntChatter_TryPlayerPilotSpotted( grunt, enemy, "OnFoundEnemy" )
+ GruntChatter_TryEnemySpotted( grunt, enemy )
+}
+
+void function GruntChatter_InterruptSignal( entity grunt )
+{
+ grunt.EndSignal( "OnDeath" )
+ grunt.EndSignal( "OnDestroy" )
+
+ grunt.EndSignal( "OnFoundEnemy" )
+ grunt.EndSignal( "OnSeeEnemy" )
+ grunt.EndSignal( "OnLostEnemy" )
+
+ wait CHATTER_SIGNAL_INTERRUPT_WAIT
+ grunt.Signal( "GruntChatter_Interrupt" )
+}
+
+// tries to send all valid events, lets the priority system handle which one should play
+void function GruntChatter_CheckGruntForEvents( entity grunt )
+{
+ GruntChatter_TryFriendlyPassingNearby( grunt )
+
+ // everything below this cares about having a living target
+ entity target = grunt.GetEnemy()
+ if ( !IsAlive( target ) )
+ return
+
+ GruntChatter_HACK_TryPilotTargetOutOfSight( grunt, target )
+ GruntChatter_TrySuppressingPilotTarget( grunt, target )
+ GruntChatter_TryMissingFastTarget( grunt, target )
+ GruntChatter_TryPilotLowHealth( grunt, target )
+ GruntChatter_TryEngagingNonPilotTarget( grunt, target )
+}
+
+// HACK fakey pilot lost if player out of sight for a while
+void function GruntChatter_HACK_TryPilotTargetOutOfSight( entity grunt, entity target )
+{
+ entity gruntEnemy = grunt.GetEnemy()
+
+ if ( !IsAlive( gruntEnemy ) )
+ return
+
+ if ( !IsPilot( gruntEnemy ) )
+ return
+
+ if ( grunt.GetNPCState() != "combat" )
+ return
+
+ if ( grunt.GetEnemyLastTimeSeen() == 0 )
+ return
+
+ if ( Time() - grunt.GetEnemyLastTimeSeen() < CHATTER_GRUNT_ENEMY_OUT_OF_SIGHT_TIME )
+ return
+
+ //if ( file.debugLevel > 1 )
+ // printt( "FAKEY LOST TARGET" )
+
+ if ( !TimerCheck( "chatter_pilot_lost" ) )
+ return
+
+ GruntChatter_TryPilotLost( grunt, gruntEnemy )
+}
+
+void function GruntChatter_TryPlayerPilotCombatStateChange( entity player, int currState, int prevState )
+{
+ // these lines are mostly written as if the state changes are happening during combat vs a Pilot
+ if ( !IsPilot( player ) )
+ return
+
+ player.Signal( "GruntChatter_CombatStateChangeThread" )
+ player.EndSignal( "GruntChatter_CombatStateChangeThread" )
+ player.EndSignal( "OnDeath" )
+
+ wait CHATTER_PLAYER_COMBAT_STATE_CHANGE_DEBOUNCE
+
+ string alias = ""
+ switch ( currState )
+ {
+ case eGruntCombatState.ALERT:
+ alias = "gruntchatter_statechange_idle2alert"
+ if ( prevState == eGruntCombatState.COMBAT )
+ alias = "gruntchatter_statechange_combat2alert"
+ break
+
+ case eGruntCombatState.COMBAT:
+ alias = "gruntchatter_statechange_idle2combat"
+ if ( prevState == eGruntCombatState.ALERT )
+ alias = "gruntchatter_statechange_alert2combat"
+ break
+ }
+
+ if ( alias == "" )
+ return
+
+ GruntChatter_AddEvent( alias )
+}
+
+void function GruntChatter_TryPilotLost( entity grunt, entity enemy )
+{
+ if ( !GruntChatter_CanGruntChatterNow( grunt ) )
+ return
+
+ if ( !IsAlive( enemy ) || !IsPilot( enemy ) )
+ return
+
+ if ( !TimerCheck( "chatter_pilot_lost" ) )
+ return
+
+ // if anyone near you can see the enemy, don't say we lost the target
+ if ( CanNearbyGruntTeammatesSeeEnemy( grunt, enemy, CHATTER_PILOT_LOST_NEARBY_TEAMMATE_DIST ) )
+ return
+
+ // if a nearby friendly grunt is close to the enemy don't chatter about losing sight of the enemy
+ if ( GruntChatter_IsFriendlyGruntCloseToLocation( grunt.GetTeam(), enemy.GetOrigin(), CHATTER_PLAYER_CLOSE_MIN_DIST ) )
+ return
+
+ string alias = "gruntchatter_pilot_lost"
+ array<entity> nearbyGrunts = GetNearbyFriendlyGrunts( grunt.GetOrigin(), grunt.GetTeam(), CHATTER_PILOT_LOST_NEARBY_TEAMMATE_DIST )
+ if ( nearbyGrunts.len() >= 2 && RandomInt( 100 ) < 40 )
+ alias = "gruntchatter_pilot_lost_neg"
+
+ GruntChatter_AddEvent( alias, grunt )
+}
+
+void function GruntChatter_TryPlayerPilotSpotted( entity grunt, entity player, string resultSignal )
+{
+ if ( !GruntChatter_CanGruntChatterNow( grunt ) )
+ return
+
+ if ( !IsAlive( player ) || !player.IsPlayer() || !IsPilot( player ) )
+ return
+
+ if ( TimerCheck ( "chatter_pilot_spotted" ) )
+ {
+ string spottedAlias = "gruntchatter_pilot_spotted"
+
+ if ( resultSignal == "OnFoundEnemy" )
+ {
+ if ( svGlobalSP.gruntCombatState != eGruntCombatState.COMBAT )
+ {
+ spottedAlias = "gruntchatter_pilot_first_sighting"
+ }
+ }
+ else
+ {
+ float distToPilot = Distance( grunt.GetOrigin(), player.GetOrigin() )
+ bool canSeePilot = grunt.CanSee( player )
+ bool pilotIsMoving = Length( player.GetVelocity() ) >= CHATTER_PILOT_SPOTTED_MID_DIST_MOVING_MIN_SPEED
+
+ if ( canSeePilot )
+ {
+ if ( distToPilot <= CHATTER_PILOT_SPOTTED_CLOSE_DIST )
+ {
+ spottedAlias = "gruntchatter_pilot_spotted_close_range"
+ }
+ else if ( canSeePilot && distToPilot > CHATTER_PILOT_SPOTTED_CLOSE_DIST && distToPilot <= CHATTER_PILOT_SPOTTED_MID_DIST )
+ {
+ spottedAlias = "gruntchatter_pilot_spotted_mid_range"
+ if ( pilotIsMoving )
+ spottedAlias = "gruntchatter_pilot_spotted_mid_range_moving"
+ }
+
+ if ( TimerCheck( "chatter_pilot_spotted_specific_range" ) && RandomInt( 100 ) < 40 )
+ {
+ table<string, float> rangeDists
+ rangeDists["chatter_pilot_spotted_specific_range_20"] <- CHATTER_PILOT_SPOTTED_RANGE_DIST_20
+ rangeDists["chatter_pilot_spotted_specific_range_25"] <- CHATTER_PILOT_SPOTTED_RANGE_DIST_25
+ rangeDists["chatter_pilot_spotted_specific_range_30"] <- CHATTER_PILOT_SPOTTED_RANGE_DIST_30
+ rangeDists["chatter_pilot_spotted_specific_range_35"] <- CHATTER_PILOT_SPOTTED_RANGE_DIST_35
+
+ if ( distToPilot >= CHATTER_PILOT_SPOTTED_RANGE_DIST_MIN && distToPilot <= CHATTER_PILOT_SPOTTED_RANGE_DIST_MAX )
+ {
+ string closestAlias
+ float closestDist
+ foreach ( rangeAlias, rangeDist in rangeDists )
+ {
+ float thisDist = fabs( distToPilot - rangeDist )
+ if ( closestAlias == "" || thisDist < closestDist )
+ {
+ closestAlias = rangeAlias
+ closestDist = thisDist
+ }
+ }
+
+ spottedAlias = closestAlias
+ }
+ }
+ }
+ }
+
+ GruntChatter_AddEvent( spottedAlias, grunt )
+ }
+
+ if ( TimerCheck ( "chatter_pilot_spotted_abovebelow" ) )
+ {
+ bool isEnemyAbove = GruntChatter_IsEnemyAbove( grunt, player )
+ bool isEnemyBelow = GruntChatter_IsEnemyBelow( grunt, player )
+
+ if ( isEnemyAbove )
+ GruntChatter_AddEvent( "gruntchatter_pilot_spotted_above", grunt )
+ else if ( isEnemyBelow )
+ GruntChatter_AddEvent( "gruntchatter_pilot_spotted_below", grunt )
+ }
+}
+
+void function GruntChatter_TryEnemySpotted( entity grunt, entity spottedEnemy )
+{
+ if ( !GruntChatter_CanGruntChatterNow( grunt ) )
+ return
+
+ if ( !IsAlive( spottedEnemy ) )
+ return
+
+ if ( spottedEnemy.GetTeam() == grunt.GetTeam() )
+ return
+
+ string alias = ""
+ float distToSpottedEnemy = Distance( grunt.GetOrigin(), spottedEnemy.GetOrigin() )
+
+ // TODO move to data files
+ if ( IsGrunt( spottedEnemy ) && TimerCheck( "chatter_enemy_grunt_spotted" ) && distToSpottedEnemy <= CHATTER_ENEMY_GRUNT_SPOTTED_DIST )
+ {
+ alias = "gruntchatter_enemy_grunt_spotted"
+ }
+ else if ( spottedEnemy.IsTitan() && TimerCheck( "chatter_enemy_titan_spotted" ) && distToSpottedEnemy <= CHATTER_ENEMY_TITAN_SPOTTED_DIST )
+ {
+ alias = "gruntchatter_enemy_titan_spotted"
+ if ( distToSpottedEnemy <= CHATTER_ENEMY_TITAN_SPOTTED_DIST_CLOSE )
+ alias = "gruntchatter_enemy_titan_spotted_close"
+ }
+ else if ( IsSpectre( spottedEnemy ) && TimerCheck( "chatter_enemy_spectre_spotted" ) && distToSpottedEnemy <= CHATTER_ENEMY_SPECTRE_SPOTTED_DIST )
+ {
+ alias = "gruntchatter_enemy_spectre_spotted"
+ if ( distToSpottedEnemy <= CHATTER_ENEMY_SPECTRE_SPOTTED_DIST_CLOSE )
+ alias = "gruntchatter_enemy_spectre_spotted_close"
+ }
+ else if ( IsTick( spottedEnemy ) && TimerCheck( "chatter_enemy_tick_spotted" ) && distToSpottedEnemy <= CHATTER_ENEMY_TICK_SPOTTED_DIST )
+ {
+ alias = "gruntchatter_enemy_tick_spotted"
+ }
+ else if ( IsPilotDecoy( spottedEnemy ) && TimerCheck( "chatter_enemy_pilot_decoy_spotted" ) && distToSpottedEnemy <= CHATTER_PILOT_DECOY_SPOTTED_DIST_MAX )
+ {
+ alias = "gruntchatter_enemy_pilot_decoy_spotted"
+ }
+
+ if ( alias == "" )
+ return
+
+ GruntChatter_AddEvent( alias, grunt, spottedEnemy )
+}
+
+void function GruntChatter_TryEngagingNonPilotTarget( entity grunt, entity target )
+{
+ if ( !GruntChatter_CanGruntChatterNow( grunt ) )
+ return
+
+ if ( !IsAlive( target ) )
+ return
+
+ string alias = ""
+
+ if ( IsGrunt( target ) && TimerCheck( "chatter_engaging_grunt" ) )
+ {
+ alias = "gruntchatter_engaging_grunt"
+ }
+ else if ( IsSpectre( target ) && TimerCheck( "chatter_engaging_spectre" ) )
+ {
+ alias = "gruntchatter_engaging_spectre"
+ if ( IsValid( target.GetBossPlayer() ) )
+ alias = "gruntchatter_engaging_hacked_spectre"
+ }
+ else if ( IsProwler( target ) && TimerCheck( "chatter_engaging_prowler" ) )
+ {
+ alias = "gruntchatter_engaging_prowler"
+ }
+ else if ( IsStalker( target ) && TimerCheck( "chatter_engaging_stalker" ) )
+ {
+ alias = "gruntchatter_engaging_stalker"
+ }
+
+ if ( alias == "" )
+ return
+
+ GruntChatter_AddEvent( alias, grunt, target )
+}
+
+void function GruntChatter_TryCloakedPilotSpotted( entity grunt, entity pilot )
+{
+ if ( !GruntChatter_CanGruntChatterNow( grunt ) )
+ return
+
+ if ( !IsAlive( pilot ) )
+ return
+
+ if ( !IsCloaked( pilot ) )
+ return
+
+ // note: CanSee doesn't work when player is cloaked (as expected...)
+ if ( !GruntChatter_CanGruntTraceToLocation( grunt, pilot.EyePosition() ) )
+ return
+
+ if ( GruntChatter_IsTargetFacingAway( pilot, grunt, CHATTER_SEE_CLOAKED_PILOT_MIN_DOT_REAR ) )
+ return
+
+ GruntChatter_AddEvent( "gruntchatter_pilot_spotted_cloaked", grunt )
+}
+
+void function GruntChatter_TryPersonalShieldDamaged( entity shieldOwner )
+{
+ GruntChatter_AddEvent( "gruntchatter_personal_shield_damaged", shieldOwner )
+}
+
+void function GruntChatter_TryFriendlyEquipmentDeployed( entity deployer, string equipmentClassName )
+{
+ string alias = ""
+ string timerAlias = ""
+
+ // TODO move to data files
+ switch ( equipmentClassName )
+ {
+ case "npc_drone":
+ alias = "gruntchatter_friendly_drone_deployed"
+ timerAlias = "chatter_friendly_drone_deployed"
+ break
+
+ case "mp_weapon_frag_drone":
+ alias = "gruntchatter_friendly_tick_deployed"
+ timerAlias = "chatter_friendly_tick_deployed"
+ break
+ }
+
+ if ( alias == "" )
+ return
+
+ if ( !TimerCheck( timerAlias ) )
+ return
+
+ entity closestGrunt = GruntChatter_FindClosestFriendlyHumanGrunt_LOS( deployer.GetOrigin(), deployer.GetTeam(), CHATTER_FRIENDLY_EQUIPMENT_DEPLOYED_NEARBY_DIST )
+ if ( !closestGrunt )
+ return
+
+ GruntChatter_AddEvent( alias, closestGrunt )
+}
+
+void function GruntChatter_TryDisplacingFromDangerousArea( entity displacingGrunt )
+{
+ string dangerousAreaWeaponName = displacingGrunt.GetDangerousAreaWeapon()
+ GruntChatter_TryDangerousAreaWeapon( displacingGrunt, dangerousAreaWeaponName )
+}
+
+void function GruntChatter_TryDangerousAreaWeapon( entity grunt, string dangerousAreaWeaponName )
+{
+ if ( !GruntChatter_CanGruntChatterNow( grunt ) )
+ return
+
+ string alias
+ string timerAlias
+
+ // TODO move to data files
+ switch ( dangerousAreaWeaponName )
+ {
+ case "mp_weapon_frag_grenade": //Since GruntChatter_TryDangerousAreaWeapon() is called from both CodeDialogue_DangerousAreaDisplace() and GruntChatter_OnGruntDamaged() this has bugs; a grunt who was not in the dangerous area created but took damage from the frag grenade will say VO like "Incoming Frag!! Take cover!". Not worth fixing this late in.
+ alias = "gruntchatter_dangerous_area_frag"
+ timerAlias = "chatter_dangerous_area_frag"
+ break
+
+ case "mp_weapon_grenade_emp": //This is triggered from GruntChatter_OnGruntDamaged(), since arc grenades don't create a dangerousarea
+ alias = "gruntchatter_dangerous_area_arc_grenade"
+ timerAlias = "chatter_dangerous_area_arc_grenade"
+ break
+
+ case "mp_weapon_thermite_grenade":
+ alias = "gruntchatter_dangerous_area_thermite"
+ timerAlias = "chatter_dangerous_area_thermite"
+ break
+
+ case "mp_weapon_grenade_gravity":
+ alias = "gruntchatter_dangerous_area_grav_grenade"
+ timerAlias = "chatter_dangerous_area_grav_grenade"
+ break
+
+ case "mp_weapon_grenade_electric_smoke":
+ alias = "gruntchatter_dangerous_area_esmoke"
+ timerAlias = "chatter_dangerous_area_esmoke"
+ break
+ }
+
+ if ( alias == "" )
+ return
+
+ if ( !TimerCheck ( timerAlias ) )
+ return
+
+ // all grunts in the area will try to call it out, in case this guy dies
+ array<entity> nearbyGrunts = GetNearbyFriendlyGrunts( grunt.GetOrigin(), grunt.GetTeam(), CHATTER_DANGEROUS_AREA_NEARBY_RANGE )
+ foreach ( nearbyGrunt in nearbyGrunts )
+ GruntChatter_AddEvent( alias, nearbyGrunt )
+}
+
+void function GruntChatter_TryEnemyTimeShifted( entity timeShiftedEnemy )
+{
+ if ( !IsAlive( timeShiftedEnemy ) )
+ return
+
+ if ( !TimerCheck( "chatter_enemy_time_shifted" ) )
+ return
+
+ entity closestGrunt = GruntChatter_FindClosestEnemyHumanGrunt_LOS( timeShiftedEnemy.GetOrigin(), timeShiftedEnemy.GetTeam(), CHATTER_ENEMY_TIME_SHIFT_NEARBY_DIST )
+ if ( !closestGrunt )
+ return
+
+ GruntChatter_AddEvent( "gruntchatter_enemy_time_shifted", closestGrunt )
+}
+
+void function GruntChatter_OnGruntDamaged( entity grunt, var damageInfo )
+{
+ if ( !IsValid( grunt ) )
+ return
+
+ string damageWeaponName
+ int damageSourceID = DamageInfo_GetDamageSourceIdentifier( damageInfo )
+ table dmgSources = expect table( getconsttable().eDamageSourceId )
+ foreach ( name, id in dmgSources )
+ {
+ if ( id == damageSourceID )
+ {
+ damageWeaponName = expect string( name )
+ break
+ }
+ }
+
+ if ( damageWeaponName != "" )
+ GruntChatter_TryDangerousAreaWeapon( grunt, damageWeaponName )
+}
+
+void function GruntChatter_OnPlayerOrNPCKilled( entity deadGuy, entity attacker, var damageInfo )
+{
+ if ( !IsValid( deadGuy ) )
+ return
+
+ if ( deadGuy.GetTeam() == TEAM_IMC )
+ {
+ GruntChatter_TryEnemyPlayerPilot_Multikill( deadGuy, damageInfo )
+ GruntChatter_TryEnemyPlayerPilot_MobilityKill( deadGuy, damageInfo )
+ GruntChatter_TryFriendlyDown( deadGuy )
+ GruntChatter_TrySquadDepleted( deadGuy )
+ }
+ else
+ {
+ GruntChatter_TryEnemyDown( deadGuy )
+ }
+}
+
+void function GruntChatter_OnPilotDecoyKilled( entity decoy, var damageInfo )
+{
+ GruntChatter_TryEnemyDown( decoy )
+}
+
+void function GruntChatter_TryEnemyPlayerPilot_Multikill( entity deadGuy, var damageInfo )
+{
+ if ( !TimerCheck( "chatter_enemy_pilot_multikill" ) )
+ return
+
+ // don't worry about larger targets
+ if ( !IsHumanSized( deadGuy ) )
+ return
+
+ int customDamageType = DamageInfo_GetCustomDamageType( damageInfo )
+
+ // explosive kills don't count for pilot multikills
+ if ( customDamageType & DF_EXPLOSION )
+ return
+
+ entity attacker = DamageInfo_GetAttacker( damageInfo )
+ if ( !IsPilot( attacker ) )
+ return
+
+ // -- multikills --
+ if ( !GruntChatter_IsKillChainStillActive( attacker ) )
+ GruntChatter_ResetPilotKillChain( attacker )
+
+ GruntChatter_UpdatePilotKillChain( attacker )
+
+ if ( GruntChatter_GetPilotKillChain( attacker ) < CHATTER_PILOT_MULTIKILL_MIN_KILLS )
+ return
+
+ entity closestGrunt = GruntChatter_FindClosestFriendlyHumanGrunt_LOS( deadGuy.GetOrigin(), deadGuy.GetTeam(), CHATTER_FRIENDLY_GRUNT_DOWN_DIST_MAX )
+ if ( !closestGrunt )
+ return
+
+ GruntChatter_AddEvent( "gruntchatter_enemy_pilot_multikill", closestGrunt, attacker )
+}
+
+void function GruntChatter_TryEnemyPlayerPilot_MobilityKill( entity deadGuy, var damageInfo )
+{
+ if ( !TimerCheck( "chatter_enemy_pilot_mobility_kill" ) )
+ return
+
+ // don't worry about larger targets
+ if ( !IsHumanSized( deadGuy ) )
+ return
+
+ entity attacker = DamageInfo_GetAttacker( damageInfo )
+ if ( !IsPilot( attacker ) )
+ return
+
+ if ( attacker.IsOnGround() )
+ return
+
+ float targetSpeed = Length( attacker.GetVelocity() )
+ if ( !attacker.IsWallRunning() && targetSpeed < CHATTER_MISS_FAST_TARGET_MIN_SPEED )
+ return
+
+ entity closestGrunt = GruntChatter_FindClosestFriendlyHumanGrunt_LOS( deadGuy.GetOrigin(), deadGuy.GetTeam(), CHATTER_FRIENDLY_GRUNT_DOWN_DIST_MAX )
+ if ( !closestGrunt )
+ return
+
+ GruntChatter_AddEvent( "gruntchatter_enemy_pilot_mobility_kill", closestGrunt, attacker )
+}
+
+void function GruntChatter_TryFriendlyDown( entity deadGuy )
+{
+ string alias = ""
+ float searchRange = -1.0
+
+ if ( IsGrunt( deadGuy ) && TimerCheck( "chatter_friendly_grunt_down" ) )
+ {
+ alias = "gruntchatter_friendly_grunt_down"
+ if ( svGlobalSP.gruntCombatState == eGruntCombatState.IDLE )
+ alias = "gruntchatter_friendly_grunt_down_notarget"
+
+ searchRange = CHATTER_FRIENDLY_GRUNT_DOWN_DIST_MAX
+ }
+ else if ( deadGuy.IsTitan() && TimerCheck( "chatter_friendly_titan_down" ) )
+ {
+ alias = "gruntchatter_friendly_titan_down"
+ searchRange = CHATTER_FRIENDLY_TITAN_DOWN_DIST_MAX
+ }
+
+ if ( alias == "" )
+ return
+
+ entity closestGrunt = GruntChatter_FindClosestFriendlyHumanGrunt_LOS( deadGuy.GetOrigin(), deadGuy.GetTeam(), searchRange )
+ if ( !closestGrunt )
+ return
+
+ GruntChatter_AddEvent( alias, closestGrunt )
+}
+
+void function GruntChatter_TrySquadDepleted( entity deadGuy )
+{
+ if ( !TimerCheck( "chatter_squad_depleted" ) )
+ return
+
+ if ( !IsGrunt( deadGuy ) )
+ return
+
+ string deadGuySquadName = GetSquadName( deadGuy )
+ if ( deadGuySquadName == "" )
+ return
+
+ array<entity> squad = GetNPCArrayBySquad( deadGuySquadName )
+ entity lastSquadMember
+ if ( squad.len() == 1 )
+ lastSquadMember = squad[0]
+
+ if ( !GruntChatter_CanGruntChatterNow( lastSquadMember ) )
+ return
+
+ // if state is idle, don't freak out about being alone
+ if ( lastSquadMember.GetNPCState() == "idle" )
+ return
+
+ // if another grunt from another squad is nearby, don't chatter about being alone
+ array<entity> nearbyGrunts = GetNearbyFriendlyGrunts( lastSquadMember.GetOrigin(), lastSquadMember.GetTeam(), CHATTER_SQUAD_DEPLETED_FRIENDLY_NEARBY_DIST )
+ nearbyGrunts.fastremovebyvalue( lastSquadMember )
+ if ( nearbyGrunts.len() )
+ return
+
+ GruntChatter_AddEvent( "gruntchatter_squad_depleted", lastSquadMember )
+}
+
+void function GruntChatter_TryEnemyDown( entity deadGuy )
+{
+ string alias = ""
+ float searchRange = -1.0
+
+ if ( IsPilot( deadGuy ) && TimerCheck( "chatter_enemy_pilot_down" ) )
+ {
+ alias = "gruntchatter_enemy_pilot_down"
+ searchRange = CHATTER_ENEMY_PILOT_DOWN_DIST_MAX
+ }
+ else if ( IsGrunt( deadGuy ) && TimerCheck( "chatter_enemy_grunt_down" ) )
+ {
+ alias = "gruntchatter_enemy_grunt_down"
+ searchRange = CHATTER_ENEMY_GRUNT_DOWN_DIST_MAX
+ }
+ else if ( deadGuy.IsTitan() && TimerCheck( "chatter_enemy_titan_down" ) )
+ {
+ alias = "gruntchatter_enemy_titan_down"
+ searchRange = CHATTER_ENEMY_TITAN_DOWN_DIST_MAX
+ }
+ else if ( IsSpectre( deadGuy ) && TimerCheck( "chatter_enemy_spectre_down" ) )
+ {
+ alias = "gruntchatter_enemy_spectre_down"
+ searchRange = CHATTER_ENEMY_SPECTRE_DOWN_DIST_MAX
+ }
+ else if ( IsPilotDecoy( deadGuy ) && TimerCheck( "chatter_enemy_pilot_decoy_revealed" ) )
+ {
+ alias = "gruntchatter_enemy_pilot_decoy_revealed"
+ searchRange = CHATTER_PILOT_DECOY_SPOTTED_DIST_MAX
+ }
+
+ if ( alias == "" )
+ return
+
+ entity closestGrunt = GruntChatter_FindClosestEnemyHumanGrunt_LOS( deadGuy.GetOrigin(), deadGuy.GetTeam(), searchRange )
+ if ( !closestGrunt )
+ return
+
+ // HACK- squad conversations don't play to dead players
+ if ( alias == "gruntchatter_enemy_pilot_down" )
+ {
+ HACK_GruntChatter_TryEnemyPilotDown( deadGuy, closestGrunt )
+ return
+ }
+
+ GruntChatter_AddEvent( alias, closestGrunt )
+}
+
+void function HACK_GruntChatter_TryEnemyPilotDown( entity deadGuy, entity closestGrunt )
+{
+ if ( !deadGuy.IsPlayer() )
+ return
+
+ if ( deadGuy.GetForcedDialogueOnly() )
+ return
+
+ TimerReset( "chatter_enemy_pilot_down" )
+
+ string rawAlias = "diag_imc_grunt1_bc_killenemypilot_01"
+ if ( CoinFlip() )
+ rawAlias = "diag_imc_grunt1_bc_killenemypilot_02"
+
+ EmitSoundOnEntity( closestGrunt, rawAlias )
+}
+
+void function GruntChatter_TryThrowingGrenade( entity grunt )
+{
+ if ( !GruntChatter_CanGruntChatterNow( grunt ) )
+ return
+
+ entity enemy = grunt.GetEnemy()
+ if ( !IsAlive( enemy ) )
+ return
+
+ if ( !TimerCheck( "chatter_throwing_grenade" ) )
+ return
+
+ string alias = ""
+ // TODO move to data files
+ switch ( grunt.kv.grenadeWeaponName )
+ {
+ case "mp_weapon_frag_grenade":
+ alias = "gruntchatter_throwing_grenade_frag"
+ break
+
+ case "mp_weapon_grenade_electric_smoke":
+ alias = "gruntchatter_throwing_grenade_electric_smoke"
+ break
+
+ case "mp_weapon_thermite_grenade":
+ alias = "gruntchatter_throwing_grenade_thermite"
+ break
+ }
+
+ if ( alias == "" )
+ return
+
+ GruntChatter_AddEvent( alias, grunt )
+}
+
+// TODO move to data files
+void function GruntChatter_TryFriendlyPassingNearby( entity grunt )
+{
+ if ( !GruntChatter_CanGruntChatterNow( grunt ) )
+ return
+
+ // these lines are written as if the grunts are in combat
+ if ( grunt.GetNPCState() != "combat" )
+ return
+
+ if ( TimerCheck( "chatter_nearby_friendly_titan" ) )
+ {
+ array<entity> nearbyTitans = GetNPCArrayEx( "npc_titan", grunt.GetTeam(), TEAM_ANY, grunt.GetOrigin(), CHATTER_NEARBY_TITAN_DIST )
+ entity nearbyTitan
+ foreach ( titan in nearbyTitans )
+ {
+ if ( !IsAlive( titan ) )
+ continue
+
+ if ( GetDoomedState( titan ) )
+ continue
+
+ if ( GruntChatter_EventTargetAlreadyUsed( titan ) )
+ continue
+
+ nearbyTitan = titan
+ break
+ }
+
+ if ( nearbyTitan )
+ GruntChatter_AddEvent( "gruntchatter_nearby_friendly_titan", grunt, nearbyTitan )
+ }
+
+ if ( TimerCheck( "chatter_nearby_friendly_reaper" ) )
+ {
+ array<entity> nearbyReapers = GetNPCArrayEx( "npc_super_spectre", grunt.GetTeam(), TEAM_ANY, grunt.GetOrigin(), CHATTER_NEARBY_REAPER_DIST )
+ foreach ( reaper in nearbyReapers )
+ {
+ if ( !IsAlive( reaper ) )
+ continue
+
+ if ( GetDoomedState( reaper ) )
+ continue
+
+ if ( GruntChatter_EventTargetAlreadyUsed( reaper ) )
+ continue
+
+ GruntChatter_AddEvent( "gruntchatter_nearby_friendly_reaper", grunt, reaper )
+ break
+ }
+ }
+
+ if ( TimerCheck( "chatter_nearby_friendly_spectre" ) )
+ {
+ array<entity> nearbySpectres = GetNPCArrayEx( "npc_spectre", grunt.GetTeam(), TEAM_ANY, grunt.GetOrigin(), CHATTER_NEARBY_SPECTRE_DIST )
+ if ( nearbySpectres.len() )
+ {
+ entity closestSpectre = GetClosest( nearbySpectres, grunt.GetOrigin() )
+ GruntChatter_AddEvent( "gruntchatter_nearby_friendly_spectre", grunt, closestSpectre )
+ }
+ }
+}
+
+void function GruntChatter_TryIncomingSpawn( entity inboundEnt, vector arrivalLocation )
+{
+ if ( !IsValid( inboundEnt ) )
+ return
+
+ string alias
+ string timer
+ float nearbyRange
+ entity closestGrunt
+
+ // TODO move to data files
+ if ( inboundEnt.GetTeam() == TEAM_IMC )
+ {
+ switch ( inboundEnt.GetClassName() )
+ {
+ case "npc_titan":
+ alias = "gruntchatter_incoming_friendly_titanfall"
+ timer = "chatter_incoming_friendly_titanfall"
+ nearbyRange = CHATTER_NEARBY_TITAN_DIST
+ break
+
+ case "npc_super_spectre":
+ alias = "gruntchatter_incoming_friendly_reaperfall"
+ timer = "chatter_incoming_friendly_reaperfall"
+ nearbyRange = CHATTER_NEARBY_REAPER_DIST
+ break
+ }
+
+ if ( alias == "" )
+ return
+
+ closestGrunt = GruntChatter_FindClosestFriendlyHumanGrunt_LOS( arrivalLocation, inboundEnt.GetTeam(), nearbyRange )
+ if ( !closestGrunt )
+ return
+ }
+ else if ( inboundEnt.GetTeam() == TEAM_MILITIA )
+ {
+ switch ( inboundEnt.GetClassName() )
+ {
+ case "npc_titan":
+ alias = "gruntchatter_incoming_enemy_titanfall"
+ timer = "chatter_incoming_enemy_titanfall"
+ nearbyRange = CHATTER_NEARBY_TITAN_DIST
+ break
+ }
+
+ if ( alias == "" )
+ return
+
+ closestGrunt = GruntChatter_FindClosestEnemyHumanGrunt_LOS( arrivalLocation, inboundEnt.GetTeam(), nearbyRange )
+ if ( !closestGrunt )
+ return
+ }
+
+ // NOTE- can't send the target for these events because the distance check to where the titanfall starts will fail
+ GruntChatter_AddEvent( alias, closestGrunt )
+}
+
+void function GruntChatter_TrySuppressingPilotTarget( entity grunt, entity target )
+{
+ if ( !GruntChatter_CanGruntChatterNow( grunt ) )
+ return
+
+ if ( !IsAlive( target ) )
+ return
+
+ // this is mostly useful for players
+ if ( !target.IsPlayer() )
+ return
+
+ if ( !IsPilot( target ) )
+ return
+
+ if ( !TimerCheck( "chatter_suppressingLKP_start" ) )
+ return
+
+ string STR_lastSuppressionTime = expect string( grunt.kv.lastSuppressionTime ) // hacky
+ float lastSuppressionTime = STR_lastSuppressionTime.tofloat()
+ float validRecentWindow_suppression = Time() - CHATTER_SUPPRESSION_EXPIRE_TIME
+
+ if ( lastSuppressionTime < validRecentWindow_suppression )
+ return
+
+ GruntChatter_AddEvent( "gruntchatter_suppressingLKP_start", grunt )
+}
+
+void function GruntChatter_TryMissingFastTarget( entity grunt, entity target )
+{
+ if ( !GruntChatter_CanGruntChatterNow( grunt ) )
+ return
+
+ if ( !IsAlive( target ) )
+ return
+
+ if ( !IsPilot( target ) )
+ return
+
+ if ( !TimerCheck( "chatter_missing_fast_target" ) )
+ return
+
+ float targetSpeed = Length( target.GetVelocity() )
+ if ( targetSpeed < CHATTER_MISS_FAST_TARGET_MIN_SPEED )
+ return
+
+ string STR_lastMissFastPlayerTime = expect string( grunt.kv.lastMissFastPlayerTime ) // hacky
+ float lastMissFastPlayerTime = STR_lastMissFastPlayerTime.tofloat()
+ float validRecentWindow_missFastTarget = Time() - CHATTER_MISS_FAST_TARGET_EXPIRE_TIME
+
+ if ( lastMissFastPlayerTime < validRecentWindow_missFastTarget )
+ return
+
+ GruntChatter_AddEvent( "gruntchatter_missing_fast_target", grunt )
+}
+
+void function GruntChatter_TryPilotLowHealth( entity grunt, entity target )
+{
+ if ( !GruntChatter_CanGruntChatterNow( grunt ) )
+ return
+
+ if ( !IsAlive( target ) )
+ return
+
+ if ( !IsPilot( target ) )
+ return
+
+ if ( !TimerCheck( "chatter_pilot_low_health" ) )
+ return
+
+ if ( target.GetHealth().tofloat() / target.GetMaxHealth().tofloat() > CHATTER_PILOT_LOW_HEALTH_FRAC )
+ return
+
+ if ( Distance( grunt.GetOrigin(), target.GetOrigin() ) > CHATTER_PILOT_LOW_HEALTH_RANGE )
+ return
+
+ GruntChatter_AddEvent( "gruntchatter_pilot_low_health", grunt )
+}
+
+void function GruntChatter_TryPlayerPilotReloading( entity player )
+{
+ if ( !IsAlive( player ) || !IsPilot( player ) )
+ return
+
+ if ( !TimerCheck( "chatter_target_reloading" ) )
+ return
+
+ entity closestGrunt = GruntChatter_FindClosestEnemyHumanGrunt_LOS( player.GetOrigin(), player.GetTeam(), CHATTER_PLAYER_RELOADING_RANGE )
+ if ( !closestGrunt )
+ return
+
+ GruntChatter_AddEvent( "gruntchatter_target_reloading", closestGrunt, player )
+}
+
+
+// ==== turret event handling ====
+void function GruntChatter_TurretSignalWait( entity turret )
+{
+ turret.EndSignal( "OnDeath" )
+ turret.EndSignal( "OnDestroy" )
+
+ while ( 1 )
+ {
+ table result = WaitSignal( turret, "OnFoundEnemy", "OnSeeEnemy" )
+
+ string signal = expect string( result.signal )
+
+ switch( signal )
+ {
+ case "OnFoundEnemy":
+ entity enemy = expect entity( result.value )
+ GruntChatter_TryFriendlyTurretFoundTarget( turret, enemy )
+ break
+
+ case "OnSeeEnemy":
+ entity enemy = expect entity( result.activator )
+ GruntChatter_TryFriendlyTurretFoundTarget( turret, enemy )
+ break
+
+ }
+ }
+}
+
+void function GruntChatter_TryFriendlyTurretFoundTarget( entity turret, entity enemy )
+{
+ if ( !IsAlive( turret ) || !IsAlive( enemy ) )
+ return
+
+ if ( !TimerCheck( "chatter_friendly_turret_found_target") )
+ return
+
+ entity closestGrunt = GruntChatter_FindClosestFriendlyHumanGrunt_LOS( turret.GetOrigin(), turret.GetTeam(), CHATTER_FRIENDLY_EQUIPMENT_DEPLOYED_NEARBY_DIST )
+ if ( !closestGrunt )
+ return
+
+ GruntChatter_AddEvent( "gruntchatter_friendly_turret_found_target", closestGrunt, enemy )
+}
+
+
+// ==== pilot kill chains ====
+// NOTE: don't technically require a pilot, but makes it easier to port to an MP environment
+void function GruntChatter_UpdatePilotKillChain( entity pilot )
+{
+ file.pilotKillChainCounter++
+ file.lastPilotKillTime = Time()
+}
+
+int function GruntChatter_GetPilotKillChain( entity pilot )
+{
+ return file.pilotKillChainCounter
+}
+
+bool function GruntChatter_IsKillChainStillActive( entity pilot )
+{
+ if ( file.lastPilotKillTime == -1 )
+ return true
+
+ return (Time() - file.lastPilotKillTime) < CHATTER_ENEMY_PILOT_MULTIKILL_EXPIRETIME
+}
+
+void function GruntChatter_ResetPilotKillChain( entity pilot )
+{
+ file.pilotKillChainCounter = 0
+}
+
+
+// ==== chatter util ====
+// won't return mechanicals like Specialists
+array<entity> function GetNearbyFriendlyHumanGrunts( vector searchOrigin, int friendlyTeam, float ornull searchRange = null )
+{
+ array<entity> nearbyGrunts = GetNearbyFriendlyGrunts( searchOrigin, friendlyTeam, searchRange )
+ array<entity> humanGrunts = []
+ foreach ( grunt in nearbyGrunts )
+ {
+ if ( grunt.IsMechanical() )
+ continue
+
+ humanGrunts.append( grunt )
+ }
+
+ return humanGrunts
+}
+
+// won't return mechanicals like Specialists
+array<entity> function GetNearbyEnemyHumanGrunts( vector searchOrigin, int enemyTeam, float ornull searchRange = null )
+{
+ array<entity> nearbyGrunts = GetNearbyEnemyGrunts( searchOrigin, enemyTeam, searchRange )
+ array<entity> humanGrunts = []
+ foreach ( grunt in nearbyGrunts )
+ {
+ if ( grunt.IsMechanical() )
+ continue
+
+ humanGrunts.append( grunt )
+ }
+
+ return humanGrunts
+}
+
+bool function GruntChatter_CanGruntChatterNow( entity grunt )
+{
+ if ( !IsAlive( grunt ) )
+ return false
+
+ if ( !GruntChatter_IsGruntTypeEligibleForChatter( grunt ) )
+ return false
+
+ if ( grunt.ContextAction_IsMeleeExecution() )
+ return false
+
+ // we only care about this because the grunt conversation system wants it
+ if ( GetSquadName( grunt ) == "" )
+ return false
+
+ return true
+}
+
+bool function GruntChatter_IsGruntTypeEligibleForChatter( entity grunt )
+{
+ if ( !IsGrunt( grunt ) )
+ return false
+
+ // mechanical grunts don't chatter
+ if ( grunt.IsMechanical() )
+ return false
+
+ if ( grunt.GetTeam() != TEAM_IMC )
+ return false
+
+ return true
+}
+
+bool function GruntChatter_CanGruntChatterToPlayer( entity grunt, entity player )
+{
+ if ( DistanceSqr( grunt.GetOrigin(), player.GetOrigin() ) > MAX_VOICE_DIST_SQRD )
+ return false
+
+ return true
+}
+
+bool function GruntChatter_CanChatterEventUseEnemyTarget( ChatterEvent chatterEvent )
+{
+ entity grunt = chatterEvent.npc
+ entity target = chatterEvent.target
+ bool trackEventTarget = chatterEvent.category.trackEventTarget
+
+ if ( !chatterEvent.hasTarget )
+ return false
+
+ if ( !IsAlive( target ) )
+ return false
+
+ if ( trackEventTarget && GruntChatter_EventTargetAlreadyUsed( target ) )
+ return false
+
+ float distToEnemySqr = DistanceSqr( grunt.GetOrigin(), target.GetOrigin() )
+ if ( distToEnemySqr > MAX_VOICE_DIST_SQRD )
+ return false
+
+ return true
+}
+
+bool function CanNearbyGruntTeammatesSeeEnemy( entity grunt, entity enemy, float nearbyRange )
+{
+ if ( !IsAlive( enemy ) )
+ return false
+
+ array<entity> nearbyGrunts = GetNearbyFriendlyGrunts( enemy.GetOrigin(), grunt.GetTeam(), nearbyRange )
+
+ foreach ( grunt in nearbyGrunts )
+ {
+ if ( grunt.CanSee( enemy ) )
+ return true
+ }
+
+ return false
+}
+
+bool function GruntChatter_IsFriendlyGruntCloseToLocation( int team, vector location, float nearbyRange )
+{
+ array<entity> nearbyGrunts = GetNearbyFriendlyGrunts( location, team, nearbyRange )
+
+ if ( nearbyGrunts.len() )
+ return true
+
+ return false
+}
+
+bool function GruntChatter_IsTargetFacingAway( entity grunt, entity target, float minDotRear )
+{
+ if ( !IsAlive( grunt ) || !IsAlive( target ) )
+ return false
+
+ vector viewAng = target.GetAngles() // overall body angles better for this than viewvec
+ vector viewVec = AnglesToForward( viewAng )
+ vector vecRear = viewVec * -1
+ vector angRear = VectorToAngles( vecRear )
+
+ vector vecToTarget = Normalize( grunt.EyePosition() - target.EyePosition() )
+ float dot2Grunt_rear = DotProduct( vecToTarget, vecRear )
+
+ //printt( "REAR dot to enemy:", dot2Grunt_rear )
+
+ return dot2Grunt_rear >= minDotRear
+}
+
+bool function GruntChatter_IsEnemyAbove( entity grunt, entity enemy )
+{
+ // Pilots jumping over guys gives false positives
+ if ( IsPilot( enemy ) && !enemy.IsOnGround() )
+ return false
+
+ vector gOrg = grunt.GetOrigin()
+ vector eOrg = enemy.GetOrigin()
+
+ vector cylinderBottom = gOrg + < 0, 0, CHATTER_PILOT_SPOTTED_ABOVE_DIST_MIN >
+ vector cylinderTop = gOrg + < 0, 0, CHATTER_PILOT_SPOTTED_ABOVE_DIST_MAX >
+
+ bool isAbove = PointInCylinder( cylinderBottom, cylinderTop, CHATTER_PILOT_SPOTTED_ABOVE_RADIUS, eOrg )
+ return isAbove
+}
+
+bool function GruntChatter_IsEnemyBelow( entity grunt, entity enemy )
+{
+ vector gOrg = grunt.GetOrigin()
+ vector eOrg = enemy.GetOrigin()
+
+ vector cylinderBottom = gOrg - < 0, 0, CHATTER_PILOT_SPOTTED_BELOW_DIST_MAX >
+ vector cylinderTop = gOrg - < 0, 0, CHATTER_PILOT_SPOTTED_BELOW_DIST_MIN >
+
+ bool isBelow = PointInCylinder( cylinderBottom, cylinderTop, CHATTER_PILOT_SPOTTED_BELOW_RADIUS, eOrg )
+ return isBelow
+}
+
+void function GruntChatter_TryGruntFlankedByPlayer( entity grunt, int aiSurprisedReactionType )
+{
+ if ( !GruntChatter_CanGruntDoFlankingCallout( grunt ) )
+ return
+
+ entity surprisingEnemy = grunt.GetEnemy()
+ if ( !IsPilot( surprisingEnemy ) || !surprisingEnemy.IsPlayer() )
+ return
+
+ string alias
+ switch ( aiSurprisedReactionType )
+ {
+ case RSR_REAR_FLANK:
+ //printt( "REAR FLANK!")
+ alias = "gruntchatter_pilot_spotted_flank_rear"
+ break
+
+ case RSR_SIDE_FLANK:
+ //printt( " SIDE FLANK!" )
+ alias = "gruntchatter_pilot_spotted_flank_side"
+ break
+ }
+
+ if ( alias == "" )
+ return
+
+ GruntChatter_AddEvent( alias, grunt, surprisingEnemy )
+}
+
+bool function GruntChatter_CanGruntDoFlankingCallout( entity grunt )
+{
+ if ( !TimerCheck( "chatter_pilot_flanking" ) )
+ return false
+
+ if ( !GruntChatter_CanGruntChatterNow( grunt ) )
+ return false
+
+ return true
+}
+
+entity function GruntChatter_FindClosestEnemyHumanGrunt_LOS( vector searchOrigin, int enemyTeam, float searchDist )
+{
+ array<entity> humanGrunts = GetNearbyEnemyHumanGrunts( searchOrigin, enemyTeam, searchDist )
+ return GruntChatter_GetClosestGrunt_LOS( humanGrunts, searchOrigin )
+}
+
+entity function GruntChatter_FindClosestFriendlyHumanGrunt_LOS( vector searchOrigin, int friendlyTeam, float searchDist )
+{
+ array<entity> humanGrunts = GetNearbyFriendlyHumanGrunts( searchOrigin, friendlyTeam, searchDist )
+ return GruntChatter_GetClosestGrunt_LOS( humanGrunts, searchOrigin )
+}
+
+entity function GruntChatter_GetClosestGrunt_LOS( array<entity> nearbyGrunts, vector searchOrigin )
+{
+ entity closestGrunt = null
+ float closestDist = 10000
+
+ foreach ( grunt in nearbyGrunts )
+ {
+ vector gruntOrigin = grunt.GetOrigin()
+
+ // CanSee doesn't return true if the target is dead
+ if ( !GruntChatter_CanGruntTraceToLocation( grunt, searchOrigin ) )
+ continue
+
+ if ( !closestGrunt )
+ {
+ closestGrunt = grunt
+ continue
+ }
+
+ float distFromSearchOrigin = Distance( grunt.GetOrigin(), searchOrigin )
+
+ if ( closestDist > distFromSearchOrigin )
+ continue
+
+ closestGrunt = grunt
+ closestDist = distFromSearchOrigin
+ }
+
+ return closestGrunt
+}
+
+bool function GruntChatter_CanGruntTraceToLocation( entity grunt, vector traceEnd )
+{
+ float traceFrac = TraceLineSimple( grunt.GetOrigin(), traceEnd, grunt )
+ return traceFrac > CHATTER_NEARBY_GRUNT_TRACEFRAC_MIN
+}
+
+string function GetSquadName( entity grunt )
+{
+ string squadName = expect string( grunt.kv.squadname )
+ return squadName
+}
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_squad_spawn.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_squad_spawn.gnut
index 9dbdd699..9dbdd699 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_squad_spawn.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_squad_spawn.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_titan_npc_behavior.gnut b/Northstar.CustomServers/mod/scripts/vscripts/ai/_titan_npc_behavior.gnut
index 347cb644..347cb644 100644
--- a/Northstar.CustomServers/scripts/vscripts/ai/_titan_npc_behavior.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/ai/_titan_npc_behavior.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/burnmeter/_burnmeter.gnut b/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut
index 8e1cb71f..8e1cb71f 100644
--- a/Northstar.CustomServers/scripts/vscripts/burnmeter/_burnmeter.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/class/CHardPointEntity.nut b/Northstar.CustomServers/mod/scripts/vscripts/class/CHardPointEntity.nut
index a340bc32..a340bc32 100644
--- a/Northstar.CustomServers/scripts/vscripts/class/CHardPointEntity.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/class/CHardPointEntity.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/class/cai_basenpc.nut b/Northstar.CustomServers/mod/scripts/vscripts/class/cai_basenpc.nut
index 631e01fc..631e01fc 100644
--- a/Northstar.CustomServers/scripts/vscripts/class/cai_basenpc.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/class/cai_basenpc.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/class/cbasecombatcharacter.nut b/Northstar.CustomServers/mod/scripts/vscripts/class/cbasecombatcharacter.nut
index 11018cea..11018cea 100644
--- a/Northstar.CustomServers/scripts/vscripts/class/cbasecombatcharacter.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/class/cbasecombatcharacter.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/class/cbaseentity.nut b/Northstar.CustomServers/mod/scripts/vscripts/class/cbaseentity.nut
index 08d2b2e1..08d2b2e1 100644
--- a/Northstar.CustomServers/scripts/vscripts/class/cbaseentity.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/class/cbaseentity.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/class/cplayer.nut b/Northstar.CustomServers/mod/scripts/vscripts/class/cplayer.nut
index b9f8f7eb..b9f8f7eb 100644
--- a/Northstar.CustomServers/scripts/vscripts/class/cplayer.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/class/cplayer.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/class/ctitansoul.nut b/Northstar.CustomServers/mod/scripts/vscripts/class/ctitansoul.nut
index 6f5ddb3e..6f5ddb3e 100644
--- a/Northstar.CustomServers/scripts/vscripts/class/ctitansoul.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/class/ctitansoul.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/conversation/_battle_chatter.gnut b/Northstar.CustomServers/mod/scripts/vscripts/conversation/_battle_chatter.gnut
index 961816c7..961816c7 100644
--- a/Northstar.CustomServers/scripts/vscripts/conversation/_battle_chatter.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/conversation/_battle_chatter.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/conversation/_conversation_schedule.gnut b/Northstar.CustomServers/mod/scripts/vscripts/conversation/_conversation_schedule.gnut
index 089d4b71..089d4b71 100644
--- a/Northstar.CustomServers/scripts/vscripts/conversation/_conversation_schedule.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/conversation/_conversation_schedule.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/conversation/_faction_dialogue.gnut b/Northstar.CustomServers/mod/scripts/vscripts/conversation/_faction_dialogue.gnut
index ccb5cd6e..ccb5cd6e 100644
--- a/Northstar.CustomServers/scripts/vscripts/conversation/_faction_dialogue.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/conversation/_faction_dialogue.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/conversation/_grunt_chatter_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/conversation/_grunt_chatter_mp.gnut
index b638e92b..b638e92b 100644
--- a/Northstar.CustomServers/scripts/vscripts/conversation/_grunt_chatter_mp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/conversation/_grunt_chatter_mp.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/conversation/_spectre_chatter_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/conversation/_spectre_chatter_mp.gnut
index 2f9e0f84..2f9e0f84 100644
--- a/Northstar.CustomServers/scripts/vscripts/conversation/_spectre_chatter_mp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/conversation/_spectre_chatter_mp.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/earn_meter/sv_earn_meter.gnut b/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter.gnut
index dda84976..dda84976 100644
--- a/Northstar.CustomServers/scripts/vscripts/earn_meter/sv_earn_meter.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut
index b41640ad..b41640ad 100644
--- a/Northstar.CustomServers/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/earn_meter/sv_earn_meter_mp.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/evac/_evac.gnut b/Northstar.CustomServers/mod/scripts/vscripts/evac/_evac.gnut
index ba473cae..ba473cae 100644
--- a/Northstar.CustomServers/scripts/vscripts/evac/_evac.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/evac/_evac.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/faction_xp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/faction_xp.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/faction_xp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/faction_xp.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_ai_frontline.gnut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_ai_frontline.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_ai_frontline.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_ai_frontline.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_ai_gamemodes.gnut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_ai_gamemodes.gnut
index cf7f7e15..cf7f7e15 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_ai_gamemodes.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_ai_gamemodes.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_capture_point.gnut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_capture_point.gnut
index e02157d1..e02157d1 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_capture_point.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_capture_point.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_featured_mode_settings.gnut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_featured_mode_settings.gnut
index 090814cb..090814cb 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_featured_mode_settings.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_featured_mode_settings.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_frontline.gnut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_frontline.gnut
index 7ece7dc1..7ece7dc1 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_frontline.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_frontline.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_aitdm.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_aitdm.nut
index a30944cf..a30944cf 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_aitdm.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_aitdm.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_at.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut
index b75ed51b..b75ed51b 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_at.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_coliseum.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_coliseum.nut
index b358cfe8..b1de4d4f 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_coliseum.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_coliseum.nut
@@ -44,6 +44,9 @@ void function ShowColiseumIntroScreenThreaded()
void function GivePlayerColiseumLoadout( entity player )
{
+ if ( GetCurrentPlaylistVarInt( "coliseum_loadouts_enabled", 1 ) == 0 )
+ return
+
// create loadout struct
PilotLoadoutDef coliseumLoadout = clone GetActivePilotLoadout( player )
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_cp.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_cp.nut
index ddfe6ee6..ddfe6ee6 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_cp.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_cp.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_ctf.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ctf.nut
index 704f55d3..704f55d3 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_ctf.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ctf.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut
index b5f700e5..b5f700e5 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fd.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_ffa.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ffa.nut
index 932f14b7..932f14b7 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_ffa.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ffa.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_fra.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fra.nut
index 9d8f84b5..9d8f84b5 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_fra.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_fra.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_lts.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_lts.nut
index 89f9c991..89f9c991 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_lts.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_lts.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_mfd.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_mfd.nut
index 6e8e9fa3..8d0545cb 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_mfd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_mfd.nut
@@ -154,7 +154,9 @@ void function MarkPlayers( entity imcMark, entity militiaMark )
// award points
entity livingMark = GetMarked( GetOtherTeam( deadMark.GetTeam() ) )
livingMark.SetPlayerGameStat( PGS_DEFENSE_SCORE, livingMark.GetPlayerGameStat( PGS_DEFENSE_SCORE ) + 1 )
- AddTeamScore( livingMark.GetTeam(), 1 )
+
+ // thread this so we don't kill our own thread
+ thread AddTeamScore( livingMark.GetTeam(), 1 )
}
void function UpdateMarksForKill( entity victim, entity attacker, var damageInfo )
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_ps.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut
index 3a852f91..3a852f91 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_ps.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_speedball.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut
index 4532fb97..4532fb97 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_speedball.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_tdm.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut
index 9e80b863..9e80b863 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_tdm.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_tdm.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_ttdm.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ttdm.nut
index faf3e5ca..faf3e5ca 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_gamemode_ttdm.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ttdm.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_hardpoints.gnut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_hardpoints.gnut
index 0a32f133..0a32f133 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_hardpoints.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_hardpoints.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_riff_floor_is_lava.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_riff_floor_is_lava.nut
index b660e89f..b660e89f 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_riff_floor_is_lava.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_riff_floor_is_lava.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/_spawnpoints.gnut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_spawnpoints.gnut
index e69de29b..e69de29b 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/_spawnpoints.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_spawnpoints.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/sh_gamemodes.gnut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/sh_gamemodes.gnut
index 9114fcad..9114fcad 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/sh_gamemodes.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/sh_gamemodes.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/gamemodes/sh_gamemodes_custom.gnut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/sh_gamemodes_custom.gnut
index 51f8bf9e..51f8bf9e 100644
--- a/Northstar.CustomServers/scripts/vscripts/gamemodes/sh_gamemodes_custom.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/sh_gamemodes_custom.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/item_inventory/sv_item_inventory.gnut b/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut
index ff2a4c7c..ff2a4c7c 100644
--- a/Northstar.CustomServers/scripts/vscripts/item_inventory/sv_item_inventory.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/item_inventory/sv_item_inventory.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/lobby/_lobby.gnut b/Northstar.CustomServers/mod/scripts/vscripts/lobby/_lobby.gnut
index fd877f8c..fd877f8c 100644
--- a/Northstar.CustomServers/scripts/vscripts/lobby/_lobby.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/lobby/_lobby.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/lobby/_private_lobby.gnut b/Northstar.CustomServers/mod/scripts/vscripts/lobby/_private_lobby.gnut
index 896ab207..60daa452 100644
--- a/Northstar.CustomServers/scripts/vscripts/lobby/_private_lobby.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/lobby/_private_lobby.gnut
@@ -11,7 +11,7 @@ struct {
void function PrivateLobby_Init()
{
print( "PrivateLobby_Init()" )
- ClearPlaylistVarOverrides()
+ //ClearPlaylistVarOverrides()
AddClientCommandCallback( "PrivateMatchLaunch", ClientCommandCallback_PrivateMatchLaunch )
AddClientCommandCallback( "PrivateMatchSetMode", ClientCommandCallback_PrivateMatchSetMode )
@@ -127,7 +127,8 @@ void function StartMatch()
RefreshPlayerTeams()
- SetPlaylistVarOverride( "return_to_private_lobby", "1" )
+ SetConVarBool( "ns_should_return_to_lobby", true ) // potentially temp?
+
// TEMP for now: start game
ServerCommand( "changelevel " + file.map )
}
@@ -164,13 +165,25 @@ void function RefreshPlayerTeams()
bool function ClientCommandCallback_PrivateMatchSetPlaylistVarOverride( entity player, array<string> args )
{
- // note: atm this doesn't actually check for the number of overrides, since there's no way to do this on server yet
- // need to expose this to script soon
-
if ( args.len() < 2 )
return true
+
+ bool found = false
+ foreach ( string category in GetPrivateMatchSettingCategories() )
+ {
+ foreach ( CustomMatchSettingContainer setting in GetPrivateMatchCustomSettingsForCategory( category ) )
+ {
+ if ( args[ 0 ] == setting.playlistVar )
+ {
+ found = true
+ break
+ }
+ }
+ }
- SetPlaylistVarOverride( args[0], args[1] )
+ if ( found )
+ SetPlaylistVarOverride( args[0], args[1] )
+
return true
}
diff --git a/Northstar.CustomServers/scripts/vscripts/lobby/sh_lobby.gnut b/Northstar.CustomServers/mod/scripts/vscripts/lobby/sh_lobby.gnut
index fda0e5ff..2c02ebdc 100644
--- a/Northstar.CustomServers/scripts/vscripts/lobby/sh_lobby.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/lobby/sh_lobby.gnut
@@ -2,6 +2,19 @@ globalize_all_functions
const string PRIVATE_MATCH_PLAYLIST = "private_match"
+global struct CustomMatchSettingContainer
+{
+ string playlistVar
+ string defaultValue
+ string localizedName
+ bool isEnumSetting
+
+ // enum setting
+ array< string > enumNames
+ array< string > enumValues
+ //table< string, string > enumValuePairs
+}
+
struct {
array<string> modes = [ // default modes in vanilla
"aitdm",
@@ -44,8 +57,11 @@ struct {
"mp_lf_township",
"mp_lf_uma"
]
+
+ table< string, array< CustomMatchSettingContainer > > customMatchSettingsByCategory // we set these up in sh_private_lobby_modes_init
} file
+
void function AddPrivateMatchMode( string mode )
{
if ( !file.modes.contains( mode ) )
@@ -68,6 +84,126 @@ void function AddPrivateMatchMap( string map )
#endif
}
+
+void function AddPrivateMatchModeSettingArbitrary( string category, string playlistVar, string defaultValue, string localizedName = "" )
+{
+ if ( localizedName == "" )
+ localizedName = "#" + playlistVar
+
+ if ( !( category in file.customMatchSettingsByCategory ) )
+ file.customMatchSettingsByCategory[ category ] <- []
+
+ bool found = false
+ foreach ( CustomMatchSettingContainer setting in file.customMatchSettingsByCategory[ category ] )
+ {
+ if ( setting.playlistVar == playlistVar )
+ {
+ found = true
+ break
+ }
+ }
+
+ if ( !found )
+ {
+ CustomMatchSettingContainer setting
+ setting.playlistVar = playlistVar
+ setting.defaultValue = defaultValue
+ setting.localizedName = localizedName
+ setting.isEnumSetting = false
+
+ file.customMatchSettingsByCategory[ category ].append( setting )
+ }
+
+ #if CLIENT
+ // call this on ui too so the client and ui states are the same
+ RunUIScript( "AddPrivateMatchModeSettingArbitrary", category, playlistVar, defaultValue, localizedName )
+ #endif
+}
+
+void function AddPrivateMatchModeSettingEnum( string category, string playlistVar, array< string > enums, string defaultValue, string localizedName = "" )
+{
+ table< string, string > pairs
+ for ( int i = 0; i < enums.len(); i++ )
+ pairs[ enums[ i ] ] <- i.tostring()
+
+ AddPrivateMatchModeSettingEnumEx( category, playlistVar, pairs, defaultValue, localizedName )
+}
+
+void function AddPrivateMatchModeSettingEnumUIHack( string category, string playlistVar, string serializedEnumPairs, string defaultValue, string localizedName )
+{
+ // this fucking sucks, but RunUIScript won't take tables, so we serialize to a string
+ // we use \n as a delimeter and basically serialize to an array
+ array< string > serializedArray = split( serializedEnumPairs, "\n" )
+ table< string, string > enumPairs
+
+ for ( int i = 0; i < serializedArray.len(); i += 2 )
+ enumPairs[ serializedArray[ i ] ] <- serializedArray[ i + 1 ]
+
+ AddPrivateMatchModeSettingEnumEx( category, playlistVar, enumPairs, defaultValue, localizedName )
+}
+
+void function AddPrivateMatchModeSettingEnumEx( string category, string playlistVar, table< string, string > enumPairs, string defaultValue, string localizedName = "" )
+{
+ if ( localizedName == "" )
+ localizedName = "#" + playlistVar
+
+ if ( !( category in file.customMatchSettingsByCategory ) )
+ file.customMatchSettingsByCategory[ category ] <- []
+
+ bool found = false
+ foreach ( CustomMatchSettingContainer setting in file.customMatchSettingsByCategory[ category ] )
+ {
+ if ( setting.playlistVar == playlistVar )
+ {
+ found = true
+ break
+ }
+ }
+
+ if ( !found )
+ {
+ CustomMatchSettingContainer setting
+ setting.playlistVar = playlistVar
+ setting.defaultValue = defaultValue
+ setting.localizedName = localizedName
+ setting.isEnumSetting = true
+ //setting.enumValuePairs = enumPairs
+
+ foreach ( string name, string value in enumPairs )
+ {
+ setting.enumNames.append( name )
+ setting.enumValues.append( value )
+ }
+
+ file.customMatchSettingsByCategory[ category ].append( setting )
+ }
+
+ #if CLIENT
+ // call this on ui too so the client and ui states are the same
+ // note: RunUIScript can't take tables, so manually serialize ( sucks, but just how it is ), using \n as a delimeter since i dont believe its ever used in vars
+ string serializedString
+ foreach ( string k, string v in enumPairs )
+ serializedString += k + "\n" + v + "\n"
+
+ RunUIScript( "AddPrivateMatchModeSettingEnumUIHack", category, playlistVar, serializedString, defaultValue, localizedName )
+ #endif
+}
+
+array< string > function GetPrivateMatchSettingCategories()
+{
+ array< string > categories
+ foreach ( string k, v in file.customMatchSettingsByCategory )
+ categories.append( k )
+
+ return categories
+}
+
+array< CustomMatchSettingContainer > function GetPrivateMatchCustomSettingsForCategory( string category )
+{
+ return file.customMatchSettingsByCategory[ category ]
+}
+
+
array<string> function GetPrivateMatchModes()
{
//array<string> modesArray
@@ -291,6 +427,9 @@ bool function ModeSettings_RequiresAI( string modeName )
case "at":
return true
}
+
+ if ( modeName.find( "fd" ) == 0 ) // bob edit: unsure if this keeps vanilla compatibility, but just make sure fd modes are counted as requiring ai
+ return true
return false
}
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/lobby/sh_private_lobby_modes_init.gnut b/Northstar.CustomServers/mod/scripts/vscripts/lobby/sh_private_lobby_modes_init.gnut
new file mode 100644
index 00000000..41806e16
--- /dev/null
+++ b/Northstar.CustomServers/mod/scripts/vscripts/lobby/sh_private_lobby_modes_init.gnut
@@ -0,0 +1,55 @@
+global function PrivateMatchModesInit
+
+void function PrivateMatchModesInit()
+{
+ // match settings
+ // super temp: do localisation strings later
+ AddPrivateMatchModeSettingArbitrary( "Match", "scorelimit", "5" ) //, "Score Limit" )
+ AddPrivateMatchModeSettingArbitrary( "Match", "roundscorelimit", "0" ) //, "Score Limit (round-based modes)" )
+ AddPrivateMatchModeSettingArbitrary( "Match", "timelimit", "12" ) //, "Time Limit" )
+ AddPrivateMatchModeSettingArbitrary( "Match", "roundtimelimit", "0" ) //, "Time Limit (round-based modes)" )
+
+ AddPrivateMatchModeSettingArbitrary( "Pilot", "pilot_health_multiplier", "1.0" )
+ AddPrivateMatchModeSettingArbitrary( "Pilot", "respawn_delay", "0.0" )
+ AddPrivateMatchModeSettingEnum( "Pilot", "boosts_enabled", [ "Default", "Disabled" ], "1" )
+ AddPrivateMatchModeSettingEnum( "Pilot", "earn_meter_pilot_overdrive", [ "Disabled", "Enabled", "Only" ], "1" )
+ AddPrivateMatchModeSettingArbitrary( "Pilot", "earn_meter_pilot_multiplier", "1.0" )
+
+ AddPrivateMatchModeSettingArbitrary( "Titan", "earn_meter_titan_multiplier", "1.0" )
+ AddPrivateMatchModeSettingEnum( "Titan", "aegis_upgrades", [ "Disabled", "Enabled" ], "0" )
+ AddPrivateMatchModeSettingEnum( "Titan", "infinite_doomed_state", [ "Disabled", "Enabled" ], "0" )
+ AddPrivateMatchModeSettingEnum( "Titan", "titan_shield_regen", [ "Disabled", "Enabled" ], "0" )
+
+ AddPrivateMatchModeSettingEnum( "Riff Settings", "riff_floorislava", [ "Default", "Enabled", "Disabled" ], "0" )
+ AddPrivateMatchModeSettingEnum( "Riff Settings", "featured_mode_all_holopilot", [ "Disabled", "Enabled" ], "0" )
+ AddPrivateMatchModeSettingEnum( "Riff Settings", "featured_mode_all_grapple", [ "Disabled", "Enabled" ], "0" )
+ AddPrivateMatchModeSettingEnum( "Riff Settings", "featured_mode_all_phase", [ "Disabled", "Enabled" ], "0" )
+ AddPrivateMatchModeSettingEnum( "Riff Settings", "featured_mode_all_ticks", [ "Disabled", "Enabled" ], "0" )
+ AddPrivateMatchModeSettingEnum( "Riff Settings", "featured_mode_tactikill", [ "Disabled", "Enabled" ], "0" )
+ AddPrivateMatchModeSettingEnum( "Riff Settings", "featured_mode_amped_tacticals", [ "Disabled", "Enabled" ], "0" )
+ AddPrivateMatchModeSettingEnum( "Riff Settings", "featured_mode_rocket_arena", [ "Disabled", "Enabled" ], "0" )
+ AddPrivateMatchModeSettingEnum( "Riff Settings", "featured_mode_shotguns_snipers", [ "Disabled", "Enabled" ], "0" )
+
+ // gamemode settings
+ AddPrivateMatchModeSettingEnum( "#GAMEMODE_cp", "amped_capture_points", [ "Disabled", "Enabled" ], "0" )
+
+ AddPrivateMatchModeSettingEnum( "#GAMEMODE_coliseum", "coliseum_loadouts_enabled", [ "Disabled", "Enabled" ], "1" )
+
+
+ // modes
+ AddPrivateMatchMode( "ffa" )
+ AddPrivateMatchMode( "fra" )
+ AddPrivateMatchMode( "coliseum" )
+
+ // playlists
+ AddPrivateMatchMode( "attdm" )
+ AddPrivateMatchMode( "turbo_ttdm" )
+ AddPrivateMatchMode( "alts" )
+ AddPrivateMatchMode( "turbo_lts" )
+ AddPrivateMatchMode( "rocket_lf" )
+ AddPrivateMatchMode( "holopilot_lf" )
+
+ // maps
+ AddPrivateMatchMap( "mp_coliseum" )
+ AddPrivateMatchMap( "mp_coliseum_column" )
+} \ No newline at end of file
diff --git a/Northstar.CustomServers/scripts/vscripts/melee/_melee.gnut b/Northstar.CustomServers/mod/scripts/vscripts/melee/_melee.gnut
index 035caf9e..035caf9e 100644
--- a/Northstar.CustomServers/scripts/vscripts/melee/_melee.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/melee/_melee.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/melee/_melee_rewards.gnut b/Northstar.CustomServers/mod/scripts/vscripts/melee/_melee_rewards.gnut
index 46b730d6..46b730d6 100644
--- a/Northstar.CustomServers/scripts/vscripts/melee/_melee_rewards.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/melee/_melee_rewards.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/melee/_melee_synced_human.gnut b/Northstar.CustomServers/mod/scripts/vscripts/melee/_melee_synced_human.gnut
index 15a8aa3e..15a8aa3e 100644
--- a/Northstar.CustomServers/scripts/vscripts/melee/_melee_synced_human.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/melee/_melee_synced_human.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/melee/_melee_synced_titan.gnut b/Northstar.CustomServers/mod/scripts/vscripts/melee/_melee_synced_titan.gnut
index 5c6285a9..5c6285a9 100644
--- a/Northstar.CustomServers/scripts/vscripts/melee/_melee_synced_titan.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/melee/_melee_synced_titan.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_ai_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_mp.gnut
index ac0c309b..ac0c309b 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_ai_mp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_mp.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_ai_mp.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_mp.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_ai_mp.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_mp.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_ai_superspectre.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_superspectre.nut
index 68e888f4..68e888f4 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_ai_superspectre.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_ai_superspectre.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_base_gametype.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype.gnut
index a4c6e187..a4c6e187 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_base_gametype.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_base_gametype_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut
index 9274854a..d7db601b 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_base_gametype_mp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut
@@ -582,13 +582,11 @@ void function TrackTitanDamageInPlayerGameStat( int playerGameStat )
file.titanDamageGameStat = playerGameStat
}
-// this should be generic, not restricted to a specific gamemode
void function AddToTitanDamageStat( entity victim, var damageInfo )
{
if ( !victim.IsTitan() || file.titanDamageGameStat == -1 )
return
- // todo: this needs to not count selfdamage
entity attacker = DamageInfo_GetAttacker( damageInfo )
float amount = DamageInfo_GetDamage( damageInfo )
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_battery_port.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_battery_port.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_battery_port.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_battery_port.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_bleedout.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_bleedout.gnut
index 2192b4b1..2192b4b1 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_bleedout.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_bleedout.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_challenges.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_challenges.gnut
index 466a5042..466a5042 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_challenges.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_challenges.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_changemap.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_changemap.nut
index 06270c39..95d7492e 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_changemap.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_changemap.nut
@@ -1,26 +1,20 @@
global function CodeCallback_MatchIsOver
-
void function CodeCallback_MatchIsOver()
{
- foreach ( entity player in GetPlayerArray() )
- SavePdataForEntityIndex( player.GetPlayerIndex() )
-
if ( !IsPrivateMatch() && IsMatchmakingServer() )
SetUIVar( level, "putPlayerInMatchmakingAfterDelay", true )
else
SetUIVar( level, "putPlayerInMatchmakingAfterDelay", false )
- if ( GetCurrentPlaylistVarInt( "return_to_private_lobby", 0 ) == 1 ) // set in _private_lobby.gnut, temp lol
+ if ( ShouldReturnToLobby() )
{
SetCurrentPlaylist( "private_match" ) // needed for private lobby to load
if ( IsSingleplayer() )
- GameRules_ChangeMap( "mp_lobby", "tdm" ) // need to change back to tdm
+ GameRules_ChangeMap( "mp_lobby", "tdm" ) // need to change back to mp playlist or loadouts will break in lobby
else
GameRules_ChangeMap( "mp_lobby", GAMETYPE )
- // this is esp important for sp, since solo will break a bunch of shit in the private lobby
- // idk if even necessary to deal with solo but eh whatever better to have it work than not
}
#if DEV
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_classic_mp.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp.nut
index ac8a397f..ac8a397f 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_classic_mp.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut
index 02c312be..02c312be 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_classic_mp_no_intro.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_no_intro.gnut
index 106f867b..106f867b 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_classic_mp_no_intro.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_no_intro.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_codecallbacks.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_codecallbacks.gnut
index 2e565142..2e565142 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_codecallbacks.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_codecallbacks.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_dropship_spawn_common.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_dropship_spawn_common.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_dropship_spawn_common.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_dropship_spawn_common.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_gamestate.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate.nut
index 603c38fa..603c38fa 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_gamestate.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_gamestate_mp.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut
index 96a61b69..197ac5e9 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_gamestate_mp.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut
@@ -4,6 +4,7 @@ global function PIN_GameStart
global function SetGameState
global function GameState_EntitiesDidLoad
global function WaittillGameStateOrHigher
+global function AddCallback_OnRoundEndCleanup
global function SetShouldUsePickLoadoutScreen
global function SetSwitchSidesBased
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_goblin_dropship.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_goblin_dropship.nut
index fe36e668..fe36e668 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_goblin_dropship.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_goblin_dropship.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_lasermesh.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_lasermesh.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_lasermesh.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_lasermesh.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_loadout_crate.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_loadout_crate.nut
index d987c774..d987c774 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_loadout_crate.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_loadout_crate.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_mp_mapspawn.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_mp_mapspawn.gnut
index 6860d817..6860d817 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_mp_mapspawn.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_mp_mapspawn.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_music.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_music.gnut
index 44320336..44320336 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_music.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_music.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_pickups.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_pickups.gnut
index ecf9b3e5..ecf9b3e5 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_pickups.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_pickups.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_pickups_glow.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_pickups_glow.gnut
index f1fe4ecc..f1fe4ecc 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_pickups_glow.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_pickups_glow.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_playlist.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_playlist.gnut
index dfceab41..dfceab41 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_playlist.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_playlist.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_revive.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_revive.gnut
index b2f5c467..b2f5c467 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_revive.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_revive.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_score.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut
index 238eab1d..238eab1d 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_score.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_serverflags.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_serverflags.nut
index a665463d..a665463d 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_serverflags.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_serverflags.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_sniper_spectres.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_sniper_spectres.nut
index ce513259..ce513259 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_sniper_spectres.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_sniper_spectres.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_spawn_functions.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_spawn_functions.nut
index 3d9b84f3..3d9b84f3 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_spawn_functions.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_spawn_functions.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_spectre_rack.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_spectre_rack.nut
index a76c0fc9..a76c0fc9 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_spectre_rack.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_spectre_rack.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_stats.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut
index 0e8b58f4..0e8b58f4 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_stats.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_stats.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_titan_npc.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_titan_npc.nut
index 58285087..58285087 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_titan_npc.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_titan_npc.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_titan_tether.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_titan_tether.gnut
index b088651a..b088651a 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_titan_tether.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_titan_tether.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_titan_transfer.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_titan_transfer.nut
index 7b126cd0..7b126cd0 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_titan_transfer.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_titan_transfer.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_tonecontroller.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_tonecontroller.nut
index 786eda23..786eda23 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_tonecontroller.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_tonecontroller.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_utility_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_utility_mp.gnut
index ea7d9d44..ea7d9d44 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_utility_mp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_utility_mp.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/_vr.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_vr.nut
index b9759ddf..b9759ddf 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/_vr.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_vr.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/_lf_maps_shared.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/_lf_maps_shared.gnut
index d61d6baa..d61d6baa 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/_lf_maps_shared.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/_lf_maps_shared.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_angel_city.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city.nut
index 68b49ad5..68b49ad5 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_angel_city.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_angel_city_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city_fd.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_angel_city_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_angel_city_fd.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_black_water_canal.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_black_water_canal.nut
index 2e35417f..2e35417f 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_black_water_canal.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_black_water_canal.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_black_water_canal_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_black_water_canal_fd.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_black_water_canal_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_black_water_canal_fd.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_coliseum.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_coliseum.nut
index 398b2fc5..398b2fc5 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_coliseum.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_coliseum.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_coliseum_column.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_coliseum_column.nut
index 398b2fc5..398b2fc5 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_coliseum_column.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_coliseum_column.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_colony02.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_colony02.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_colony02.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_colony02.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_colony02_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_colony02_fd.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_colony02_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_colony02_fd.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_complex3.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_complex3.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_complex3.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_complex3.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_crashsite3.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_crashsite3.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_crashsite3.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_crashsite3.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_drydock.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_drydock.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_drydock.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_drydock.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_drydock_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_drydock_fd.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_drydock_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_drydock_fd.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_eden.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_eden.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_eden.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_eden.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_forwardbase_kodai.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_forwardbase_kodai.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_forwardbase_kodai.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_forwardbase_kodai.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_forwardbase_kodai_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_forwardbase_kodai_fd.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_forwardbase_kodai_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_forwardbase_kodai_fd.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_glitch.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_glitch.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_glitch.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_glitch.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_glitch_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_glitch_fd.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_glitch_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_glitch_fd.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_grave.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_grave.nut
index f4b48f6d..f4b48f6d 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_grave.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_grave.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_grave_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_grave_fd.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_grave_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_grave_fd.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_homestead.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_homestead.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_homestead.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_homestead.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_homestead_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_homestead_fd.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_homestead_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_homestead_fd.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_deck.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_deck.nut
index 398b2fc5..398b2fc5 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_deck.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_deck.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_meadow.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_meadow.nut
index 398b2fc5..398b2fc5 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_meadow.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_meadow.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_stacks.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_stacks.nut
index 398b2fc5..398b2fc5 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_stacks.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_stacks.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_township.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_township.nut
index 398b2fc5..398b2fc5 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_township.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_township.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_traffic.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_traffic.nut
index 398b2fc5..398b2fc5 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_traffic.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_traffic.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_uma.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_uma.nut
index 398b2fc5..398b2fc5 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_lf_uma.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_lf_uma.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_relic02.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_relic02.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_relic02.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_relic02.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_relic02_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_relic02_fd.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_relic02_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_relic02_fd.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_rise.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_rise.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_rise.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_rise.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_rise_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_rise_fd.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_rise_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_rise_fd.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_thaw.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_thaw.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_thaw.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_thaw.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_thaw_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_thaw_fd.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_thaw_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_thaw_fd.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_wargames.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut
index b6c8cfc2..b6c8cfc2 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_wargames.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_wargames_fd.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames_fd.nut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/levels/mp_wargames_fd.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/levels/mp_wargames_fd.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/pintelemetry.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/pintelemetry.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/pintelemetry.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/pintelemetry.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/player_cloak.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/player_cloak.nut
index 8ef7dcd9..8ef7dcd9 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/player_cloak.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/player_cloak.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/spawn.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut
index 26e4c713..26e4c713 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/spawn.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/spawn_debug.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn_debug.gnut
index 75ec8cf2..75ec8cf2 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/spawn_debug.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn_debug.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/spawn_on_friendly.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn_on_friendly.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/spawn_on_friendly.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn_on_friendly.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/spawn_wave.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn_wave.gnut
index b8895c55..b8895c55 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/spawn_wave.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn_wave.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/mp/spawn_wave_dropship.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn_wave_dropship.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/mp/spawn_wave_dropship.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/spawn_wave_dropship.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/pilot/_leeching.gnut b/Northstar.CustomServers/mod/scripts/vscripts/pilot/_leeching.gnut
index c9d1f9dd..c9d1f9dd 100644
--- a/Northstar.CustomServers/scripts/vscripts/pilot/_leeching.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/pilot/_leeching.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/pilot/_pilot_leeching.gnut b/Northstar.CustomServers/mod/scripts/vscripts/pilot/_pilot_leeching.gnut
index 596ca711..596ca711 100644
--- a/Northstar.CustomServers/scripts/vscripts/pilot/_pilot_leeching.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/pilot/_pilot_leeching.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/pilot/_slamzoom.nut b/Northstar.CustomServers/mod/scripts/vscripts/pilot/_slamzoom.nut
index 83ee3916..83ee3916 100644
--- a/Northstar.CustomServers/scripts/vscripts/pilot/_slamzoom.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/pilot/_slamzoom.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/pilot/_zipline.gnut b/Northstar.CustomServers/mod/scripts/vscripts/pilot/_zipline.gnut
index a129c479..a129c479 100644
--- a/Northstar.CustomServers/scripts/vscripts/pilot/_zipline.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/pilot/_zipline.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/pilot/class_wallrun.gnut b/Northstar.CustomServers/mod/scripts/vscripts/pilot/class_wallrun.gnut
index 58de59c1..58de59c1 100644
--- a/Northstar.CustomServers/scripts/vscripts/pilot/class_wallrun.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/pilot/class_wallrun.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/rodeo/_rodeo.gnut b/Northstar.CustomServers/mod/scripts/vscripts/rodeo/_rodeo.gnut
index 72ff58b7..72ff58b7 100644
--- a/Northstar.CustomServers/scripts/vscripts/rodeo/_rodeo.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/rodeo/_rodeo.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/rodeo/_rodeo_titan.gnut b/Northstar.CustomServers/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut
index 9f05a0cd..9f05a0cd 100644
--- a/Northstar.CustomServers/scripts/vscripts/rodeo/_rodeo_titan.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/rodeo/_rodeo_titan.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/sh_calling_cards.gnut b/Northstar.CustomServers/mod/scripts/vscripts/sh_calling_cards.gnut
index 67461945..67461945 100644
--- a/Northstar.CustomServers/scripts/vscripts/sh_calling_cards.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_calling_cards.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/sh_loadouts_mp.nut b/Northstar.CustomServers/mod/scripts/vscripts/sh_loadouts_mp.nut
index 3b1c8a8a..3b1c8a8a 100644
--- a/Northstar.CustomServers/scripts/vscripts/sh_loadouts_mp.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_loadouts_mp.nut
diff --git a/bobthebob.testing/scripts/vscripts/sh_northstar_utils.gnut b/Northstar.CustomServers/mod/scripts/vscripts/sh_northstar_utils.gnut
index 15eed9b2..20d742d0 100644
--- a/bobthebob.testing/scripts/vscripts/sh_northstar_utils.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_northstar_utils.gnut
@@ -23,14 +23,7 @@ bool function IsNorthstarServer()
// whether the game should return to the lobby on GameRules_EndMatch()
bool function ShouldReturnToLobby()
{
- bool shouldReturnToLobby = false
- try
- {
- // need this in a trycatch because the var might not exist atm
- shouldReturnToLobby = GetConVarInt( "northstar_should_return_to_lobby" ) == 1
- } catch ( ex ) {}
-
- return shouldReturnToLobby
+ return GetConVarBool( "ns_should_return_to_lobby" )
}
int function GetNorthstarLobbyType()
diff --git a/Northstar.CustomServers/scripts/vscripts/sh_remote_functions_mp_custom.gnut b/Northstar.CustomServers/mod/scripts/vscripts/sh_remote_functions_mp_custom.gnut
index c1e49e76..c1e49e76 100644
--- a/Northstar.CustomServers/scripts/vscripts/sh_remote_functions_mp_custom.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_remote_functions_mp_custom.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/sh_stats.gnut b/Northstar.CustomServers/mod/scripts/vscripts/sh_stats.gnut
index 31634a9b..31634a9b 100644
--- a/Northstar.CustomServers/scripts/vscripts/sh_stats.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/sh_stats.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/superbar/orbitalstrike.nut b/Northstar.CustomServers/mod/scripts/vscripts/superbar/orbitalstrike.nut
index 7e622432..7e622432 100644
--- a/Northstar.CustomServers/scripts/vscripts/superbar/orbitalstrike.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/superbar/orbitalstrike.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/superbar/smokescreen.nut b/Northstar.CustomServers/mod/scripts/vscripts/superbar/smokescreen.nut
index 6bbb3e89..6bbb3e89 100644
--- a/Northstar.CustomServers/scripts/vscripts/superbar/smokescreen.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/superbar/smokescreen.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/sv_globals.gnut b/Northstar.CustomServers/mod/scripts/vscripts/sv_globals.gnut
index e69de29b..e69de29b 100644
--- a/Northstar.CustomServers/scripts/vscripts/sv_globals.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/sv_globals.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/titan/_battery_generator.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan/_battery_generator.gnut
index 567ad6e7..567ad6e7 100644
--- a/Northstar.CustomServers/scripts/vscripts/titan/_battery_generator.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/titan/_battery_generator.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/titan/_replacement_titans.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan/_replacement_titans.gnut
index c9d986bc..c9d986bc 100644
--- a/Northstar.CustomServers/scripts/vscripts/titan/_replacement_titans.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/titan/_replacement_titans.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/titan/_replacement_titans_drop.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan/_replacement_titans_drop.gnut
index 5970f7ea..5970f7ea 100644
--- a/Northstar.CustomServers/scripts/vscripts/titan/_replacement_titans_drop.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/titan/_replacement_titans_drop.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/titan/_titan_commands.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_commands.gnut
index 06232c08..06232c08 100644
--- a/Northstar.CustomServers/scripts/vscripts/titan/_titan_commands.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_commands.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/titan/_titan_health.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_health.gnut
index d600cb03..d600cb03 100644
--- a/Northstar.CustomServers/scripts/vscripts/titan/_titan_health.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_health.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/titan/_titan_hints.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_hints.gnut
index 0e8b4b5b..0e8b4b5b 100644
--- a/Northstar.CustomServers/scripts/vscripts/titan/_titan_hints.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_hints.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/titan/_titan_hotdrop.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_hotdrop.gnut
index e3410de8..e3410de8 100644
--- a/Northstar.CustomServers/scripts/vscripts/titan/_titan_hotdrop.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_hotdrop.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/titan/_titan_triple_health.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_triple_health.gnut
index 7515b868..7515b868 100644
--- a/Northstar.CustomServers/scripts/vscripts/titan/_titan_triple_health.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/titan/_titan_triple_health.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/titan/class_titan.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan/class_titan.gnut
index 5f72385e..5f72385e 100644
--- a/Northstar.CustomServers/scripts/vscripts/titan/class_titan.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/titan/class_titan.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/titan_xp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/titan_xp.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/titan_xp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/titan_xp.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/vehicle/_vehicle_behavior.gnut b/Northstar.CustomServers/mod/scripts/vscripts/vehicle/_vehicle_behavior.gnut
index 2d0dd920..2d0dd920 100644
--- a/Northstar.CustomServers/scripts/vscripts/vehicle/_vehicle_behavior.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/vehicle/_vehicle_behavior.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/vehicle/_vehicle_dropship_new.nut b/Northstar.CustomServers/mod/scripts/vscripts/vehicle/_vehicle_dropship_new.nut
index 87010ca7..87010ca7 100644
--- a/Northstar.CustomServers/scripts/vscripts/vehicle/_vehicle_dropship_new.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/vehicle/_vehicle_dropship_new.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/weapon_xp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/weapon_xp.gnut
index 37b89169..37b89169 100644
--- a/Northstar.CustomServers/scripts/vscripts/weapon_xp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/weapon_xp.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/weapons/_arc_cannon.nut b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_arc_cannon.nut
index 1601330c..1601330c 100644
--- a/Northstar.CustomServers/scripts/vscripts/weapons/_arc_cannon.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_arc_cannon.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/weapons/_at_turrets.gnut b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_at_turrets.gnut
index b061c182..b061c182 100644
--- a/Northstar.CustomServers/scripts/vscripts/weapons/_at_turrets.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_at_turrets.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/weapons/_ball_lightning.gnut b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_ball_lightning.gnut
index 9aae59e5..9aae59e5 100644
--- a/Northstar.CustomServers/scripts/vscripts/weapons/_ball_lightning.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_ball_lightning.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/weapons/_cloaker.gnut b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_cloaker.gnut
index 6ec0bc0a..6ec0bc0a 100644
--- a/Northstar.CustomServers/scripts/vscripts/weapons/_cloaker.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_cloaker.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/weapons/_grenade.nut b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_grenade.nut
index c2036e85..c2036e85 100644
--- a/Northstar.CustomServers/scripts/vscripts/weapons/_grenade.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_grenade.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/weapons/_particle_wall.gnut b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_particle_wall.gnut
index a46bfff8..a46bfff8 100644
--- a/Northstar.CustomServers/scripts/vscripts/weapons/_particle_wall.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_particle_wall.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/weapons/_team_emp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_team_emp.gnut
index 41d42848..41d42848 100644
--- a/Northstar.CustomServers/scripts/vscripts/weapons/_team_emp.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_team_emp.gnut
diff --git a/Northstar.CustomServers/scripts/vscripts/weapons/_vortex.nut b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_vortex.nut
index f1e46a53..f1e46a53 100644
--- a/Northstar.CustomServers/scripts/vscripts/weapons/_vortex.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_vortex.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/weapons/_weapon_dialogue.nut b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_weapon_dialogue.nut
index 04fd24d3..04fd24d3 100644
--- a/Northstar.CustomServers/scripts/vscripts/weapons/_weapon_dialogue.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_weapon_dialogue.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/weapons/_weapon_utility.nut b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_weapon_utility.nut
index b3e5f5a3..b3e5f5a3 100644
--- a/Northstar.CustomServers/scripts/vscripts/weapons/_weapon_utility.nut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/weapons/_weapon_utility.nut
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_droppod.gnut b/Northstar.CustomServers/scripts/vscripts/ai/_droppod.gnut
deleted file mode 100644
index 847efa8b..00000000
--- a/Northstar.CustomServers/scripts/vscripts/ai/_droppod.gnut
+++ /dev/null
@@ -1,6 +0,0 @@
-global function DropPod_Init
-
-void function DropPod_Init()
-{
-
-} \ No newline at end of file
diff --git a/Northstar.CustomServers/scripts/vscripts/lobby/sh_private_lobby_modes_init.gnut b/Northstar.CustomServers/scripts/vscripts/lobby/sh_private_lobby_modes_init.gnut
deleted file mode 100644
index b1474a15..00000000
--- a/Northstar.CustomServers/scripts/vscripts/lobby/sh_private_lobby_modes_init.gnut
+++ /dev/null
@@ -1,21 +0,0 @@
-global function PrivateMatchModesInit
-
-void function PrivateMatchModesInit()
-{
- // modes
- AddPrivateMatchMode( "ffa" )
- AddPrivateMatchMode( "fra" )
- AddPrivateMatchMode( "coliseum" )
-
- // playlists
- AddPrivateMatchMode( "attdm" )
- AddPrivateMatchMode( "turbo_ttdm" )
- AddPrivateMatchMode( "alts" )
- AddPrivateMatchMode( "turbo_lts" )
- AddPrivateMatchMode( "rocket_lf" )
- AddPrivateMatchMode( "holopilot_lf" )
-
- // maps
- AddPrivateMatchMap( "mp_coliseum" )
- AddPrivateMatchMap( "mp_coliseum_column" )
-} \ No newline at end of file
diff --git a/Northstar.CustomServers/scripts/vscripts/sh_northstar_utils.gnut b/Northstar.CustomServers/scripts/vscripts/sh_northstar_utils.gnut
deleted file mode 100644
index 15eed9b2..00000000
--- a/Northstar.CustomServers/scripts/vscripts/sh_northstar_utils.gnut
+++ /dev/null
@@ -1,49 +0,0 @@
-globalize_all_functions
-
-enum eNorthstarLobbyType
-{
- PrivateMatchLobby, // normal vanilla private lobby
- IntermissionLobby, // similar to tf1's intermission lobby, chooses next map automatically
- CompetitiveLobby // similar to vanilla privates, but with ready up system
-}
-
-// whether the server is a modded, northstar server
-bool function IsNorthstarServer()
-{
- bool isModded = true // TEMP for testing
- try
- {
- // need this in a trycatch because the var might not exist atm
- isModded = GetConVarInt( "northstar_is_modded_server" ) == 1
- } catch ( ex ) {}
-
- return isModded
-}
-
-// whether the game should return to the lobby on GameRules_EndMatch()
-bool function ShouldReturnToLobby()
-{
- bool shouldReturnToLobby = false
- try
- {
- // need this in a trycatch because the var might not exist atm
- shouldReturnToLobby = GetConVarInt( "northstar_should_return_to_lobby" ) == 1
- } catch ( ex ) {}
-
- return shouldReturnToLobby
-}
-
-int function GetNorthstarLobbyType()
-{
- if ( !IsNorthstarServer() )
- return eNorthstarLobbyType.PrivateMatchLobby
-
- int lobbyType = eNorthstarLobbyType.PrivateMatchLobby
- try
- {
- // need this in a trycatch because the var might not exist atm
- lobbyType = GetConVarInt( "northstar_lobby_type" )
- } catch ( ex ) {}
-
- return lobbyType
-} \ No newline at end of file
diff --git a/bobthebob.testing/mod.json b/bobthebob.testing/mod.json
deleted file mode 100644
index b0da73e5..00000000
--- a/bobthebob.testing/mod.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "ApiId" : "bobthebob.testing",
- "Name" : "bobthebob.testing",
- "Description" : "a place to put custom testing/debug functions and shit, shouldn't mess with game core behaviour at all",
- "Authors" : [
- "BobTheBob"
- ],
- "Contacts" : [
- "BobTheBob#1150"
- ],
- "Version" : "0.1",
- "CustomScripts": [
- {
- "Path": "sh_bobtestingfunctions_mp.gnut",
- "RunOn": "( CLIENT || SERVER ) && MP"
- },
- {
- "Path": "_bobtestingfunctions_sp.gnut",
- "RunOn": "SERVER && SP"
- },
- {
- "Path": "_bobtestingfunctions_mp.gnut",
- "RunOn": "SERVER && MP",
- "ServerPreCallback": "SvTestingMPInit"
- },
-
- {
- "Path": "sh_bleedout_test.gnut",
- "RunOn": "( CLIENT || SERVER ) && MP",
- "ServerPreCallback": "BleedoutTest_Init",
- "ClientPreCallback": "BleedoutTest_Init",
- },
- ]
-} \ No newline at end of file
diff --git a/bobthebob.testing/scripts/vscripts/_bobtestingfunctions_mp.gnut b/bobthebob.testing/scripts/vscripts/_bobtestingfunctions_mp.gnut
deleted file mode 100644
index b782243a..00000000
--- a/bobthebob.testing/scripts/vscripts/_bobtestingfunctions_mp.gnut
+++ /dev/null
@@ -1,239 +0,0 @@
-untyped
-globalize_all_functions
-
-void function SvTestingMPInit()
-{
- Bleedout_Init()
- AddCallback_EntitiesDidLoad( CreateSpawns )
-}
-
-void function CreateSpawns()
-{
- //thread CreateSpawns_Threaded()
-}
-
-void function CreateSpawns_Threaded()
-{
- WaitEndFrame() // wait for spawns to get cleared, game ctds if we don't do this
- entity validSpawn = GetEntArrayByClass_Expensive( "info_spawnpoint_human" )[ 0 ]
-
- for ( int i = 0; i < 50; i++ )
- {
- entity newSpawn = CreateEntity( "info_spawnpoint_human" )
- newSpawn.SetOrigin( validSpawn.GetOrigin() )
- DispatchSpawn( newSpawn )
- }
-}
-
-void function TestSpawnpoints( bool titan = false )
-{
- entity player = GetPlayerArray()[0]
- array<entity> spawnpoints
- if ( !titan )
- spawnpoints = SpawnPoints_GetPilotStart( player.GetTeam() )
- else
- spawnpoints = SpawnPoints_GetTitanStart( player.GetTeam() )
-
- SpawnPoints_InitRatings( player, player.GetTeam() )
-
- foreach ( entity spawnpoint in spawnpoints )
- spawnpoint.CalculateRating( titan ? TD_TITAN : TD_PILOT, player.GetTeam(), RandomFloat( 7.0 ) - 3.5, RandomFloat( 7.0 ) - 3.5 )
-
- if ( !titan )
- {
- SpawnPoints_SortPilotStart()
- spawnpoints = SpawnPoints_GetPilotStart( player.GetTeam() )
- }
- else
- {
- SpawnPoints_SortTitanStart()
- spawnpoints = SpawnPoints_GetTitanStart( player.GetTeam() )
- }
-
- entity chosenPoint
- foreach ( entity spawnpoint in spawnpoints )
- if ( IsSpawnpointValid( spawnpoint, player.GetTeam() ) )
- {
- chosenPoint = spawnpoint
- break
- }
-
- player.SetOrigin( chosenPoint.GetOrigin() )
- player.SetAngles( chosenPoint.GetAngles() )
-
- //SpawnPoints_DiscardRatings() // somehow the game seems to call this automatically so unneeded
-}
-
-bool function IsSpawnpointValid( entity spawnpoint, int team )
-{
- if ( GameModeRemove( spawnpoint ) )
- return false
-
- // ultra temp
- print( spawnpoint.GetTeam() )
- if ( spawnpoint.GetTeam() == 0 )
- return false
-
- if ( spawnpoint.GetTeam() > 0 && spawnpoint.GetTeam() != team )
- return false
-
-
-
- return true
-}
-
-void function TestScoreEvent( entity player, int id )
-{
- ScoreEvent event = ScoreEvent_FromId( id )
-
- Remote_CallFunction_NonReplay( player, "ServerCallback_ScoreEvent", id, event.pointValue, event.displayType, player.GetEncodedEHandle(), event.earnMeterOwnValue, event.earnMeterEarnValue )
-}
-
-void function TestDrop( entity player )
-{
- thread CreateTitanForPlayerAndHotdrop( player, GetTitanReplacementPoint( player, false ) )
-}
-
-void function WarpThroughSpawnpoints( string modeOverride = "" )
-{
- if ( !modeOverride.len() )
- modeOverride = GAMETYPE
-
- entity player = GetPlayerArray()[0]
-
- array<entity> spawnpoints = GetEntArrayByClass_Expensive( "info_hardpoint" ) //SpawnPoints_GetPilot()
- foreach ( entity spawnpoint in spawnpoints )
- {
- //string gamemodeKey = "gamemode_" + modeOverride
- //if ( spawnpoint.HasKey( gamemodeKey ) && ( spawnpoint.kv[ gamemodeKey ] == "0" || spawnpoint.kv[ gamemodeKey ] == "" ) )
- // continue
- //
- //if ( !spawnpoint.HasKey( gamemodeKey ) )
- // continue
-
- if ( spawnpoint.HasKey( "hardpointGroup" ) )
- print( spawnpoint.kv.hardpointGroup )
-
- player.SetOrigin( spawnpoint.GetOrigin() )
- player.SetAngles( spawnpoint.GetAngles() )
-
- wait 0.5
- }
-}
-
-void function AttemptSpawnBuddyTitan()
-{
- PrecacheModel( $"models/titans/buddy/titan_buddy.mdl" )
- PrecacheModel( $"models/weapons/arms/buddypov.mdl" )
-
- entity player = GetPlayerArray()[0]
- entity titan = CreateNPCTitan( "titan_buddy", player.GetTeam(), player.GetOrigin(), <0, 0, 0> )
- SetSpawnOption_AISettings( titan, "npc_titan_buddy" )
- SetSpawnOption_Weapon( titan, "mp_titanweapon_xo16_vanguard", [ ] )
-
- DispatchSpawn( titan )
-
- player.SetPetTitan( titan )
- titan.SetOwner( player )
- titan.SetUsable()
-}
-
-
-void function SetPlayerCameraToHead()
-{
- entity viewControl = CreateEntity( "point_viewcontrol" )
- viewControl.kv.spawnflags = 56
- DispatchSpawn( viewControl )
-
- viewControl.SetParent( GetPlayerArray()[0], "headshot" )
- viewControl.SetOrigin( < 4, 0, 1 > )
- viewControl.SetAngles( < 0, 0, 0 > )
- GetPlayerArray()[0].SetViewEntity( viewControl, true )
-}
-
-void function CreateTestControlPanel()
-{
- entity player = GetPlayerArray()[0]
-
- entity panel = CreateEntity( "prop_control_panel" )
- panel.SetValueForModelKey( $"models/communication/terminal_usable_imc_01.mdl" )
- panel.SetOrigin( player.GetOrigin() )
- panel.SetAngles( player.GetAngles() )
- panel.kv.solid = SOLID_VPHYSICS
- SetTargetName( panel, "cpanel" )
- DispatchSpawn( panel )
-
- panel.SetModel( $"models/communication/terminal_usable_imc_01.mdl" )
- panel.s.onPlayerFinishesUsing_func = TestOnPanelHacked
-
-}
-
-function TestOnPanelHacked( panel, player, success )
-{
- expect entity( panel )
- expect entity( player )
- expect bool( success )
-
- if ( !success )
- return
-
- print( panel + " was hacked by " + player )
- PanelFlipsToPlayerTeamAndUsableByEnemies( panel, player )
-}
-
-void function TestFastball()
-{
- PrecacheModel( $"models/titans/buddy/titan_buddy.mdl" )
- RegisterSignal( "fastball_start_throw" )
- RegisterSignal( "fastball_release" )
- PrecacheParticleSystem( $"P_BT_eye_SM" )
-
- entity player = GetPlayerArray()[0]
-
- entity prop = CreatePropDynamic( $"models/titans/buddy/titan_buddy.mdl", player.GetOrigin(), player.GetAngles() )
- thread PlayAnim( prop, "bt_beacon_fastball_throw_end" )
-
- player.ContextAction_SetFastball()
- FirstPersonSequenceStruct throwSequence
- throwSequence.attachment = "REF"
- throwSequence.useAnimatedRefAttachment = true
- throwSequence.hideProxy = true
- throwSequence.firstPersonAnim = "ptpov_beacon_fastball_throw_end"
- //throwSequence.thirdPersonAnim = "pt_beacon_fastball_throw_end"
- throwSequence.firstPersonBlendOutTime = 0.0
-
- thread FirstPersonSequence( throwSequence, player, prop )
- player.HolsterWeapon()
-
- EmitSoundOnEntityOnlyToPlayer( player, player, "Music_Beacon_14_BTThrowThruFirstCrane" )
-
- prop.WaitSignal( "fastball_start_throw" )
- float duration = EmitSoundOnEntity( prop, "diag_sp_spoke1_BE117_04_01_mcor_bt" ) // trust me
- vector eyeAngles = player.EyeAngles()
-
- // particle effect
- StartParticleEffectOnEntity( prop, GetParticleSystemIndex( $"P_BT_eye_SM" ), FX_PATTACH_POINT_FOLLOW, prop.LookupAttachment( "EYEGLOW" ) )
- wait duration
-
- prop.WaitSignal( "fastball_release" )
- player.ContextAction_ClearFastball()
- player.ClearParent()
- ClearPlayerAnimViewEntity( player )
- player.SetVelocity( AnglesToForward( eyeAngles ) * 1250 )
- player.DeployWeapon()
-
- wait 0.5
- prop.Destroy()
-}
-
-void function TestPlanetExplosion() // won't look good until we can load textures from rpak for these models
-{
- PrecacheModel( $"models/vistas/planet_ex_static.mdl" )
- PrecacheModel( $"models/vistas/planet_explosion_animated.mdl" )
-
- entity cam = GetEnt( "skybox_cam_level" )
- cam.SetOrigin( < 7000, 7000, 7000 > ) // arbitrary point
- CreatePropDynamic( $"models/vistas/planet_ex_static.mdl", cam.GetOrigin(), cam.GetAngles() )
- entity explosion = CreatePropDynamic( $"models/vistas/planet_explosion_animated.mdl", cam.GetOrigin(), cam.GetAngles() )
- thread PlayAnim( explosion, "planet_ex_ending" )
-} \ No newline at end of file
diff --git a/bobthebob.testing/scripts/vscripts/_bobtestingfunctions_sp.gnut b/bobthebob.testing/scripts/vscripts/_bobtestingfunctions_sp.gnut
deleted file mode 100644
index 2ad814fe..00000000
--- a/bobthebob.testing/scripts/vscripts/_bobtestingfunctions_sp.gnut
+++ /dev/null
@@ -1,13 +0,0 @@
-globalize_all_functions
-
-void function TestPlanetExplosion()
-{
- PrecacheModel( $"models/vistas/planet_ex_static.mdl" )
- PrecacheModel( $"models/vistas/planet_explosion_animated.mdl" )
-
- entity cam = GetEnt( "skybox_cam_level" )
- cam.SetOrigin( < 7000, 7000, 7000 > ) // arbitrary point
- CreatePropDynamic( $"models/vistas/planet_ex_static.mdl", cam.GetOrigin(), cam.GetAngles() )
- entity explosion = CreatePropDynamic( $"models/vistas/planet_explosion_animated.mdl", cam.GetOrigin(), cam.GetAngles() )
- thread PlayAnim( explosion, "planet_ex_ending" )
-} \ No newline at end of file
diff --git a/bobthebob.testing/scripts/vscripts/mp/levels/mp_box.nut b/bobthebob.testing/scripts/vscripts/mp/levels/mp_box.nut
deleted file mode 100644
index aa94be52..00000000
--- a/bobthebob.testing/scripts/vscripts/mp/levels/mp_box.nut
+++ /dev/null
@@ -1,24 +0,0 @@
-/*global function CodeCallback_MapInit
-global function SpawnGamemodeObjects
-
-void function CodeCallback_MapInit()
-{
- AddCallback_EntitiesDidLoad( SpawnGamemodeObjects )
-}
-
-void function SpawnGamemodeObjects()
-{
- thread SpawnGamemodeObjects_Threaded()
-
-}
-
-void function SpawnGamemodeObjects_Threaded()
-{
- WaitEndFrame()
- entity liveFireFlagSpawn = CreateEntity( "script_ref" )
- liveFireFlagSpawn.kv.editorclass = "info_speedball_flag"
- liveFireFlagSpawn.kv.origin = < 0.0, -382.0, 60.0 >
- liveFireFlagSpawn.kv.angles = < 0, 0, 0 >
- DispatchSpawn( liveFireFlagSpawn )
- liveFireFlagSpawn.kv.editorclass = "info_speedball_flag"
-}*/ \ No newline at end of file
diff --git a/bobthebob.testing/scripts/vscripts/mp/sh_revive.gnut b/bobthebob.testing/scripts/vscripts/mp/sh_revive.gnut
deleted file mode 100644
index 8caa2a82..00000000
--- a/bobthebob.testing/scripts/vscripts/mp/sh_revive.gnut
+++ /dev/null
@@ -1,19 +0,0 @@
-#if SERVER
-global const REVIVE_ENABLED = true // currently not used anywhere
-global function ReviveEnabled
-
-bool function ReviveEnabled()
-{
- return GetCurrentPlaylistVarInt( "player_revive_enabled", 0 ) == 1
-}
-#elseif true
-global const REVIVE_ENABLED = false // currently not used anywhere
-global function ReviveEnabled
-
-bool function ReviveEnabled()
-{
- // client version of this doesn't work lol
- return false
- //return GetCurrentPlaylistVarInt( "player_revive_enabled", 0 ) == 1
-}
-#endif \ No newline at end of file
diff --git a/bobthebob.testing/scripts/vscripts/sh_bleedout_test.gnut b/bobthebob.testing/scripts/vscripts/sh_bleedout_test.gnut
deleted file mode 100644
index 42727adc..00000000
--- a/bobthebob.testing/scripts/vscripts/sh_bleedout_test.gnut
+++ /dev/null
@@ -1,34 +0,0 @@
-global function BleedoutTest_Init
-
-void function BleedoutTest_Init()
-{
- return // not in use rn
-
- AddCallback_OnRegisteringCustomNetworkVars( RegisterBleedoutVars )
-
- BleedoutShared_Init( 30.0, 3.0, -1.0, 1.0, 0.0, false, false )
-
- #if SERVER
- Bleedout_Init()
- if ( ReviveEnabled() )
- AddCallback_OnPlayerKilled( StartRevive )
- #elseif CLIENT
- BleedoutClient_Init()
- #endif
-}
-
-#if SERVER
-void function StartRevive( entity victim, entity attacker, var damageInfo )
-{
- DeathPackage_PlayerRevive( victim )
- thread PlayerRevivesOrBleedsOut( victim )
-}
-#endif
-
-void function RegisterBleedoutVars()
-{
- Remote_RegisterFunction( "ServerCallback_BLEEDOUT_StartFirstAidProgressBar" )
- Remote_RegisterFunction( "ServerCallback_BLEEDOUT_StopFirstAidProgressBar" )
- Remote_RegisterFunction( "ServerCallback_BLEEDOUT_ShowWoundedMarker" )
- Remote_RegisterFunction( "ServerCallback_BLEEDOUT_HideWoundedMarker" )
-} \ No newline at end of file
diff --git a/bobthebob.testing/scripts/vscripts/sh_bobtestingfunctions_mp.gnut b/bobthebob.testing/scripts/vscripts/sh_bobtestingfunctions_mp.gnut
deleted file mode 100644
index 852fbfe1..00000000
--- a/bobthebob.testing/scripts/vscripts/sh_bobtestingfunctions_mp.gnut
+++ /dev/null
@@ -1,135 +0,0 @@
-untyped
-globalize_all_functions
-
-void function DumpPdefEnum( string pdefEnum )
-{
- for ( int i = 0; i < PersistenceGetEnumCount( pdefEnum ); i++ )
- print( PersistenceGetEnumItemNameForIndex( pdefEnum, i ) )
-}
-
-void function ListPlayers()
-{
- foreach ( entity player in GetPlayerArray() )
- {
- if ( player == null )
- continue
-
- print( "player " + player.GetPlayerName() + ": G" + player.GetGen() + "." + player.GetLevel() )
- }
-}
-
-void function DumpPdefTable()
-{
- foreach ( key0, value0 in shGlobalMP.playerStatVars )
- {
- foreach ( key1, value1 in value0 )
- {
- foreach ( key2, statData in value1 )
- {
- print ( statData.statVar )
- }
- }
- }
-}
-
-void function DumpModels()
-{
- for ( int i = 0; i < 2048; i++ )
- if ( GetEntByIndex( i ) != null && GetEntByIndex( i ).GetModelName() != $"?" )
- print( i + ": " + GetEntByIndex( i ).GetModelName() )
-}
-
-void function DumpScoreEvents()
-{
- int i = 0;
- while ( true )
- {
- ScoreEvent event
- try event = ScoreEvent_FromId( i ) catch ( exception ) break
-
- print( "event " + i + ":" )
- print( "name: " + event.name )
- print( "splashText: " + event.splashText )
-
- // get string representation of displaytype
- // if squirrel has a better way to do this i don't know it
- string displayType
-
- if ( event.displayType & eEventDisplayType.HIDDEN )
- displayType += "HIDDEN, "
- if ( event.displayType & eEventDisplayType.CENTER )
- displayType += "CENTER, "
- if ( event.displayType & eEventDisplayType.MEDAL )
- displayType += "MEDAL, "
- if ( event.displayType & eEventDisplayType.CALLINGCARD )
- displayType += "CALLINGCARD, "
- if ( event.displayType & eEventDisplayType.ATTRITION )
- displayType += "ATTRITION, "
- if ( event.displayType & eEventDisplayType.BIG )
- displayType += "BIG, "
- if ( event.displayType & eEventDisplayType.GAMEMODE )
- displayType += "GAMEMODE, "
- if ( event.displayType & eEventDisplayType.CHALLENGE )
- displayType += "CHALLENGE, "
- if ( event.displayType & eEventDisplayType.MEDAL_FORCED )
- displayType += "MEDAL_FORCED, "
- if ( event.displayType & eEventDisplayType.SHOW_SCORE )
- displayType += "SHOW_SCORE, "
-
- print( "displayType: " + displayType )
- print( " " ) // newline
-
- i++
- }
-
- print( "got " + i + " events!" )
-}
-
-void function DumpConversations()
-{
- foreach ( string k, v in GetConversationToIndexTable() )
- print( k )
-}
-
-#if CLIENT
-void function TestMarkRUI()
-{
- var rui = CreateCockpitRui( $"ui/speedball_flag_marker.rpak", 200 )
- RuiSetBool( rui, "isVisible", true )
- RuiSetFloat3( rui, "pos", GetLocalViewPlayer().GetOrigin() )
- RuiSetBool( rui, "playerIsCarrying", false )
- RuiSetInt( rui, "teamRelation", TEAM_IMC )
- RuiSetBool( rui, "isCarried", false )
-}
-
-void function TestObjectiveRUIHunted()
-{
- var rui = CreateCockpitRui( $"ui/hunted_objective.rpak", 200 )
- RuiSetGameTime( rui, "startTime", Time() )
- RuiSetGameTime( rui, "endTime", Time() + 20.0 )
- RuiSetString( rui, "objectiveTitleText", "#HUNTED_OBJECTIVE_TITLE" )
- RuiSetFloat( rui, "blingDuration", 5.0 )
- RuiSetBool( rui, "showAll", true )
-}
-
-void function TestObjectiveRUIFW()
-{
- var rui = CreateCockpitRui( $"ui/fw_objective_text.rpak" )
- RuiSetString( rui, "objective", "deez nuts" )
-
- float time = Time() + 10.0
- while ( time > Time() )
- {
- RuiSetString( rui, "objective", "deez nuts " + ( time - Time() ) )
- WaitFrame()
- }
-
- RuiDestroy( rui )
-}
-
-void function RespawnWhy()
-{
- for ( int i = 0; i < 500; i++ ) // this only works in lobby, luckily
- GetLocalViewPlayer().ClientCommand( "test_clientsetplaylistvaroverride " + i + " whyyyyy" )
-}
-#endif \ No newline at end of file
diff --git a/bobthebob.testing/scripts/vscripts/ui/menu_dev.nut b/bobthebob.testing/scripts/vscripts/ui/menu_dev.nut
deleted file mode 100644
index d9b9234b..00000000
--- a/bobthebob.testing/scripts/vscripts/ui/menu_dev.nut
+++ /dev/null
@@ -1,707 +0,0 @@
-untyped
-
-global function InitDevMenu
-global function GetActionBlocks
-global function SetDevMenu_SinglePlayer
-global function SetupDevCommand // for dev
-global function SetupDevFunc // for dev
-global function SetDevMenu_SpawnNPCWithWeapon
-global function RepeatLastDevCommand
-global function SetDevMenu_ArmedNPC
-global function UpdatePrecachedSPWeapons
-
-struct DevCommand
-{
- string label
- string command
- var opParm
- void functionref( var ) func
- bool storeAsLastCommand = true
-}
-
-
-struct
-{
- void functionref() devMenuFunc
- void functionref( var ) devMenuFuncWithOpParm
- var devMenuOpParm
- array<var> buttons
- array actionBlocks
- array<DevCommand> devCommands
- DevCommand& lastDevCommand
- bool lastDevCommandAssigned
- bool precachedWeapons
-} file
-
-void function OnOpenDevMenu()
-{
- file.devMenuFunc = null
- file.devMenuFuncWithOpParm = null
- file.devMenuOpParm = null
- if ( IsMultiplayer() )
- SetDevMenu_MP()
- else
- SetDevMenu_Default()
-}
-
-void function InitDevMenu()
-{
- var menu = GetMenu( "DevMenu" )
-
- AddMenuEventHandler( menu, eUIEvent.MENU_OPEN, OnOpenDevMenu )
-
-
- AddMenuFooterOption( menu, BUTTON_A, "#A_BUTTON_SELECT" )
- AddMenuFooterOption( menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" )
-
- OnOpenDevMenu()
-
- file.buttons = GetElementsByClassname( menu, "DevButtonClass" )
- foreach ( button in file.buttons )
- {
- Hud_AddEventHandler( button, UIE_CLICK, OnDevButton_Activate )
-
- RuiSetString( Hud_GetRui( button ), "buttonText", "" )
- Hud_SetEnabled( button, false )
- }
-
-}
-
-function UpdateDevMenuButtons()
-{
- file.devCommands.clear()
- if ( developer() == 0 )
- return
-
- if ( file.devMenuOpParm != null )
- file.devMenuFuncWithOpParm( file.devMenuOpParm )
- else
- file.devMenuFunc()
-
- foreach ( index, button in file.buttons )
- {
- int buttonID = int( Hud_GetScriptID( button ) )
-
- if ( buttonID < file.devCommands.len() )
- {
- RuiSetString( Hud_GetRui( button ), "buttonText", file.devCommands[buttonID].label )
- Hud_SetEnabled( button, true )
- }
- else
- {
- RuiSetString( Hud_GetRui( button ), "buttonText", "" )
- Hud_SetEnabled( button, false )
- }
- }
-}
-
-void function SetDevMenu_Default()
-{
- file.devMenuFunc = SetupDefaultDevCommands
- UpdateDevMenuButtons()
-}
-
-
-void function SetDevMenu_MP()
-{
- file.devMenuFunc = SetupDefaultDevCommandsMP
- UpdateDevMenuButtons()
-}
-
-void function ChangeToThisMenu( void functionref() menuFunc )
-{
- file.devMenuFunc = menuFunc
- file.devMenuFuncWithOpParm = null
- file.devMenuOpParm = null
- UpdateDevMenuButtons()
-}
-
-void function ChangeToThisMenu_WithOpParm( void functionref( var ) menuFuncWithOpParm, opParm = null )
-{
- file.devMenuFunc = null
- file.devMenuFuncWithOpParm = menuFuncWithOpParm
- file.devMenuOpParm = opParm
- UpdateDevMenuButtons()
-}
-
-void function SetDevMenu_SinglePlayer( var _ )
-{
- CloseAllInGameMenus()
- AdvanceMenu( GetMenu( "SinglePlayerDevMenu" ), true )
-}
-
-void function SetupDefaultDevCommands()
-{
- SetupDevFunc( "Frontier Defense", SetDevMenu_FrontierDefense )
- // SetupDevFunc( "Difficulty", SetDevMenu_Difficulty )
- SetupDevFunc( "Single Player", SetDevMenu_SinglePlayer )
- if ( GetStartPointsForMap( GetActiveLevel() ).len() )
- {
- SetupDevFunc( "Start Points", SetDevMenu_StartPoints )
- }
- SetupDevFunc( "Level Commands", SetDevMenu_LevelCommands )
-
- SetupRepeatLastDevCommand()
- SetupDevFunc( "Spawn IMC NPC", SetDevMenu_AISpawn, 2 )
- SetupDevFunc( "Spawn IMC Boss Titan", SetDevMenu_BossTitans )
- SetupDevFunc( "Spawn Militia NPC", SetDevMenu_AISpawn, 3 )
- SetupDevFunc( "Spawn Team 4 NPC", SetDevMenu_AISpawn, 4 )
-
- if ( IsSingleplayer() )
- {
- SetupDevCommand( "Spawn BT", "script thread DEV_SpawnBTAtCrosshair( false )" )
- SetupDevCommand( "Hotdrop BT", "script thread DEV_SpawnBTAtCrosshair( true )" )
- }
-
- SetupDevFunc( "Spawn Titan Weapon", SetDevMenu_TitanWeapons )
- SetupDevFunc( "Spawn Pilot Weapons", SetDevMenu_PilotWeapons )
- SetupDevFunc( "Spawn Pilot Offhands", SetDevMenu_PilotOffhands )
-
- SetupDevFunc( "AI Commands", SetDevMenu_AICommands )
- SetupDevCommand( "Toggle Model Viewer", "script thread ToggleModelViewer()" )
- SetupDevCommand( "AI Titan Duel", "script DEV_AITitanDuel()" )
- SetupDevCommand( "Free Titans for everybody", "script GiveAllTitans()" )
-
- if ( IsSingleplayer() )
- {
- SetupDevCommand( "Checkpoint", "script CheckPoint_Forced()" )
- SetupDevCommand( "Test Next Checkpoint Spawnpoint", "script TestDevSpawnPoint()" )
- }
-
- SetupDevCommand( "Disable NPCs", "script disable_npcs()" )
- // SetupDevCommand( "Disable New NPCs", "script disable_new_npcs()" )
-
- if ( IsMultiplayer() )
- {
- SetupDevCommand( "Swap the teams", "script teamswap()" )
- SetupDevCommand( "Force time limit", "script ForceTimeLimitDone()" )
- SetupDevCommand( "Force My Team Win", "script_client GetLocalClientPlayer().ClientCommand(\"ForceMyTeamWin\")" )
- SetupDevCommand( "Force My Team Lose", "script_client GetLocalClientPlayer().ClientCommand(\"ForceMyTeamLose\")" )
- SetupDevCommand( "Force Match End", "script ForceMatchEnd()" )
- SetupDevCommand( "Force Draw", "script ForceDraw()" )
- }
-
- SetupDevCommand( "Toggle Friendly Highlights", "script DEV_ToggleFriendlyHighlight()" )
- SetupDevCommand( "Export precache script", "script_ui Dev_CommandLineAddParm( \"-autoprecache\", \"\" ); script_ui Dev_CommandLineRemoveParm( \"" + STARTPOINT_DEV_STRING + "\" ); reload" )
- // SetupDevCommand( "Toggle Blood Spray Decals", "script_client BloodSprayDecals_Toggle()" )
-
- //SetupDevCommand( "PlaySpyglassVDU", "script ForcePlayConversationToAll(\"SpyglassVDU\")" )
- //SetupDevCommand( "PlayGravesVDU", "script ForcePlayConversationToAll(\"GravesVDU\")" )
- //SetupDevCommand( "PlayBliskVDU", "script ForcePlayConversationToAll(\"BliskVDU\")" )
- //SetupDevCommand( "PlaySarahVDU", "script ForcePlayConversationToAll(\"SarahVDU\")" )
- //SetupDevCommand( "PlayMacVDU", "script ForcePlayConversationToAll(\"MacVDU\")" )
- //SetupDevCommand( "PlayBishVDU", "script ForcePlayConversationToAll(\"BishVDU\")" )
- //SetupDevCommand( "PlayMCORGruntBattleRifleVDU", "script ForcePlayConversationToAll(\"MCORGruntBattleRifleVDU\")" )
- //SetupDevCommand( "PlayMCORGruntAntiTitanVDU", "script ForcePlayConversationToAll(\"MCORGruntAntiTitanVDU\")" )
- //SetupDevCommand( "PlayIMCSoldierBattleRifleVDU", "script ForcePlayConversationToAll(\"IMCSoldierBattleRifleVDU\")" )
- SetupDevCommand( "Doom my titan", "script_client GetLocalViewPlayer().ClientCommand( \"DoomTitan\" )" )
- SetupDevCommand( "DoF debug (ads)", "script_client ToggleDofDebug()" )
-
- SetupDevCommand( "ToggleTitanCallInEffects", "script FlagToggle( \"EnableIncomingTitanDropEffects\" )" )
- //SetupDevCommand( "TrailerTitanDrop", "script_client GetLocalViewPlayer().ClientCommand( \"TrailerTitanDrop\" )" )
- //SetupDevCommand( "AI Chatter: aichat_callout_pilot_dev", "script playconvtest(\"aichat_callout_pilot_dev\")" )
- SetupDevCommand( "Spawn IMC grunt", "SpawnViewGrunt " + TEAM_IMC )
- SetupDevCommand( "Spawn Militia grunt", "SpawnViewGrunt " + TEAM_MILITIA )
- SetupDevCommand( "Enable titan-always-executes-titan", "script FlagSet( \"ForceSyncedMelee\" )" )
- //SetupDevCommand( "Display Embark times", "script DebugEmbarkTimes()" )
- SetupDevCommand( "Kill All Titans", "script killtitans()" )
- SetupDevCommand( "Kill All Minions", "script killminions()" )
- if ( IsSingleplayer() )
- SetupDevCommand( "Kill All Enemies", "script KillAllBadguys()" )
-
- SetupDevCommand( "Export leveled_weapons.def / r2_weapons.fgd", "script thread LeveledWeaponDump()" )
-
-
- if ( IsMultiplayer() )
- {
- SetupDevCommand( "Summon Players to player 0", "script summonplayers()" )
- SetupDevCommand( "Display Titanfall spots", "script thread ShowAllTitanFallSpots()" )
- SetupDevCommand( "Toggle check inside Titanfall Blocker", "script thread DevCheckInTitanfallBlocker()" )
- SetupDevCommand( "Simulate Game Scoring", "script thread SimulateGameScore()" )
- SetupDevCommand( "Test Dropship Intro Spawns with Bots", "script thread DebugTestDropshipStartSpawnsForAll()" )
- SetupDevCommand( "Preview Dropship Spawn at this location", "script SetCustomPlayerDropshipSpawn()" )
- SetupDevCommand( "Test Dropship Spawn at this location", "script thread DebugTestCustomDropshipSpawn()" )
- SetupDevCommand( "Max Activity (Pilots)", "script SetMaxActivityMode(1)" )
- SetupDevCommand( "Max Activity (Titans)", "script SetMaxActivityMode(2)" )
- SetupDevCommand( "Max Activity (Conger Mode)", "script SetMaxActivityMode(4)" )
- SetupDevCommand( "Max Activity (Disabled)", "script SetMaxActivityMode(0)" )
- }
- else
- {
- SetupDevCommand( "Reset Collectibles Progress (level)", "script Dev_ResetCollectiblesProgress_Level()" )
- SetupDevCommand( "Reset Collectibles Progress (all)", "script ResetCollectiblesProgress_All()" )
-
- SetupDevCommand( "BT Loadouts - Reset", "script SetBTLoadoutsUnlockedBitfield( 1 )" )
- SetupDevCommand( "BT Loadouts - Unlock All", "script SetBTLoadoutsUnlockedBitfield( 65535 )" )
- SetupDevCommand( "BT Loadouts - Spawn Unlock Pickup", "script SPTitanLoadout_SpawnAtCrosshairDEV( -1 )" )
- }
-
- SetupDevCommand( "Toggle Skybox View", "script thread ToggleSkyboxView()" )
- //SetupDevCommand( "Toggle Bubble Shield", "ToggleBubbleShield" )
- //SetupDevCommand( "Toggle Grenade Indicators", "script_client ToggleGrenadeIndicators()" )
- SetupDevCommand( "Toggle HUD", "ToggleHUD" )
- SetupDevCommand( "Toggle Offhand Low Recharge", "ToggleOffhandLowRecharge" )
- SetupDevCommand( "Map Metrics Toggle", "script_client GetLocalClientPlayer().ClientCommand( \"toggle map_metrics 0 1 2 3\" )" )
- SetupDevCommand( "Toggle Pain Death sound debug", "script TogglePainDeathDebug()" )
- SetupDevCommand( "Jump Randomly Forever", "script_client thread JumpRandomlyForever()" )
-}
-
-
-void function SetupDefaultDevCommandsMP()
-{
- SetupRepeatLastDevCommand()
-
- SetupDevFunc( "Frontier Defense", SetDevMenu_FrontierDefense )
-
- SetupDevFunc( "Spawn IMC NPC", SetDevMenu_AISpawn, 2 )
- SetupDevFunc( "Spawn IMC Boss Titan", SetDevMenu_BossTitans )
- SetupDevFunc( "Spawn Militia NPC", SetDevMenu_AISpawn, 3 )
- SetupDevFunc( "Spawn Team 4 NPC", SetDevMenu_AISpawn, 4 )
-
- SetupDevFunc( "Spawn Titan Weapon", SetDevMenu_TitanWeapons )
- SetupDevFunc( "Spawn Pilot Weapons", SetDevMenu_PilotWeapons )
- SetupDevFunc( "Spawn Pilot Offhands", SetDevMenu_PilotOffhands )
-
- SetupDevFunc( "AI Commands", SetDevMenu_AICommands )
- SetupDevCommand( "Toggle Model Viewer", "script thread ToggleModelViewer()" )
- SetupDevCommand( "AI Titan Duel", "script DEV_AITitanDuel()" )
- SetupDevCommand( "Free Titans for everybody", "script GiveAllTitans()" )
-
- SetupDevCommand( "Disable NPCs", "script disable_npcs()" )
- // SetupDevCommand( "Disable New NPCs", "script disable_new_npcs()" )
-
- SetupDevCommand( "Swap the teams", "script teamswap()" )
- SetupDevCommand( "Force time limit", "script ForceTimeLimitDone()" )
- SetupDevCommand( "Force My Team Win", "script_client GetLocalClientPlayer().ClientCommand(\"ForceMyTeamWin\")" )
- SetupDevCommand( "Force My Team Lose", "script_client GetLocalClientPlayer().ClientCommand(\"ForceMyTeamLose\")" )
- SetupDevCommand( "Force Match End", "script ForceMatchEnd()" )
- SetupDevCommand( "Force Draw", "script ForceDraw()" )
-
- SetupDevCommand( "Toggle Friendly Highlights", "script DEV_ToggleFriendlyHighlight()" )
- SetupDevCommand( "Export precache script", "script_ui Dev_CommandLineAddParm( \"-autoprecache\", \"\" ); script_ui Dev_CommandLineRemoveParm( \"" + STARTPOINT_DEV_STRING + "\" ); reload" )
-
- SetupDevCommand( "Doom my titan", "script_client GetLocalViewPlayer().ClientCommand( \"DoomTitan\" )" )
- SetupDevCommand( "DoF debug (ads)", "script_client ToggleDofDebug()" )
-
- SetupDevCommand( "ToggleTitanCallInEffects", "script FlagToggle( \"EnableIncomingTitanDropEffects\" )" )
-
- SetupDevCommand( "Spawn IMC grunt", "SpawnViewGrunt " + TEAM_IMC )
- SetupDevCommand( "Spawn Militia grunt", "SpawnViewGrunt " + TEAM_MILITIA )
-
- SetupDevCommand( "Enable titan-always-executes-titan", "script FlagSet( \"ForceSyncedMelee\" )" )
-
- SetupDevCommand( "Kill All Titans", "script killtitans()" )
- SetupDevCommand( "Kill All Minions", "script killminions()" )
-
- SetupDevCommand( "Export leveled_weapons.def / r2_weapons.fgd", "script thread LeveledWeaponDump()" )
-
- SetupDevCommand( "Summon Players to player 0", "script summonplayers()" )
- SetupDevCommand( "Display Titanfall spots", "script thread ShowAllTitanFallSpots()" )
- SetupDevCommand( "Toggle check inside Titanfall Blocker", "script thread DevCheckInTitanfallBlocker()" )
- SetupDevCommand( "Simulate Game Scoring", "script thread SimulateGameScore()" )
- SetupDevCommand( "Test Dropship Intro Spawns with Bots", "script thread DebugTestDropshipStartSpawnsForAll()" )
- SetupDevCommand( "Preview Dropship Spawn at this location", "script SetCustomPlayerDropshipSpawn()" )
- SetupDevCommand( "Test Dropship Spawn at this location", "script thread DebugTestCustomDropshipSpawn()" )
- SetupDevCommand( "Max Activity (Pilots)", "script SetMaxActivityMode(1)" )
- SetupDevCommand( "Max Activity (Titans)", "script SetMaxActivityMode(2)" )
- SetupDevCommand( "Max Activity (Conger Mode)", "script SetMaxActivityMode(4)" )
- SetupDevCommand( "Max Activity (Disabled)", "script SetMaxActivityMode(0)" )
-
- SetupDevCommand( "Toggle Skybox View", "script thread ToggleSkyboxView()" )
- SetupDevCommand( "Toggle HUD", "ToggleHUD" )
- SetupDevCommand( "Toggle Offhand Low Recharge", "ToggleOffhandLowRecharge" )
- SetupDevCommand( "Map Metrics Toggle", "script_client GetLocalClientPlayer().ClientCommand( \"toggle map_metrics 0 1 2 3\" )" )
- SetupDevCommand( "Toggle Pain Death sound debug", "script TogglePainDeathDebug()" )
- SetupDevCommand( "Jump Randomly Forever", "script_client thread JumpRandomlyForever()" )
-}
-
-
-void function SetupRepeatLastDevCommand()
-{
- DevCommand cmd
- cmd.label = "Repeat Last Dev Command"
- cmd.func = RepeatLastDevCommand
- cmd.storeAsLastCommand = false
-
- file.devCommands.append( cmd )
-}
-
-void function SetDevMenu_LevelCommands( var _ )
-{
- ChangeToThisMenu( SetupLevelDevCommands )
-}
-
-void function SetupLevelDevCommands()
-{
- string activeLevel = GetActiveLevel()
- if ( activeLevel == "" )
- return
-
- switch ( activeLevel )
- {
- case "mp_titan_rodeo":
- SetupDevCommand( "Atlas titans", "script thread TitanTypes( \"titan_atlas_stickybomb\")" )
- SetupDevCommand( "Ogre titans", "script thread TitanTypes( \"titan_ogre_meteor\")" )
- SetupDevCommand( "Stryder titans", "script thread TitanTypes( \"titan_stryder_leadwall\")" )
- break
-
- case "model_viewer":
- SetupDevCommand( "Toggle Rebreather Masks", "script ToggleRebreatherMasks()" )
- break
-
- case "sp_grunt_arena":
- SetupDevCommand( "Toggle health pickups", "script ToggleHealthRegen(); reload" )
- break
- }
-}
-
-void function SetDevMenu_SpawnNPCWithWeapon( var parms )
-{
- ChangeToThisMenu_WithOpParm( SetupMenu_SpawnNPCWithWeapons, parms )
-}
-
-
-void function SetDevMenu_StartPoints( var _ )
-{
- string currentMap = GetActiveLevel()
- array<StartPointCSV> foundStartPoints = GetStartPointsForMap( currentMap )
-// foreach ( index, startPointEnum in foundStartPoints )
-// {
-// table parms = { currentMap = currentMap, startPointEnum = startPointEnum }
-// SetupDevCommand( "#" + startPointEnum, SetDevMenu_SelectStartPointDifficulty, parms )
-// //SetupDevCommand( "#" + startPointEnum, "script PickStartPoint( \"" + currentMap + "\", \"" + startPointEnum + "\" )" )
-// }
-
- CloseAllInGameMenus()
- AdvanceMenu( GetMenu( "SinglePlayerDevMenu" ), true )
- DisplayStartPointButtons( currentMap, foundStartPoints )
-}
-
-
-void function SetDevMenu_ActionBlocks()
-{
- ChangeToThisMenu( SetupActionBlocks )
-}
-
-function DefineActionBlocks()
-{
- file.actionBlocks = []
-
- /* [Menu name] [action block name] [owner] [description] [load commands] */
- AddActionBlock( "Week 1", "Timed Switch Panel Run", "Sean", "Test your wallrunning abilities by jumping on timed platforms", "playlist Load a map on the command line; map sp_platform_test01" )
- AddActionBlock( "Week 1", "Energon Room", "Mackey", "Combat test arena. Collect all Energon Spheres to win", "playlist Load a map on the command line; map sp_abmac1" )
- AddActionBlock( "Week 1", "Titan Buddy + Turret Columns", "Carlos", null, "playlist Load a map on the command line; map carlos_test" )
- AddActionBlock( "Week 1", "Titan Maze", "Soupy", null, "playlist Load a map on the command line; map sp_act-block_maze" )
- AddActionBlock( "Week 1", "Catch me if you Can", "Chin", "Catch up to a moving pilot and kill him to win", "launchplaylist catchmeifyoucan" )
- AddActionBlock( "Week 1", "Jumping Puzzles", "ChadG", "Various pilot jumping puzzles with moving platforms", "playlist Load a map on the command line; mp_gamemode at; map mp_chad" )
- AddActionBlock( "Week 1", "FLANKER BOOST loadout basics", "Brent", "Non-wallrunning pilot jumping basics", "playlist Load a map on the command line; mp_gamemode at; map mp_ab_test" )
- AddActionBlock( "Week 1", "Flee Titan Attack by wallrunning", "Roger", null, "playlist Load a map on the command line; map sp_ab_flee" )
- AddActionBlock( "Week 1", "Protect Grunt squad from Mortar fire", "Roger", null, "playlist Load a map on the command line; map sp_ab_vortex" )
- AddActionBlock( "Week 1", "Catch me if you Can Part 2", "Soupy", null, "playlist catchmeifyoucan;mp_gamemode ps; map mp_catchme" )
- AddActionBlock( "Week 2", "Environment Puzzles", "ChadG", "Get your titan to the exit by solving some puzzles", "playlist Load a map on the command line; mp_gamemode at; map mp_chad2" )
-// AddActionBlock( "Week 2", "Fun House - survive to the end", "Mo", null, "playlist Load a map on the command line; map mp_ab_funhouse" )
- AddActionBlock( "Week 2", "Assassin Arena - boss fight with the Assassin", "Mo", null, "playlist Load a map on the command line; map sp_ab_assassin" )
- AddActionBlock( "Week 2", "Creature Ship", "LumberJake", "Explore a crashed ship with mysterious cargo", "playlist Load a map on the command line; mp_gamemode at; map mp_actionblockjake01" )
- AddActionBlock( "Week 2", "Titan/Pilot Puzzles", "RyanR", "Get your titan to the green room", "playlist Load a map on the command line; mp_gamemode at; map mp_ryanr_actionblock_01" )
- AddActionBlock( "Week 2", "Titan/Pilot Core Combat", "Carlos", null, "playlist Load a map on the command line; map sp_ammo_pickup" )
- AddActionBlock( "Week 2", "Titan Overwatch", "Roger", "Your sniping titan will cover you as you advance to the bunker", "playlist Load a map on the command line; map sp_ab_titanbuddy" )
- AddActionBlock( "Week 2", "Rodeo Express", "Chin", "Use your titan to get you through a pilot hazard area", "playlist lava; mp_gamemode at; map mp_chin_rodeo_express" )
- AddActionBlock( "Week 2", "Wallrun Gauntlet", "McCord", "Wallrun through the geo and don't fall to your death", "playlist Load a map on the command line; map sp_zipline_action_block01" )
- AddActionBlock( "Week 2", "Titan Mortar Targeting Test", "Soupy", null, "playlist Load a map on the command line; map sp_mortar_targeting_test" )
- AddActionBlock( "Week 2", "Tremors", "David", null, "playlist Load a map on the command line; map sp_tremors" )
- AddActionBlock( "Week 2", "Titan Combat Blok", "Mackey", "Combat arena. Kill all enemies.", "playlist Load a map on the command line; map sp_abmac3" )
- AddActionBlock( "Week 2", "Smart Targeted Switch Panels", "Sean", "Wallrun from wall to wall while activating switches", "playlist Load a map on the command line; map sp_platform_test02" )
- AddActionBlock( "Week 3", "Combat Canyon", "Mo", "Kill enemies in the canyon and extract", "playlist Load a map on the command line; map sp_ab_ski" )
- AddActionBlock( "Week 3", "Titan v Titan", "Roger", "Test Titan vs Titan combat against various titan AI", "playlist Load a map on the command line; map sp_ab_tvt" )
- AddActionBlock( "Week 3", "Train Raid", "ChadG", "Board a speeding train and hack the explosives on board", "playlist Load a map on the command line; map sp_ab_trainride01" )
- AddActionBlock( "Week 3", "Super Spectre Bros", "David", "Survive 6 waves against super spectres", "playlist Load a map on the command line; map mp_ab_super_spectre_bros" )
- AddActionBlock( "Week 4", "Nightshot", "David", "Help your titan buddy hunt in the dark.", "playlist Load a map on the command line; map sp_ab_nightshot" )
- //AddActionBlock( "Week 4", "Space Battle", "Mo", "Pilot a ship in space. \n -Play with Always run OFF. \n -Use low sensitivity. \n -Use bug_reproNum 1 to invert flight controls.\n -Use bug_reproNum 2 for PRO flight controls. (free look) \n -Use bug_reproNum 3 for inverted PRO flight controls.", "playlist Load a map on the command line; map sp_ab_week4" )
- AddActionBlock( "Week 4", "Buddy Fight", "Mackey", "Arena fight with buddy Titan", "playlist Load a map on the command line; map sp_buddy_fight" )
- AddActionBlock( "Week 4", "Fastball Special", "Slayback/McCord", "Use a new Titan ability to hurl yourself to new heights.", "playlist Load a map on the command line; map sp_fastball" )
- AddActionBlock( "Week 4", "Time Travel Mechanic", "LumberJake", "Travel back and forth through time to complete your mission.", "playlist Load a map on the command line; map sp_actionblockjake02" )
- AddActionBlock( "Week 5", "Titan Ability: Death Blossom", "Mo", "Use Up on D-Pad to use Death Blossom\n\nUse your new ability to defeat the enemies", "playlist Load a map on the command line; bug_reproNum 0; map sp_ab_blossom" )
- AddActionBlock( "Week 5", "Titan Ability: Arc Blast", "Mo", "Use Down on D-Pad to use Arc Blast\n\nUse your new ability to defeat the enemies", "playlist Load a map on the command line; bug_reproNum 1; map sp_ab_blossom" )
- AddActionBlock( "Week 5", "Titan Abilities: Death Blossom + Arc Blast", "Mo", "D-Pad Up = Death Blossom\nD-Pad Down = Arc Blast\n\nUse your new abilities to defeat the enemies", "playlist Load a map on the command line; bug_reproNum 2; map sp_ab_blossom" )
- AddActionBlock( "Week 5", "Time Stasis Gun", "LumberJake", "Titan freezes enemies allowing the Pilot \nto do a one-shot kill", "playlist Load a map on the command line; map sp_actionblockjake03" )
- AddActionBlock( "Week 5", "Fastball Mortar Battle", "McCord/Slayback", "Freeform Buddy Titan arena battle. \n - Fastball Special \n - Mortar Crews \n - Buddy Hibernation \n - Harvester Defense", "playlist Load a map on the command line; map sp_ab_mortar_battle01" )
- AddActionBlock( "Week 5", "Zipline Gun", "ChadG", "Create permanent ziplines in the map", "playlist Load a map on the command line; mp_gamemode tdm; bug_reproNum 1234; map mp_angel_city" )
- AddActionBlock( "Week 6", "Titan Hulk", "David", "Buddy Titan hulks out and throws things.", "playlist Load a map on the command line; map sp_ab_titan_thrower" )
- AddActionBlock( "Week 6", "Player & Titan vs Enemy Titan", "Roger", "Bare bones Pilot & Auto Titan vs Enemy Titan", "playlist Load a map on the command line; map sp_ab_ptvt" )
- AddActionBlock( "Week 6", "Pilot Stasis Gun", "Soupy", "Pilot has a Stasis gun to help a friendly Titan out", "playlist Load a map on the command line; map sp_ab_synergy" )
- AddActionBlock( "Week 6", "Acid Rain", "LumberJake", "- Destroy 3 harvesters in a poison rain storm\n- Avoid poison rain by staying in your Titan or indoors\n- Collect powerups to get rain immunity", "map sp_actionblockjake04" )
- AddActionBlock( "Week 6", "Freeform Hallway Fight", "McCord/Slayback", "Move through the tight hallways with your Titan Buddy.", "playlist Load a map on the command line; map sp_ab_hallway_fight01" )
- AddActionBlock( "Week 6", "Stealth Town", "Carlos", "Stealth through a group of enemy titans", "playlist Load a map on the command line; map sp_titan_stealth" )
- AddActionBlock( "Week 6", "Titan Attack Command", "Mo", "Command your buddy titan to attack a position.", "playlist Load a map on the command line; map sp_ab_break" )
- AddActionBlock( "Week 7", "SP Shell", "Chad/McCord", "", "playlist Load a map on the command line; map sp_shell1" )
- AddActionBlock( "Week 7", "Smart Pistol Progression", "Soupy", "Try different smart pistol mods in different combat situations", "playlist Load a map on the command line; map sp_ab_smart_pistol_ramp" )
-}
-
-
-function AddActionBlock( subMenu, actionBlockName, owner, description, command )
-{
- local subMenuIndex = null
- foreach( i, Table in file.actionBlocks )
- {
- if ( Table.name == subMenu )
- subMenuIndex = i
- }
- if ( subMenuIndex == null )
- {
- file.actionBlocks.append( { name = subMenu, actionBlocks = [] } )
- subMenuIndex = file.actionBlocks.len() - 1
- }
-
- local Table = {}
- Table.name <- actionBlockName
- Table.owner <- owner
- Table.description <- description
- Table.command <- command
-
- file.actionBlocks[ subMenuIndex ].actionBlocks.append( Table )
-}
-
-function GetActionBlocks()
-{
- DefineActionBlocks()
- return file.actionBlocks
-}
-
-void function SetupActionBlocks()
-{
- DefineActionBlocks()
-
- // For the in-game dev menu we only add the current week of action blocks
- foreach ( week, actionBlock in file.actionBlocks )
- {
- SetupDevFunc( "Week " + ( week + 1 ), SetDevMenu_Week, week )
- }
-}
-
-void function SetDevMenu_Week( var week )
-{
- ChangeToThisMenu_WithOpParm( SetupActionBlocksByWeek, week )
-}
-
-void function SetupActionBlocksByWeek( var week )
-{
- foreach ( actionBlock in file.actionBlocks[ week ].actionBlocks )
- {
- SetupDevCommand( actionBlock.name + " - " + actionBlock.owner, expect string( actionBlock.command ) )
- }
-}
-
-void function SetDevMenu_AICommands( var _ )
-{
- ChangeToThisMenu( SetupAIDevCommands )
-}
-
-void function SetDevMenu_AISpawn( var enemy )
-{
-#if DEV
- InitNpcSettingsFileNamesForDevMenu()
- ChangeToThisMenu_WithOpParm( SetupSpawnAIButtons, enemy )
-#endif
-}
-
-void function SetDevMenu_BossTitans( var _ )
-{
-#if DEV
- InitNpcSettingsFileNamesForDevMenu()
- ChangeToThisMenu( SetupSpawnBossTitans )
-#endif
-}
-
-void function SetDevMenu_FrontierDefense( var _ )
-{
- #if DEV
- thread ChangeToThisMenu( SetupFrontierDefense )
- #endif
-}
-
-void function SetDevMenu_TitanWeapons( var _ )
-{
-#if DEV
- thread ChangeToThisMenu_PrecacheWeapons( SetupTitanWeapon )
-#endif
-}
-
-void function SetDevMenu_ArmedNPC( var data )
-{
-#if DEV
- thread ChangeToThisMenu_PrecacheWeapons_WithOpParm( SetupSpawnArmedNPC, data )
-#endif
-}
-
-void function SetDevMenu_PilotWeapons( var _ )
-{
-#if DEV
- thread ChangeToThisMenu_PrecacheWeapons_WithOpParm( SetupPilotWeaponsFromFields, "not_set" )
-#endif
-}
-
-void function SetDevMenu_PilotOffhands( var _ )
-{
-#if DEV
- thread ChangeToThisMenu_PrecacheWeapons_WithOpParm( SetupPilotWeaponsFromFields, "offhand" )
-#endif
-}
-
-void function ChangeToThisMenu_PrecacheWeapons( void functionref() menuFunc )
-{
- waitthread PrecacheWeaponsIfNecessary()
-
- file.devMenuFunc = menuFunc
- file.devMenuFuncWithOpParm = null
- file.devMenuOpParm = null
- UpdateDevMenuButtons()
-}
-
-void function ChangeToThisMenu_PrecacheWeapons_WithOpParm( void functionref( var ) menuFuncWithOpParm, opParm = null )
-{
- waitthread PrecacheWeaponsIfNecessary()
-
- file.devMenuFunc = null
- file.devMenuFuncWithOpParm = menuFuncWithOpParm
- file.devMenuOpParm = opParm
- UpdateDevMenuButtons()
-}
-
-void function PrecacheWeaponsIfNecessary()
-{
- if ( file.precachedWeapons )
- return
-
- file.precachedWeapons = true
- CloseAllInGameMenus()
-
- DisablePrecacheErrors()
- wait 0.1
- ClientCommand( "script PrecacheSPWeapons()" )
- wait 0.1
- ClientCommand( "script_client PrecacheSPWeapons()" )
- wait 0.1
- RestorePrecacheErrors()
-
- AdvanceMenu( GetMenu( "DevMenu" ) )
-}
-
-void function UpdatePrecachedSPWeapons()
-{
- file.precachedWeapons = IsMultiplayer()
-}
-
-void function SetupMenu_SpawnNPCWithWeapons( parms )
-{
- string weaponCapacity = expect string( parms.weaponCapacity )
- string baseClass = expect string( parms.baseClass )
- string aiSettings = expect string( parms.aiSettings )
- int team = expect int( parms.team )
-
- array<int> itemTypes
- switch ( weaponCapacity )
- {
- case "PilotMainWeapons":
- itemTypes = [ eItemTypes.PILOT_PRIMARY, eItemTypes.PILOT_SECONDARY ]
- break
-
- case "TitanMainWeapons":
- itemTypes = [ eItemTypes.TITAN_PRIMARY ]
- break
-
- default:
- Assert( 0, "Unknown weapon capacity " + weaponCapacity )
- break
- }
-
- array<string> itemNames
- foreach ( itemType in itemTypes )
- {
- array<string> items = GetAllItemRefsOfType( itemType )
- foreach ( item in items )
- {
- itemNames.append( item )
- }
- }
-
- foreach ( ref in itemNames )
- {
- string weaponName = expect string( GetWeaponInfoFileKeyField_GlobalNotNull( ref, "printname" ) )
-
- string cmd = "thread DEV_SpawnNPCWithWeaponAtCrosshair( \"" + baseClass + "\", \"" + aiSettings + "\", " + team + ", \"" + ref + "\" )"
- SetupDevCommand( weaponName, "script " + cmd )
- }
-}
-
-void function SetupAIDevCommands()
-{
-}
-
-void function SetDevMenu_titanSelection( var _ )
-{
- ChangeToThisMenu( SetupTitanSelection )
-}
-
-void function SetupTitanSelection()
-{
-}
-
-void function SetupDevCommand( string label, string command )
-{
- DevCommand cmd
- cmd.label = label
- cmd.command = command
-
- file.devCommands.append( cmd )
-}
-
-void function SetupDevFunc( string label, void functionref( var ) func, var opParm = null )
-{
- DevCommand cmd
- cmd.label = label
- cmd.func = func
- cmd.opParm = opParm
-
- file.devCommands.append( cmd )
-}
-
-function OnDevButton_Activate( button )
-{
- //if ( level.ui.disableDev )
- //{
- // CodeWarning( "Dev commands disabled on matchmaking servers." )
- // return
- //}
-
- int buttonID = int( Hud_GetScriptID( button ) )
- DevCommand cmd = file.devCommands[buttonID]
-
- RunDevCommand( cmd )
-}
-
-void function RunDevCommand( DevCommand cmd )
-{
- if ( cmd.storeAsLastCommand )
- {
- file.lastDevCommand = cmd
- file.lastDevCommandAssigned = true
- }
-
- if ( cmd.command != "" )
- {
- ClientCommand( cmd.command )
- CloseAllInGameMenus()
- }
- else
- {
- cmd.func( cmd.opParm )
- }
-}
-
-void function RepeatLastDevCommand( var _ )
-{
- if ( !file.lastDevCommandAssigned )
- return
-
- RunDevCommand( file.lastDevCommand )
-} \ No newline at end of file
diff --git a/bobthebob.testing/scripts/vscripts/ui/menu_map_select.nut b/bobthebob.testing/scripts/vscripts/ui/menu_map_select.nut
deleted file mode 100644
index 7ed0d177..00000000
--- a/bobthebob.testing/scripts/vscripts/ui/menu_map_select.nut
+++ /dev/null
@@ -1,162 +0,0 @@
-untyped
-
-
-global function MenuMapSelect_Init
-
-global function InitMapsMenu
-
-struct {
- int mapsPerPage = 21
- int currentMapPage
-} file
-
-// note: this does have a scrolling system in vanilla, but it's honestly really weird and jank and i don't like it
-// so for parity with menu_mode_select i'm removing it in favour of a page system
-
-function MenuMapSelect_Init()
-{
- RegisterSignal( "OnCloseMapsMenu" )
-}
-
-void function InitMapsMenu()
-{
- var menu = GetMenu( "MapsMenu" )
-
- AddMenuEventHandler( menu, eUIEvent.MENU_OPEN, OnOpenMapsMenu )
- AddMenuEventHandler( menu, eUIEvent.MENU_CLOSE, OnCloseMapsMenu )
-
- AddEventHandlerToButtonClass( menu, "MapButtonClass", UIE_GET_FOCUS, MapButton_Focused )
- AddEventHandlerToButtonClass( menu, "MapButtonClass", UIE_LOSE_FOCUS, MapButton_LostFocus )
- AddEventHandlerToButtonClass( menu, "MapButtonClass", UIE_CLICK, MapButton_Activate )
-
- AddMenuFooterOption( menu, BUTTON_A, "#A_BUTTON_SELECT" )
- AddMenuFooterOption( menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" )
-
- AddMenuFooterOption( menu, BUTTON_SHOULDER_LEFT, "#PRIVATE_MATCH_PAGE_PREV", "#PRIVATE_MATCH_PAGE_PREV", CycleModesBack, IsNorthstarServer )
- AddMenuFooterOption( menu, BUTTON_SHOULDER_RIGHT, "#PRIVATE_MATCH_PAGE_NEXT", "#PRIVATE_MATCH_PAGE_NEXT", CycleModesForward, IsNorthstarServer )
-}
-
-void function OnOpenMapsMenu()
-{
- if ( IsNorthstarServer() )
- file.mapsPerPage = 15
- else
- file.mapsPerPage = 21
-
- UpdateVisibleMaps()
-}
-
-void function UpdateVisibleMaps()
-{
- array<var> buttons = GetElementsByClassname( GetMenu( "MapsMenu" ), "MapButtonClass" )
- array<string> mapsArray = GetPrivateMatchMaps()
-
- foreach ( button in buttons )
- {
- int buttonID = int( Hud_GetScriptID( button ) )
- int mapID = buttonID + ( file.currentMapPage * file.mapsPerPage )
-
- if ( buttonID < file.mapsPerPage && mapID < GetPrivateMatchMaps().len() )
- {
- string name = mapsArray[ mapID ]
- SetButtonRuiText( button, GetMapDisplayName( name ) )
- Hud_SetEnabled( button, true )
-
- if ( IsItemInEntitlementUnlock( name ) && IsValid( GetUIPlayer() ) )
- {
- if ( IsItemLocked( GetUIPlayer(), name ) && GetCurrentPlaylistVarInt( name + "_available" , 0 ) == 0 )
- {
- SetButtonRuiText( button, Localize( "#MAP_LOCKED", Localize( GetMapDisplayName( name ) ) ) )
- }
- }
-
- bool mapSupportsMode = PrivateMatch_IsValidMapModeCombo( name, PrivateMatch_GetSelectedMode() )
- Hud_SetLocked( button, !mapSupportsMode )
-
- if ( !mapSupportsMode )
- SetButtonRuiText( button, Localize( "#PRIVATE_MATCH_UNAVAILABLE", Localize( GetMapDisplayName( name ) ) ) )
- }
- else
- {
- SetButtonRuiText( button, "" )
- Hud_SetEnabled( button, false )
- }
-
- if ( mapID == level.ui.privatematch_map )
- {
- printt( buttonID, mapsArray[buttonID] )
- Hud_SetFocused( button )
- }
- }
-}
-
-void function OnCloseMapsMenu()
-{
- Signal( uiGlobal.signalDummy, "OnCloseMapsMenu" )
-}
-
-void function MapButton_Focused( var button )
-{
- int mapID = int( Hud_GetScriptID( button ) ) + ( file.currentMapPage * file.mapsPerPage )
-
- var menu = GetMenu( "MapsMenu" )
- var nextMapImage = Hud_GetChild( menu, "NextMapImage" )
- var nextMapName = Hud_GetChild( menu, "NextMapName" )
- var nextMapDesc = Hud_GetChild( menu, "NextMapDesc" )
-
- array<string> mapsArray = GetPrivateMatchMaps()
- string mapName = mapsArray[ mapID ]
-
- asset mapImage = GetMapImageForMapName( mapName )
- RuiSetImage( Hud_GetRui( nextMapImage ), "basicImage", mapImage )
- Hud_SetText( nextMapName, GetMapDisplayName( mapName ) )
-
- string modeName = PrivateMatch_GetSelectedMode()
- bool mapSupportsMode = PrivateMatch_IsValidMapModeCombo( mapName, modeName )
- if ( !mapSupportsMode )
- Hud_SetText( nextMapDesc, Localize( "#PRIVATE_MATCH_MAP_NO_MODE_SUPPORT", Localize( GetMapDisplayName( mapName ) ), Localize( GetGameModeDisplayName( modeName ) ) ) )
- else
- Hud_SetText( nextMapDesc, GetMapDisplayDesc( mapName ) )
-
-}
-
-void function MapButton_LostFocus( var button )
-{
- HandleLockedCustomMenuItem( GetMenu( "MapsMenu" ), button, [], true )
-}
-
-void function MapButton_Activate( var button )
-{
- if ( Hud_IsLocked( button ) )
- return
-
- if ( !AmIPartyLeader() && GetPartySize() > 1 )
- return
-
- array<string> mapsArray = GetPrivateMatchMaps()
- int mapID = int( Hud_GetScriptID( button ) )
- string mapName = mapsArray[ mapID + ( file.currentMapPage * file.mapsPerPage ) ]
-
- printt( mapName, mapID )
-
- ClientCommand( "SetCustomMap " + mapName )
- CloseActiveMenu()
-}
-
-void function CycleModesBack( var button )
-{
- if ( file.currentMapPage == 0 )
- return
-
- file.currentMapPage--
- UpdateVisibleMaps()
-}
-
-void function CycleModesForward( var button )
-{
- if ( ( file.currentMapPage + 1 ) * file.mapsPerPage >= GetPrivateMatchMaps().len() )
- return
-
- file.currentMapPage++
- UpdateVisibleMaps()
-}
diff --git a/bobthebob.testing/scripts/vscripts/ui/menu_team_titan_select.nut b/bobthebob.testing/scripts/vscripts/ui/menu_team_titan_select.nut
deleted file mode 100644
index d0ee5f0f..00000000
--- a/bobthebob.testing/scripts/vscripts/ui/menu_team_titan_select.nut
+++ /dev/null
@@ -1,723 +0,0 @@
-global function InitTeamTitanSelectMenu
-global function TeamTitanSelectMenuIsOpen
-global function ServerCallback_OpenTeamTitanMenu
-global function ServerCallback_CloseTeamTitanMenu
-global function ServerCallback_UpdateTeamTitanMenuTime
-global function ServerCallback_RegisterTeamTitanMenuButtons
-global function TTSUpdateDoubleXP
-global function TTSUpdateDoubleXPStatus
-global function TTSMenuModeFD
-global function TTSMenuModeDefault
-global function TTSMenu_UpdateGameMode
-global function EnableDoubleXP
-
-const float SELECT_DELAY = 0.2
-
-enum eTTSMenuMode
-{
- DEFAULT,
- FD
-}
-
-struct
-{
- var menu
- bool allowManualClose = false
- bool isReady = false
- bool menuOpened = false
- bool allowSelection = false
-
- array<var> titanButtons
- array<var> titanUpgradeButtons
- var editButton
- var readyPanel
- var cover
- var doubleXPButton
- var chatBox
-
- bool buttonsRegistered = false
-
- int menuMode
-
- float nextAllowSoundTime = 0.0
-} file
-
-void function InitTeamTitanSelectMenu()
-{
- file.menu = GetMenu( "TeamTitanSelectMenu" )
-
- AddMenuEventHandler( file.menu, eUIEvent.MENU_NAVIGATE_BACK, OnTeamTitanSelectMenu_NavigateBack )
- AddMenuEventHandler( file.menu, eUIEvent.MENU_OPEN, OnTeamTitanSelectMenu_Open )
- AddMenuEventHandler( file.menu, eUIEvent.MENU_SHOW, OnTeamTitanSelectMenu_Open )
- AddMenuEventHandler( file.menu, eUIEvent.MENU_HIDE, OnTeamTitanSelectMenu_Hide )
- AddMenuEventHandler( file.menu, eUIEvent.MENU_CLOSE, OnTeamTitanSelectMenu_Close )
-
- RegisterSignal( "TTSMenuClosed" )
- RegisterSignal( "Delayed_RequestTitanLoadout" )
-
- float margin = 10.0
- float totalWidth = 0.0
- for ( int i=0; i<NUM_PERSISTENT_TITAN_LOADOUTS; i++ )
- {
- var button = Hud_GetChild( file.menu, "TitanButton" + i )
- file.titanButtons.append( button )
- float xPos = totalWidth * -1
- totalWidth += Hud_GetWidth( button ) + margin
- Hud_SetPos( button, xPos, Hud_GetY( button ) )
- }
-
- var bg = Hud_GetChild( file.menu, "BG" )
- totalWidth -= margin
- float bgWidth = float( Hud_GetWidth( bg ) )
- float startPos = (bgWidth*0.5 - totalWidth*0.5) * -1
- for ( int i=0; i<NUM_PERSISTENT_TITAN_LOADOUTS; i++ )
- {
- var button = file.titanButtons[i]
- Hud_SetPos( button, startPos + Hud_GetX( button ), Hud_GetY( button ) )
-
- Hud_AddEventHandler( button, UIE_CLICK, TitanButton_OnClick )
- Hud_AddEventHandler( button, UIE_GET_FOCUS, TitanButton_OnFocused )
- }
-
- for ( int i=0; i<7; i++ )
- {
- var button = Hud_GetChild( file.menu, "BtnSub" + i )
-
- Hud_AddEventHandler( button, UIE_LOSE_FOCUS, TitanUpgradeButton_OnLoseFocus )
- Hud_AddEventHandler( button, UIE_GET_FOCUS, TitanUpgradeButton_OnFocused )
- }
-
- SetNavLeftRight( file.titanButtons, true )
-
- //file.editButton = Hud_GetChild( file.menu, "EditTitanButton" )
- //Hud_AddEventHandler( file.editButton, UIE_CLICK, EditTitanButton_OnClick )
- file.readyPanel = Hud_GetChild( file.menu, "ReadyRui" )
- file.cover = Hud_GetChild( file.menu, "Cover" )
-
- #if PC_PROG
- file.chatBox = Hud_GetChild( file.menu, "LobbyChatBox" )
- #endif // PC_PROG
-
- file.doubleXPButton = Hud_GetChild( file.menu, "DoubleXP" )
-
- AddMenuFooterOption( file.menu, BUTTON_A, "#A_BUTTON_SELECT", "", null, TeamTitanSelect_IsNotReady )
- AddMenuFooterOption( file.menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" )
- AddMenuFooterOption( file.menu, BUTTON_X, "#MENU_X_BUTTON_EDIT_TITAN", "#MENU_EDIT_TITAN", EditTitanButton_OnClick, TeamTitanSelect_IsReady )
- AddMenuFooterOption( file.menu, BUTTON_Y, "#MENU_Y_BUTTON_EDIT_PILOT", "#MENU_EDIT_PILOT", EditPilotButton_OnClick, CoverIsOff )
-}
-
-void function TTSUpdateDoubleXP( int count, bool avialable, float status )
-{
- var rui = Hud_GetRui( file.doubleXPButton )
- RuiSetInt( rui, "doubleXPCount", count )
- RuiSetBool( rui, "doubleXPAvailable", avialable )
- RuiSetFloat( rui, "doubleXPStatus", status )
-}
-
-void function TTSUpdateDoubleXPStatus( int status )
-{
- var rui = Hud_GetRui( file.doubleXPButton )
- RuiSetFloat( rui, "doubleXPStatus", float( status ) )
-}
-
-void function ServerCallback_UpdateTeamTitanMenuTime( float endTime )
-{
- Signal( uiGlobal.signalDummy, "TTSMenuClosed" )
-
- file.allowSelection = true
-
- if ( file.nextAllowSoundTime < Time() )
- {
- EmitUISound( "ui_ctf_1p_playerscore" )
- file.nextAllowSoundTime = Time() + 5.0
- }
-
- Hud_SetEnabled( file.cover, false )
- Hud_Hide( file.cover )
- Hud_SetAlpha( file.cover, 0 )
-
- if ( endTime > 5 )
- file.allowSelection = true
-
- thread UpdateSubText( Time() + endTime )
-}
-
-void function ServerCallback_OpenTeamTitanMenu( float endTime )
-{
- if ( TeamTitanSelectMenuIsOpen() )
- return
-
- if ( uiGlobal.activeMenu != null )
- CloseAllMenus()
-
- RunClientScript( "PlayTTSMusic" )
-
- file.allowManualClose = false
- file.allowSelection = true
- file.isReady = true // set to true so selection mode kicks in
- thread MenuFadeIn()
- BeginSelectionMode()
- AdvanceMenu( file.menu )
- thread UpdateSubText( Time() + endTime )
-}
-
-void function MenuFadeIn()
-{
- Hud_SetEnabled( file.cover, true )
- Hud_SetAlpha( file.cover, 255 )
- Hud_Show( file.cover )
- wait 1.0
- Hud_FadeOverTime( file.cover, 0, 1.0 )
- wait 1.0
- Hud_Hide( file.cover )
- Hud_SetEnabled( file.cover, false )
-}
-
-void function UpdateSubText( float endTime )
-{
- EndSignal( uiGlobal.signalDummy, "TTSMenuClosed" )
-
- var subText = Hud_GetChild( file.menu, "MenuSubTitle" )
- var rui = Hud_GetRui( file.readyPanel )
- RuiSetBool( rui, "isReady", true )
-
- thread Countdown( endTime )
- while ( Time() < endTime )
- {
- int countdownTime = int( ceil( endTime - Time() ) )
- Hud_SetText( subText, Localize( "#MENU_STARTS_IN", countdownTime ) )
- RuiSetInt( rui, "timer", countdownTime )
- WaitFrame()
- }
-
- Hud_SetText( subText, Localize( "#MENU_STARTS_IN", 0 ) )
- RuiSetInt( rui, "timer", 0 )
-}
-
-void function Countdown( float endTime )
-{
- EndSignal( uiGlobal.signalDummy, "TTSMenuClosed" )
-
- float countdownTime = 5.0
- float startCountdownTime = endTime - countdownTime
-
- if ( Time() > startCountdownTime )
- return
-
- wait startCountdownTime - Time()
-
- while ( Time() < endTime )
- {
- EmitUISound( "UI_InGame_MarkedForDeath_CountdownToMarked" )
- wait 1.0
- }
-
- file.allowSelection = false
- BeginEditMode(null)
-
- Hud_SetAlpha( file.cover, 0 )
- Hud_SetEnabled( file.cover, true )
- Hud_Show( file.cover )
- Hud_FadeOverTime( file.cover, 255, 1.0 )
-
- float soundTime = DoPrematchWarpSound() ? PICK_LOADOUT_SOUND_TIME : 1.5
- wait soundTime
-
- thread ServerCallback_CloseTeamTitanMenu()
-}
-
-void function ServerCallback_CloseTeamTitanMenu()
-{
- if ( TeamTitanSelectMenuIsOpen() )
- {
- file.allowManualClose = true
- UI_SetPresentationType( ePresentationType.INACTIVE )
- CloseAllMenus()
- OnTeamTitanSelectMenu_Close()
- }
-}
-
-void function OnTeamTitanSelectMenu_NavigateBack()
-{
- if ( file.allowManualClose )
- {
- CloseActiveMenu()
- return
- }
-
- if ( file.isReady && file.allowSelection )
- {
- BeginSelectionMode()
- return
- }
-
- LeaveDialog()
- return
-}
-
-void function TTSMenu_UpdateGameMode( string modeName )
-{
- var title = Hud_GetChild( file.menu, "MenuTitle" )
- Hud_SetText( title, Localize( modeName ) )
-}
-
-void function ServerCallback_RegisterTeamTitanMenuButtons()
-{
- RegisterButtonCallbacks()
-}
-
-void function RegisterButtonCallbacks()
-{
- if ( file.buttonsRegistered )
- return
-
- file.buttonsRegistered = true
- RegisterButtonPressedCallback( BUTTON_BACK, EnableDoubleXP )
- RegisterButtonPressedCallback( KEY_RSHIFT, EnableDoubleXP )
-}
-
-void function OnTeamTitanSelectMenu_Open()
-{
- file.menuOpened = true
-
- var dataTable = GetDataTable( $"datatable/titan_properties.rpak" )
- int loadoutIconCol = GetDataTableColumnByName( dataTable, "loadoutIconFD" )
- int titanCol = GetDataTableColumnByName( dataTable, "titanRef" )
-
- entity player = GetUIPlayer()
-
- var nextMapImage = Hud_GetChild( file.menu, "NextMapImage" )
- string mapName = GetActiveLevel()
- asset mapImage = GetMapImageForMapName( mapName )
-
- RefreshCreditsAvailable()
-
- RuiSetImage( Hud_GetRui( nextMapImage ), "basicImage", mapImage )
- Hud_Show( nextMapImage )
- Hud_SetText( Hud_GetChild( file.menu, "NextMapName" ), GetMapDisplayName( mapName ) )
- Hud_Show( Hud_GetChild( file.menu, "NextMapName" ) )
-
- var buttonToFocus
-
- for ( int i=0; i<NUM_PERSISTENT_TITAN_LOADOUTS; i++ )
- {
- var button = file.titanButtons[i]
- TitanLoadoutDef loadout = GetCachedTitanLoadout( i )
- int row = GetDataTableRowMatchingStringValue( dataTable, titanCol, loadout.titanClass )
-
- asset icon = GetDataTableAsset( dataTable, row, loadoutIconCol )
- var rui = Hud_GetRui( button )
-
- RuiSetImage( rui, "buttonImage", icon )
- Hud_SetLocked( button, true )
-
- if ( !IsTitanLoadoutAvailable( player, loadout.titanClass ) )
- {
- Hud_SetLocked( button, true )
- if ( !IsItemLocked( player, loadout.titanClass ) )
- RefreshButtonCost( button, loadout.titanClass, "", 0, 0 )
- }
- else
- {
- Hud_SetLocked( button, IsItemLocked( player, loadout.titanClass ) )
- RefreshButtonCost( button, loadout.titanClass )
-
- if ( uiGlobal.titanSpawnLoadoutIndex == i )
- {
- buttonToFocus = button
- }
- }
- }
-
- if ( buttonToFocus == null )
- buttonToFocus = FindValidTitanButton()
- thread HACK_DelayedSetFocus_BecauseWhy( buttonToFocus )
-
- TitanLoadoutDef loadout = GetCachedTitanLoadout( uiGlobal.titanSpawnLoadoutIndex )
-
- for ( int i=0; i<7; i++ )
- {
- var button = Hud_GetChild( file.menu, "BtnSub"+i )
- file.titanUpgradeButtons.append( button )
-
- if ( file.menuMode == eTTSMenuMode.FD )
- {
- Hud_Show( button )
- }
- else
- {
- Hud_Hide( button )
- }
- }
- SetNavLeftRight( file.titanUpgradeButtons, true )
-
- SetBlurEnabled( false )
- var title = Hud_GetChild( file.menu, "MenuTitle" )
- string name = expect string( GetCurrentPlaylistVar( "name" ) )
- Hud_SetText( title, Localize( name ) )
- RunMenuClientFunction( "ShowTTSPanel" )
-
- if ( file.isReady )
- UI_SetPresentationType( ePresentationType.STORE_CAMO_PACKS )
- else
- UI_SetPresentationType( ePresentationType.STORE_CAMO_PACKS )
-
-
- RunClientScript( "TTS_UpdateLocalPlayerTitan", loadout.setFile, loadout.primary, loadout.passive1, loadout.passive2 )
-}
-
-void function EnableDoubleXP( var button )
-{
- #if PC_PROG
- if ( Hud_IsFocused( file.chatBox ) )
- return
- #endif // PC_PROG
-
- if ( CanRunClientScript() )
- {
- EmitUISound( "Menu_Email_Sent" )
- RunClientScript( "UseDoubleXP" )
- }
-}
-
-void function OnTeamTitanSelectMenu_Hide()
-{
- RunMenuClientFunction( "HideTTSPanel" )
-
- DeregisterButtonCallbacks()
-}
-
-void function DeregisterButtonCallbacks()
-{
- if ( !file.buttonsRegistered )
- return
-
- file.buttonsRegistered = false
-
- DeregisterButtonPressedCallback( BUTTON_BACK, EnableDoubleXP )
- DeregisterButtonPressedCallback( KEY_RSHIFT, EnableDoubleXP )
-}
-
-void function OnTeamTitanSelectMenu_Close()
-{
- RunMenuClientFunction( "ClearAllPilotPreview" )
- Signal( uiGlobal.signalDummy, "TTSMenuClosed" )
- file.menuOpened = false
- UI_SetPresentationType( ePresentationType.INACTIVE )
-
- DeregisterButtonCallbacks()
-}
-
-void function TitanButton_OnClick( var button )
-{
- int scriptID = int( Hud_GetScriptID( button ) )
- if ( Hud_IsLocked( button ) )
- {
- TitanLoadoutDef loadout = GetCachedTitanLoadout( scriptID )
- if ( !IsTitanLoadoutAvailable( GetUIPlayer(), loadout.titanClass ) )
- return
-
- OpenBuyItemDialog( file.titanButtons, button, GetItemName( loadout.titanClass ), loadout.titanClass )
- return
- }
-
- if ( file.isReady )
- {
- BeginSelectionMode()
- return
- }
-
- uiGlobal.titanSpawnLoadoutIndex = scriptID
- Signal( uiGlobal.signalDummy, "Delayed_RequestTitanLoadout" )
- ClientCommand( "RequestTitanLoadout " + uiGlobal.titanSpawnLoadoutIndex )
- BeginEditMode( button )
-}
-
-void function TitanButton_OnFocused( var button )
-{
- int scriptID = int( Hud_GetScriptID( button ) )
-
- var rui = Hud_GetRui( Hud_GetChild( file.menu, "TitanName" ) )
-
- TitanLoadoutDef loadout = GetCachedTitanLoadout( scriptID )
-
- RuiSetString( rui, "titanName", GetTitanLoadoutName( loadout ) )
- RuiSetString( rui, "titanLevelString", "" )
- RuiSetString( rui, "titanRole", "" )
-
- entity player = GetUIPlayer()
-
- var dataTable = GetDataTable( $"datatable/titan_properties.rpak" )
- int row = GetDataTableRowMatchingStringValue( dataTable, GetDataTableColumnByName( dataTable, "titanRef" ), loadout.titanClass )
- string role = GetDataTableString( dataTable, row, GetDataTableColumnByName( dataTable, "fdRole" ) )
- int titanLevel = FD_TitanGetLevelForXP( loadout.titanClass, FD_TitanGetXP( GetUIPlayer(), loadout.titanClass ) )
- array<ItemDisplayData> titanUpgrades = FD_GetUpgradesForTitanClass( loadout.titanClass )
-
- if ( file.menuMode == eTTSMenuMode.FD )
- {
- RuiSetString( rui, "titanLevelString", Localize( "#FD_TITAN_LEVEL", titanLevel ) )
- RuiSetString( rui, "titanRole", Localize( "#FD_ROLE", Localize(role) ) )
-
- foreach ( index, item in titanUpgrades )
- {
- var button = file.titanUpgradeButtons[index]
- var upgradeRui = Hud_GetRui( button )
-
- bool locked = IsSubItemLocked( GetUIPlayer(), item.ref, item.parentRef )
-
- if ( locked )
- RuiSetImage( upgradeRui, "buttonImage", expect asset( item.i.lockedImage ) )
- else
- RuiSetImage( upgradeRui, "buttonImage", item.image )
-
- Hud_SetLocked( button, locked )
- }
- }
-
- if ( !Hud_IsLocked( button ) )
- {
- uiGlobal.titanSpawnLoadoutIndex = scriptID
- thread Delayed_RequestTitanLoadout( uiGlobal.titanSpawnLoadoutIndex )
- SetLabelRuiText( Hud_GetChild( file.menu, "TitanSelectTitle" ), "#MENU_TITAN_SELECT" )
- }
- else
- {
- RuiSetString( rui, "titanLevelString", GetItemUnlockReqText( loadout.titanClass ) )
- }
-
- SetLabelRuiText( Hud_GetChild( file.menu, "TitanSelectTitle" ), GetTitanAvailableText( player, loadout.titanClass) )
-
- RunMenuClientFunction( "UpdateTitanModel", scriptID )
- RunClientScript( "TTS_UpdateLocalPlayerTitan", loadout.setFile, loadout.primary, loadout.passive1, loadout.passive2 )
-}
-
-string function GetTitanAvailableText( entity player, string titanClass )
-{
- int titanAvailableState = GetTitanLoadAvailableState( player, titanClass )
-
- if ( titanAvailableState == TITAN_CLASS_LOCK_STATE_AVAILABLE )
- return "#MENU_TITAN_SELECT_HINT"
-
- if ( titanAvailableState == TITAN_CLASS_LOCK_STATE_LEVELREQUIRED || titanAvailableState == TITAN_CLASS_LOCK_STATE_LEVELRECOMMENDED )
- {
- int difficultyLevel = GetCurrentPlaylistVarInt( "fd_difficulty", 0 )
- int requiredTitanLevel = 0
- switch ( difficultyLevel )
- {
- case eFDDifficultyLevel.EASY:
- if ( GetItemUnlockType( "fd_easy" ) == eUnlockType.STAT )
- requiredTitanLevel = int( GetStatUnlockStatVal( "fd_easy" ) )
- break
- case eFDDifficultyLevel.NORMAL:
- if ( GetItemUnlockType( "fd_normal" ) == eUnlockType.STAT )
- requiredTitanLevel = int( GetStatUnlockStatVal( "fd_normal" ) )
- break
- case eFDDifficultyLevel.HARD:
- if ( GetItemUnlockType( "fd_hard" ) == eUnlockType.STAT )
- requiredTitanLevel = int( GetStatUnlockStatVal( "fd_hard" ) )
- break
- case eFDDifficultyLevel.MASTER:
- if ( GetItemUnlockType( "fd_master" ) == eUnlockType.STAT )
- requiredTitanLevel = int( GetStatUnlockStatVal( "fd_master" ) )
- break
- case eFDDifficultyLevel.INSANE:
- if ( GetItemUnlockType( "fd_insane" ) == eUnlockType.STAT )
- requiredTitanLevel = int( GetStatUnlockStatVal( "fd_insane" ) )
- break
- }
-
- if ( titanAvailableState == TITAN_CLASS_LOCK_STATE_LEVELREQUIRED )
- return Localize( "#MENU_TITAN_SELECT_LEVELREQUIRED", requiredTitanLevel )
- else
- return Localize( "#MENU_TITAN_SELECT_LEVELRECOMMENDED", requiredTitanLevel )
- }
-
- if ( titanAvailableState == TITAN_CLASS_LOCK_STATE_INUSE )
- return "#MENU_TITAN_SELECT_INUSE"
-
- if ( titanAvailableState == TITAN_CLASS_LOCK_STATE_LOCKED )
- return "#MENU_TITAN_SELECT_LOCKED"
-
- return "#MENU_TITAN_SELECT_HINT"
-}
-
-void function Delayed_RequestTitanLoadout( int index )
-{
- Signal( uiGlobal.signalDummy, "Delayed_RequestTitanLoadout" )
- EndSignal( uiGlobal.signalDummy, "Delayed_RequestTitanLoadout" )
- wait 0.5
- ClientCommand( "RequestTitanLoadout " + uiGlobal.titanSpawnLoadoutIndex )
-}
-
-void function TitanUpgradeButton_OnFocused( var button )
-{
- if ( file.menuMode == eTTSMenuMode.DEFAULT )
- return
-
- int scriptID = int( Hud_GetScriptID( button ) )
- TitanLoadoutDef loadout = GetCachedTitanLoadout( uiGlobal.titanSpawnLoadoutIndex )
- array<ItemDisplayData> titanUpgrades = FD_GetUpgradesForTitanClass( loadout.titanClass )
-
- ItemDisplayData item = titanUpgrades[ scriptID ]
- var panel = Hud_GetChild( file.menu, "UpgradeName" )
- Hud_Show( panel )
- var rui = Hud_GetRui( panel )
- RuiSetString( rui, "upgradeName", item.name )
- RuiSetString( rui, "upgradeDesc", item.desc )
- RuiSetBool( rui, "isLocked", IsSubItemLocked( GetUIPlayer(), item.ref, item.parentRef ) )
-}
-
-void function TitanUpgradeButton_OnLoseFocus( var button )
-{
- Hud_Hide( Hud_GetChild( file.menu, "UpgradeName" ) )
-}
-
-void function BeginEditMode( var button )
-{
- if ( file.isReady )
- return
-
- file.isReady = true
-
- EmitUISound( "UI_InGame_FD_TitanSelected" )
- SetLabelRuiText( Hud_GetChild( file.menu, "TitanSelectTitle" ), "#MENU_TITAN_SELECTED" )
- Hud_Hide( Hud_GetChild( file.menu, "TitanSelectTitle" ) )
- Hud_Show( file.readyPanel )
- var rui = Hud_GetRui( file.readyPanel )
- RuiSetBool( rui, "isReady", true )
-
- foreach ( b in file.titanButtons )
- {
- Hud_Hide( b )
- }
-
- //Hud_Show( file.editButton )
- //Hud_SetFocused( file.editButton )
- Hud_SetFocused( file.titanUpgradeButtons[0] )
-
- TitanLoadoutDef loadout = GetCachedTitanLoadout( uiGlobal.titanSpawnLoadoutIndex )
- string primeTitanString = ""
-
- if ( loadout.isPrime == "titan_is_prime" )
- primeTitanString = "_prime"
-
- string modifiedAlias = "diag_gs_titan" + loadout.titanClass + primeTitanString + "_embark"
- EmitUISound( modifiedAlias )
-
- if ( uiGlobal.activeMenu == file.menu )
- UI_SetPresentationType( ePresentationType.TITAN_CENTER_SELECTED )
-
- Signal( uiGlobal.signalDummy, "Delayed_RequestTitanLoadout" )
- ClientCommand( "RequestTitanLoadout " + uiGlobal.titanSpawnLoadoutIndex )
- RunMenuClientFunction( "UpdateTitanModel", uiGlobal.titanSpawnLoadoutIndex )
-
- var subText = Hud_GetChild( file.menu, "MenuSubTitle" )
- // Hud_Hide( subText )
-}
-
-void function BeginSelectionMode()
-{
- if ( !file.isReady )
- return
-
- file.isReady = false
- //Hud_Hide( file.editButton )
-
- SetLabelRuiText( Hud_GetChild( file.menu, "TitanSelectTitle" ), "#MENU_TITAN_SELECT_HINT" )
- Hud_Show( Hud_GetChild( file.menu, "TitanSelectTitle" ) )
- Hud_Hide( file.readyPanel )
- var rui = Hud_GetRui( file.readyPanel )
- RuiSetBool( rui, "isReady", false )
-
- Hud_SetFocused( FindValidTitanButton() )
-
- for ( int i=0; i<file.titanButtons.len(); i++ )
- {
- var b = file.titanButtons[i]
- Hud_Show( b )
- if ( i == uiGlobal.titanSpawnLoadoutIndex && !Hud_IsLocked( b ) )
- {
- Hud_SetFocused( b )
- }
- }
-
- Hud_Hide( Hud_GetChild( file.menu, "UpgradeName" ) )
-
- UI_SetPresentationType( ePresentationType.TITAN_CENTER )
- RunMenuClientFunction( "UpdateTitanModel", uiGlobal.titanSpawnLoadoutIndex )
-
- var subText = Hud_GetChild( file.menu, "MenuSubTitle" )
- // Hud_Show( subText )
-}
-
-void function EditPilotButton_OnClick( var button )
-{
- // SetEditLoadout( "pilot", uiGlobal.pilotSpawnLoadoutIndex )
- // RunMenuClientFunction( "SetEditingPilotLoadoutIndex", uiGlobal.pilotSpawnLoadoutIndex )
- AdvanceMenu( GetMenu( "EditPilotLoadoutsMenu" ) )
- RunMenuClientFunction( "HideTTSPanel" )
-}
-
-void function EditTitanButton_OnClick( var button )
-{
- SetEditLoadout( "titan", uiGlobal.titanSpawnLoadoutIndex )
- RunMenuClientFunction( "SetEditingTitanLoadoutIndex", uiGlobal.titanSpawnLoadoutIndex )
- AdvanceMenu( GetMenu( "EditTitanLoadoutMenu" ) )
- RunMenuClientFunction( "HideTTSPanel" )
-}
-
-bool function CoverIsOff()
-{
- return !Hud_IsEnabled( file.cover )
-}
-
-bool function TeamTitanSelectMenuIsOpen()
-{
- return file.menuOpened
-}
-
-bool function TeamTitanSelect_IsReady()
-{
- return file.isReady
-}
-
-bool function TeamTitanSelect_IsNotReady()
-{
- return !file.isReady
-}
-
-void function TTSMenuModeFD()
-{
- file.menuMode = eTTSMenuMode.FD
-
- foreach ( button in file.titanUpgradeButtons )
- {
- Hud_Show( button )
- }
-}
-
-void function TTSMenuModeDefault()
-{
- file.menuMode = eTTSMenuMode.DEFAULT
-
- foreach ( button in file.titanUpgradeButtons )
- {
- Hud_Hide( button )
- }
-
- var panel = Hud_GetChild( file.menu, "UpgradeName" )
- Hud_Hide( panel )
-}
-
-var function FindValidTitanButton()
-{
- foreach ( button in file.titanButtons )
- {
- if ( Hud_IsLocked( button ) )
- continue
-
- return button
- }
-
- return file.titanButtons[0]
-} \ No newline at end of file