5188 lines
133 KiB
Plaintext
5188 lines
133 KiB
Plaintext
#include common_scripts\utility;
|
|
#include maps\_utility;
|
|
#include maps\_debug;
|
|
#include maps\_vehicle;
|
|
#include maps\_hud_util;
|
|
|
|
main()
|
|
{
|
|
if ( !isdefined( level.func ) )
|
|
{
|
|
level.func = [];
|
|
}
|
|
level.func[ "setsaveddvar" ] = ::setsaveddvar;
|
|
level.func[ "useanimtree" ] = ::useAnimTree;
|
|
level.func[ "setanim" ] = ::setAnim;
|
|
level.func[ "setanimknob" ] = ::setAnimKnob;
|
|
level.func[ "clearanim" ] = ::clearAnim;
|
|
level.func[ "kill" ] = ::Kill;
|
|
|
|
set_early_level();
|
|
|
|
//***************************************** STEALTH SYSTEM CALLBACKS *****************************************/
|
|
|
|
//->since stealth is so integrated into many global scripts, these call backs refer to an empty function...if they are actually
|
|
//called, that means the designer called a stealth function without initilizing the stealth system first. This is done so stealth
|
|
//scripts dont have to be loaded globally into every level
|
|
level.global_callbacks = [];
|
|
|
|
level.global_callbacks[ "_autosave_stealthcheck" ] = ::global_empty_callback;
|
|
level.global_callbacks[ "_patrol_endon_spotted_flag" ] = ::global_empty_callback;
|
|
level.global_callbacks[ "_spawner_stealth_default" ] = ::global_empty_callback;
|
|
//this one's for _idle...its peppered with stealth stuff so it got quarentined too.
|
|
level.global_callbacks[ "_idle_call_idle_func" ] = ::global_empty_callback;
|
|
|
|
//***************************************** STEALTH SYSTEM CALLBACKS *****************************************/
|
|
|
|
/#
|
|
weapon_list_debug();
|
|
#/
|
|
|
|
if ( !isdefined( level.visionThermalDefault ) )
|
|
level.visionThermalDefault = "cheat_bw";
|
|
VisionSetThermal( level.visionThermalDefault );
|
|
|
|
VisionSetPain( "near_death" );
|
|
|
|
level.func[ "damagefeedback" ] = maps\_damagefeedback::updateDamageFeedback;// for player shooting sentry guns
|
|
array_thread( GetEntArray( "script_model_pickup_claymore", "classname" ), ::claymore_pickup_think_global );
|
|
array_thread( GetEntArray( "ammo_cache", "targetname" ), ::ammo_cache_think_global );
|
|
|
|
/# star( 4 + RandomInt( 4 ) ); #/
|
|
|
|
if ( GetDvar( "debug" ) == "" )
|
|
SetDvar( "debug", "0" );
|
|
|
|
if ( GetDvar( "fallback" ) == "" )
|
|
SetDvar( "fallback", "0" );
|
|
|
|
if ( GetDvar( "angles" ) == "" )
|
|
SetDvar( "angles", "0" );
|
|
|
|
if ( GetDvar( "noai" ) == "" )
|
|
SetDvar( "noai", "off" );
|
|
|
|
if ( GetDvar( "scr_RequiredMapAspectratio" ) == "" )
|
|
SetDvar( "scr_RequiredMapAspectratio", "1" );
|
|
|
|
//if ( GetDvar( "ac130_player_num" ) == "" )
|
|
SetDvar( "ac130_player_num", -1 ); // reset ac130 player number for proper display of HUD
|
|
|
|
clear_custom_eog_summary();
|
|
SetDvar( "ui_remotemissile_playernum", 0 );
|
|
SetDvar( "ui_pmc_won", 0 );
|
|
|
|
CreatePrintChannel( "script_debug" );
|
|
|
|
if ( !isdefined( anim.notetracks ) )
|
|
{
|
|
// string based array for notetracks
|
|
anim.notetracks = [];
|
|
animscripts\shared::registerNoteTracks();
|
|
}
|
|
|
|
// default start for killing script.
|
|
add_start( "no_game", ::start_nogame );
|
|
|
|
level._loadStarted = true;
|
|
level.first_frame = true;
|
|
level.level_specific_dof = false;
|
|
thread remove_level_first_frame();
|
|
|
|
level.wait_any_func_array = [];
|
|
level.run_func_after_wait_array = [];
|
|
level.run_call_after_wait_array = [];
|
|
level.run_noself_call_after_wait_array = [];
|
|
level.do_wait_endons_array = [];
|
|
level.abort_wait_any_func_array = [];
|
|
if ( !isdefined( level.script ) )
|
|
level.script = ToLower( GetDvar( "mapname" ) );
|
|
|
|
maps\_specialops::specialops_remove_unused();
|
|
|
|
// set solo_play dvar correctly upon returning from a friend's game in which you were invited while playing solo play mode previously
|
|
if ( is_specialop() && ( IsSplitScreen() || ( GetDvar( "coop" ) == "1" ) ) )
|
|
SetDvar( "solo_play", "" );
|
|
|
|
/*
|
|
no_game_levels = [];
|
|
no_game_levels[ "contingency" ] = true;
|
|
|
|
if ( IsDefined( no_game_levels[ level.script ] ) )
|
|
{
|
|
SetDvar( "start", "no_game" );
|
|
}
|
|
else
|
|
{
|
|
if ( GetDvar( "start" ) == "no_game" )
|
|
SetDvar( "start", "" );
|
|
}
|
|
*/
|
|
|
|
level.dirtEffectMenu[ "center" ] = "dirt_effect_center";
|
|
level.dirtEffectMenu[ "left" ] = "dirt_effect_left";
|
|
level.dirtEffectMenu[ "right" ] = "dirt_effect_right";
|
|
PrecacheMenu( level.dirtEffectMenu[ "center" ] );
|
|
PrecacheMenu( level.dirtEffectMenu[ "left" ] );
|
|
PrecacheMenu( level.dirtEffectMenu[ "right" ] );
|
|
PreCacheShader( "fullscreen_dirt_bottom_b" );
|
|
PreCacheShader( "fullscreen_dirt_bottom" );
|
|
PreCacheShader( "fullscreen_dirt_left" );
|
|
PreCacheShader( "fullscreen_dirt_right" );
|
|
|
|
|
|
level.is_legacy_map = set_legacy_map();
|
|
|
|
level.ai_number = 0;
|
|
// flag_struct is used as a placeholder when a flag is set without an entity
|
|
|
|
if ( !isdefined( level.flag ) )
|
|
{
|
|
init_flags();
|
|
}
|
|
else
|
|
{
|
|
// flags initialized before this should be checked for stat tracking
|
|
flags = GetArrayKeys( level.flag );
|
|
array_levelthread( flags, ::check_flag_for_stat_tracking );
|
|
}
|
|
|
|
// disabled, prototyping PMC/COOP money
|
|
if ( GetDvar( "xp_enable", "0" ) == "" )
|
|
SetDvar( "xp_enable", "0" );
|
|
|
|
if ( string_starts_with( level.script, "co_" ) )
|
|
{
|
|
SetDvar( "money_enable", "1" );
|
|
SetDvar( "in_game_reward", "0" ); // this includes getting reward from kills and objectives
|
|
}
|
|
else if ( string_starts_with( level.script, "pmc_" ) )
|
|
{
|
|
SetDvar( "money_enable", "1" );
|
|
SetDvar( "in_game_reward", "1" );
|
|
}
|
|
else
|
|
{
|
|
SetDvar( "money_enable", "0" );
|
|
SetDvar( "in_game_reward", "0" );
|
|
}
|
|
|
|
if ( GetDvar( "money_sharing" ) == "" )
|
|
SetDvar( "money_sharing", "1" );
|
|
|
|
|
|
init_level_players();
|
|
|
|
if ( is_coop() )
|
|
maps\_coop::main();
|
|
|
|
if ( IsSplitScreen() )
|
|
{
|
|
SetSavedDvar( "cg_fovScale", "0.75" );// 65 - > 40 fov// 0.54
|
|
}
|
|
else
|
|
{
|
|
SetSavedDvar( "cg_fovScale", "1" );
|
|
}
|
|
|
|
level.radiation_totalpercent = 0;
|
|
|
|
flag_init( "missionfailed" );
|
|
flag_init( "auto_adjust_initialized" );
|
|
flag_init( "_radiation_poisoning" );
|
|
flag_init( "gameskill_selected" );
|
|
flag_init( "battlechatter_on_thread_waiting" );
|
|
|
|
thread maps\_gameskill::aa_init_stats();
|
|
thread player_death_detection();
|
|
|
|
level.default_run_speed = 190;
|
|
SetSavedDvar( "g_speed", level.default_run_speed );
|
|
|
|
if ( is_specialop() )
|
|
{
|
|
SetSavedDvar( "sv_saveOnStartMap", false );
|
|
}
|
|
else if ( arcadeMode() )
|
|
{
|
|
SetSavedDvar( "sv_saveOnStartMap", false );
|
|
thread arcademode_save();
|
|
}
|
|
else
|
|
{
|
|
SetSavedDvar( "sv_saveOnStartMap", true );
|
|
}
|
|
|
|
level.dronestruct = [];
|
|
|
|
|
|
// remove delete_on_load structs
|
|
foreach ( index, struct in level.struct )
|
|
{
|
|
if ( !isdefined( struct.targetname ) )
|
|
continue;
|
|
if ( struct.targetname == "delete_on_load" )
|
|
level.struct[ index ] = undefined;
|
|
}
|
|
|
|
struct_class_init();
|
|
|
|
// can be turned on and off to control friendly_respawn_trigger
|
|
flag_init( "respawn_friendlies" );
|
|
flag_init( "player_flashed" );
|
|
|
|
//function pointers so I can share _destructible script with SP and MP where code commands don't exist in MP
|
|
level.arcadeMode_kill_func = ::arcadeMode_kill;
|
|
level.connectPathsFunction = ::connectPaths;
|
|
level.disconnectPathsFunction = ::disconnectPaths;
|
|
level.badplace_cylinder_func = ::badplace_cylinder;
|
|
level.badplace_delete_func = ::badplace_delete;
|
|
level.isAIfunc = ::isAI;
|
|
level.createClientFontString_func = maps\_hud_util::createClientFontString;
|
|
level.HUDsetPoint_func = maps\_hud_util::setPoint;
|
|
level.makeEntitySentient_func = ::makeEntitySentient;
|
|
level.freeEntitySentient_func = ::freeEntitySentient;
|
|
level.sentry_money_init_func = maps\_money::AI_money_init;
|
|
level.laserOn_func = ::laserForceOn;
|
|
level.laserOff_func = ::laserForceOff;
|
|
level.stat_track_kill_func = maps\_player_stats::register_kill;
|
|
level.stat_track_damage_func = maps\_player_stats::register_shot_hit;
|
|
level.doPickyAutosaveChecks = true;
|
|
level.autosave_threat_check_enabled = true;
|
|
level.getNodeFunction = ::GetNode;
|
|
level.getNodeArrayFunction = ::GetNodeArray;
|
|
|
|
if ( !isdefined( level._notetrackFX ) )
|
|
level._notetrackFX = [];
|
|
|
|
foreach ( player in level.players )
|
|
{
|
|
player.maxhealth = level.player.health;
|
|
player.shellshocked = false;
|
|
player.inWater = false;
|
|
player.dirt_on_screen = [];
|
|
player.dirt_on_screen[ "bottom_b" ] = 0;
|
|
player.dirt_on_screen[ "left" ] = 0;
|
|
player.dirt_on_screen[ "right" ] = 0;
|
|
player thread watchWeaponChange();// for thermal
|
|
}
|
|
|
|
level.last_mission_sound_time = -5000;
|
|
level.hero_list = [];
|
|
thread precache_script_models();
|
|
|
|
// level.ai_array = [];
|
|
|
|
for ( i = 0; i < level.players.size; i++ )
|
|
{
|
|
player = level.players[ i ];
|
|
player thread maps\_utility::flashMonitor();
|
|
player thread maps\_utility::shock_ondeath();
|
|
}
|
|
|
|
// level.player thread ai_eq();
|
|
// level.player thread maps\_spawner::setup_ai_eq_triggers();
|
|
// level.eq_trigger_num = 0;
|
|
// level.eq_trigger_table = [];
|
|
// level.touched_eq_function[ true ] = ::player_touched_eq_trigger;
|
|
// level.touched_eq_function[ false ] = ::ai_touched_eq_trigger;
|
|
|
|
//un-developer commented. I was precaching this model in _vehicle anyway.
|
|
PreCacheModel( "fx" );
|
|
|
|
PreCacheModel( "tag_origin" );
|
|
PreCacheShellShock( "victoryscreen" );
|
|
PreCacheShellShock( "default" );
|
|
PreCacheShellShock( "flashbang" );
|
|
PreCacheShellShock( "dog_bite" );
|
|
PreCacheRumble( "damage_heavy" );
|
|
PreCacheRumble( "damage_light" );
|
|
PreCacheRumble( "grenade_rumble" );
|
|
PreCacheRumble( "artillery_rumble" );
|
|
|
|
// You are Hurt. Get to Cover!
|
|
PreCacheString( &"GAME_GET_TO_COVER" );
|
|
// You were killed by a grenade.\nWatch out for the grenade danger indicator.
|
|
PreCacheString( &"SCRIPT_GRENADE_DEATH" );
|
|
// You died holding a grenade for too long.
|
|
PreCacheString( &"SCRIPT_GRENADE_SUICIDE_LINE1" );
|
|
// Holding ^3[{+frag}]^7 allows you to cook off live grenades.
|
|
PreCacheString( &"SCRIPT_GRENADE_SUICIDE_LINE2" );
|
|
// You were killed by an exploding vehicle.\nVehicles on fire are likely to explode.
|
|
PreCacheString( &"SCRIPT_EXPLODING_VEHICLE_DEATH" );
|
|
// You were killed by an explosion.\nSome burning objects can explode.
|
|
PreCacheString( &"SCRIPT_EXPLODING_DESTRUCTIBLE_DEATH" );
|
|
// You were killed by an exploding barrel.\nRed barrels will explode when shot.
|
|
PreCacheString( &"SCRIPT_EXPLODING_BARREL_DEATH" );
|
|
PreCacheShader( "hud_grenadeicon" );
|
|
PreCacheShader( "hud_grenadepointer" );
|
|
PreCacheShader( "hud_burningcaricon" );
|
|
PreCacheShader( "death_juggernaut" );
|
|
PreCacheShader( "death_friendly_fire" );
|
|
PreCacheShader( "hud_destructibledeathicon" );
|
|
PreCacheShader( "hud_burningbarrelicon" );
|
|
PreCacheShader( "waypoint_ammo" );
|
|
|
|
level._effect[ "deathfx_bloodpool_generic" ] = LoadFX( "impacts/deathfx_bloodpool_generic" );
|
|
animscripts\pain::initPainFx();
|
|
|
|
animscripts\melee::Melee_Init();
|
|
|
|
level.createFX_enabled = ( GetDvar( "createfx" ) != "" );
|
|
|
|
slowmo_system_init();
|
|
|
|
maps\_mgturret::main();
|
|
|
|
setupExploders();
|
|
maps\_art::main();
|
|
maps\_noder::main();
|
|
common_scripts\_painter::main();
|
|
maps\_gameskill::setSkill();
|
|
|
|
maps\_anim::init();
|
|
|
|
thread common_scripts\_fx::initFX();
|
|
if ( level.createFX_enabled )
|
|
{
|
|
level.stop_load = true;
|
|
maps\_createfx::createfx();
|
|
}
|
|
|
|
maps\_detonategrenades::init();
|
|
|
|
thread setup_simple_primary_lights();
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// ---- PAST THIS POINT THE SCRIPTS DONT RUN WHEN GENERATING REFLECTION PROBES ----
|
|
// --------------------------------------------------------------------------------
|
|
/#
|
|
if ( GetDvar( "r_reflectionProbeGenerate" ) == "1" )
|
|
{
|
|
level.stop_load = true;
|
|
maps\_global_fx::main();
|
|
level waittill( "eternity" );
|
|
}
|
|
#/
|
|
|
|
/#
|
|
if ( string_starts_with( level.script, "so_" ) && !is_specialop() )
|
|
AssertMsg( "Attempted to run a Special Op, but not in Special Ops mode. Probably need to add +set specialops 1 to Launcher Custom Command Line Options." );
|
|
#/
|
|
|
|
maps\_names::setup_names();
|
|
|
|
thread handle_starts();
|
|
thread handle_getviewpos();
|
|
thread handle_getviewangle();
|
|
|
|
/#
|
|
thread maps\_debug::mainDebug();
|
|
#/
|
|
|
|
if ( !isdefined( level.trigger_flags ) )
|
|
{
|
|
// may have been defined by AI spawning
|
|
init_trigger_flags();
|
|
}
|
|
|
|
level.killspawn_groups = [];
|
|
init_script_triggers();
|
|
|
|
SetSavedDvar( "ufoHitsTriggers", "0" );
|
|
|
|
//don't go past here on no_game start
|
|
if ( level.start_point == "no_game" )
|
|
{
|
|
// we want ufo/noclip to hit triggers in no_game
|
|
SetSavedDvar( "ufoHitsTriggers", "1" );
|
|
|
|
level.stop_load = true;
|
|
// SRS 11/25/08: LDs can run a custom setup function for their levels to get back some
|
|
// selected script calls (loadout, vision, etc). be careful, this function is not threaded!
|
|
if ( IsDefined( level.custom_no_game_setupFunc ) )
|
|
{
|
|
level [[ level.custom_no_game_setupFunc ]]();
|
|
}
|
|
maps\_loadout::init_loadout();
|
|
maps\_ambient::init();
|
|
level waittill( "eternity" );
|
|
}
|
|
|
|
thread maps\_vehicle::init_vehicles();
|
|
|
|
if ( GetDvar( "g_connectpaths" ) == "2" )
|
|
{
|
|
/# PrintLn( "g_connectpaths == 2; halting script execution" ); #/
|
|
level waittill( "eternity" );
|
|
}
|
|
|
|
PrintLn( "level.script: ", level.script );
|
|
|
|
maps\_autosave::main();
|
|
if ( !isdefined( level.animSounds ) )
|
|
thread maps\_debug::init_animSounds();
|
|
maps\_anim::init();
|
|
maps\_ambient::init();
|
|
|
|
// lagacy... necessary?
|
|
anim.useFacialAnims = false;
|
|
|
|
if ( !isdefined( level.MissionFailed ) )
|
|
level.MissionFailed = false;
|
|
|
|
maps\_loadout::init_loadout();
|
|
|
|
common_scripts\_destructible::init();
|
|
thread common_scripts\_elevator::init();
|
|
thread common_scripts\_pipes::main();
|
|
|
|
SetObjectiveTextColors();
|
|
|
|
// global effects for objects
|
|
maps\_global_fx::main();
|
|
common_scripts\_dynamic_world::init();
|
|
|
|
//thread devhelp();// disabled due to localization errors
|
|
|
|
SetSavedDvar( "ui_campaign", level.campaign );// level.campaign is set in maps\_loadout::init_loadout
|
|
|
|
thread maps\_introscreen::main();
|
|
thread maps\_quotes::main();
|
|
// thread maps\_minefields::main();
|
|
thread maps\_shutter::main();
|
|
// thread maps\_breach::main();
|
|
// thread maps\_inventory::main();
|
|
// thread maps\_photosource::main();
|
|
thread maps\_endmission::main();
|
|
thread maps\_damagefeedback::init();
|
|
thread maps\_escalator::init();
|
|
maps\_friendlyfire::main();
|
|
|
|
// For _anim to track what animations have been used. Uncomment this locally if you need it.
|
|
// thread usedAnimations();
|
|
|
|
array_levelthread( GetEntArray( "badplace", "targetname" ), ::badplace_think );
|
|
array_levelthread( GetEntArray( "delete_on_load", "targetname" ), ::deleteEnt );
|
|
array_thread( GetNodeArray( "traverse", "targetname" ), ::traverseThink );
|
|
/# array_thread( GetNodeArray( "deprecated_traverse", "targetname" ), ::deprecatedTraverseThink ); #/
|
|
array_thread( GetEntArray( "piano_key", "targetname" ), ::pianoThink );
|
|
array_thread( GetEntArray( "piano_damage", "targetname" ), ::pianoDamageThink );
|
|
array_thread( GetEntArray( "water", "targetname" ), ::waterThink );
|
|
array_thread( GetEntArray( "kill_all_players", "targetname" ), ::kill_all_players_trigger );
|
|
|
|
flag_init( "allow_ammo_pickups" );
|
|
flag_set( "allow_ammo_pickups" );
|
|
|
|
array_thread( GetEntArray( "ammo_pickup_grenade_launcher", "targetname" ), ::ammo_pickup, "grenade_launcher" );
|
|
array_thread( GetEntArray( "ammo_pickup_rpg", "targetname" ), ::ammo_pickup, "rpg" );
|
|
array_thread( GetEntArray( "ammo_pickup_c4", "targetname" ), ::ammo_pickup, "c4" );
|
|
array_thread( GetEntArray( "ammo_pickup_claymore", "targetname" ), ::ammo_pickup, "claymore" );
|
|
array_thread( GetEntArray( "ammo_pickup_556", "targetname" ), ::ammo_pickup, "556" );
|
|
array_thread( GetEntArray( "ammo_pickup_762", "targetname" ), ::ammo_pickup, "762" );
|
|
array_thread( GetEntArray( "ammo_pickup_45", "targetname" ), ::ammo_pickup, "45" );
|
|
array_thread( GetEntArray( "ammo_pickup_pistol", "targetname" ), ::ammo_pickup, "pistol" );
|
|
|
|
thread maps\_interactive_objects::main();
|
|
thread maps\_intelligence::main();
|
|
|
|
thread maps\_gameskill::playerHealthRegenInit();
|
|
|
|
for ( i = 0; i < level.players.size; i++ )
|
|
{
|
|
player = level.players[ i ];
|
|
player thread maps\_gameskill::playerHealthRegen();
|
|
player thread playerDamageRumble();
|
|
}
|
|
|
|
thread player_special_death_hint();
|
|
|
|
// this has to come before _spawner moves the turrets around
|
|
thread massNodeInitFunctions();
|
|
|
|
// Various newvillers globalized scripts
|
|
flag_init( "spawning_friendlies" );
|
|
flag_init( "friendly_wave_spawn_enabled" );
|
|
flag_clear( "spawning_friendlies" );
|
|
|
|
level.friendly_spawner[ "rifleguy" ] = GetEntArray( "rifle_spawner", "script_noteworthy" );
|
|
level.friendly_spawner[ "smgguy" ] = GetEntArray( "smg_spawner", "script_noteworthy" );
|
|
level.spawn_funcs = [];
|
|
level.spawn_funcs[ "allies" ] = [];
|
|
level.spawn_funcs[ "axis" ] = [];
|
|
level.spawn_funcs[ "team3" ] = [];
|
|
level.spawn_funcs[ "neutral" ] = [];
|
|
thread maps\_spawner::goalVolumes();
|
|
thread maps\_spawner::friendlyChains();
|
|
thread maps\_spawner::friendlychain_onDeath();
|
|
|
|
// array_thread( GetEntArray( "ally_spawn", "targetname" ), maps\_spawner::squadThink );
|
|
array_thread( GetEntArray( "friendly_spawn", "targetname" ), maps\_spawner::friendlySpawnWave );
|
|
array_thread( GetEntArray( "flood_and_secure", "targetname" ), maps\_spawner::flood_and_secure );
|
|
|
|
// Do various things on triggers
|
|
array_thread( GetEntArray( "ambient_volume", "targetname" ), maps\_ambient::ambientVolume );
|
|
|
|
|
|
array_thread( GetEntArray( "window_poster", "targetname" ), ::window_destroy );
|
|
|
|
|
|
if ( !isdefined( level.trigger_hint_string ) )
|
|
{
|
|
level.trigger_hint_string = [];
|
|
level.trigger_hint_func = [];
|
|
}
|
|
|
|
level.shared_portable_turrets = [];
|
|
level.spawn_groups = [];
|
|
maps\_spawner::main();
|
|
|
|
// for cobrapilot extended visible distance and potentially others, stretch that horizon! - nate
|
|
// origin of prefab is copied manually by LD to brushmodel contained in the prefab, no real way to automate this AFAIK
|
|
array_thread( GetEntArray( "background_block", "targetname" ), ::background_block );
|
|
|
|
maps\_hud::init();
|
|
// maps\_hud_weapons::init();
|
|
|
|
thread load_friendlies();
|
|
|
|
// level.player thread stun_test();
|
|
|
|
thread maps\_animatedmodels::main();
|
|
thread maps\_cagedchickens::initChickens();
|
|
if ( is_coop() )
|
|
thread maps\_loadout::coop_gamesetup_menu();
|
|
thread weapon_ammo();
|
|
thread filmy();
|
|
|
|
if ( is_specialop() )
|
|
maps\_specialops::specialops_init();
|
|
|
|
// set has-played-SP when player plays the frist level in the game for the first time.
|
|
assert( isdefined( level.missionsettings ) && isdefined( level.missionsettings.levels ) );
|
|
assert( isdefined( level.script ) );
|
|
|
|
if ( level.script == level.missionsettings.levels[0].name && !( level.player getLocalPlayerProfileData( "hasEverPlayed_SP" ) ) )
|
|
{
|
|
level.player SetLocalPlayerProfileData( "hasEverPlayed_SP", true );
|
|
UpdateGamerProfile();
|
|
}
|
|
}
|
|
|
|
/*QUAKED trigger_multiple_spawn (1.0 0.5 0.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="spawner_trigger"
|
|
Spawns whatever is targetted. Currently supports AI.*/
|
|
|
|
/*QUAKED trigger_multiple_spawn_reinforcement (0.12 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="spawner_trigger"
|
|
Spawns whatever is targetted. When the targeted AI dies a reinforcement spawner will be spawned if the spawner targets another spawner. Currently supports AI.*/
|
|
|
|
/*QUAKED trigger_use_flag_set (0.12 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="flag"
|
|
Sets the script_flag when triggered. The entity that triggered it is passed with the level notify and to the flag_wait.*/
|
|
|
|
/*QUAKED trigger_use_flag_clear (0.12 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="flag"
|
|
Sets the script_flag when triggered. The entity that triggered it is passed with the level notify and to the flag_wait.*/
|
|
|
|
/*QUAKED trigger_damage_doradius_damage (0.12 0.23 1.0) ? PISTOL_NO RIFLE_NO PROJ_NO EXPLOSION_NO SPLASH_NO MELEE_NO
|
|
defaulttexture="trigger"
|
|
Wait for trigger then do lots of damage at target spot. */
|
|
|
|
/*QUAKED trigger_multiple_doradius_damage (0.12 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN
|
|
defaulttexture="trigger"
|
|
Wait for trigger then do lots of damage at target spot. */
|
|
|
|
/*QUAKED trigger_damage_player_flag_set (0.12 0.23 1.0) ? PISTOL_NO RIFLE_NO PROJ_NO EXPLOSION_NO SPLASH_NO MELEE_NO
|
|
defaulttexture="flag"
|
|
Sets the script_flag when player does damage to the trigger. */
|
|
|
|
/*QUAKED trigger_multiple_nobloodpool (0.12 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN
|
|
defaulttexture="trigger_nobloodpool"
|
|
When triggered the touching character will no longer spawn blood pools on death. When the character leaves the trigger the blood pool will be re-enabled after a short delay. */
|
|
|
|
/*QUAKED trigger_multiple_flag_set (0.12 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="flag"
|
|
Sets the script_flag when triggered. The entity that triggered it is passed with the level notify and to the flag_wait.*/
|
|
|
|
/*QUAKED trigger_multiple_flag_clear (0.12 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="flag"
|
|
Clears the script_flag when triggered.*/
|
|
|
|
/*QUAKED trigger_multiple_flag_set_touching (0.12 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="flag"
|
|
Sets the script_flag when touched and then clears the flag when no longer touched.*/
|
|
|
|
/*QUAKED trigger_multiple_flag_lookat (0.12 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="flag"
|
|
The trigger targets a script origin. When the trigger is touched and a player looks at the origin, the script_flag gets set. If there is no script_flag then any triggers targetted by the trigger_multiple_lookat get triggered. Change SCRIPT_DOT to change required dot product*/
|
|
|
|
/*QUAKED trigger_multiple_flag_looking (0.12 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="flag"
|
|
The trigger targets a script origin. When the trigger is touched and a player looks at the origin, the script_flag gets set. Change SCRIPT_DOT to change required dot product.
|
|
|
|
When the player looks away from the script origin, the script_flag is cleared.
|
|
|
|
If there is no script_flag then any triggers targetted by the trigger_multiple_lookat get triggered.
|
|
*/
|
|
|
|
/*QUAKED trigger_multiple_no_prone (0.12 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL ? ? ? TOUCH_ONCE
|
|
defaulttexture="trigger_no_prone"
|
|
*/
|
|
|
|
/*QUAKED trigger_multiple_no_crouch_or_prone (0.12 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL ? ? ? TOUCH_ONCE
|
|
defaulttexture="trigger_no_crouch_or_prone"
|
|
*/
|
|
|
|
|
|
/*QUAKED trigger_multiple_autosave (1.0 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="autosave"
|
|
Autosaves when the trigger is hit.
|
|
*/
|
|
|
|
/*QUAKED trigger_multiple_physics ( 0.0 0.63 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="trigger"
|
|
Activate a physics jolt at a specified origin.
|
|
Use script_parameters to set amount of jolt.
|
|
*/
|
|
|
|
/*QUAKED trigger_multiple_visionset (1.0 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="trigger_environment"
|
|
Changes vision set to script_visionset. Script_delay specifies how long to spend on the transition.
|
|
If it can find a fogset with the same name, it will change that as well.
|
|
*/
|
|
|
|
/*QUAKED trigger_multiple_slide (1.0 0.23 1.0) ?
|
|
defaulttexture="trigger"
|
|
Forces the player to slide.
|
|
*/
|
|
|
|
/*QUAKED script_origin_mini (1.0 0.0 0.0) (-2 -2 -2) (2 2 2)*/
|
|
|
|
/*QUAKED script_origin_small (1.0 0.0 0.0) (-4 -4 -4) (4 4 4)*/
|
|
|
|
/*QUAKED script_struct_mini (0.9 0.3 0.0) (-1 -1 -1) (1 1 1)*/
|
|
|
|
/*QUAKED script_struct_small (0.9 0.3 0.0) (-2 -2 -2) (2 2 2)*/
|
|
|
|
|
|
/*QUAKED trigger_multiple_fog (1.0 0.23 1.0) ?
|
|
defaulttexture="trigger"
|
|
Fog transition trigger.
|
|
script_fogset_start="example_start_fog"
|
|
script_fogset_end="example_end_fog"
|
|
"example_start_fog" is made from maps\_utility::create_fog("example_start_fog")
|
|
|
|
Trigger must target a script_origin to define the entry side,
|
|
this script_origin can target another optional script_origin to define exit side.
|
|
*/
|
|
|
|
/*QUAKED trigger_multiple_ambient (1.0 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="ambient"
|
|
.ambient determines the ambience for the trigger. Can be two values, like "interior exterior" and it will blend between them.
|
|
For blending, needs a targetted origin to determine blend direction.
|
|
|
|
Current sets are:
|
|
ac130
|
|
alley
|
|
bunker
|
|
city
|
|
container
|
|
exterior
|
|
exterior1
|
|
exterior2
|
|
exterior3
|
|
exterior4
|
|
exterior5
|
|
forrest
|
|
hangar
|
|
interior
|
|
interior_metal
|
|
interior_stone
|
|
interior_vehicle
|
|
interior_wood
|
|
mountains
|
|
pipe
|
|
shanty
|
|
snow_base
|
|
snow_cliff
|
|
tunnel
|
|
underpass
|
|
|
|
|
|
*/
|
|
|
|
/*QUAKED trigger_radius_glass_break (0 0.25 0.5) (-16 -16 -16) (16 16 16) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE
|
|
Target to a func_glass. When an entity touching this trigger sends a level notify of "glass_break", the func_glass targeted by this trigger will break.
|
|
*/
|
|
|
|
/*QUAKED trigger_multiple_glass_break (0 0.25 0.5) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE
|
|
defaulttexture="trigger"
|
|
Target to a func_glass. When an entity touching this trigger sends a level notify of "glass_break", the func_glass targeted by this trigger will break.
|
|
*/
|
|
|
|
/*QUAKED trigger_multiple_friendly_respawn (0 1 0.25) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="aitrig"
|
|
Target a script origin. Replacement friendlies will spawn from the origin.
|
|
*/
|
|
|
|
/*QUAKED trigger_multiple_friendly_stop_respawn (0.25 1 0.25) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="aitrig"
|
|
Stops friendly respawning.
|
|
*/
|
|
|
|
/*QUAKED trigger_multiple_friendly (0 1.0 0.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="aitrig"
|
|
Assign color codes to this trigger to control friendlies.
|
|
*/
|
|
|
|
/*QUAKED trigger_multiple_compass (0.2 0.9 0.7) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="trigger"
|
|
Activates the compass map set in its script_parameters.
|
|
*/
|
|
|
|
/*QUAKED trigger_multiple_specialops_flag_set (0.12 0.23 1.0) ? AI_AXIS AI_ALLIES AI_NEUTRAL NOTPLAYER VEHICLE TRIGGER_SPAWN TOUCH_ONCE
|
|
defaulttexture="flag"
|
|
Sets the script_flag after being triggered by all player in a specialops map. The last entity that triggered it is passed with the level notify and to the flag_wait.*/
|
|
|
|
get_load_trigger_classes()
|
|
{
|
|
trigger_classes = [];
|
|
trigger_classes[ "trigger_multiple_nobloodpool" ] = ::trigger_nobloodpool;
|
|
trigger_classes[ "trigger_multiple_flag_set" ] = ::flag_set_trigger;
|
|
trigger_classes[ "trigger_multiple_flag_clear" ] = ::flag_unset_trigger;
|
|
trigger_classes[ "trigger_use_flag_set" ] = ::flag_set_trigger;
|
|
trigger_classes[ "trigger_use_flag_clear" ] = ::flag_unset_trigger;
|
|
trigger_classes[ "trigger_multiple_flag_set_touching" ] = ::flag_set_touching;
|
|
trigger_classes[ "trigger_multiple_flag_lookat" ] = ::trigger_lookat;
|
|
trigger_classes[ "trigger_multiple_flag_looking" ] = ::trigger_looking;
|
|
trigger_classes[ "trigger_multiple_no_prone" ] = ::no_prone_think;
|
|
trigger_classes[ "trigger_multiple_no_crouch_or_prone" ] = ::no_crouch_or_prone_think;
|
|
trigger_classes[ "trigger_multiple_compass" ] = ::trigger_multiple_compass;
|
|
trigger_classes[ "trigger_multiple_specialops_flag_set" ] = ::flag_set_trigger_specialops;
|
|
|
|
if ( level.start_point != "no_game" )
|
|
{
|
|
trigger_classes[ "trigger_multiple_autosave" ] = maps\_autosave::trigger_autosave;
|
|
trigger_classes[ "trigger_multiple_spawn" ] = maps\_spawner::trigger_spawner;
|
|
trigger_classes[ "trigger_multiple_spawn_reinforcement" ] = maps\_spawner::trigger_spawner_reinforcement;
|
|
}
|
|
|
|
trigger_classes[ "trigger_multiple_slide" ] = ::trigger_slide;
|
|
trigger_classes[ "trigger_multiple_fog" ] = ::trigger_fog;
|
|
//trigger_classes[ "trigger_multiple_ambient" ] = ::trigger_ambient; // runs from global .ambient check
|
|
|
|
trigger_classes[ "trigger_damage_doradius_damage" ] = ::trigger_damage_do_radius_damage;
|
|
trigger_classes[ "trigger_multiple_doradius_damage" ] = ::trigger_multiple_do_radius_damage;
|
|
|
|
trigger_classes[ "trigger_damage_player_flag_set" ] = ::trigger_damage_player_flag_set;
|
|
trigger_classes[ "trigger_multiple_visionset" ] = ::trigger_multiple_visionset;
|
|
trigger_classes[ "trigger_multiple_glass_break" ] = ::trigger_glass_break;
|
|
trigger_classes[ "trigger_radius_glass_break" ] = ::trigger_glass_break;
|
|
trigger_classes[ "trigger_multiple_friendly_respawn" ] = ::trigger_multiple_friendly_respawn;
|
|
trigger_classes[ "trigger_multiple_friendly_stop_respawn" ] = ::trigger_multiple_friendly_stop_respawn;
|
|
trigger_classes[ "trigger_multiple_physics" ] = ::trigger_multiple_physics;
|
|
trigger_classes[ "trigger_multiple_fx_watersheeting" ] = maps\_fx::watersheeting;
|
|
|
|
|
|
|
|
|
|
|
|
return trigger_classes;
|
|
}
|
|
|
|
get_load_trigger_funcs()
|
|
{
|
|
|
|
trigger_funcs = [];
|
|
trigger_funcs[ "friendly_wave" ] = maps\_spawner::friendly_wave;
|
|
trigger_funcs[ "friendly_wave_off" ] = maps\_spawner::friendly_wave;
|
|
trigger_funcs[ "friendly_mgTurret" ] = maps\_spawner::friendly_mgTurret;
|
|
|
|
if ( level.start_point != "no_game" )
|
|
{
|
|
trigger_funcs[ "camper_spawner" ] = maps\_spawner::camper_trigger_think;
|
|
trigger_funcs[ "flood_spawner" ] = maps\_spawner::flood_trigger_think;
|
|
trigger_funcs[ "trigger_spawner" ] = maps\_spawner::trigger_spawner;
|
|
trigger_funcs[ "trigger_autosave" ] = maps\_autosave::trigger_autosave;
|
|
trigger_funcs[ "trigger_spawngroup" ] = ::trigger_spawngroup;
|
|
trigger_funcs[ "two_stage_spawner" ] = maps\_spawner::two_stage_spawner_think;
|
|
trigger_funcs[ "trigger_vehicle_spline_spawn" ] = ::trigger_vehicle_spline_spawn;
|
|
trigger_funcs[ "trigger_vehicle_spawn" ] = ::trigger_vehicle_spawn;
|
|
trigger_funcs[ "trigger_vehicle_getin_spawn" ] = ::trigger_vehicle_getin_spawn;
|
|
trigger_funcs[ "random_spawn" ] = maps\_spawner::random_spawn;
|
|
}
|
|
|
|
trigger_funcs[ "autosave_now" ] = maps\_autosave::autosave_now_trigger;
|
|
trigger_funcs[ "trigger_autosave_tactical" ] = maps\_autosave::trigger_autosave_tactical;
|
|
trigger_funcs[ "trigger_autosave_stealth" ] = maps\_autosave::trigger_autosave_stealth;
|
|
trigger_funcs[ "trigger_unlock" ] = ::trigger_unlock;
|
|
trigger_funcs[ "trigger_lookat" ] = ::trigger_lookat;
|
|
trigger_funcs[ "trigger_looking" ] = ::trigger_looking;
|
|
trigger_funcs[ "trigger_cansee" ] = ::trigger_cansee;
|
|
trigger_funcs[ "autosave_immediate" ] = maps\_autosave::trigger_autosave_immediate;
|
|
trigger_funcs[ "flag_set" ] = ::flag_set_trigger;
|
|
if ( is_coop() )
|
|
trigger_funcs[ "flag_set_coop" ] = ::flag_set_coop_trigger;
|
|
trigger_funcs[ "flag_set_player" ] = ::flag_set_player_trigger;
|
|
trigger_funcs[ "flag_unset" ] = ::flag_unset_trigger;
|
|
trigger_funcs[ "flag_clear" ] = ::flag_unset_trigger;
|
|
trigger_funcs[ "objective_event" ] = maps\_spawner::objective_event_init;
|
|
// trigger_funcs[ "eq_trigger" ] = ::eq_trigger;
|
|
trigger_funcs[ "friendly_respawn_trigger" ] = ::trigger_multiple_friendly_respawn;
|
|
trigger_funcs[ "friendly_respawn_clear" ] = ::friendly_respawn_clear;
|
|
trigger_funcs[ "radio_trigger" ] = ::radio_trigger;
|
|
trigger_funcs[ "trigger_ignore" ] = ::trigger_ignore;
|
|
trigger_funcs[ "trigger_pacifist" ] = ::trigger_pacifist;
|
|
trigger_funcs[ "trigger_delete" ] = ::trigger_turns_off;
|
|
trigger_funcs[ "trigger_delete_on_touch" ] = ::trigger_delete_on_touch;
|
|
trigger_funcs[ "trigger_off" ] = ::trigger_turns_off;
|
|
trigger_funcs[ "trigger_outdoor" ] = maps\_spawner::outdoor_think;
|
|
trigger_funcs[ "trigger_indoor" ] = maps\_spawner::indoor_think;
|
|
trigger_funcs[ "trigger_hint" ] = ::trigger_hint;
|
|
trigger_funcs[ "trigger_grenade_at_player" ] = ::throw_grenade_at_player_trigger;
|
|
trigger_funcs[ "flag_on_cleared" ] = maps\_load::flag_on_cleared;
|
|
trigger_funcs[ "flag_set_touching" ] = ::flag_set_touching;
|
|
trigger_funcs[ "delete_link_chain" ] = ::delete_link_chain;
|
|
trigger_funcs[ "trigger_fog" ] = ::trigger_fog;
|
|
trigger_funcs[ "trigger_slide" ] = ::trigger_slide;
|
|
trigger_funcs[ "trigger_dooropen" ] = ::trigger_dooropen;
|
|
|
|
trigger_funcs[ "no_crouch_or_prone" ] = ::no_crouch_or_prone_think;
|
|
trigger_funcs[ "no_prone" ] = ::no_prone_think;
|
|
return trigger_funcs;
|
|
}
|
|
|
|
|
|
init_script_triggers()
|
|
{
|
|
// run logic on these triggers from radiant
|
|
trigger_classes = get_load_trigger_classes();
|
|
trigger_funcs = get_load_trigger_funcs();
|
|
|
|
|
|
foreach ( classname, function in trigger_classes )
|
|
{
|
|
triggers = GetEntArray( classname, "classname" );
|
|
array_levelthread( triggers, function );
|
|
}
|
|
|
|
// old style targetname triggering
|
|
|
|
// trigger_multiple and trigger_radius can have the trigger_spawn flag set
|
|
trigger_multiple = GetEntArray( "trigger_multiple", "classname" );
|
|
trigger_radius = GetEntArray( "trigger_radius", "classname" );
|
|
triggers = array_merge( trigger_multiple, trigger_radius );
|
|
trigger_disk = GetEntArray( "trigger_disk", "classname" );
|
|
triggers = array_merge( triggers, trigger_disk );
|
|
trigger_once = GetEntArray( "trigger_once", "classname" );
|
|
triggers = array_merge( triggers, trigger_once );
|
|
|
|
if ( level.start_point != "no_game" )
|
|
{
|
|
for ( i = 0; i < triggers.size; i++ )
|
|
{
|
|
if ( triggers[ i ].spawnflags & 32 )
|
|
thread maps\_spawner::trigger_spawner( triggers[ i ] );
|
|
}
|
|
}
|
|
|
|
for ( p = 0; p < 7; p++ )
|
|
{
|
|
switch( p )
|
|
{
|
|
case 0:
|
|
triggertype = "trigger_multiple";
|
|
break;
|
|
|
|
case 1:
|
|
triggertype = "trigger_once";
|
|
break;
|
|
|
|
case 2:
|
|
triggertype = "trigger_use";
|
|
break;
|
|
|
|
case 3:
|
|
triggertype = "trigger_radius";
|
|
break;
|
|
|
|
case 4:
|
|
triggertype = "trigger_lookat";
|
|
break;
|
|
|
|
case 5:
|
|
triggertype = "trigger_disk";
|
|
break;
|
|
|
|
default:
|
|
Assert( p == 6 );
|
|
triggertype = "trigger_damage";
|
|
break;
|
|
}
|
|
|
|
triggers = GetEntArray( triggertype, "code_classname" );
|
|
|
|
for ( i = 0; i < triggers.size; i++ )
|
|
{
|
|
if ( IsDefined( triggers[ i ].script_flag_true ) )
|
|
level thread script_flag_true_trigger( triggers[ i ] );
|
|
|
|
if ( IsDefined( triggers[ i ].script_flag_false ) )
|
|
level thread script_flag_false_trigger( triggers[ i ] );
|
|
|
|
if ( IsDefined( triggers[ i ].script_autosavename ) || IsDefined( triggers[ i ].script_autosave ) )
|
|
level thread maps\_autosave::autoSaveNameThink( triggers[ i ] );
|
|
|
|
if ( IsDefined( triggers[ i ].script_fallback ) )
|
|
level thread maps\_spawner::fallback_think( triggers[ i ] );
|
|
|
|
if ( IsDefined( triggers[ i ].script_mgTurretauto ) )
|
|
level thread maps\_mgturret::mgTurret_auto( triggers[ i ] );
|
|
|
|
if ( IsDefined( triggers[ i ].script_killspawner ) )
|
|
level thread maps\_spawner::kill_spawner( triggers[ i ] );
|
|
|
|
if ( IsDefined( triggers[ i ].script_kill_vehicle_spawner ) )
|
|
level thread maps\_vehicle::kill_vehicle_spawner( triggers[ i ] );
|
|
|
|
if ( IsDefined( triggers[ i ].script_emptyspawner ) )
|
|
level thread maps\_spawner::empty_spawner( triggers[ i ] );
|
|
|
|
if ( IsDefined( triggers[ i ].script_prefab_exploder ) )
|
|
triggers[ i ].script_exploder = triggers[ i ].script_prefab_exploder;
|
|
|
|
if ( IsDefined( triggers[ i ].script_exploder ) )
|
|
level thread maps\_load::exploder_load( triggers[ i ] );
|
|
|
|
if ( IsDefined( triggers[ i ].ambient ) )
|
|
triggers[ i ] thread maps\_ambient::ambient_trigger();
|
|
|
|
if ( IsDefined( triggers[ i ].script_triggered_playerseek ) )
|
|
level thread triggered_playerseek( triggers[ i ] );
|
|
|
|
if ( IsDefined( triggers[ i ].script_bctrigger ) )
|
|
level thread bctrigger( triggers[ i ] );
|
|
|
|
if ( IsDefined( triggers[ i ].script_trigger_group ) )
|
|
triggers[ i ] thread trigger_group();
|
|
|
|
if ( IsDefined( triggers[ i ].script_random_killspawner ) )
|
|
level thread maps\_spawner::random_killspawner( triggers[ i ] );
|
|
|
|
if ( IsDefined( triggers[ i ].targetname ) )
|
|
{
|
|
// do targetname specific functions
|
|
targetname = triggers[ i ].targetname;
|
|
if ( IsDefined( trigger_funcs[ targetname ] ) )
|
|
{
|
|
level thread [[ trigger_funcs[ targetname ] ]]( triggers[ i ] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
trigger_ambient( trigger )
|
|
{
|
|
if ( !isdefined( trigger.ambient ) )
|
|
return;
|
|
trigger thread maps\_ambient::ambient_trigger();
|
|
}
|
|
|
|
set_early_level()
|
|
{
|
|
level.early_level = [];
|
|
level.early_level[ "trainer" ] = true;
|
|
level.early_level[ "roadkill" ] = true;
|
|
level.early_level[ "cliffhanger" ] = true;
|
|
level.early_level[ "airport" ] = true;
|
|
level.early_level[ "favela" ] = true;
|
|
// level.early_level[ "invasion" ] = true;
|
|
// level.early_level[ "favela_escape" ] = true;
|
|
// level.early_level[ "arcadia" ] = true;
|
|
}
|
|
|
|
trigger_slide( trigger )
|
|
{
|
|
while ( 1 )
|
|
{
|
|
trigger waittill( "trigger", player );
|
|
player thread slideTriggerPlayerThink( trigger );
|
|
}
|
|
}
|
|
|
|
slideTriggerPlayerThink( trig )
|
|
{
|
|
if ( IsDefined( self.vehicle ) )
|
|
return;
|
|
|
|
if ( self IsSliding() )
|
|
return;
|
|
|
|
if ( isdefined( self.player_view ) )
|
|
return;
|
|
|
|
self endon( "death" );
|
|
|
|
if ( SoundExists( "SCN_cliffhanger_player_hillslide" ) )
|
|
self PlaySound( "SCN_cliffhanger_player_hillslide" );
|
|
|
|
self BeginSliding();
|
|
while ( 1 )
|
|
{
|
|
if ( !self IsTouching( trig ) )
|
|
break;
|
|
wait .05;
|
|
}
|
|
if ( IsDefined( level.end_slide_delay ) )
|
|
wait( level.end_slide_delay );
|
|
self EndSliding();
|
|
}
|
|
|
|
|
|
|
|
setup_simple_primary_lights()
|
|
{
|
|
flickering_lights = GetEntArray( "generic_flickering", "targetname" );
|
|
pulsing_lights = GetEntArray( "generic_pulsing", "targetname" );
|
|
double_strobe = GetEntArray( "generic_double_strobe", "targetname" );
|
|
|
|
array_thread( flickering_lights, maps\_lights::generic_flickering );
|
|
array_thread( pulsing_lights, maps\_lights::generic_pulsing );
|
|
array_thread( double_strobe, maps\_lights::generic_double_strobe );
|
|
}
|
|
|
|
weapon_ammo()
|
|
{
|
|
ents = GetEntArray();
|
|
for ( i = 0; i < ents.size; i++ )
|
|
{
|
|
if ( ( IsDefined( ents[ i ].classname ) ) && ( GetSubStr( ents[ i ].classname, 0, 7 ) == "weapon_" ) )
|
|
{
|
|
weap = ents[ i ];
|
|
|
|
weaponName = GetSubStr( weap.classname, 7 );
|
|
|
|
// if we're maxing everything out, do that and earlyout
|
|
if ( IsDefined( weap.script_ammo_max ) )
|
|
{
|
|
clip = WeaponClipSize( weaponName );
|
|
reserve = WeaponMaxAmmo( weaponName );
|
|
|
|
weap ItemWeaponSetAmmo( clip, reserve, clip, 0 ); // primary mode
|
|
|
|
altWeaponName = WeaponAltWeaponName( weaponName );
|
|
if( altWeaponName != "none" )
|
|
{
|
|
altclip = WeaponClipSize( altWeaponName );
|
|
altreserve = WeaponMaxAmmo( altWeaponName );
|
|
weap ItemWeaponSetAmmo( altclip, altreserve, altclip, 1 ); // altmode
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
change_ammo = false;
|
|
clip = undefined;
|
|
extra = undefined;
|
|
|
|
change_alt_ammo = false;
|
|
alt_clip = undefined;
|
|
alt_extra = undefined;
|
|
|
|
if ( IsDefined( weap.script_ammo_clip ) )
|
|
{
|
|
clip = weap.script_ammo_clip;
|
|
change_ammo = true;
|
|
}
|
|
if ( IsDefined( weap.script_ammo_extra ) )
|
|
{
|
|
extra = weap.script_ammo_extra;
|
|
change_ammo = true;
|
|
}
|
|
|
|
if ( IsDefined( weap.script_ammo_alt_clip ) )
|
|
{
|
|
alt_clip = weap.script_ammo_alt_clip;
|
|
change_alt_ammo = true;
|
|
}
|
|
if ( IsDefined( weap.script_ammo_alt_extra ) )
|
|
{
|
|
alt_extra = weap.script_ammo_alt_extra;
|
|
change_alt_ammo = true;
|
|
}
|
|
|
|
if ( change_ammo )
|
|
{
|
|
if ( !isdefined( clip ) )
|
|
AssertMsg( "weapon: " + weap.classname + " " + weap.origin + " sets script_ammo_extra but not script_ammo_clip" );
|
|
if ( !isdefined( extra ) )
|
|
AssertMsg( "weapon: " + weap.classname + " " + weap.origin + " sets script_ammo_clip but not script_ammo_extra" );
|
|
|
|
weap ItemWeaponSetAmmo( clip, extra );
|
|
}
|
|
|
|
if ( change_alt_ammo )
|
|
{
|
|
if ( !isdefined( alt_clip ) )
|
|
AssertMsg( "weapon: " + weap.classname + " " + weap.origin + " sets script_ammo_alt_extra but not script_ammo_alt_clip" );
|
|
if ( !isdefined( alt_extra ) )
|
|
AssertMsg( "weapon: " + weap.classname + " " + weap.origin + " sets script_ammo_alt_clip but not script_ammo_alt_extra" );
|
|
|
|
weap ItemWeaponSetAmmo( alt_clip, alt_extra, 0, 1 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
trigger_group()
|
|
{
|
|
self thread trigger_group_remove();
|
|
|
|
level endon( "trigger_group_" + self.script_trigger_group );
|
|
self waittill( "trigger" );
|
|
level notify( "trigger_group_" + self.script_trigger_group, self );
|
|
}
|
|
|
|
trigger_group_remove()
|
|
{
|
|
level waittill( "trigger_group_" + self.script_trigger_group, trigger );
|
|
if ( self != trigger )
|
|
self Delete();
|
|
}
|
|
|
|
/#
|
|
star( total )
|
|
{
|
|
PrintLn( " " );
|
|
PrintLn( " " );
|
|
PrintLn( " " );
|
|
for ( i = 0; i < total; i++ )
|
|
{
|
|
for ( z = total - i; z > 1; z-- )
|
|
Print( " " );
|
|
Print( " * " );
|
|
for ( z = 0; z < i; z++ )
|
|
Print( " ** " );
|
|
PrintLn( "" );
|
|
}
|
|
for ( i = total - 2; i > -1; i-- )
|
|
{
|
|
for ( z = total - i; z > 1; z-- )
|
|
Print( " " );
|
|
Print( " * " );
|
|
for ( z = 0; z < i; z++ )
|
|
Print( " ** " );
|
|
PrintLn( "" );
|
|
}
|
|
|
|
PrintLn( " " );
|
|
PrintLn( " " );
|
|
PrintLn( " " );
|
|
}
|
|
#/
|
|
|
|
|
|
exploder_load( trigger )
|
|
{
|
|
level endon( "killexplodertridgers" + trigger.script_exploder );
|
|
trigger waittill( "trigger" );
|
|
if ( IsDefined( trigger.script_chance ) && RandomFloat( 1 ) > trigger.script_chance )
|
|
{
|
|
if ( !trigger script_delay() )
|
|
wait 4;
|
|
|
|
level thread exploder_load( trigger );
|
|
return;
|
|
}
|
|
|
|
if ( !trigger script_delay() && IsDefined( trigger.script_exploder_delay ) )
|
|
{
|
|
wait( trigger.script_exploder_delay );
|
|
}
|
|
|
|
exploder( trigger.script_exploder );
|
|
level notify( "killexplodertridgers" + trigger.script_exploder );
|
|
}
|
|
|
|
shock_onpain()
|
|
{
|
|
PreCacheShellShock( "pain" );
|
|
PreCacheShellShock( "default" );
|
|
level.player endon( "death" );
|
|
SetDvarIfUninitialized( "blurpain", "on" );
|
|
|
|
while ( 1 )
|
|
{
|
|
oldhealth = level.player.health;
|
|
level.player waittill( "damage" );
|
|
if ( GetDvar( "blurpain" ) == "on" )
|
|
{
|
|
// PrintLn( "health dif was ", oldhealth - level.player.health );
|
|
if ( oldhealth - level.player.health < 129 )
|
|
{
|
|
// level.player ShellShock( "pain", 0.4 );
|
|
}
|
|
else
|
|
{
|
|
level.player ShellShock( "default", 5 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
usedAnimations()
|
|
{
|
|
SetDvar( "usedanim", "" );
|
|
while ( 1 )
|
|
{
|
|
if ( GetDvar( "usedanim" ) == "" )
|
|
{
|
|
wait( 2 );
|
|
continue;
|
|
}
|
|
|
|
animname = GetDvar( "usedanim" );
|
|
SetDvar( "usedanim", "" );
|
|
|
|
if ( !isdefined( level.completedAnims[ animname ] ) )
|
|
{
|
|
PrintLn( "^d -- -- No anims for ", animname, "^d -- -- -- -- -- - " );
|
|
continue;
|
|
}
|
|
|
|
PrintLn( "^d -- -- Used animations for ", animname, "^d: ", level.completedAnims[ animname ].size, "^d -- -- -- -- -- - " );
|
|
for ( i = 0; i < level.completedAnims[ animname ].size; i++ )
|
|
PrintLn( level.completedAnims[ animname ][ i ] );
|
|
}
|
|
}
|
|
|
|
|
|
badplace_think( badplace )
|
|
{
|
|
if ( !isdefined( level.badPlaces ) )
|
|
level.badPlaces = 0;
|
|
|
|
level.badPlaces++;
|
|
BadPlace_Cylinder( "badplace" + level.badPlaces, -1, badplace.origin, badplace.radius, 1024 );
|
|
}
|
|
|
|
setup_individual_exploder( ent )
|
|
{
|
|
exploder_num = ent.script_exploder;
|
|
if ( !isdefined( level.exploders[ exploder_num ] ) )
|
|
{
|
|
level.exploders[ exploder_num ] = [];
|
|
}
|
|
|
|
targetname = ent.targetname;
|
|
if ( !isdefined( targetname ) )
|
|
targetname = "";
|
|
|
|
level.exploders[ exploder_num ][ level.exploders[ exploder_num ].size ] = ent;
|
|
if ( exploder_model_starts_hidden( ent ) )
|
|
{
|
|
ent Hide();
|
|
return;
|
|
}
|
|
|
|
if ( exploder_model_is_damaged_model( ent ) )
|
|
{
|
|
ent Hide();
|
|
ent NotSolid();
|
|
if ( IsDefined( ent.script_disconnectpaths ) )
|
|
ent ConnectPaths();
|
|
return;
|
|
}
|
|
|
|
if ( exploder_model_is_chunk( ent ) )
|
|
{
|
|
ent Hide();
|
|
ent NotSolid();
|
|
if ( IsDefined( ent.spawnflags ) && ( ent.spawnflags & 1 ) )
|
|
ent ConnectPaths();
|
|
return;
|
|
}
|
|
}
|
|
|
|
setupExploders()
|
|
{
|
|
level.exploders = [];
|
|
|
|
// Hide exploder models.
|
|
ents = GetEntArray( "script_brushmodel", "classname" );
|
|
smodels = GetEntArray( "script_model", "classname" );
|
|
for ( i = 0; i < smodels.size; i++ )
|
|
ents[ ents.size ] = smodels[ i ];
|
|
|
|
foreach ( ent in ents )
|
|
{
|
|
if ( IsDefined( ent.script_prefab_exploder ) )
|
|
ent.script_exploder = ent.script_prefab_exploder;
|
|
|
|
if ( IsDefined( ent.script_exploder ) )
|
|
{
|
|
setup_individual_exploder( ent );
|
|
}
|
|
}
|
|
|
|
script_exploders = [];
|
|
|
|
potentialExploders = GetEntArray( "script_brushmodel", "classname" );
|
|
for ( i = 0; i < potentialExploders.size; i++ )
|
|
{
|
|
if ( IsDefined( potentialExploders[ i ].script_prefab_exploder ) )
|
|
potentialExploders[ i ].script_exploder = potentialExploders[ i ].script_prefab_exploder;
|
|
|
|
if ( IsDefined( potentialExploders[ i ].script_exploder ) )
|
|
script_exploders[ script_exploders.size ] = potentialExploders[ i ];
|
|
}
|
|
|
|
potentialExploders = GetEntArray( "script_model", "classname" );
|
|
for ( i = 0; i < potentialExploders.size; i++ )
|
|
{
|
|
if ( IsDefined( potentialExploders[ i ].script_prefab_exploder ) )
|
|
potentialExploders[ i ].script_exploder = potentialExploders[ i ].script_prefab_exploder;
|
|
|
|
if ( IsDefined( potentialExploders[ i ].script_exploder ) )
|
|
script_exploders[ script_exploders.size ] = potentialExploders[ i ];
|
|
}
|
|
|
|
potentialExploders = GetEntArray( "item_health", "classname" );
|
|
for ( i = 0; i < potentialExploders.size; i++ )
|
|
{
|
|
if ( IsDefined( potentialExploders[ i ].script_prefab_exploder ) )
|
|
potentialExploders[ i ].script_exploder = potentialExploders[ i ].script_prefab_exploder;
|
|
|
|
if ( IsDefined( potentialExploders[ i ].script_exploder ) )
|
|
script_exploders[ script_exploders.size ] = potentialExploders[ i ];
|
|
}
|
|
|
|
if ( !isdefined( level.createFXent ) )
|
|
level.createFXent = [];
|
|
|
|
acceptableTargetnames = [];
|
|
acceptableTargetnames[ "exploderchunk visible" ] = true;
|
|
acceptableTargetnames[ "exploderchunk" ] = true;
|
|
acceptableTargetnames[ "exploder" ] = true;
|
|
|
|
thread setup_flag_exploders();
|
|
|
|
for ( i = 0; i < script_exploders.size; i++ )
|
|
{
|
|
exploder = script_exploders[ i ];
|
|
ent = createExploder( exploder.script_fxid );
|
|
ent.v = [];
|
|
ent.v[ "origin" ] = exploder.origin;
|
|
ent.v[ "angles" ] = exploder.angles;
|
|
ent.v[ "delay" ] = exploder.script_delay;
|
|
ent.v[ "delay_post" ] = exploder.script_delay_post;
|
|
ent.v[ "firefx" ] = exploder.script_firefx;
|
|
ent.v[ "firefxdelay" ] = exploder.script_firefxdelay;
|
|
ent.v[ "firefxsound" ] = exploder.script_firefxsound;
|
|
ent.v[ "firefxtimeout" ] = exploder.script_firefxtimeout;
|
|
ent.v[ "earthquake" ] = exploder.script_earthquake;
|
|
ent.v[ "rumble" ] = exploder.script_rumble;
|
|
ent.v[ "damage" ] = exploder.script_damage;
|
|
ent.v[ "damage_radius" ] = exploder.script_radius;
|
|
ent.v[ "soundalias" ] = exploder.script_soundalias;
|
|
ent.v[ "repeat" ] = exploder.script_repeat;
|
|
ent.v[ "delay_min" ] = exploder.script_delay_min;
|
|
ent.v[ "delay_max" ] = exploder.script_delay_max;
|
|
ent.v[ "target" ] = exploder.target;
|
|
ent.v[ "ender" ] = exploder.script_ender;
|
|
ent.v[ "physics" ] = exploder.script_physics;
|
|
ent.v[ "type" ] = "exploder";
|
|
// ent.v[ "worldfx" ] = true;
|
|
if ( !isdefined( exploder.script_fxid ) )
|
|
ent.v[ "fxid" ] = "No FX";
|
|
else
|
|
ent.v[ "fxid" ] = exploder.script_fxid;
|
|
ent.v[ "exploder" ] = exploder.script_exploder;
|
|
AssertEx( IsDefined( exploder.script_exploder ), "Exploder at origin " + exploder.origin + " has no script_exploder" );
|
|
|
|
if ( !isdefined( ent.v[ "delay" ] ) )
|
|
ent.v[ "delay" ] = 0;
|
|
|
|
|
|
|
|
if ( IsDefined( exploder.target ) )
|
|
{
|
|
get_ent = GetEntArray( ent.v[ "target" ], "targetname" )[ 0 ];
|
|
if ( IsDefined( get_ent ) )
|
|
{
|
|
org = get_ent.origin;
|
|
ent.v[ "angles" ] = VectorToAngles( org - ent.v[ "origin" ] );
|
|
}
|
|
else
|
|
{
|
|
get_ent = get_target_ent( ent.v[ "target" ] );
|
|
if ( IsDefined( get_ent ) )
|
|
{
|
|
org = get_ent.origin;
|
|
ent.v[ "angles" ] = VectorToAngles( org - ent.v[ "origin" ] );
|
|
}
|
|
}
|
|
// forward = AnglesToForward( angles );
|
|
// up = AnglesToUp( angles );
|
|
}
|
|
|
|
// this basically determines if its a brush / model exploder or not
|
|
if ( exploder.code_classname == "script_brushmodel" || IsDefined( exploder.model ) )
|
|
{
|
|
ent.model = exploder;
|
|
ent.model.disconnect_paths = exploder.script_disconnectpaths;
|
|
}
|
|
|
|
if ( IsDefined( exploder.targetname ) && IsDefined( acceptableTargetnames[ exploder.targetname ] ) )
|
|
ent.v[ "exploder_type" ] = exploder.targetname;
|
|
else
|
|
ent.v[ "exploder_type" ] = "normal";
|
|
|
|
ent common_scripts\_createfx::post_entity_creation_function();
|
|
}
|
|
}
|
|
|
|
setup_flag_exploders()
|
|
{
|
|
// createfx has to do 2 waittillframeends so we have to do 3 to make sure this comes after
|
|
// createfx is all done setting up. Who will raise the gambit to 4?
|
|
waittillframeend;
|
|
waittillframeend;
|
|
waittillframeend;
|
|
exploder_flags = [];
|
|
|
|
foreach ( ent in level.createFXent )
|
|
{
|
|
if ( ent.v[ "type" ] != "exploder" )
|
|
continue;
|
|
theFlag = ent.v[ "flag" ];
|
|
|
|
if ( !isdefined( theFlag ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( theFlag == "nil" )
|
|
{
|
|
ent.v[ "flag" ] = undefined;
|
|
}
|
|
|
|
exploder_flags[ theFlag ] = true;
|
|
}
|
|
|
|
foreach ( msg, _ in exploder_flags )
|
|
{
|
|
thread exploder_flag_wait( msg );
|
|
}
|
|
}
|
|
|
|
exploder_flag_wait( msg )
|
|
{
|
|
if ( !flag_exist( msg ) )
|
|
flag_init( msg );
|
|
flag_wait( msg );
|
|
|
|
foreach ( ent in level.createFXent )
|
|
{
|
|
if ( ent.v[ "type" ] != "exploder" )
|
|
continue;
|
|
theFlag = ent.v[ "flag" ];
|
|
|
|
if ( !isdefined( theFlag ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( theFlag != msg )
|
|
continue;
|
|
ent activate_individual_exploder();
|
|
}
|
|
}
|
|
|
|
|
|
nearAIRushesPlayer()
|
|
{
|
|
if ( IsAlive( level.enemySeekingPlayer ) )
|
|
return;
|
|
enemy = get_closest_ai( level.player.origin, "bad_guys" );
|
|
if ( !isdefined( enemy ) )
|
|
return;
|
|
|
|
if ( Distance( enemy.origin, level.player.origin ) > 400 )
|
|
return;
|
|
|
|
level.enemySeekingPlayer = enemy;
|
|
enemy SetGoalEntity( level.player );
|
|
enemy.goalradius = 512;
|
|
|
|
}
|
|
|
|
|
|
playerDamageRumble()
|
|
{
|
|
while ( true )
|
|
{
|
|
self waittill( "damage", amount );
|
|
|
|
if ( IsDefined( self.specialDamage ) )
|
|
continue;
|
|
|
|
self PlayRumbleOnEntity( "damage_heavy" );
|
|
}
|
|
}
|
|
|
|
playerDamageShellshock()
|
|
{
|
|
while ( true )
|
|
{
|
|
level.player waittill( "damage", damage, attacker, direction_vec, point, cause );
|
|
|
|
if ( cause == "MOD_EXPLOSIVE" ||
|
|
cause == "MOD_GRENADE" ||
|
|
cause == "MOD_GRENADE_SPLASH" ||
|
|
cause == "MOD_PROJECTILE" ||
|
|
cause == "MOD_PROJECTILE_SPLASH" )
|
|
{
|
|
time = 0;
|
|
|
|
multiplier = level.player.maxhealth / 100;
|
|
scaled_damage = damage * multiplier;
|
|
|
|
if ( scaled_damage >= 90 )
|
|
time = 4;
|
|
else if ( scaled_damage >= 50 )
|
|
time = 3;
|
|
else if ( scaled_damage >= 25 )
|
|
time = 2;
|
|
else if ( scaled_damage > 10 )
|
|
time = 1;
|
|
|
|
if ( time )
|
|
level.player ShellShock( "default", time );
|
|
}
|
|
}
|
|
}
|
|
|
|
map_is_early_in_the_game()
|
|
{
|
|
/#
|
|
if ( IsDefined( level.testmap ) )
|
|
return true;
|
|
#/
|
|
|
|
if ( IsDefined( level.early_level[ level.script ] ) )
|
|
return level.early_level[ level.script ];
|
|
else
|
|
return false;
|
|
}
|
|
|
|
player_throwgrenade_timer()
|
|
{
|
|
self endon( "death" );
|
|
self.lastgrenadetime = 0;
|
|
while ( 1 )
|
|
{
|
|
while ( ! self IsThrowingGrenade() )
|
|
wait .05;
|
|
self.lastgrenadetime = GetTime();
|
|
while ( self IsThrowingGrenade() )
|
|
wait .05;
|
|
}
|
|
}
|
|
|
|
player_special_death_hint()
|
|
{
|
|
// Special Ops requires a different style of tracking and custom language in the hints.
|
|
// Safer to branch cleanly and track separately from SP.
|
|
if ( is_specialop() )
|
|
return;
|
|
|
|
if ( IsAlive( level.player ) )
|
|
thread maps\_quotes::setDeadQuote();
|
|
|
|
level.player thread player_throwgrenade_timer();
|
|
|
|
level.player waittill( "death", attacker, cause, weaponName );
|
|
|
|
if ( cause != "MOD_GRENADE" && cause != "MOD_GRENADE_SPLASH" && cause != "MOD_SUICIDE" && cause != "MOD_EXPLOSIVE" )
|
|
return;
|
|
|
|
if ( level.gameskill >= 2 )
|
|
{
|
|
// less death hinting on hard / fu
|
|
if ( !map_is_early_in_the_game() )
|
|
return;
|
|
}
|
|
|
|
if ( cause == "MOD_SUICIDE" )
|
|
{
|
|
if ( ( level.player.lastgrenadetime - GetTime() ) > 3.5 * 1000 )
|
|
return;// magic number copied from fraggrenade asset.
|
|
level notify( "new_quote_string" );
|
|
// You died holding a grenade for too long.
|
|
// Holding ^3[{+frag}]^7 allows you to cook off live grenades.
|
|
thread grenade_death_text_hudelement( &"SCRIPT_GRENADE_SUICIDE_LINE1", &"SCRIPT_GRENADE_SUICIDE_LINE2" );
|
|
return;
|
|
}
|
|
|
|
if ( cause == "MOD_EXPLOSIVE" )
|
|
{
|
|
if ( level.player destructible_death( attacker ) )
|
|
return;
|
|
|
|
|
|
if ( level.player exploding_barrel_death_af_chase( attacker ) )
|
|
return;
|
|
|
|
if ( level.player vehicle_death( attacker ) )
|
|
return;
|
|
|
|
if ( level.player exploding_barrel_death( attacker ) )
|
|
return;
|
|
}
|
|
|
|
if ( cause == "MOD_GRENADE" || cause == "MOD_GRENADE_SPLASH" )
|
|
{
|
|
if ( IsDefined( weaponName ) && !IsWeaponDetonationTimed( weaponName ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
level notify( "new_quote_string" );
|
|
// Would putting the content of the string here be so hard?
|
|
SetDvar( "ui_deadquote", "@SCRIPT_GRENADE_DEATH" );
|
|
thread grenade_death_indicator_hudelement();
|
|
return;
|
|
}
|
|
}
|
|
|
|
vehicle_death( attacker )
|
|
{
|
|
if ( !isdefined( attacker ) )
|
|
return false;
|
|
|
|
if ( attacker.code_classname != "script_vehicle" )
|
|
return false;
|
|
|
|
level notify( "new_quote_string" );
|
|
|
|
// You were killed by an exploding vehicle. Vehicles on fire are likely to explode.
|
|
SetDvar( "ui_deadquote", "@SCRIPT_EXPLODING_VEHICLE_DEATH" );
|
|
thread special_death_indicator_hudelement( "hud_burningcaricon", 96, 96 );
|
|
|
|
return true;
|
|
}
|
|
|
|
destructible_death( attacker )
|
|
{
|
|
if ( !isdefined( attacker ) )
|
|
return false;
|
|
|
|
if ( !isdefined( attacker.destructible_type ) )
|
|
return false;
|
|
|
|
level notify( "new_quote_string" );
|
|
|
|
if ( IsSubStr( attacker.destructible_type, "vehicle" ) )
|
|
{
|
|
// You were killed by an exploding vehicle. Vehicles on fire are likely to explode.
|
|
SetDvar( "ui_deadquote", "@SCRIPT_EXPLODING_VEHICLE_DEATH" );
|
|
thread special_death_indicator_hudelement( "hud_burningcaricon", 96, 96 );
|
|
}
|
|
else
|
|
{
|
|
// You were killed by an explosion.\nSome burning objects can explode.
|
|
SetDvar( "ui_deadquote", "@SCRIPT_EXPLODING_DESTRUCTIBLE_DEATH" );
|
|
thread special_death_indicator_hudelement( "hud_destructibledeathicon", 96, 96 );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
exploding_barrel_death_af_chase( attacker )
|
|
{
|
|
// paranoid.. can't imagine how this would break the game but just in case.
|
|
// just reordering things so the that we get the exploding barrel death message before the vehilce one.
|
|
// see bugzilla 110565
|
|
// next game maybe just put this before the vehicle death.
|
|
if( level.script != "af_chase" )
|
|
return false;
|
|
return exploding_barrel_death( attacker );
|
|
}
|
|
|
|
exploding_barrel_death( attacker )
|
|
{
|
|
// check if the death was caused by a barrel
|
|
// have to check time and location against the last explosion because the attacker isn't the
|
|
// barrel because the ent that damaged the barrel is passed through as the attacker instead
|
|
if ( IsDefined( level.lastExplodingBarrel ) )
|
|
{
|
|
// killed the same frame a barrel exploded
|
|
if ( GetTime() != level.lastExplodingBarrel[ "time" ] )
|
|
return false;
|
|
|
|
// within the blast radius of the barrel that exploded
|
|
d = Distance( self.origin, level.lastExplodingBarrel[ "origin" ] );
|
|
if ( d > level.lastExplodingBarrel[ "radius" ] )
|
|
return false;
|
|
|
|
// must have been killed by that barrel
|
|
level notify( "new_quote_string" );
|
|
// You were killed by an exploding barrel. Red barrels will explode when shot.
|
|
SetDvar( "ui_deadquote", "@SCRIPT_EXPLODING_BARREL_DEATH" );
|
|
thread special_death_indicator_hudelement( "hud_burningbarrelicon", 64, 64 );
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
grenade_death_text_hudelement( textLine1, textLine2 )
|
|
{
|
|
level.player.failingMission = true;
|
|
|
|
SetDvar( "ui_deadquote", "" );
|
|
|
|
wait( 1.5 );
|
|
|
|
fontElem = NewHudElem();
|
|
fontElem.elemType = "font";
|
|
fontElem.font = "default";
|
|
fontElem.fontscale = 1.5;
|
|
fontElem.x = 0;
|
|
fontElem.y = -30;
|
|
fontElem.alignX = "center";
|
|
fontElem.alignY = "middle";
|
|
fontElem.horzAlign = "center";
|
|
fontElem.vertAlign = "middle";
|
|
fontElem SetText( textLine1 );
|
|
fontElem.foreground = true;
|
|
fontElem.alpha = 0;
|
|
fontElem FadeOverTime( 1 );
|
|
fontElem.alpha = 1;
|
|
|
|
if ( IsDefined( textLine2 ) )
|
|
{
|
|
fontElem = NewHudElem();
|
|
fontElem.elemType = "font";
|
|
fontElem.font = "default";
|
|
fontElem.fontscale = 1.5;
|
|
fontElem.x = 0;
|
|
fontElem.y = -25 + level.fontHeight * fontElem.fontscale;
|
|
fontElem.alignX = "center";
|
|
fontElem.alignY = "middle";
|
|
fontElem.horzAlign = "center";
|
|
fontElem.vertAlign = "middle";
|
|
fontElem SetText( textLine2 );
|
|
fontElem.foreground = true;
|
|
fontElem.alpha = 0;
|
|
fontElem FadeOverTime( 1 );
|
|
fontElem.alpha = 1;
|
|
}
|
|
}
|
|
|
|
grenade_death_indicator_hudelement()
|
|
{
|
|
wait( 1.5 );
|
|
overlay = NewHudElem();
|
|
overlay.x = 0;
|
|
overlay.y = 68;
|
|
overlay SetShader( "hud_grenadeicon", 50, 50 );
|
|
overlay.alignX = "center";
|
|
overlay.alignY = "middle";
|
|
overlay.horzAlign = "center";
|
|
overlay.vertAlign = "middle";
|
|
overlay.foreground = true;
|
|
overlay.alpha = 0;
|
|
overlay FadeOverTime( 1 );
|
|
overlay.alpha = 1;
|
|
|
|
overlay = NewHudElem();
|
|
overlay.x = 0;
|
|
overlay.y = 25;
|
|
overlay SetShader( "hud_grenadepointer", 50, 25 );
|
|
overlay.alignX = "center";
|
|
overlay.alignY = "middle";
|
|
overlay.horzAlign = "center";
|
|
overlay.vertAlign = "middle";
|
|
overlay.foreground = true;
|
|
overlay.alpha = 0;
|
|
overlay FadeOverTime( 1 );
|
|
overlay.alpha = 1;
|
|
}
|
|
|
|
special_death_indicator_hudelement( shader, iWidth, iHeight, fDelay )
|
|
{
|
|
if ( !isdefined( fDelay ) )
|
|
fDelay = 1.5;
|
|
wait fDelay;
|
|
overlay = NewHudElem();
|
|
overlay.x = 0;
|
|
overlay.y = 40;
|
|
overlay SetShader( shader, iWidth, iHeight );
|
|
overlay.alignX = "center";
|
|
overlay.alignY = "middle";
|
|
overlay.horzAlign = "center";
|
|
overlay.vertAlign = "middle";
|
|
overlay.foreground = true;
|
|
overlay.alpha = 0;
|
|
overlay FadeOverTime( 1 );
|
|
overlay.alpha = 1;
|
|
}
|
|
|
|
triggered_playerseek( trig )
|
|
{
|
|
groupNum = trig.script_triggered_playerseek;
|
|
trig waittill( "trigger" );
|
|
|
|
ai = GetAIArray();
|
|
for ( i = 0; i < ai.size; i++ )
|
|
{
|
|
if ( !isAlive( ai[ i ] ) )
|
|
continue;
|
|
if ( ( IsDefined( ai[ i ].script_triggered_playerseek ) ) && ( ai[ i ].script_triggered_playerseek == groupNum ) )
|
|
{
|
|
ai[ i ].goalradius = 800;
|
|
ai[ i ] SetGoalEntity( level.player );
|
|
level thread maps\_spawner::delayed_player_seek_think( ai[ i ] );
|
|
}
|
|
}
|
|
}
|
|
|
|
traverseThink()
|
|
{
|
|
ent = GetEnt( self.target, "targetname" );
|
|
self.traverse_height = ent.origin[ 2 ];
|
|
ent Delete();
|
|
}
|
|
|
|
/#
|
|
deprecatedTraverseThink()
|
|
{
|
|
wait .05;
|
|
PrintLn( "^1Warning: deprecated traverse used in this map somewhere around " + self.origin );
|
|
if ( GetDvarInt( "scr_traverse_debug" ) )
|
|
{
|
|
while ( 1 )
|
|
{
|
|
Print3d( self.origin, "deprecated traverse!" );
|
|
wait .05;
|
|
}
|
|
}
|
|
}
|
|
#/
|
|
|
|
pianoDamageThink()
|
|
{
|
|
org = self GetOrigin();
|
|
//
|
|
// self SetHintString( &"SCRIPT_PLATFORM_PIANO" );
|
|
note[ 0 ] = "large";
|
|
note[ 1 ] = "small";
|
|
for ( ;; )
|
|
{
|
|
self waittill( "trigger" );
|
|
thread play_sound_in_space( "bullet_" + random( note ) + "_piano", org );
|
|
}
|
|
}
|
|
|
|
pianoThink()
|
|
{
|
|
org = self GetOrigin();
|
|
note = "piano_" + self.script_noteworthy;
|
|
//
|
|
self SetHintString( &"SCRIPT_PLATFORM_PIANO" );
|
|
for ( ;; )
|
|
{
|
|
self waittill( "trigger" );
|
|
thread play_sound_in_space( note, org );
|
|
}
|
|
}
|
|
|
|
|
|
bcTrigger( trigger )
|
|
{
|
|
realTrigger = undefined;
|
|
|
|
// see if this targets an auxiliary trigger for advanced usage
|
|
if ( IsDefined( trigger.target ) )
|
|
{
|
|
targetEnts = GetEntArray( trigger.target, "targetname" );
|
|
|
|
if ( IsSubStr( targetEnts[ 0 ].classname, "trigger" ) )
|
|
{
|
|
realTrigger = targetEnts[ 0 ];
|
|
}
|
|
}
|
|
|
|
// if we target an auxiliary trigger, that one kicks off the custom battlechatter event
|
|
if ( IsDefined( realTrigger ) )
|
|
{
|
|
realTrigger waittill( "trigger", other );
|
|
}
|
|
else
|
|
{
|
|
trigger waittill( "trigger", other );
|
|
}
|
|
|
|
soldier = undefined;
|
|
|
|
// for advanced usage: target an auxiliary trigger that kicks off the battlechatter event, but only
|
|
// if the player is touching the trigger that targets it.
|
|
if ( IsDefined( realTrigger ) )
|
|
{
|
|
// enemy touched trigger, have a friendly tell the player about it
|
|
if ( ( other.team != level.player.team ) && level.player IsTouching( trigger ) )
|
|
{
|
|
soldier = level.player animscripts\battlechatter::getClosestFriendlySpeaker( "custom" );
|
|
}
|
|
// friendly touched auxiliary trigger, have the enemy AI chatter about it
|
|
else if ( other.team == level.player.team )
|
|
{
|
|
enemyTeam = "axis";
|
|
if ( level.player.team == "axis" )
|
|
{
|
|
enemyTeam = "allies";
|
|
}
|
|
|
|
soldiers = animscripts\battlechatter::getSpeakers( "custom", enemyTeam );
|
|
// for some reason, get_array_of_farthest returns the closest at index 0
|
|
soldiers = get_array_of_farthest( level.player.origin, soldiers );
|
|
|
|
foreach ( guy in soldiers )
|
|
{
|
|
if ( guy IsTouching( trigger ) )
|
|
{
|
|
soldier = guy;
|
|
|
|
if ( bcTrigger_validate_distance( guy.origin ) )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// otherwise we're just using one trigger
|
|
else if ( IsPlayer( other ) )
|
|
{
|
|
soldier = other animscripts\battlechatter::getClosestFriendlySpeaker( "custom" );
|
|
}
|
|
else
|
|
{
|
|
soldier = other;
|
|
}
|
|
|
|
if ( !IsDefined( soldier ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( !bcTrigger_validate_distance( soldier.origin ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
success = soldier custom_battlechatter( trigger.script_bctrigger );
|
|
|
|
// if the chatter didn't play successfully, rethread the function on the trigger
|
|
if ( !success )
|
|
{
|
|
level delayThread( 0.25, ::bcTrigger, trigger );
|
|
}
|
|
else
|
|
{
|
|
trigger notify( "custom_battlechatter_done" );
|
|
}
|
|
}
|
|
|
|
bcTrigger_validate_distance( speakerOrigin )
|
|
{
|
|
if ( Distance( speakerOrigin, level.player GetOrigin() ) <= 512 )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
waterThink()
|
|
{
|
|
Assert( IsDefined( self.target ) );
|
|
targeted = GetEnt( self.target, "targetname" );
|
|
Assert( IsDefined( targeted ) );
|
|
waterHeight = targeted.origin[ 2 ];
|
|
targeted = undefined;
|
|
|
|
level.depth_allow_prone = 8;
|
|
level.depth_allow_crouch = 33;
|
|
level.depth_allow_stand = 50;
|
|
|
|
wasInWater = false;
|
|
//prof_begin( "water_stance_controller" );
|
|
|
|
for ( ;; )
|
|
{
|
|
wait 0.05;
|
|
// restore all defaults
|
|
if ( !level.player.inWater && wasInWater )
|
|
{
|
|
wasInWater = false;
|
|
level.player AllowProne( true );
|
|
level.player AllowCrouch( true );
|
|
level.player AllowStand( true );
|
|
thread waterThink_rampSpeed( level.default_run_speed );
|
|
}
|
|
|
|
// wait until in water
|
|
self waittill( "trigger" );
|
|
level.player.inWater = true;
|
|
wasInWater = true;
|
|
while ( level.player IsTouching( self ) )
|
|
{
|
|
level.player.inWater = true;
|
|
playerOrg = level.player GetOrigin();
|
|
d = ( playerOrg[ 2 ] - waterHeight );
|
|
if ( d > 0 )
|
|
break;
|
|
|
|
// slow the players movement based on how deep it is
|
|
newSpeed = Int( level.default_run_speed - abs( d * 5 ) );
|
|
if ( newSpeed < 50 )
|
|
newSpeed = 50;
|
|
Assert( newSpeed <= 190 );
|
|
thread waterThink_rampSpeed( newSpeed );
|
|
|
|
// controll the allowed stances in this water height
|
|
if ( abs( d ) > level.depth_allow_crouch )
|
|
level.player AllowCrouch( false );
|
|
else
|
|
level.player AllowCrouch( true );
|
|
|
|
if ( abs( d ) > level.depth_allow_prone )
|
|
level.player AllowProne( false );
|
|
else
|
|
level.player AllowProne( true );
|
|
|
|
wait 0.5;
|
|
}
|
|
level.player.inWater = false;
|
|
wait 0.05;
|
|
}
|
|
|
|
//prof_end( "water_stance_controller" );
|
|
}
|
|
|
|
waterThink_rampSpeed( newSpeed )
|
|
{
|
|
level notify( "ramping_water_movement_speed" );
|
|
level endon( "ramping_water_movement_speed" );
|
|
|
|
rampTime = 0.5;
|
|
numFrames = Int( rampTime * 20 );
|
|
|
|
currentSpeed = GetDvarInt( "g_speed" );
|
|
|
|
qSlower = false;
|
|
if ( newSpeed < currentSpeed )
|
|
qSlower = true;
|
|
|
|
speedDifference = Int( abs( currentSpeed - newSpeed ) );
|
|
speedStepSize = Int( speedDifference / numFrames );
|
|
|
|
for ( i = 0; i < numFrames; i++ )
|
|
{
|
|
currentSpeed = GetDvarInt( "g_speed" );
|
|
if ( qSlower )
|
|
SetSavedDvar( "g_speed", ( currentSpeed - speedStepSize ) );
|
|
else
|
|
SetSavedDvar( "g_speed", ( currentSpeed + speedStepSize ) );
|
|
wait 0.05;
|
|
}
|
|
SetSavedDvar( "g_speed", newSpeed );
|
|
}
|
|
|
|
|
|
|
|
massNodeInitFunctions()
|
|
{
|
|
nodes = GetAllNodes();
|
|
|
|
thread maps\_mgturret::auto_mgTurretLink( nodes );
|
|
thread maps\_mgturret::saw_mgTurretLink( nodes );
|
|
thread maps\_colors::init_color_grouping( nodes );
|
|
}
|
|
|
|
|
|
/*
|
|
* * * * * * * * * *
|
|
|
|
TRIGGER_UNLOCK
|
|
|
|
* * * * * * * * * *
|
|
*/
|
|
|
|
trigger_unlock( trigger )
|
|
{
|
|
// trigger unlocks unlock another trigger. When that trigger is hit, all unlocked triggers relock
|
|
// trigger_unlocks with the same script_noteworthy relock the same triggers
|
|
|
|
noteworthy = "not_set";
|
|
if ( IsDefined( trigger.script_noteworthy ) )
|
|
noteworthy = trigger.script_noteworthy;
|
|
|
|
target_triggers = GetEntArray( trigger.target, "targetname" );
|
|
|
|
trigger thread trigger_unlock_death( trigger.target );
|
|
|
|
for ( ;; )
|
|
{
|
|
array_thread( target_triggers, ::trigger_off );
|
|
trigger waittill( "trigger" );
|
|
array_thread( target_triggers, ::trigger_on );
|
|
|
|
wait_for_an_unlocked_trigger( target_triggers, noteworthy );
|
|
|
|
array_notify( target_triggers, "relock" );
|
|
}
|
|
}
|
|
|
|
trigger_unlock_death( target )
|
|
{
|
|
self waittill( "death" );
|
|
target_triggers = GetEntArray( target, "targetname" );
|
|
array_thread( target_triggers, ::trigger_off );
|
|
}
|
|
|
|
wait_for_an_unlocked_trigger( triggers, noteworthy )
|
|
{
|
|
level endon( "unlocked_trigger_hit" + noteworthy );
|
|
ent = SpawnStruct();
|
|
for ( i = 0; i < triggers.size; i++ )
|
|
{
|
|
triggers[ i ] thread report_trigger( ent, noteworthy );
|
|
}
|
|
ent waittill( "trigger" );
|
|
level notify( "unlocked_trigger_hit" + noteworthy );
|
|
}
|
|
|
|
report_trigger( ent, noteworthy )
|
|
{
|
|
self endon( "relock" );
|
|
level endon( "unlocked_trigger_hit" + noteworthy );
|
|
self waittill( "trigger" );
|
|
ent notify( "trigger" );
|
|
}
|
|
|
|
/*
|
|
* * * * * * * * * *
|
|
|
|
TRIGGER_LOOKAT
|
|
|
|
* * * * * * * * * *
|
|
*/
|
|
|
|
get_trigger_targs()
|
|
{
|
|
triggers = [];
|
|
target_origin = undefined;// was self.origin
|
|
if ( IsDefined( self.target ) )
|
|
{
|
|
targets = GetEntArray( self.target, "targetname" );
|
|
orgs = [];
|
|
foreach ( target in targets )
|
|
{
|
|
if ( target.classname == "script_origin" )
|
|
orgs[ orgs.size ] = target;
|
|
if ( IsSubStr( target.classname, "trigger" ) )
|
|
triggers[ triggers.size ] = target;
|
|
}
|
|
|
|
targets = getstructarray( self.target, "targetname" );
|
|
|
|
foreach ( target in targets )
|
|
{
|
|
orgs[ orgs.size ] = target;
|
|
}
|
|
|
|
AssertEx( orgs.size < 2, "Trigger at " + self.origin + " targets multiple script origins" );
|
|
if ( orgs.size == 1 )
|
|
{
|
|
org = orgs[ 0 ];
|
|
target_origin = org.origin;
|
|
if ( IsDefined( org.code_classname ) )
|
|
org Delete();
|
|
}
|
|
}
|
|
|
|
/#
|
|
if ( IsDefined( self.targetname ) )
|
|
AssertEx( IsDefined( target_origin ), self.targetname + " at " + self.origin + " has no target origin." );
|
|
else
|
|
AssertEx( IsDefined( target_origin ), self.classname + " at " + self.origin + " has no target origin." );
|
|
#/
|
|
|
|
array = [];
|
|
array[ "triggers" ] = triggers;
|
|
array[ "target_origin" ] = target_origin;
|
|
return array;
|
|
}
|
|
|
|
trigger_lookat( trigger )
|
|
{
|
|
// ends when the flag is hit
|
|
trigger_lookat_think( trigger, true );
|
|
}
|
|
|
|
trigger_looking( trigger )
|
|
{
|
|
// flag is only set while the thing is being looked at
|
|
trigger_lookat_think( trigger, false );
|
|
}
|
|
|
|
trigger_visionset_change( trigger )
|
|
{
|
|
AssertEx( IsDefined( trigger.script_visionset ), "trigger_multiple_visionset at " + trigger.origin + " has no script_visionset." );
|
|
transition = 3;
|
|
|
|
if ( IsDefined( trigger.script_delay ) )
|
|
transition = trigger.script_delay;
|
|
|
|
while ( 1 )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
|
|
set_vision_set( trigger.script_visionset, transition );
|
|
wait transition;
|
|
}
|
|
}
|
|
|
|
trigger_lookat_think( trigger, endOnFlag )
|
|
{
|
|
success_dot = 0.78;
|
|
if ( IsDefined( trigger.script_dot ) )
|
|
{
|
|
success_dot = trigger.script_dot;
|
|
AssertEx( success_dot <= 1, "Script_dot should be between 0 and 1" );
|
|
}
|
|
|
|
array = trigger get_trigger_targs();
|
|
triggers = array[ "triggers" ];
|
|
target_origin = array[ "target_origin" ];
|
|
|
|
has_flag = IsDefined( trigger.script_flag ) || IsDefined( trigger.script_noteworthy );
|
|
flagName = undefined;
|
|
|
|
if ( has_flag )
|
|
{
|
|
flagName = trigger get_trigger_flag();
|
|
if ( !isdefined( level.flag[ flagName ] ) )
|
|
flag_init( flagName );
|
|
}
|
|
else
|
|
{
|
|
if ( !triggers.size )
|
|
AssertEx( IsDefined( trigger.script_flag ) || IsDefined( trigger.script_noteworthy ), "Trigger_lookat at " + trigger.origin + " has no script_flag! The script_flag is used as a flag that gets set when the trigger is activated." );
|
|
}
|
|
|
|
if ( endOnFlag && has_flag )
|
|
{
|
|
level endon( flagName );
|
|
}
|
|
|
|
trigger endon( "death" );
|
|
do_sighttrace = false;
|
|
|
|
if ( IsDefined( trigger.script_parameters ) )
|
|
{
|
|
do_sighttrace = !issubstr( "no_sight", trigger.script_parameters );
|
|
}
|
|
|
|
// touching_trigger = [];
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( has_flag )
|
|
flag_clear( flagName );
|
|
|
|
trigger waittill( "trigger", other );
|
|
|
|
AssertEx( IsPlayer( other ), "trigger_lookat currently only supports looking from the player" );
|
|
touching_trigger = [];
|
|
|
|
while ( other IsTouching( trigger ) )
|
|
{
|
|
if ( do_sighttrace && !sightTracePassed( other GetEye(), target_origin, false, undefined ) )
|
|
{
|
|
if ( has_flag )
|
|
flag_clear( flagName );
|
|
wait( 0.5 );
|
|
continue;
|
|
}
|
|
|
|
normal = VectorNormalize( target_origin - other.origin );
|
|
player_angles = other GetPlayerAngles();
|
|
player_forward = AnglesToForward( player_angles );
|
|
|
|
// angles = VectorToAngles( target_origin - other.origin );
|
|
// forward = AnglesToForward( angles );
|
|
// draw_arrow( level.player.origin, level.player.origin + vector_multiply( forward, 150 ), ( 1, 0.5, 0 ) );
|
|
// draw_arrow( level.player.origin, level.player.origin + vector_multiply( player_forward, 150 ), ( 0, 0.5, 1 ) );
|
|
|
|
dot = VectorDot( player_forward, normal );
|
|
if ( dot >= success_dot )
|
|
{
|
|
// notify targetted triggers as well
|
|
array_thread( triggers, ::send_notify, "trigger" );
|
|
|
|
if ( has_flag )
|
|
flag_set( flagName, other );
|
|
|
|
if ( endOnFlag )
|
|
return;
|
|
wait( 2 );
|
|
}
|
|
else
|
|
{
|
|
if ( has_flag )
|
|
flag_clear( flagName );
|
|
}
|
|
|
|
if ( do_sighttrace )
|
|
wait( 0.5 );
|
|
else
|
|
wait 0.05;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* * * * * * * * * *
|
|
|
|
TRIGGER_CANSEE
|
|
|
|
* * * * * * * * * *
|
|
*/
|
|
|
|
trigger_cansee( trigger )
|
|
{
|
|
triggers = [];
|
|
target_origin = undefined;// was trigger.origin
|
|
|
|
array = trigger get_trigger_targs();
|
|
triggers = array[ "triggers" ];
|
|
target_origin = array[ "target_origin" ];
|
|
|
|
has_flag = IsDefined( trigger.script_flag ) || IsDefined( trigger.script_noteworthy );
|
|
flagName = undefined;
|
|
|
|
if ( has_flag )
|
|
{
|
|
flagName = trigger get_trigger_flag();
|
|
if ( !isdefined( level.flag[ flagName ] ) )
|
|
flag_init( flagName );
|
|
}
|
|
else
|
|
{
|
|
if ( !triggers.size )
|
|
AssertEx( IsDefined( trigger.script_flag ) || IsDefined( trigger.script_noteworthy ), "Trigger_cansee at " + trigger.origin + " has no script_flag! The script_flag is used as a flag that gets set when the trigger is activated." );
|
|
}
|
|
|
|
trigger endon( "death" );
|
|
|
|
range = 12;
|
|
offsets = [];
|
|
offsets[ offsets.size ] = ( 0, 0, 0 );
|
|
offsets[ offsets.size ] = ( range, 0, 0 );
|
|
offsets[ offsets.size ] = ( range * -1, 0, 0 );
|
|
offsets[ offsets.size ] = ( 0, range, 0 );
|
|
offsets[ offsets.size ] = ( 0, range * -1, 0 );
|
|
offsets[ offsets.size ] = ( 0, 0, range );
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( has_flag )
|
|
flag_clear( flagName );
|
|
|
|
trigger waittill( "trigger", other );
|
|
AssertEx( IsPlayer( other ), "trigger_cansee currently only supports looking from the player" );
|
|
|
|
while ( level.player IsTouching( trigger ) )
|
|
{
|
|
if ( !( other cantraceto( target_origin, offsets ) ) )
|
|
{
|
|
if ( has_flag )
|
|
flag_clear( flagName );
|
|
wait( 0.1 );
|
|
continue;
|
|
}
|
|
|
|
if ( has_flag )
|
|
flag_set( flagName );
|
|
|
|
// notify targetted triggers as well
|
|
array_thread( triggers, ::send_notify, "trigger" );
|
|
wait( 0.5 );
|
|
}
|
|
}
|
|
}
|
|
|
|
cantraceto( target_origin, offsets )
|
|
{
|
|
for ( i = 0; i < offsets.size; i++ )
|
|
{
|
|
if ( SightTracePassed( self GetEye(), target_origin + offsets[ i ], true, self ) )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
indicate_start( start )
|
|
{
|
|
hudelem = NewHudElem();
|
|
hudelem.alignX = "left";
|
|
hudelem.alignY = "middle";
|
|
hudelem.x = 10;
|
|
hudelem.y = 400;
|
|
// hudelem.label = "Loading from start: " + start;
|
|
hudelem SetText( start );
|
|
hudelem.alpha = 0;
|
|
hudelem.fontScale = 3;
|
|
wait( 1 );
|
|
hudelem FadeOverTime( 1 );
|
|
hudelem.alpha = 1;
|
|
wait( 5 );
|
|
hudelem FadeOverTime( 1 );
|
|
hudelem.alpha = 0;
|
|
wait( 1 );
|
|
hudelem Destroy();
|
|
}
|
|
|
|
handle_starts()
|
|
{
|
|
create_dvar( "start", "" );
|
|
|
|
if ( GetDvar( "scr_generateClipModels" ) != "" && GetDvar( "scr_generateClipModels" ) != "0" )
|
|
return;// shortcut for generating clipmodels gah.
|
|
|
|
if ( !isdefined( level.start_functions ) )
|
|
level.start_functions = [];
|
|
|
|
PrecacheMenu( "start" );
|
|
|
|
AssertEx( GetDvar( "jumpto" ) == "", "Use the START dvar instead of JUMPTO" );
|
|
|
|
start = ToLower( GetDvar( "start" ) );
|
|
|
|
// find the start that matches the one the dvar is set to, and execute it
|
|
dvars = get_start_dvars();
|
|
|
|
if ( IsDefined( level.start_point ) )
|
|
start = level.start_point;
|
|
|
|
// first try to find the start based on the dvar
|
|
start_index = 0;
|
|
for ( i = 0; i < dvars.size; i++ )
|
|
{
|
|
if ( start == dvars[ i ] )
|
|
{
|
|
start_index = i;
|
|
level.start_point = dvars[ i ];
|
|
break;
|
|
}
|
|
}
|
|
|
|
// then try based on the override
|
|
if ( IsDefined( level.default_start_override ) && !isdefined( level.start_point ) )
|
|
{
|
|
foreach ( index, dvar in dvars )
|
|
{
|
|
if ( level.default_start_override == dvar )
|
|
{
|
|
start_index = index;
|
|
level.start_point = dvar;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( !isdefined( level.start_point ) )
|
|
{
|
|
// was a start set with default_start()?
|
|
if ( IsDefined( level.default_start ) )
|
|
level.start_point = "default";
|
|
else
|
|
if ( level_has_start_points() )
|
|
level.start_point = level.start_functions[ 0 ][ "name" ];
|
|
else
|
|
level.start_point = "default";
|
|
}
|
|
|
|
waittillframeend;// starts happen at the end of the first frame, so threads in the mission have a chance to run and init stuff
|
|
thread start_menu();
|
|
|
|
if ( level.start_point == "default" )
|
|
{
|
|
if ( IsDefined( level.default_start ) )
|
|
{
|
|
level thread [[ level.default_start ]]();
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
/#
|
|
if ( IsDefined( level.start_loc_string[ level.start_point ] ) )
|
|
thread indicate_start( level.start_loc_string[ level.start_point ] );
|
|
else
|
|
thread indicate_start( level.start_point );
|
|
#/
|
|
start_array = level.start_arrays[ level.start_point ];
|
|
thread [[ start_array[ "start_func" ] ]]();
|
|
}
|
|
|
|
if ( is_default_start() )
|
|
{
|
|
string = get_string_for_starts( dvars );
|
|
SetDvar( "start", string );
|
|
}
|
|
|
|
waittillframeend;// let the frame finish for all ai init type stuff that goes on in start points
|
|
|
|
previously_run_logic_functions = [];
|
|
// run each logic function in order
|
|
for ( i = start_index; i < level.start_functions.size; i++ )
|
|
{
|
|
start_array = level.start_functions[ i ];
|
|
if ( !isdefined( start_array[ "logic_func" ] ) )
|
|
continue;
|
|
|
|
if ( already_ran_function( start_array[ "logic_func" ], previously_run_logic_functions ) )
|
|
continue;
|
|
|
|
[[ start_array[ "logic_func" ] ]]();
|
|
previously_run_logic_functions[ previously_run_logic_functions.size ] = start_array[ "logic_func" ];
|
|
}
|
|
}
|
|
|
|
already_ran_function( func, previously_run_logic_functions )
|
|
{
|
|
foreach ( logic_function in previously_run_logic_functions )
|
|
{
|
|
if ( logic_function == func )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
get_string_for_starts( dvars )
|
|
{
|
|
string = " ** No starts have been set up for this map with maps\_utility::add_start().";
|
|
if ( dvars.size )
|
|
{
|
|
string = " ** ";
|
|
for ( i = dvars.size - 1; i >= 0; i-- )
|
|
{
|
|
string = string + dvars[ i ] + " ";
|
|
}
|
|
}
|
|
|
|
SetDvar( "start", string );
|
|
return string;
|
|
}
|
|
|
|
|
|
create_start( start, index )
|
|
{
|
|
hudelem = NewHudElem();
|
|
hudelem.alignX = "left";
|
|
hudelem.alignY = "middle";
|
|
hudelem.x = 80;
|
|
hudelem.y = 80 + index * 18;
|
|
hudelem SetText( start );
|
|
hudelem.alpha = 0;
|
|
hudelem.foreground = true;
|
|
|
|
hudelem.fontScale = 1.75;
|
|
hudelem FadeOverTime( 0.5 );
|
|
hudelem.alpha = 1;
|
|
return hudelem;
|
|
}
|
|
|
|
start_menu()
|
|
{
|
|
/#
|
|
if ( !isdefined( level.start_loc_string ) )
|
|
{
|
|
level.start_loc_string = [];
|
|
}
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( GetDvarInt( "debug_start" ) )
|
|
{
|
|
SetDevDvar( "debug_start", 0 );
|
|
SetSavedDvar( "hud_drawhud", 1 );
|
|
display_starts();
|
|
}
|
|
else
|
|
{
|
|
level.display_starts_Pressed = false;
|
|
}
|
|
wait( 0.05 );
|
|
}
|
|
#/
|
|
}
|
|
|
|
start_nogame()
|
|
{
|
|
//empty.. this start for when you want to play without playing. for viewing geo maybe?
|
|
array_call( GetAIArray(), ::Delete );
|
|
array_call( GetSpawnerArray(), ::Delete );
|
|
//array_call( GetEntArray( "trigger_multiple", "code_classname" ), ::Delete );
|
|
//array_call( GetEntArray( "trigger_radius", "code_classname" ), ::Delete );
|
|
}
|
|
|
|
get_start_dvars()
|
|
{
|
|
dvars = [];
|
|
for ( i = 0; i < level.start_functions.size; i++ )
|
|
{
|
|
dvars[ dvars.size ] = level.start_functions[ i ][ "name" ];
|
|
}
|
|
return dvars;
|
|
}
|
|
|
|
display_starts()
|
|
{
|
|
|
|
level.display_starts_Pressed = true;
|
|
if ( level.start_functions.size <= 0 )
|
|
return;
|
|
|
|
dvars = get_start_dvars();
|
|
dvars[ dvars.size ] = "default";
|
|
dvars[ dvars.size ] = "cancel";
|
|
|
|
dvars = array_reverse( dvars );
|
|
// Available Starts:
|
|
title = create_start( "Available Starts:", -1 );
|
|
title.color = ( 1, 1, 1 );
|
|
elems = [];
|
|
|
|
for ( i = 0; i < dvars.size; i++ )
|
|
{
|
|
dvar = dvars[ i ];
|
|
start_string = "[" + dvars[ i ] + "]";
|
|
if ( IsDefined( level.start_loc_string[ dvar ] ) )
|
|
{
|
|
start_string += " -> ";
|
|
start_string += level.start_loc_string[ dvar ];
|
|
}
|
|
|
|
elems[ elems.size ] = create_start( start_string, dvars.size - i );
|
|
}
|
|
|
|
selected = dvars.size - 1;
|
|
up_pressed = false;
|
|
down_pressed = false;
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( !( level.player ButtonPressed( "F10" ) ) )
|
|
{
|
|
level.display_starts_Pressed = false;
|
|
}
|
|
|
|
|
|
for ( i = 0; i < dvars.size; i++ )
|
|
{
|
|
elems[ i ].color = ( 0.7, 0.7, 0.7 );
|
|
}
|
|
|
|
elems[ selected ].color = ( 1, 1, 0 );
|
|
|
|
if ( !up_pressed )
|
|
{
|
|
if ( level.player ButtonPressed( "UPARROW" ) || level.player ButtonPressed( "DPAD_UP" ) || level.player ButtonPressed( "APAD_UP" ) )
|
|
{
|
|
up_pressed = true;
|
|
selected++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( !level.player ButtonPressed( "UPARROW" ) && !level.player ButtonPressed( "DPAD_UP" ) && !level.player ButtonPressed( "APAD_UP" ) )
|
|
up_pressed = false;
|
|
}
|
|
|
|
|
|
if ( !down_pressed )
|
|
{
|
|
if ( level.player ButtonPressed( "DOWNARROW" ) || level.player ButtonPressed( "DPAD_DOWN" ) || level.player ButtonPressed( "APAD_DOWN" ) )
|
|
{
|
|
down_pressed = true;
|
|
selected--;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( !level.player ButtonPressed( "DOWNARROW" ) && !level.player ButtonPressed( "DPAD_DOWN" ) && !level.player ButtonPressed( "APAD_DOWN" ) )
|
|
down_pressed = false;
|
|
}
|
|
|
|
if ( selected < 0 )
|
|
selected = dvars.size - 1;
|
|
|
|
if ( selected >= dvars.size )
|
|
selected = 0;
|
|
|
|
|
|
if ( level.player ButtonPressed( "kp_enter" ) || level.player ButtonPressed( "BUTTON_A" ) || level.player ButtonPressed( "enter" ) )
|
|
{
|
|
if ( dvars[ selected ] == "cancel" )
|
|
{
|
|
title Destroy();
|
|
for ( i = 0; i < elems.size; i++ )
|
|
{
|
|
elems[ i ] Destroy();
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
SetDvar( "start", dvars[ selected ] );
|
|
level.player OpenPopupMenu( "start" );
|
|
// ChangeLevel( level.script, false );
|
|
}
|
|
wait( 0.05 );
|
|
}
|
|
|
|
}
|
|
|
|
start_button_combo()
|
|
{
|
|
if ( !( level.player ButtonPressed( "BUTTON_RSTICK" ) ) )
|
|
return false;
|
|
|
|
if ( !( level.player ButtonPressed( "BUTTON_RSHLDR" ) ) )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
devhelp_hudElements( hudarray, alpha )
|
|
{
|
|
for ( i = 0; i < hudarray.size; i++ )
|
|
for ( p = 0; p < 5; p++ )
|
|
hudarray[ i ][ p ].alpha = alpha;
|
|
|
|
}
|
|
|
|
devhelp()
|
|
{
|
|
/#
|
|
helptext = [];
|
|
helptext[ helptext.size ] = "P: pause ";
|
|
helptext[ helptext.size ] = "T: super speed ";
|
|
helptext[ helptext.size ] = ".: fullbright ";
|
|
helptext[ helptext.size ] = "U: toggle normal maps ";
|
|
helptext[ helptext.size ] = "Y: print a line of text, useful for putting it in a screenshot ";
|
|
helptext[ helptext.size ] = "H: toggle detailed ent info ";
|
|
helptext[ helptext.size ] = "g: toggle simplified ent info ";
|
|
helptext[ helptext.size ] = ", : show the triangle outlines ";
|
|
helptext[ helptext.size ] = " - : Back 10 seconds ";
|
|
helptext[ helptext.size ] = "6: Replay mark ";
|
|
helptext[ helptext.size ] = "7: Replay goto ";
|
|
helptext[ helptext.size ] = "8: Replay live ";
|
|
helptext[ helptext.size ] = "0: Replay back 3 seconds ";
|
|
helptext[ helptext.size ] = "[ : Replay restart ";
|
|
helptext[ helptext.size ] = "\: map_restart ";
|
|
helptext[ helptext.size ] = "U: draw material name ";
|
|
helptext[ helptext.size ] = "J: display tri counts ";
|
|
helptext[ helptext.size ] = "B: cg_ufo ";
|
|
helptext[ helptext.size ] = "N: ufo ";
|
|
helptext[ helptext.size ] = "C: god ";
|
|
helptext[ helptext.size ] = "K: Show ai nodes ";
|
|
helptext[ helptext.size ] = "L: Show ai node connections ";
|
|
helptext[ helptext.size ] = "Semicolon: Show ai pathing ";
|
|
|
|
|
|
strOffsetX = [];
|
|
strOffsetY = [];
|
|
strOffsetX[ 0 ] = 0;
|
|
strOffsetY[ 0 ] = 0;
|
|
strOffsetX[ 1 ] = 1;
|
|
strOffsetY[ 1 ] = 1;
|
|
strOffsetX[ 2 ] = -2;
|
|
strOffsetY[ 2 ] = 1;
|
|
strOffsetX[ 3 ] = 1;
|
|
strOffsetY[ 3 ] = -1;
|
|
strOffsetX[ 4 ] = -2;
|
|
strOffsetY[ 4 ] = -1;
|
|
hudarray = [];
|
|
for ( i = 0; i < helptext.size; i++ )
|
|
{
|
|
newStrArray = [];
|
|
for ( p = 0; p < 5; p++ )
|
|
{
|
|
// setup instructional text
|
|
newStr = NewHudElem();
|
|
newStr.alignX = "left";
|
|
newStr.location = 0;
|
|
newStr.foreground = 1;
|
|
newStr.fontScale = 1.30;
|
|
newStr.sort = 20 - p;
|
|
newStr.alpha = 1;
|
|
newStr.x = 54 + strOffsetX[ p ];
|
|
newStr.y = 80 + strOffsetY[ p ] + i * 15;
|
|
newstr SetText( helptext[ i ] );
|
|
if ( p > 0 )
|
|
newStr.color = ( 0, 0, 0 );
|
|
|
|
newStrArray[ newStrArray.size ] = newStr;
|
|
}
|
|
hudarray[ hudarray.size ] = newStrArray;
|
|
}
|
|
|
|
devhelp_hudElements( hudarray, 0 );
|
|
|
|
while ( 1 )
|
|
{
|
|
update = false;
|
|
if ( level.player ButtonPressed( "F1" ) )
|
|
{
|
|
devhelp_hudElements( hudarray, 1 );
|
|
while ( level.player ButtonPressed( "F1" ) )
|
|
wait .05;
|
|
}
|
|
devhelp_hudElements( hudarray, 0 );
|
|
wait .05;
|
|
}
|
|
#/
|
|
}
|
|
|
|
flag_set_player_trigger( trigger )
|
|
{
|
|
if ( is_coop() )
|
|
{
|
|
thread flag_set_coop_trigger( trigger );
|
|
return;
|
|
}
|
|
|
|
flag = trigger get_trigger_flag();
|
|
|
|
if ( !isdefined( level.flag[ flag ] ) )
|
|
{
|
|
flag_init( flag );
|
|
}
|
|
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger", other );
|
|
if ( !isplayer( other ) )
|
|
continue;
|
|
trigger script_delay();
|
|
flag_set( flag );
|
|
}
|
|
}
|
|
|
|
trigger_nobloodpool( trigger )
|
|
{
|
|
// Issue: If a guy dies and animates into the trigger, he will still spawn a blood pool.
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger", other );
|
|
if ( !isalive( other ) )
|
|
continue;
|
|
|
|
other.skipBloodPool = true;
|
|
other thread set_wait_then_clear_skipBloodPool();
|
|
}
|
|
}
|
|
|
|
set_wait_then_clear_skipBloodPool()
|
|
{
|
|
|
|
// Issue: If a guy dies during this timer even though he has left the trigger area, he will not spawn a pool. Deemed acceptable.
|
|
self notify( "notify_wait_then_clear_skipBloodPool" );
|
|
self endon( "notify_wait_then_clear_skipBloodPool" );
|
|
self endon( "death" );
|
|
|
|
wait 2;
|
|
self.skipBloodPool = undefined;
|
|
}
|
|
|
|
flag_set_trigger( trigger )
|
|
{
|
|
flag = trigger get_trigger_flag();
|
|
|
|
if ( !isdefined( level.flag[ flag ] ) )
|
|
{
|
|
flag_init( flag );
|
|
}
|
|
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger", other );
|
|
trigger script_delay();
|
|
flag_set( flag, other );
|
|
}
|
|
}
|
|
|
|
flag_set_trigger_specialops( trigger )
|
|
{
|
|
flag = trigger get_trigger_flag();
|
|
|
|
if ( !isdefined( level.flag[ flag ] ) )
|
|
{
|
|
flag_init( flag );
|
|
}
|
|
|
|
trigger.player_touched_arr = level.players;
|
|
trigger thread flag_set_trigger_specialops_clear( flag );
|
|
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger", other );
|
|
|
|
trigger.player_touched_arr = array_remove( trigger.player_touched_arr, other );
|
|
if ( trigger.player_touched_arr.size )
|
|
continue;
|
|
|
|
trigger script_delay();
|
|
flag_set( flag, other );
|
|
}
|
|
}
|
|
|
|
flag_set_trigger_specialops_clear( flag )
|
|
{
|
|
// sets self.player_touched_arr when the flag is set or cleared from script.
|
|
while ( true )
|
|
{
|
|
level waittill( flag );
|
|
if ( flag( flag ) )
|
|
{
|
|
self.player_touched_arr = [];
|
|
}
|
|
else
|
|
{
|
|
self.player_touched_arr = level.players;
|
|
}
|
|
}
|
|
}
|
|
|
|
trigger_damage_player_flag_set( trigger )
|
|
{
|
|
flag = trigger get_trigger_flag();
|
|
|
|
if ( !isdefined( level.flag[ flag ] ) )
|
|
{
|
|
flag_init( flag );
|
|
}
|
|
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger", other );
|
|
if ( !isalive( other ) )
|
|
continue;
|
|
if ( !isplayer( other ) )
|
|
continue;
|
|
trigger script_delay();
|
|
flag_set( flag, other );
|
|
}
|
|
}
|
|
|
|
flag_set_coop_trigger( trigger )
|
|
{
|
|
AssertEx( is_coop(), "flag_set_coop_trigger() was called but co-op is not enabled." );
|
|
flag = trigger get_trigger_flag();
|
|
|
|
if ( !isdefined( level.flag[ flag ] ) )
|
|
{
|
|
flag_init( flag );
|
|
}
|
|
|
|
agents = [];
|
|
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger", user );
|
|
|
|
if ( !isplayer( user ) )
|
|
continue;
|
|
|
|
add = [];
|
|
add[ add.size ] = user;
|
|
|
|
agents = array_merge( agents, add );
|
|
|
|
if ( agents.size == level.players.size )
|
|
break;
|
|
}
|
|
|
|
trigger script_delay();
|
|
flag_set( flag );
|
|
}
|
|
|
|
flag_unset_trigger( trigger )
|
|
{
|
|
flag = trigger get_trigger_flag();
|
|
|
|
if ( !isdefined( level.flag[ flag ] ) )
|
|
flag_init( flag );
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
trigger script_delay();
|
|
flag_clear( flag );
|
|
}
|
|
}
|
|
|
|
eq_trigger( trigger )
|
|
{
|
|
level.set_eq_func[ true ] = ::set_eq_on;
|
|
level.set_eq_func[ false ] = ::set_eq_off;
|
|
targ = GetEnt( trigger.target, "targetname" );
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
ai = GetAIArray( "allies" );
|
|
for ( i = 0; i < ai.size; i++ )
|
|
{
|
|
ai[ i ] [[ level.set_eq_func[ ai[ i ] IsTouching( targ ) ] ]]();
|
|
}
|
|
while ( level.player IsTouching( trigger ) )
|
|
wait( 0.05 );
|
|
|
|
ai = GetAIArray( "allies" );
|
|
for ( i = 0; i < ai.size; i++ )
|
|
{
|
|
ai[ i ] [[ level.set_eq_func[ false ] ]]();
|
|
}
|
|
}
|
|
/*
|
|
num = level.eq_trigger_num;
|
|
trigger.eq_num = num;
|
|
level.eq_trigger_num ++ ;
|
|
waittillframeend;// let the ai get their eq_num table created
|
|
waittillframeend;// let the ai get their eq_num table created
|
|
level.eq_trigger_table[ num ] = [];
|
|
if ( IsDefined( trigger.script_linkTo ) )
|
|
{
|
|
tokens = StrTok( trigger.script_linkto, " " );
|
|
for ( i = 0; i < tokens.size; i ++ )
|
|
{
|
|
target_trigger = GetEnt( tokens[ i ], "script_linkname" );
|
|
// add the trigger num to the list of triggers this trigger hears
|
|
level.eq_trigger_table[ num ][ level.eq_trigger_table[ num ].size ] = target_trigger.eq_num;
|
|
}
|
|
}
|
|
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger", other );
|
|
|
|
// are we already registered with this trigger?
|
|
if ( other.eq_table[ num ] )
|
|
continue;
|
|
|
|
other thread [[ level.touched_eq_function[ other.is_the_player ] ]]( num, trigger );
|
|
}
|
|
*/
|
|
}
|
|
|
|
|
|
player_ignores_triggers()
|
|
{
|
|
self endon( "death" );
|
|
self.ignoretriggers = true;
|
|
wait( 1 );
|
|
self.ignoretriggers = false;
|
|
}
|
|
|
|
get_trigger_eq_nums( num )
|
|
{
|
|
// tally up the triggers this trigger hears into, including itself
|
|
nums = [];
|
|
nums[ 0 ] = num;
|
|
for ( i = 0; i < level.eq_trigger_table[ num ].size; i++ )
|
|
{
|
|
nums[ nums.size ] = level.eq_trigger_table[ num ][ i ];
|
|
}
|
|
return nums;
|
|
}
|
|
|
|
|
|
player_touched_eq_trigger( num, trigger )
|
|
{
|
|
self endon( "death" );
|
|
|
|
nums = get_trigger_eq_nums( num );
|
|
for ( r = 0; r < nums.size; r++ )
|
|
{
|
|
self.eq_table[ nums[ r ] ] = true;
|
|
self.eq_touching[ nums[ r ] ] = true;
|
|
}
|
|
|
|
thread player_ignores_triggers();
|
|
|
|
ai = GetAIArray();
|
|
for ( i = 0; i < ai.size; i++ )
|
|
{
|
|
guy = ai[ i ];
|
|
// is the ai in this trigger with us?
|
|
for ( r = 0; r < nums.size; r++ )
|
|
{
|
|
if ( guy.eq_table[ nums[ r ] ] )
|
|
{
|
|
guy EQOff();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
while ( self IsTouching( trigger ) )
|
|
wait( 0.05 );
|
|
|
|
for ( r = 0; r < nums.size; r++ )
|
|
{
|
|
self.eq_table[ nums[ r ] ] = false;
|
|
self.eq_touching[ nums[ r ] ] = undefined;
|
|
}
|
|
|
|
ai = GetAIArray();
|
|
for ( i = 0; i < ai.size; i++ )
|
|
{
|
|
guy = ai[ i ];
|
|
|
|
was_in_our_trigger = false;
|
|
// is the ai in the trigger we just left?
|
|
for ( r = 0; r < nums.size; r++ )
|
|
{
|
|
// was the guy in a trigger we could hear into?
|
|
if ( guy.eq_table[ nums[ r ] ] )
|
|
{
|
|
was_in_our_trigger = true;
|
|
}
|
|
}
|
|
|
|
if ( !was_in_our_trigger )
|
|
continue;
|
|
|
|
// check to see if the guy is in any of the triggers we're still in
|
|
|
|
touching = GetArrayKeys( self.eq_touching );
|
|
shares_trigger = false;
|
|
for ( p = 0; p < touching.size; p++ )
|
|
{
|
|
if ( !guy.eq_table[ touching[ p ] ] )
|
|
continue;
|
|
|
|
shares_trigger = true;
|
|
break;
|
|
}
|
|
|
|
// if he's not in a trigger with us, turn his eq back on
|
|
if ( !shares_trigger )
|
|
guy EQOn();
|
|
}
|
|
}
|
|
|
|
ai_touched_eq_trigger( num, trigger )
|
|
{
|
|
self endon( "death" );
|
|
|
|
nums = get_trigger_eq_nums( num );
|
|
for ( r = 0; r < nums.size; r++ )
|
|
{
|
|
self.eq_table[ nums[ r ] ] = true;
|
|
self.eq_touching[ nums[ r ] ] = true;
|
|
}
|
|
|
|
// are we in the same trigger as the player?
|
|
for ( r = 0; r < nums.size; r++ )
|
|
{
|
|
if ( level.player.eq_table[ nums[ r ] ] )
|
|
{
|
|
self EQOff();
|
|
break;
|
|
}
|
|
}
|
|
|
|
// so other AI can touch the trigger
|
|
self.ignoretriggers = true;
|
|
wait( 1 );
|
|
self.ignoretriggers = false;
|
|
while ( self IsTouching( trigger ) )
|
|
wait( 0.5 );
|
|
|
|
nums = get_trigger_eq_nums( num );
|
|
for ( r = 0; r < nums.size; r++ )
|
|
{
|
|
self.eq_table[ nums[ r ] ] = false;
|
|
self.eq_touching[ nums[ r ] ] = undefined;
|
|
}
|
|
|
|
touching = GetArrayKeys( self.eq_touching );
|
|
for ( i = 0; i < touching.size; i++ )
|
|
{
|
|
// is the player in a trigger that we're still in?
|
|
if ( level.player.eq_table[ touching[ i ] ] )
|
|
{
|
|
// then don't turn eq back on
|
|
return;
|
|
}
|
|
}
|
|
|
|
self EQOn();
|
|
}
|
|
|
|
ai_eq()
|
|
{
|
|
level.set_eq_func[ false ] = ::set_eq_on;
|
|
level.set_eq_func[ true ] = ::set_eq_off;
|
|
index = 0;
|
|
for ( ;; )
|
|
{
|
|
while ( !level.ai_array.size )
|
|
{
|
|
wait( 0.05 );
|
|
}
|
|
waittillframeend;
|
|
waittillframeend;
|
|
keys = GetArrayKeys( level.ai_array );
|
|
index++;
|
|
if ( index >= keys.size )
|
|
index = 0;
|
|
guy = level.ai_array[ keys[ index ] ];
|
|
guy [[ level.set_eq_func[ SightTracePassed( level.player GetEye(), guy GetEye(), false, undefined ) ] ]]();
|
|
wait( 0.05 );
|
|
}
|
|
}
|
|
|
|
set_eq_on()
|
|
{
|
|
self EQOn();
|
|
}
|
|
|
|
set_eq_off()
|
|
{
|
|
self EQOff();
|
|
}
|
|
|
|
add_tokens_to_trigger_flags( tokens )
|
|
{
|
|
for ( i = 0; i < tokens.size; i++ )
|
|
{
|
|
flag = tokens[ i ];
|
|
if ( !isdefined( level.trigger_flags[ flag ] ) )
|
|
{
|
|
level.trigger_flags[ flag ] = [];
|
|
}
|
|
|
|
level.trigger_flags[ flag ][ level.trigger_flags[ flag ].size ] = self;
|
|
}
|
|
}
|
|
|
|
script_flag_false_trigger( trigger )
|
|
{
|
|
// all of these flags must be false for the trigger to be enabled
|
|
tokens = create_flags_and_return_tokens( trigger.script_flag_false );
|
|
trigger add_tokens_to_trigger_flags( tokens );
|
|
trigger update_trigger_based_on_flags();
|
|
}
|
|
|
|
script_flag_true_trigger( trigger )
|
|
{
|
|
// all of these flags must be false for the trigger to be enabled
|
|
tokens = create_flags_and_return_tokens( trigger.script_flag_true );
|
|
trigger add_tokens_to_trigger_flags( tokens );
|
|
trigger update_trigger_based_on_flags();
|
|
}
|
|
|
|
/*
|
|
for( ;; )
|
|
{
|
|
trigger trigger_on();
|
|
wait_for_flag( tokens );
|
|
|
|
trigger trigger_off();
|
|
wait_for_flag( tokens );
|
|
for ( i = 0; i < tokens.size; i ++ )
|
|
{
|
|
flag_wait( tokens[ i ] );
|
|
}
|
|
}
|
|
*/
|
|
|
|
|
|
/*
|
|
script_flag_true_trigger( trigger )
|
|
{
|
|
// any of these flags have to be true for the trigger to be enabled
|
|
tokens = create_flags_and_return_tokens( trigger.script_flag_true );
|
|
|
|
for ( ;; )
|
|
{
|
|
trigger trigger_off();
|
|
wait_for_flag( tokens );
|
|
trigger trigger_on();
|
|
for ( i = 0; i < tokens.size; i ++ )
|
|
{
|
|
flag_waitopen( tokens[ i ] );
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
wait_for_flag( tokens )
|
|
{
|
|
for ( i = 0; i < tokens.size; i++ )
|
|
{
|
|
level endon( tokens[ i ] );
|
|
}
|
|
level waittill( "foreverrr" );
|
|
}
|
|
|
|
trigger_multiple_physics( trigger )
|
|
{
|
|
AssertEx( IsDefined( trigger.target ), "Trigger_multiple_physics at " + trigger.origin + " has no target for physics." );
|
|
|
|
ents = [];
|
|
|
|
structs = getstructarray( trigger.target, "targetname" );
|
|
orgs = GetEntArray( trigger.target, "targetname" );
|
|
|
|
foreach ( org in orgs )
|
|
{
|
|
// save ents by moving script origins to structs
|
|
struct = SpawnStruct();
|
|
struct.origin = org.origin;
|
|
struct.script_parameters = org.script_parameters;
|
|
struct.script_damage = org.script_damage;
|
|
struct.radius = org.radius;
|
|
structs[ structs.size ] = struct;
|
|
org Delete();
|
|
}
|
|
|
|
AssertEx( structs.size, "Trigger_multiple_physics at " + trigger.origin + " has no target for physics." );
|
|
|
|
trigger.org = structs[ 0 ].origin;
|
|
trigger waittill( "trigger" );
|
|
trigger script_delay();
|
|
|
|
foreach ( struct in structs )
|
|
{
|
|
radius = struct.radius;
|
|
vel = struct.script_parameters;
|
|
damage = struct.script_damage;
|
|
|
|
if ( !isdefined( radius ) )
|
|
radius = 350;
|
|
if ( !isdefined( vel ) )
|
|
vel = 0.25;
|
|
|
|
// convert string to float
|
|
SetDvar( "tempdvar", vel );
|
|
vel = GetDvarFloat( "tempdvar" );
|
|
|
|
if ( IsDefined( damage ) )
|
|
{
|
|
RadiusDamage( struct.origin, radius, damage, damage * 0.5 );
|
|
}
|
|
PhysicsExplosionSphere( struct.origin, radius, radius * 0.5, vel );
|
|
}
|
|
}
|
|
|
|
trigger_multiple_friendly_stop_respawn( trigger )
|
|
{
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
flag_clear( "respawn_friendlies" );
|
|
}
|
|
}
|
|
|
|
trigger_multiple_friendly_respawn( trigger )
|
|
{
|
|
org = GetEnt( trigger.target, "targetname" );
|
|
origin = undefined;
|
|
if ( IsDefined( org ) )
|
|
{
|
|
origin = org.origin;
|
|
org Delete();
|
|
|
|
}
|
|
else
|
|
{
|
|
org = getstruct( trigger.target, "targetname" );
|
|
AssertEx( IsDefined( org ), "trigger_multiple_friendly_respawn doesn't target an origin." );
|
|
origin = org.origin;
|
|
}
|
|
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
level.respawn_spawner_org = origin;
|
|
flag_set( "respawn_friendlies" );
|
|
wait( 0.5 );
|
|
}
|
|
}
|
|
|
|
friendly_respawn_clear( trigger )
|
|
{
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
flag_clear( "respawn_friendlies" );
|
|
wait( 0.5 );
|
|
}
|
|
}
|
|
|
|
trigger_multiple_do_radius_damage( trigger )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
trigger do_radius_damage_from_target();
|
|
}
|
|
|
|
do_radius_damage_from_target()
|
|
{
|
|
radius = 80;
|
|
if ( IsDefined( self.radius ) )
|
|
radius = self.radius;
|
|
|
|
targs = self get_all_target_ents();
|
|
foreach ( targ in targs )
|
|
{
|
|
RadiusDamage( targ.origin, radius, 5000, 5000 );
|
|
}
|
|
self Delete();
|
|
}
|
|
|
|
trigger_damage_do_radius_damage( trigger )
|
|
{
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "damage", damage, attacker, direction_vec, point, type, modelName, tagName );
|
|
if ( !isalive( attacker ) )
|
|
continue;
|
|
// if ( attacker != level.player )
|
|
// continue;
|
|
if ( Distance( attacker.origin, trigger.origin ) > 940 )
|
|
continue;
|
|
break;
|
|
}
|
|
|
|
trigger do_radius_damage_from_target();
|
|
}
|
|
|
|
radio_trigger( trigger )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
radio_dialogue( trigger.script_noteworthy );
|
|
}
|
|
|
|
background_block()
|
|
{
|
|
Assert( IsDefined( self.script_bg_offset ) );
|
|
self.origin -= self.script_bg_offset;
|
|
}
|
|
|
|
trigger_ignore( trigger )
|
|
{
|
|
thread trigger_runs_function_on_touch( trigger, ::set_ignoreme, ::get_ignoreme );
|
|
}
|
|
|
|
trigger_pacifist( trigger )
|
|
{
|
|
thread trigger_runs_function_on_touch( trigger, ::set_pacifist, ::get_pacifist );
|
|
}
|
|
|
|
trigger_runs_function_on_touch( trigger, set_func, get_func )
|
|
{
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger", other );
|
|
if ( !isalive( other ) )
|
|
continue;
|
|
if ( other [[ get_func ]]() )
|
|
continue;
|
|
other thread touched_trigger_runs_func( trigger, set_func );
|
|
}
|
|
}
|
|
|
|
touched_trigger_runs_func( trigger, set_func )
|
|
{
|
|
self endon( "death" );
|
|
self.ignoreme = true;
|
|
[[ set_func ]]( true );
|
|
// so others can touch the trigger
|
|
self.ignoretriggers = true;
|
|
wait( 1 );
|
|
self.ignoretriggers = false;
|
|
|
|
while ( self IsTouching( trigger ) )
|
|
{
|
|
wait( 1 );
|
|
}
|
|
|
|
[[ set_func ]]( false );
|
|
}
|
|
|
|
trigger_turns_off( trigger )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
trigger trigger_off();
|
|
|
|
if ( !isdefined( trigger.script_linkTo ) )
|
|
return;
|
|
|
|
// also turn off all triggers this trigger links to
|
|
tokens = StrTok( trigger.script_linkto, " " );
|
|
for ( i = 0; i < tokens.size; i++ )
|
|
array_thread( GetEntArray( tokens[ i ], "script_linkname" ), ::trigger_off );
|
|
}
|
|
|
|
|
|
set_player_viewhand_model( viewhandModel )
|
|
{
|
|
Assert( !isdefined( level.player_viewhand_model ) ); // only set this once per level
|
|
AssertEx( IsSubStr( viewhandModel, "player" ), "Must set with viewhands_player_*" );
|
|
level.player_viewhand_model = viewhandModel;
|
|
PreCacheModel( level.player_viewhand_model );
|
|
}
|
|
|
|
trigger_hint( trigger )
|
|
{
|
|
AssertEx( IsDefined( trigger.script_hint ), "Trigger_hint at " + trigger.origin + " has no .script_hint" );
|
|
|
|
if ( !isdefined( level.displayed_hints ) )
|
|
{
|
|
level.displayed_hints = [];
|
|
}
|
|
// give level script a chance to set the hint string and optional boolean functions on this hint
|
|
waittillframeend;
|
|
|
|
hint = trigger.script_hint;
|
|
AssertEx( IsDefined( level.trigger_hint_string[ hint ] ), "Trigger_hint with hint " + hint + " had no hint string assigned to it. Define hint strings with add_hint_string()" );
|
|
trigger waittill( "trigger", other );
|
|
|
|
AssertEx( IsPlayer( other ), "Tried to do a trigger_hint on a non player entity" );
|
|
|
|
if ( IsDefined( level.displayed_hints[ hint ] ) )
|
|
return;
|
|
level.displayed_hints[ hint ] = true;
|
|
|
|
other display_hint( hint );
|
|
}
|
|
|
|
stun_test()
|
|
{
|
|
|
|
if ( GetDvar( "stuntime" ) == "" )
|
|
SetDvar( "stuntime", "1" );
|
|
level.player.AllowAds = true;
|
|
|
|
|
|
for ( ;; )
|
|
{
|
|
self waittill( "damage" );
|
|
if ( GetDvarInt( "stuntime" ) == 0 )
|
|
continue;
|
|
|
|
thread stun_player( self PlayerAds() );
|
|
}
|
|
}
|
|
|
|
stun_player( ADS_fraction )
|
|
{
|
|
self notify( "stun_player" );
|
|
self endon( "stun_player" );
|
|
|
|
if ( ADS_fraction > .3 )
|
|
{
|
|
if ( level.player.AllowAds == true )
|
|
level.player PlaySound( "player_hit_while_ads" );
|
|
|
|
level.player.AllowAds = false;
|
|
level.player AllowAds( false );
|
|
}
|
|
level.player SetSpreadOverride( 20 );
|
|
|
|
wait( GetDvarInt( "stuntime" ) );
|
|
|
|
level.player AllowAds( true );
|
|
level.player.AllowAds = true;
|
|
level.player ResetSpreadOverride();
|
|
}
|
|
|
|
throw_grenade_at_player_trigger( trigger )
|
|
{
|
|
trigger endon( "death" );
|
|
|
|
trigger waittill( "trigger" );
|
|
|
|
ThrowGrenadeAtPlayerASAP();
|
|
}
|
|
|
|
flag_on_cleared( trigger )
|
|
{
|
|
flag = trigger get_trigger_flag();
|
|
|
|
if ( !isdefined( level.flag[ flag ] ) )
|
|
{
|
|
flag_init( flag );
|
|
}
|
|
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
wait( 1 );
|
|
if ( trigger found_toucher() )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
flag_set( flag );
|
|
}
|
|
|
|
found_toucher()
|
|
{
|
|
ai = GetAIArray( "bad_guys" );
|
|
for ( i = 0; i < ai.size; i++ )
|
|
{
|
|
guy = ai[ i ];
|
|
if ( !isalive( guy ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( guy IsTouching( self ) )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// spread the touches out over time
|
|
wait( 0.1 );
|
|
}
|
|
|
|
// couldnt find any touchers so do a single frame complete check just to make sure
|
|
|
|
ai = GetAIArray( "bad_guys" );
|
|
for ( i = 0; i < ai.size; i++ )
|
|
{
|
|
guy = ai[ i ];
|
|
if ( guy IsTouching( self ) )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
trigger_delete_on_touch( trigger )
|
|
{
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger", other );
|
|
if ( IsDefined( other ) )
|
|
{
|
|
// might've been removed before we got it
|
|
other Delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
flag_set_touching( trigger )
|
|
{
|
|
flag = trigger get_trigger_flag();
|
|
|
|
if ( !isdefined( level.flag[ flag ] ) )
|
|
{
|
|
flag_init( flag );
|
|
}
|
|
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger", other );
|
|
trigger script_delay();
|
|
if ( IsAlive( other ) && other IsTouching( trigger ) && IsDefined( trigger ) )
|
|
flag_set( flag );
|
|
while ( IsAlive( other ) && other IsTouching( trigger ) && IsDefined( trigger ) )
|
|
{
|
|
wait( 0.25 );
|
|
}
|
|
flag_clear( flag );
|
|
}
|
|
}
|
|
|
|
/*
|
|
rpg_aim_assist()
|
|
{
|
|
level.player endon( "death" );
|
|
for ( ;; )
|
|
{
|
|
level.player waittill( "weapon_fired" );
|
|
currentweapon = level.player GetCurrentWeapon();
|
|
if ( ( currentweapon == "rpg" ) || ( currentweapon == "rpg_player" ) )
|
|
thread rpg_aim_assist_attractor();
|
|
}
|
|
}
|
|
|
|
rpg_aim_assist_attractor()
|
|
{
|
|
prof_begin( "rpg_aim_assist" );
|
|
|
|
// Trace to where the player is looking
|
|
start = level.player GetEye();
|
|
direction = level.player GetPlayerAngles();
|
|
coord = BulletTrace( start, start + vector_multiply( AnglesToForward( direction ), 15000 ), true, level.player )[ "position" ];
|
|
|
|
thread draw_line_for_time( level.player.origin, coord, 1, 0, 0, 10000 );
|
|
|
|
prof_end( "rpg_aim_assist" );
|
|
|
|
attractor = Missile_CreateAttractorOrigin( coord, 10000, 3000 );
|
|
wait 3.0;
|
|
Missile_DeleteAttractor( attractor );
|
|
}
|
|
*/
|
|
|
|
SetObjectiveTextColors()
|
|
{
|
|
// The darker the base color, the more-readable the text is against a stark-white backdrop.
|
|
// However; this sacrifices the "white-hot"ness of the text against darker backdrops.
|
|
|
|
MY_TEXTBRIGHTNESS_DEFAULT = "1.0 1.0 1.0";
|
|
MY_TEXTBRIGHTNESS_90 = "0.9 0.9 0.9";
|
|
MY_TEXTBRIGHTNESS_85 = "0.85 0.85 0.85";
|
|
|
|
if ( level.script == "armada" )
|
|
{
|
|
SetSavedDvar( "con_typewriterColorBase", MY_TEXTBRIGHTNESS_90 );
|
|
return;
|
|
}
|
|
|
|
SetSavedDvar( "con_typewriterColorBase", MY_TEXTBRIGHTNESS_DEFAULT );
|
|
}
|
|
|
|
ammo_pickup( sWeaponType )
|
|
{
|
|
// possible weapons that the player could have that get this type of ammo
|
|
validWeapons = [];
|
|
if ( sWeaponType == "grenade_launcher" )
|
|
{
|
|
validWeapons[ validWeapons.size ] = "m203_m4";
|
|
validWeapons[ validWeapons.size ] = "m203_m4_acog";
|
|
validWeapons[ validWeapons.size ] = "m203_m4_eotech";
|
|
validWeapons[ validWeapons.size ] = "m203_m4_motion_tracker";
|
|
validWeapons[ validWeapons.size ] = "m203_m4_reflex";
|
|
validWeapons[ validWeapons.size ] = "m203_m4_silencer";
|
|
validWeapons[ validWeapons.size ] = "m203_m4_silencer_reflex";
|
|
validWeapons[ validWeapons.size ] = "m203";
|
|
validWeapons[ validWeapons.size ] = "gp25";
|
|
validWeapons[ validWeapons.size ] = "m4m203_silencer_reflex";
|
|
validWeapons[ validWeapons.size ] = "m203_m4_silencer_reflex";
|
|
}
|
|
else if ( sWeaponType == "rpg" )
|
|
{
|
|
validWeapons[ validWeapons.size ] = "rpg";
|
|
validWeapons[ validWeapons.size ] = "rpg_player";
|
|
validWeapons[ validWeapons.size ] = "rpg_straight";
|
|
}
|
|
else if ( sWeaponType == "c4" )
|
|
{
|
|
validWeapons[ validWeapons.size ] = "c4";
|
|
}
|
|
else if ( sWeaponType == "claymore" )
|
|
{
|
|
validWeapons[ validWeapons.size ] = "claymore";
|
|
}
|
|
else if ( sWeaponType == "556" )
|
|
{
|
|
validWeapons[ validWeapons.size ] = "m4_grenadier";
|
|
validWeapons[ validWeapons.size ] = "m4_grunt";
|
|
validWeapons[ validWeapons.size ] = "m4_sd_cloth";
|
|
validWeapons[ validWeapons.size ] = "m4_shotgun";
|
|
validWeapons[ validWeapons.size ] = "m4_silencer";
|
|
validWeapons[ validWeapons.size ] = "m4_silencer_acog";
|
|
validWeapons[ validWeapons.size ] = "m4m203_acog";
|
|
validWeapons[ validWeapons.size ] = "m4m203_eotech";
|
|
validWeapons[ validWeapons.size ] = "m4m203_motion_tracker";
|
|
validWeapons[ validWeapons.size ] = "m4m203_reflex";
|
|
validWeapons[ validWeapons.size ] = "m4m203_reflex_arctic";
|
|
validWeapons[ validWeapons.size ] = "m4m203_silencer";
|
|
validWeapons[ validWeapons.size ] = "m4m203_silencer_reflex";
|
|
validWeapons[ validWeapons.size ] = "m4m203_silencer";
|
|
}
|
|
else if ( sWeaponType == "762" )
|
|
{
|
|
validWeapons[ validWeapons.size ] = "ak47";
|
|
validWeapons[ validWeapons.size ] = "ak47_acog";
|
|
validWeapons[ validWeapons.size ] = "ak47_eotech";
|
|
validWeapons[ validWeapons.size ] = "ak47_grenadier";
|
|
validWeapons[ validWeapons.size ] = "ak47_reflex";
|
|
validWeapons[ validWeapons.size ] = "ak47_shotgun";
|
|
validWeapons[ validWeapons.size ] = "ak47_silencer";
|
|
validWeapons[ validWeapons.size ] = "ak47_thermal";
|
|
|
|
validWeapons[ validWeapons.size ] = "ak47_desert";
|
|
validWeapons[ validWeapons.size ] = "ak47_desert_acog";
|
|
validWeapons[ validWeapons.size ] = "ak47_desert_eotech";
|
|
validWeapons[ validWeapons.size ] = "ak47_desert_grenadier";
|
|
validWeapons[ validWeapons.size ] = "ak47_desert_reflex";
|
|
|
|
validWeapons[ validWeapons.size ] = "ak47_digital";
|
|
validWeapons[ validWeapons.size ] = "ak47_digital_acog";
|
|
validWeapons[ validWeapons.size ] = "ak47_digital_eotech";
|
|
validWeapons[ validWeapons.size ] = "ak47_digital_grenadier";
|
|
validWeapons[ validWeapons.size ] = "ak47_digital_reflex";
|
|
|
|
validWeapons[ validWeapons.size ] = "ak47_fall";
|
|
validWeapons[ validWeapons.size ] = "ak47_fall_acog";
|
|
validWeapons[ validWeapons.size ] = "ak47_fall_eotech";
|
|
validWeapons[ validWeapons.size ] = "ak47_fall_grenadier";
|
|
validWeapons[ validWeapons.size ] = "ak47_fall_reflex";
|
|
|
|
validWeapons[ validWeapons.size ] = "ak47_woodland";
|
|
validWeapons[ validWeapons.size ] = "ak47_woodland_acog";
|
|
validWeapons[ validWeapons.size ] = "ak47_woodland_eotech";
|
|
validWeapons[ validWeapons.size ] = "ak47_woodland_grenadier";
|
|
validWeapons[ validWeapons.size ] = "ak47_woodland_reflex";
|
|
}
|
|
else if ( sWeaponType == "45" )
|
|
{
|
|
validWeapons[ validWeapons.size ] = "ump45";
|
|
validWeapons[ validWeapons.size ] = "ump45_acog";
|
|
validWeapons[ validWeapons.size ] = "ump45_eotech";
|
|
validWeapons[ validWeapons.size ] = "ump45_reflex";
|
|
validWeapons[ validWeapons.size ] = "ump45_silencer";
|
|
|
|
validWeapons[ validWeapons.size ] = "ump45_arctic";
|
|
validWeapons[ validWeapons.size ] = "ump45_arctic_acog";
|
|
validWeapons[ validWeapons.size ] = "ump45_arctic_eotech";
|
|
validWeapons[ validWeapons.size ] = "ump45_arctic_reflex";
|
|
|
|
validWeapons[ validWeapons.size ] = "ump45_digital";
|
|
validWeapons[ validWeapons.size ] = "ump45_digital_acog";
|
|
validWeapons[ validWeapons.size ] = "ump45_digital_eotech";
|
|
validWeapons[ validWeapons.size ] = "ump45_digital_reflex";
|
|
}
|
|
else if ( sWeaponType == "pistol" )
|
|
{
|
|
validWeapons[ validWeapons.size ] = "beretta";
|
|
validWeapons[ validWeapons.size ] = "beretta393";
|
|
validWeapons[ validWeapons.size ] = "usp";
|
|
validWeapons[ validWeapons.size ] = "usp_scripted";
|
|
validWeapons[ validWeapons.size ] = "usp_silencer";
|
|
validWeapons[ validWeapons.size ] = "glock";
|
|
}
|
|
|
|
Assert( validWeapons.size > 0 );
|
|
|
|
trig = Spawn( "trigger_radius", self.origin, 0, 25, 32 );
|
|
|
|
for ( ;; )
|
|
{
|
|
flag_wait( "allow_ammo_pickups" );
|
|
|
|
trig waittill( "trigger", triggerer );
|
|
|
|
if ( !flag( "allow_ammo_pickups" ) )
|
|
continue;
|
|
|
|
if ( !isdefined( triggerer ) )
|
|
continue;
|
|
|
|
if ( !isplayer( triggerer ) )
|
|
continue;
|
|
|
|
// check if the player is carrying one of the valid grenade launcher weapons
|
|
weaponToGetAmmo = undefined;
|
|
emptyActionSlotAmmo = undefined;
|
|
weapons = triggerer GetWeaponsListAll();
|
|
for ( i = 0; i < weapons.size; i++ )
|
|
{
|
|
for ( j = 0; j < validWeapons.size; j++ )
|
|
{
|
|
if ( weapons[ i ] == validWeapons[ j ] )
|
|
weaponToGetAmmo = weapons[ i ];
|
|
}
|
|
}
|
|
|
|
//check if weapon if C4 or claymore and the player has zero of them
|
|
if ( ( !isdefined( weaponToGetAmmo ) ) && ( sWeaponType == "claymore" ) )
|
|
{
|
|
emptyActionSlotAmmo = true;
|
|
weaponToGetAmmo = "claymore";
|
|
break;
|
|
}
|
|
|
|
|
|
//check if weapon if C4 or claymore and the player has zero of them
|
|
if ( ( !isdefined( weaponToGetAmmo ) ) && ( sWeaponType == "c4" ) )
|
|
{
|
|
emptyActionSlotAmmo = true;
|
|
weaponToGetAmmo = "c4";
|
|
break;
|
|
}
|
|
|
|
// no grenade launcher found
|
|
if ( !isdefined( weaponToGetAmmo ) )
|
|
continue;
|
|
|
|
// grenade launcher found - check if the player has max ammo already
|
|
if ( triggerer GetFractionMaxAmmo( weaponToGetAmmo ) >= 1 )
|
|
continue;
|
|
|
|
// player picks up the ammo
|
|
break;
|
|
}
|
|
|
|
// give player one more ammo, play pickup sound, and delete the ammo and trigger
|
|
if ( IsDefined( emptyActionSlotAmmo ) )
|
|
triggerer GiveWeapon( weaponToGetAmmo ); // this will only be for C4 and claymores if the player is totally out of them
|
|
else
|
|
{
|
|
rounds = 1;
|
|
if ( sWeaponType == "556" || sWeaponType == "762" )
|
|
{
|
|
rounds = 30;
|
|
}
|
|
else if ( sWeaponType == "45" )
|
|
{
|
|
rounds = 25;
|
|
}
|
|
else if ( sWeaponType == "pistol" )
|
|
{
|
|
rounds = 15;
|
|
}
|
|
triggerer SetWeaponAmmoStock( weaponToGetAmmo, triggerer GetWeaponAmmoStock( weaponToGetAmmo ) + rounds );
|
|
}
|
|
|
|
triggerer PlayLocalSound( "grenade_pickup" );
|
|
trig Delete();
|
|
|
|
// usable items might not exist anymore at this point since they are deleted in code on player touch
|
|
if ( IsDefined( self ) )
|
|
{
|
|
self Delete();
|
|
}
|
|
}
|
|
|
|
get_script_linkto_targets()
|
|
{
|
|
targets = [];
|
|
if ( !isdefined( self.script_linkTo ) )
|
|
return targets;
|
|
|
|
tokens = StrTok( self.script_linkto, " " );
|
|
for ( i = 0; i < tokens.size; i++ )
|
|
{
|
|
token = tokens[ i ];
|
|
target = GetEnt( token, "script_linkname" );
|
|
if ( IsDefined( target ) )
|
|
targets[ targets.size ] = target;
|
|
}
|
|
return targets;
|
|
}
|
|
|
|
delete_link_chain( trigger )
|
|
{
|
|
// deletes all entities that it script_linkto's, and all entities that entity script linktos, etc.
|
|
trigger waittill( "trigger" );
|
|
|
|
targets = trigger get_script_linkto_targets();
|
|
array_thread( targets, ::delete_links_then_self );
|
|
}
|
|
|
|
delete_links_then_self()
|
|
{
|
|
targets = get_script_linkto_targets();
|
|
array_thread( targets, ::delete_links_then_self );
|
|
self Delete();
|
|
}
|
|
|
|
/*
|
|
A depth trigger that sets fog
|
|
*/
|
|
trigger_fog( trigger )
|
|
{
|
|
waittillframeend;
|
|
|
|
start_fog = trigger.script_fogset_start;
|
|
end_fog = trigger.script_fogset_end;
|
|
|
|
AssertEx( IsDefined( start_fog ), "Fog trigger is missing .script_fogset_start" );
|
|
AssertEx( IsDefined( end_fog ), "Fog trigger is missing .script_fogset_end" );
|
|
|
|
trigger.sunfog_enabled = false;
|
|
|
|
if ( IsDefined( start_fog ) && IsDefined( end_fog ) )
|
|
{
|
|
start_fog_ent = get_fog( start_fog );
|
|
end_fog_ent = get_fog( end_fog );
|
|
|
|
AssertEx( IsDefined( start_fog_ent ), "Fog set " + start_fog + " does not exist, please use create_fog() in level_fog.gsc." );
|
|
AssertEx( IsDefined( end_fog_ent ), "Fog set " + end_fog + " does not exist, please use create_fog() in level_fog.gsc." );
|
|
|
|
trigger.start_neardist = start_fog_ent.startDist;
|
|
trigger.start_fardist = start_fog_ent.halfwayDist;
|
|
trigger.start_color = ( start_fog_ent.red, start_fog_ent.green, start_fog_ent.blue );
|
|
trigger.start_opacity = start_fog_ent.maxOpacity;
|
|
trigger.sunfog_enabled = ( IsDefined( start_fog_ent.sunred ) || IsDefined( end_fog_ent.sunred ) );
|
|
|
|
if ( IsDefined( start_fog_ent.sunred ) )
|
|
{
|
|
Assert( IsDefined( start_fog_ent.sungreen ) );
|
|
Assert( IsDefined( start_fog_ent.sunblue ) );
|
|
Assert( IsDefined( start_fog_ent.sundir ) );
|
|
Assert( IsDefined( start_fog_ent.sunBeginFadeAngle ) );
|
|
Assert( IsDefined( start_fog_ent.sunEndFadeAngle ) );
|
|
Assert( IsDefined( start_fog_ent.normalFogScale ) );
|
|
|
|
trigger.start_suncolor = ( start_fog_ent.sunred, start_fog_ent.sungreen, start_fog_ent.sunblue );
|
|
trigger.start_sundir = start_fog_ent.sundir;
|
|
trigger.start_sunBeginFadeAngle = start_fog_ent.sunBeginFadeAngle;
|
|
trigger.start_sunEndFadeAngle = start_fog_ent.sunEndFadeAngle;
|
|
trigger.start_sunFogScale = start_fog_ent.normalFogScale;
|
|
}
|
|
else
|
|
{
|
|
if ( trigger.sunfog_enabled )
|
|
{
|
|
trigger.start_suncolor = trigger.start_color;
|
|
trigger.start_sundir = ( 0, 0, 0 );
|
|
trigger.start_sunBeginFadeAngle = 0;
|
|
trigger.start_sunEndFadeAngle = 90;
|
|
trigger.start_sunFogScale = 1;
|
|
}
|
|
}
|
|
|
|
trigger.end_neardist = end_fog_ent.startDist;
|
|
trigger.end_fardist = end_fog_ent.halfwayDist;
|
|
trigger.end_color = ( start_fog_ent.red, start_fog_ent.green, start_fog_ent.blue );
|
|
trigger.end_opacity = end_fog_ent.maxOpacity;
|
|
|
|
if ( IsDefined( end_fog_ent.sunred ) )
|
|
{
|
|
Assert( IsDefined( end_fog_ent.sungreen ) );
|
|
Assert( IsDefined( end_fog_ent.sunblue ) );
|
|
Assert( IsDefined( end_fog_ent.sundir ) );
|
|
Assert( IsDefined( end_fog_ent.sunBeginFadeAngle ) );
|
|
Assert( IsDefined( end_fog_ent.sunEndFadeAngle ) );
|
|
Assert( IsDefined( end_fog_ent.normalFogScale ) );
|
|
|
|
trigger.end_suncolor = ( end_fog_ent.sunred, end_fog_ent.sungreen, end_fog_ent.sunblue );
|
|
trigger.end_sundir = end_fog_ent.sundir;
|
|
trigger.end_sunBeginFadeAngle = end_fog_ent.sunBeginFadeAngle;
|
|
trigger.end_sunEndFadeAngle = end_fog_ent.sunEndFadeAngle;
|
|
trigger.end_sunFogScale = end_fog_ent.normalFogScale;
|
|
}
|
|
else
|
|
{
|
|
if ( trigger.sunfog_enabled )
|
|
{
|
|
trigger.end_suncolor = trigger.end_color;
|
|
trigger.end_sundir = ( 0, 0, 0 );
|
|
trigger.end_sunBeginFadeAngle = 0;
|
|
trigger.end_sunEndFadeAngle = 90;
|
|
trigger.end_sunFogScale = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
AssertEx( IsDefined( trigger.start_neardist ), "trigger_fog lacks start_neardist" );
|
|
AssertEx( IsDefined( trigger.start_fardist ), "trigger_fog lacks start_fardist" );
|
|
AssertEx( IsDefined( trigger.start_color ), "trigger_fog lacks start_color" );
|
|
|
|
AssertEx( IsDefined( trigger.end_color ), "trigger_fog lacks end_color" );
|
|
AssertEx( IsDefined( trigger.end_neardist ), "trigger_fog lacks end_neardist" );
|
|
AssertEx( IsDefined( trigger.end_fardist ), "trigger_fog lacks end_fardist" );
|
|
|
|
AssertEx( IsDefined( trigger.target ), "trigger_fog doesnt target an origin to set the start plane" );
|
|
ent = GetEnt( trigger.target, "targetname" );
|
|
AssertEx( IsDefined( ent ), "trigger_fog doesnt target an origin to set the start plane" );
|
|
|
|
start = ent.origin;
|
|
end = undefined;
|
|
|
|
if ( IsDefined( ent.target ) )
|
|
{
|
|
// if the origin targets a second origin, use it as the end point
|
|
target_ent = GetEnt( ent.target, "targetname" );
|
|
end = target_ent.origin;
|
|
}
|
|
else
|
|
{
|
|
// otherwise double the difference between the target origin and start to get the endpoint
|
|
end = start + vector_multiply( trigger.origin - start, 2 );
|
|
}
|
|
|
|
// thread linedraw( start, end, (1,0.5,1) );
|
|
// thread print3ddraw( start, "start", (1,0.5,1) );
|
|
// thread print3ddraw( end, "end", (1,0.5,1) );
|
|
dist = Distance( start, end );
|
|
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger", other );
|
|
AssertEx( IsPlayer( other ), "Non - player entity touched a trigger_fog." );
|
|
|
|
progress = 0;
|
|
while ( other IsTouching( trigger ) )
|
|
{
|
|
progress = maps\_ambient::get_progress( start, end, dist, other.origin );
|
|
// PrintLn( "progress " + progress );
|
|
|
|
if ( progress < 0 )
|
|
progress = 0;
|
|
|
|
if ( progress > 1 )
|
|
progress = 1;
|
|
|
|
trigger set_fog_progress( progress );
|
|
wait( 0.05 );
|
|
}
|
|
|
|
// when you leave the trigger set it to whichever point it was closest too
|
|
if ( progress > 0.5 )
|
|
progress = 1;
|
|
else
|
|
progress = 0;
|
|
|
|
trigger set_fog_progress( progress );
|
|
}
|
|
}
|
|
|
|
set_fog_progress( progress )
|
|
{
|
|
anti_progress = 1 - progress;
|
|
startdist = self.start_neardist * anti_progress + self.end_neardist * progress;
|
|
halfwayDist = self.start_fardist * anti_progress + self.end_fardist * progress;
|
|
color = self.start_color * anti_progress + self.end_color * progress;
|
|
start_opacity = self.start_opacity;
|
|
end_opacity = self.end_opacity;
|
|
|
|
if ( !isdefined( start_opacity ) )
|
|
start_opacity = 1;
|
|
|
|
if ( !isdefined( end_opacity ) )
|
|
end_opacity = 1;
|
|
|
|
opacity = start_opacity * anti_progress + end_opacity * progress;
|
|
|
|
if ( self.sunfog_enabled )
|
|
{
|
|
sun_color = self.start_suncolor * anti_progress + self.end_suncolor * progress;
|
|
sun_dir = self.start_sundir * anti_progress + self.end_sundir * progress;
|
|
begin_angle = self.start_sunBeginFadeAngle * anti_progress + self.end_sunBeginFadeAngle * progress;
|
|
end_angle = self.start_sunEndFadeAngle * anti_progress + self.end_sunEndFadeAngle * progress;
|
|
sun_fog_scale = self.start_sunFogScale * anti_progress + self.end_sunFogScale * progress;
|
|
|
|
SetExpFog(
|
|
startdist,
|
|
halfwaydist,
|
|
color[ 0 ],
|
|
color[ 1 ],
|
|
color[ 2 ],
|
|
opacity,
|
|
0.4,
|
|
sun_color[ 0 ],
|
|
sun_color[ 1 ],
|
|
sun_color[ 2 ],
|
|
sun_dir,
|
|
begin_angle,
|
|
end_angle,
|
|
sun_fog_scale
|
|
);
|
|
}
|
|
else
|
|
{
|
|
SetExpFog(
|
|
startdist,
|
|
halfwaydist,
|
|
color[ 0 ],
|
|
color[ 1 ],
|
|
color[ 2 ],
|
|
opacity,
|
|
0.4
|
|
);
|
|
}
|
|
}
|
|
|
|
remove_level_first_frame()
|
|
{
|
|
wait( 0.05 );
|
|
level.first_frame = -1;
|
|
}
|
|
|
|
no_crouch_or_prone_think( trigger )
|
|
{
|
|
array_thread( level.players, ::no_crouch_or_prone_think_for_player, trigger );
|
|
}
|
|
|
|
no_crouch_or_prone_think_for_player( trigger )
|
|
{
|
|
assert( isplayer( self ) );
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger", player );
|
|
|
|
if ( !isdefined( player ) )
|
|
continue;
|
|
|
|
if ( player != self )
|
|
continue;
|
|
|
|
while ( player IsTouching( trigger ) )
|
|
{
|
|
player AllowProne( false );
|
|
player AllowCrouch( false );
|
|
wait( 0.05 );
|
|
}
|
|
player AllowProne( true );
|
|
player AllowCrouch( true );
|
|
}
|
|
}
|
|
|
|
no_prone_think( trigger )
|
|
{
|
|
array_thread( level.players, ::no_prone_think_for_player, trigger );
|
|
}
|
|
|
|
no_prone_think_for_player( trigger )
|
|
{
|
|
assert( isplayer( self ) );
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger", player );
|
|
|
|
if ( !isdefined( player ) )
|
|
continue;
|
|
|
|
if ( player != self )
|
|
continue;
|
|
|
|
while ( player IsTouching( trigger ) )
|
|
{
|
|
player AllowProne( false );
|
|
wait( 0.05 );
|
|
}
|
|
player AllowProne( true );
|
|
}
|
|
}
|
|
|
|
load_friendlies()
|
|
{
|
|
if ( IsDefined( game[ "total characters" ] ) )
|
|
{
|
|
game_characters = game[ "total characters" ];
|
|
PrintLn( "Loading Characters: ", game_characters );
|
|
}
|
|
else
|
|
{
|
|
PrintLn( "Loading Characters: None!" );
|
|
return;
|
|
}
|
|
|
|
ai = GetAIArray( "allies" );
|
|
total_ai = ai.size;
|
|
index_ai = 0;
|
|
|
|
spawners = GetSpawnerTeamArray( "allies" );
|
|
total_spawners = spawners.size;
|
|
index_spawners = 0;
|
|
|
|
while ( 1 )
|
|
{
|
|
if ( ( ( total_ai <= 0 ) && ( total_spawners <= 0 ) ) || ( game_characters <= 0 ) )
|
|
return;
|
|
|
|
if ( total_ai > 0 )
|
|
{
|
|
if ( IsDefined( ai[ index_ai ].script_friendname ) )
|
|
{
|
|
total_ai--;
|
|
index_ai++;
|
|
continue;
|
|
}
|
|
|
|
PrintLn( "Loading character.. ", game_characters );
|
|
ai[ index_ai ] codescripts\character::new();
|
|
ai[ index_ai ] thread codescripts\character::load( game[ "character" + ( game_characters - 1 ) ] );
|
|
total_ai--;
|
|
index_ai++;
|
|
game_characters--;
|
|
continue;
|
|
}
|
|
|
|
if ( total_spawners > 0 )
|
|
{
|
|
if ( IsDefined( spawners[ index_spawners ].script_friendname ) )
|
|
{
|
|
total_spawners--;
|
|
index_spawners++;
|
|
continue;
|
|
}
|
|
|
|
PrintLn( "Loading character.. ", game_characters );
|
|
info = game[ "character" + ( game_characters - 1 ) ];
|
|
precache( info [ "model" ] );
|
|
precache( info [ "model" ] );
|
|
spawners[ index_spawners ] thread spawn_setcharacter( game[ "character" + ( game_characters - 1 ) ] );
|
|
total_spawners--;
|
|
index_spawners++;
|
|
game_characters--;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
check_flag_for_stat_tracking( msg )
|
|
{
|
|
if ( !issuffix( msg, "aa_" ) )
|
|
return;
|
|
|
|
[[ level.sp_stat_tracking_func ]]( msg );
|
|
}
|
|
|
|
|
|
|
|
precache_script_models()
|
|
{
|
|
waittillframeend;
|
|
if ( !isdefined( level.scr_model ) )
|
|
return;
|
|
models = GetArrayKeys( level.scr_model );
|
|
for ( i = 0; i < models.size; i++ )
|
|
{
|
|
if ( IsArray( level.scr_model[ models[ i ] ] ) )
|
|
{
|
|
for ( modelIndex = 0; modelIndex < level.scr_model[ models[ i ] ].size; modelIndex++ )
|
|
PreCacheModel( level.scr_model[ models[ i ] ][ modelIndex ] );
|
|
}
|
|
else
|
|
PreCacheModel( level.scr_model[ models[ i ] ] );
|
|
}
|
|
}
|
|
|
|
|
|
filmy()
|
|
{
|
|
if ( GetDvar( "grain_test" ) == "" )
|
|
return;
|
|
effect = LoadFX( "misc/grain_test" );
|
|
looper = Spawn( "script_model", level.player GetEye() );
|
|
looper SetModel( "tag_origin" );
|
|
looper Hide();
|
|
PlayFXOnTag( effect, looper, "tag_origin" );
|
|
SetTimeScale( 1.7 );
|
|
while ( 1 )
|
|
{
|
|
wait .05;
|
|
VisionSetNaked( "sepia" );
|
|
looper.origin = level.player GetEye() + ( vector_multiply( AnglesToForward( level.player GetPlayerAngles() ), 50 ) );
|
|
}
|
|
}
|
|
|
|
arcademode_save()
|
|
{
|
|
has_save = [];
|
|
has_save[ "cargoship" ] = true;
|
|
has_save[ "blackout" ] = true;
|
|
has_save[ "armada" ] = true;
|
|
has_save[ "bog_a" ] = true;
|
|
has_save[ "hunted" ] = true;
|
|
has_save[ "ac130" ] = true;
|
|
has_save[ "bog_b" ] = true;
|
|
has_save[ "airlift" ] = true;
|
|
has_save[ "village_assault" ] = true;
|
|
has_save[ "scoutsniper" ] = true;
|
|
has_save[ "ambush" ] = true;
|
|
has_save[ "sniperescape" ] = false;
|
|
has_save[ "village_defend" ] = false;
|
|
has_save[ "icbm" ] = true;
|
|
has_save[ "launchfacility_a" ] = true;
|
|
has_save[ "launchfacility_b" ] = false;
|
|
has_save[ "jeepride" ] = false;
|
|
has_save[ "airplane" ] = true;
|
|
|
|
if ( has_save[ level.script ] )
|
|
return;
|
|
|
|
wait 2.5;
|
|
imagename = "levelshots / autosave / autosave_" + level.script + "start";
|
|
// string not found for AUTOSAVE_LEVELSTART
|
|
SaveGame( "levelstart", &"AUTOSAVE_LEVELSTART", imagename, true );
|
|
}
|
|
|
|
player_death_detection()
|
|
{
|
|
// a dvar starts high then degrades over time whenever the player dies,
|
|
// checked from maps\_utility::player_died_recently()
|
|
SetDvar( "player_died_recently", "0" );
|
|
thread player_died_recently_degrades();
|
|
|
|
level add_wait( ::flag_wait, "missionfailed" );
|
|
level.player add_wait( ::waittill_msg, "death" );
|
|
do_wait_any();
|
|
|
|
recently_skill = [];
|
|
recently_skill[ 0 ] = 70;
|
|
recently_skill[ 1 ] = 30;
|
|
recently_skill[ 2 ] = 0;
|
|
recently_skill[ 3 ] = 0;
|
|
|
|
SetDvar( "player_died_recently", recently_skill[ level.gameskill ] );
|
|
}
|
|
|
|
player_died_recently_degrades()
|
|
{
|
|
for ( ;; )
|
|
{
|
|
recent_death_time = GetDvarInt( "player_died_recently", 0 );
|
|
if ( recent_death_time > 0 )
|
|
{
|
|
recent_death_time -= 5;
|
|
SetDvar( "player_died_recently", recent_death_time );
|
|
}
|
|
wait( 5 );
|
|
}
|
|
}
|
|
|
|
set_legacy_map()
|
|
{
|
|
switch( level.script )
|
|
{
|
|
case "killhouse":
|
|
case "cargoship":
|
|
case "coup":
|
|
case "blackout":
|
|
case "armada":
|
|
case "bog_a":
|
|
case "hunted":
|
|
case "ac130":
|
|
case "bog_b":
|
|
case "airlift":
|
|
case "aftermath":
|
|
case "village_assault":
|
|
case "scoutsniper":
|
|
case "sniperescape":
|
|
case "village_defend":
|
|
case "ambush":
|
|
case "icbm":
|
|
case "launchfacility_a":
|
|
case "launchfacility_b":
|
|
case "jeepride":
|
|
case "airplane":
|
|
return true;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
trigger_spawngroup( trigger )
|
|
{
|
|
waittillframeend;// so level.spawn_groups is defined
|
|
|
|
AssertEx( IsDefined( trigger.script_spawngroup ), "spawngroup Trigger at " + trigger.origin + " has no script_spawngroup" );
|
|
spawngroup = trigger.script_spawngroup;
|
|
if ( !isdefined( level.spawn_groups[ spawngroup ] ) )
|
|
return;
|
|
|
|
trigger waittill( "trigger" );
|
|
|
|
spawners = random( level.spawn_groups[ spawngroup ] );
|
|
|
|
foreach ( _, spawner in spawners )
|
|
{
|
|
spawner spawn_ai();
|
|
}
|
|
}
|
|
|
|
init_level_players()
|
|
{
|
|
level.players = GetEntArray( "player", "classname" );
|
|
for ( i = 0; i < level.players.size; i++ )
|
|
{
|
|
level.players[ i ].unique_id = "player" + i;
|
|
}
|
|
|
|
level.player = level.players[ 0 ];
|
|
if ( level.players.size > 1 )
|
|
level.player2 = level.players[ 1 ];
|
|
|
|
level notify( "level.players initialized" );
|
|
}
|
|
|
|
kill_all_players_trigger()
|
|
{
|
|
self waittill( "trigger", player );
|
|
|
|
// disable co-op revive
|
|
if ( flag_exist( "coop_revive" ) )
|
|
flag_clear( "coop_revive" );
|
|
|
|
if ( flag_exist( "coop_alldowned" ) )
|
|
flag_set( "coop_alldowned" );
|
|
|
|
if ( IsDefined( player ) && IsAlive( player ) )
|
|
{
|
|
player EnableHealthShield( false );
|
|
player Kill( player.origin );
|
|
}
|
|
}
|
|
|
|
trigger_vehicle_spline_spawn( trigger )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
//wait( 3 );
|
|
spawners = GetEntArray( trigger.target, "targetname" );
|
|
foreach ( spawner in spawners )
|
|
{
|
|
spawner thread maps\_vehicle::spawn_vehicle_and_attach_to_spline_path( 70 );
|
|
wait( 0.05 );// slow start it up so spread it out
|
|
}
|
|
}
|
|
|
|
trigger_vehicle_spawn( trigger )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
|
|
spawners = GetEntArray( trigger.target, "targetname" );
|
|
foreach ( spawner in spawners )
|
|
{
|
|
spawner thread maps\_vehicle::spawn_vehicle_and_gopath();
|
|
wait( 0.05 );// slow start it up so spread it out
|
|
}
|
|
}
|
|
|
|
trigger_dooropen( trigger )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
targets = GetEntArray( trigger.target, "targetname" );
|
|
rotations = [];
|
|
rotations[ "left_door" ] = -170;
|
|
rotations[ "right_door" ] = 170;
|
|
foreach ( door in targets )
|
|
{
|
|
AssertEx( IsDefined( door.script_noteworthy ), "Door had no script_noteworthy to indicate which door it is. Must be left_door or right_door." );
|
|
rotation = rotations[ door.script_noteworthy ];
|
|
door ConnectPaths();
|
|
door RotateYaw( rotation, 1, 0, 0.5 );
|
|
}
|
|
}
|
|
|
|
trigger_glass_break( trigger )
|
|
{
|
|
glassID = GetGlassArray( trigger.target );
|
|
|
|
if ( !IsDefined( glassID ) || glassID.size == 0 )
|
|
{
|
|
AssertMsg( "Glass shatter trigger at origin " + trigger.origin + " needs to target a func_glass." );
|
|
return;
|
|
}
|
|
|
|
while ( 1 )
|
|
{
|
|
level waittill( "glass_break", other );
|
|
|
|
// the ent that sent the notify needs to be touching the trigger_glass_break
|
|
if ( other IsTouching( trigger ) )
|
|
{
|
|
// try to figure out the direction of movement
|
|
ref1 = other.origin;
|
|
wait( 0.05 );
|
|
ref2 = other.origin;
|
|
|
|
direction = undefined;
|
|
if ( ref1 != ref2 )
|
|
{
|
|
direction = ref2 - ref1;
|
|
}
|
|
|
|
if ( IsDefined( direction ) )
|
|
{
|
|
foreach ( glass in glassID )
|
|
DestroyGlass( glass, direction );
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
foreach ( glass in glassID )
|
|
DestroyGlass( glass );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
trigger Delete();
|
|
}
|
|
|
|
trigger_vehicle_getin_spawn( trigger )
|
|
{
|
|
vehicle_spawners = GetEntArray( trigger.target, "targetname" );
|
|
foreach ( spawner in vehicle_spawners )
|
|
{
|
|
targets = GetEntArray( spawner.target, "targetname" );
|
|
foreach ( target in targets )
|
|
{
|
|
if ( !IsSubStr( target.code_classname, "actor" ) )
|
|
continue;
|
|
if ( !( target.spawnflags & 1 ) )
|
|
continue;
|
|
target.dont_auto_ride = true;
|
|
}
|
|
}
|
|
trigger waittill( "trigger" );
|
|
|
|
vehicle_spawners = GetEntArray( trigger.target, "targetname" );
|
|
array_thread( vehicle_spawners, ::add_spawn_function, ::vehicle_spawns_targets_and_rides );
|
|
array_thread( vehicle_spawners, ::spawn_vehicle );
|
|
}
|
|
|
|
vehicle_spawns_targets_and_rides()
|
|
{
|
|
targets = GetEntArray( self.target, "targetname" );
|
|
spawners = [];
|
|
foreach ( target in targets )
|
|
{
|
|
if ( target.code_classname == "info_vehicle_node" )
|
|
continue;
|
|
spawners[ spawners.size ] = target;
|
|
}
|
|
|
|
// make the closest spawner the driver
|
|
spawners = get_array_of_closest( self.origin, spawners );
|
|
|
|
foreach ( index, spawner in spawners )
|
|
{
|
|
spawner thread add_spawn_function( ::guy_spawns_and_gets_in_vehicle, self, index );
|
|
}
|
|
|
|
array_thread( spawners, ::spawn_ai );
|
|
self waittill( "guy_entered" );
|
|
wait( 3 );
|
|
|
|
self thread vehicle_becomes_crashable();
|
|
if ( !self.riders.size )
|
|
return;
|
|
|
|
|
|
self gopath();
|
|
self leave_path_for_spline_path();
|
|
}
|
|
|
|
guy_spawns_and_gets_in_vehicle( vehicle, position )
|
|
{
|
|
self mount_snowmobile( vehicle, position );
|
|
}
|
|
|
|
|
|
watchWeaponChange()
|
|
{
|
|
if ( !isdefined( level.friendly_thermal_Reflector_Effect ) )
|
|
level.friendly_thermal_Reflector_Effect = LoadFX( "misc/thermal_tapereflect_inverted" );
|
|
self endon( "death" );
|
|
|
|
//if ( IsSubStr( self GetCurrentWeapon(), "_thermal" ) )
|
|
weap = self GetCurrentWeapon();
|
|
if ( weap_has_thermal( weap ) )
|
|
self thread thermal_tracker();
|
|
|
|
while ( 1 )
|
|
{
|
|
self waittill( "weapon_change", newWeapon );
|
|
|
|
if ( weap_has_thermal( newWeapon ) )
|
|
self thread thermal_tracker();
|
|
else
|
|
self notify( "acogThermalTracker" );
|
|
}
|
|
}
|
|
|
|
weap_has_thermal( weap )
|
|
{
|
|
if ( !isdefined( weap ) )
|
|
return false;
|
|
if ( weap == "none" )
|
|
return false;
|
|
if ( WeaponHasThermalScope( weap ) )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
thermal_tracker()
|
|
{
|
|
self endon( "death" );
|
|
|
|
self notify( "acogThermalTracker" );
|
|
self endon( "acogThermalTracker" );
|
|
|
|
curADS = 0;
|
|
|
|
for ( ;; )
|
|
{
|
|
lastADS = curADS;
|
|
curADS = self PlayerAds();
|
|
|
|
if ( turn_thermal_on( curADS, lastADS ) )
|
|
{
|
|
thermal_EffectsOn();
|
|
}
|
|
else
|
|
if ( turn_thermal_off( curADS, lastADS ) )
|
|
{
|
|
thermal_EffectsOff();
|
|
}
|
|
|
|
wait( 0.05 );
|
|
}
|
|
}
|
|
|
|
turn_thermal_on( curADS, lastADS )
|
|
{
|
|
if ( curADS <= lastADS )
|
|
return false;
|
|
|
|
if ( curADS <= 0.65 )
|
|
return false;
|
|
|
|
return !isdefined( self.is_in_thermal_Vision );
|
|
}
|
|
|
|
turn_thermal_off( curADS, lastADS )
|
|
{
|
|
if ( curADS >= lastADS )
|
|
return false;
|
|
|
|
if ( curADS >= 0.80 )
|
|
return false;
|
|
|
|
return IsDefined( self.is_in_thermal_Vision );
|
|
}
|
|
|
|
|
|
thermal_EffectsOn()
|
|
{
|
|
self.is_in_thermal_Vision = true;
|
|
|
|
friendlies = GetAIArray( "allies" );
|
|
foreach ( guy in friendlies )
|
|
{
|
|
if ( IsDefined( guy.has_thermal_fx ) )
|
|
continue;
|
|
|
|
guy.has_thermal_fx = true;
|
|
guy thread loop_friendly_thermal_Reflector_Effect( self.unique_id );
|
|
}
|
|
|
|
if ( is_coop() )
|
|
{
|
|
other_player = get_other_player( self );
|
|
if ( !isdefined( other_player.has_thermal_fx ) )
|
|
{
|
|
other_player.has_thermal_fx = true;
|
|
other_player thread loop_friendly_thermal_Reflector_Effect( self.unique_id, self );
|
|
}
|
|
}
|
|
}
|
|
|
|
thermal_EffectsOff()
|
|
{
|
|
self.is_in_thermal_Vision = undefined;
|
|
level notify( "thermal_fx_off" + self.unique_id );
|
|
|
|
friendlies = GetAIArray( "allies" );
|
|
for ( index = 0; index < friendlies.size; index++ )
|
|
{
|
|
friendlies[ index ].has_thermal_fx = undefined;
|
|
}
|
|
|
|
if ( is_coop() )
|
|
{
|
|
other_player = get_other_player( self );
|
|
other_player.has_thermal_fx = undefined;
|
|
}
|
|
}
|
|
|
|
loop_friendly_thermal_Reflector_Effect( player_id, onlyForThisPlayer )
|
|
{
|
|
if ( IsDefined( self.has_no_ir ) )
|
|
{
|
|
AssertEx( self.has_no_ir, ".has_ir must be true or undefined" );
|
|
return;
|
|
}
|
|
|
|
level endon( "thermal_fx_off" + player_id );
|
|
self endon( "death" );
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( IsDefined( onlyForThisPlayer ) )
|
|
PlayFXOnTagForClients( level.friendly_thermal_Reflector_Effect, self, "J_Spine4", onlyForThisPlayer );
|
|
else
|
|
PlayFXOnTag( level.friendly_thermal_Reflector_Effect, self, "J_Spine4" );
|
|
|
|
//"tag_reflector_arm_ri"
|
|
|
|
wait( 0.2 );
|
|
}
|
|
}
|
|
|
|
|
|
claymore_pickup_think_global()
|
|
{
|
|
PreCacheItem( "claymore" );
|
|
self endon( "deleted" );
|
|
self SetCursorHint( "HINT_NOICON" );
|
|
// Press and hold &&1 to pickup claymore
|
|
self SetHintString( &"WEAPON_CLAYMORE_PICKUP" );
|
|
self MakeUsable();
|
|
|
|
// if nothing no ammo count is set assume max ammo.
|
|
ammo_count = WeaponMaxAmmo( "claymore" ) + WeaponClipSize( "claymore" );
|
|
|
|
if ( isdefined( self.script_ammo_clip ) )
|
|
{
|
|
ammo_count = self.script_ammo_clip;
|
|
}
|
|
|
|
while( ammo_count > 0 )
|
|
{
|
|
self waittill( "trigger", player );
|
|
|
|
player PlaySound( "weap_pickup" );
|
|
|
|
current_ammo_count = 0;
|
|
if ( !player HasWeapon( "claymore" ) )
|
|
{
|
|
player GiveWeapon( "claymore" );
|
|
}
|
|
else
|
|
{
|
|
current_ammo_count = player GetAmmoCount( "claymore" );
|
|
}
|
|
|
|
if ( IsDefined( ammo_count ) && ammo_count > 0 )
|
|
{
|
|
ammo_count = current_ammo_count + ammo_count;
|
|
|
|
max_ammo = WeaponMaxAmmo( "claymore" );
|
|
clip_size = WeaponClipSize( "claymore" );
|
|
|
|
if ( ammo_count >= clip_size )
|
|
{
|
|
ammo_count -= clip_size;
|
|
player setweaponammoclip( "claymore", clip_size );
|
|
}
|
|
|
|
if ( ammo_count >= max_ammo )
|
|
{
|
|
ammo_count -= max_ammo;
|
|
player SetWeaponAmmoStock( "claymore", max_ammo );
|
|
}
|
|
else if ( ammo_count > 0 )
|
|
{
|
|
player SetWeaponAmmoStock( "claymore", ammo_count );
|
|
ammo_count = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
player GiveMaxAmmo( "claymore" );
|
|
}
|
|
|
|
slotnum = 4;
|
|
if ( IsDefined( player.remotemissile_actionslot ) && player.remotemissile_actionslot == 4 )
|
|
{
|
|
slotnum = 2;
|
|
}
|
|
player SetActionSlot( slotnum, "weapon", "claymore" );
|
|
|
|
player SwitchToWeapon( "claymore" );
|
|
}
|
|
|
|
if ( IsDefined( self.target ) )
|
|
{
|
|
targets = GetEntArray( self.target, "targetname" );
|
|
//give_ammo_count = targets.size + 1;
|
|
foreach ( t in targets )
|
|
t Delete();
|
|
}
|
|
|
|
self MakeUnusable();
|
|
self Delete();
|
|
|
|
}
|
|
|
|
|
|
ammo_cache_think_global()
|
|
{
|
|
self.use_trigger = spawn( "script_model", self.origin + ( 0, 0, 28 ) ); // offset can't be higher than prone height of 30
|
|
self.use_trigger setModel( "tag_origin" );
|
|
self.use_trigger makeUsable();
|
|
self.use_trigger SetCursorHint( "HINT_NOICON" );
|
|
// Press and hold &&1 to refill your ammo
|
|
self.use_trigger setHintString( &"WEAPON_CACHE_USE_HINT" );
|
|
|
|
self thread ammo_icon_think();
|
|
|
|
while ( 1 )
|
|
{
|
|
self.use_trigger waittill( "trigger", player );
|
|
|
|
self.use_trigger MakeUnusable();
|
|
player PlaySound( "player_refill_all_ammo" );
|
|
player DisableWeapons();
|
|
heldweapons = player GetWeaponsListAll();
|
|
foreach ( weapon in heldweapons )
|
|
{
|
|
if ( weapon == "claymore" )
|
|
continue;
|
|
if ( weapon == "c4" )
|
|
continue;
|
|
player GiveMaxAmmo( weapon );
|
|
|
|
clipSize = WeaponClipSize( weapon );
|
|
if( isdefined( clipSize ) )
|
|
{
|
|
if ( player GetWeaponAmmoClip( weapon ) < clipSize )
|
|
player SetWeaponAmmoClip( weapon, clipSize );
|
|
}
|
|
}
|
|
wait 1.5;
|
|
player EnableWeapons();
|
|
self.use_trigger MakeUsable();
|
|
}
|
|
}
|
|
|
|
ammo_icon_think()
|
|
{
|
|
trigger = Spawn( "trigger_radius", self.origin, 0, 320, 72 );
|
|
|
|
icon = NewHudElem();
|
|
icon SetShader( "waypoint_ammo", 1, 1 );
|
|
icon.alpha = 0;
|
|
icon.color = ( 1, 1, 1 );
|
|
icon.x = self.origin[ 0 ];
|
|
icon.y = self.origin[ 1 ];
|
|
icon.z = self.origin[ 2 ] + 16;
|
|
icon SetWayPoint( true, true );
|
|
|
|
wait( 0.05 );
|
|
|
|
while ( true )
|
|
{
|
|
trigger waittill( "trigger", other );
|
|
|
|
if ( !isplayer( other ) )
|
|
continue;
|
|
|
|
while ( other IsTouching( trigger ) )
|
|
{
|
|
show = true;
|
|
weapon = other GetCurrentPrimaryWeapon();
|
|
if ( weapon == "none" )
|
|
show = false;
|
|
else
|
|
if ( ( other GetFractionMaxAmmo( weapon ) ) > .9 )
|
|
show = false;
|
|
|
|
if ( player_looking_at( self.origin, 0.8, true ) && show )
|
|
ammo_icon_fade_in( icon );
|
|
else
|
|
ammo_icon_fade_out( icon );
|
|
wait 0.25;
|
|
}
|
|
ammo_icon_fade_out( icon );
|
|
}
|
|
}
|
|
|
|
ammo_icon_fade_in( icon )
|
|
{
|
|
if ( icon.alpha != 0 )
|
|
return;
|
|
|
|
icon FadeOverTime( 0.2 );
|
|
icon.alpha = .3;
|
|
wait( 0.2 );
|
|
}
|
|
|
|
ammo_icon_fade_out( icon )
|
|
{
|
|
if ( icon.alpha == 0 )
|
|
return;
|
|
|
|
icon FadeOverTime( 0.2 );
|
|
icon.alpha = 0;
|
|
wait( 0.2 );
|
|
}
|
|
|
|
handle_getviewpos()
|
|
{
|
|
/#
|
|
SetDevDvarIfUninitialized( "launcher_viewpos", 0 );
|
|
playerviewpos = ( 0, 0, 0 );
|
|
while ( 1 )
|
|
{
|
|
while ( ! GetDebugDvarInt( "launcher_viewpos" ) )
|
|
wait .05;
|
|
SetDevDvar( "launcher_viewpos", "0" );
|
|
playerviewpos = level.player.origin + ( 0, 0, level.player GetPlayerViewHeight() ) ;
|
|
playerviewangle = level.player GetPlayerAngles();
|
|
launcher_write_clipboard( playerviewpos[ 0 ] + ", " + playerviewpos[ 1 ] + ", " + playerviewpos[ 2 ] );
|
|
|
|
//this part doesn't do anything for radiant. gonna have to make it work sometime.
|
|
// + " " + playerviewangle[0] + " " + playerviewangle[1]
|
|
}
|
|
#/
|
|
}
|
|
|
|
trigger_multiple_visionset( trigger )
|
|
{
|
|
AssertEx( IsDefined( trigger.script_delay ), "Vision set trigger at " + trigger.origin + " has no script_delay to control the fade time." );
|
|
AssertEx( IsDefined( trigger.script_visionset ), "Vision set trigger at " + trigger.origin + " has no script_visionset to control the vision set." );
|
|
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
vision_set_fog_changes( trigger.script_visionset, trigger.script_delay );
|
|
}
|
|
}
|
|
|
|
|
|
handle_getviewangle()
|
|
{
|
|
/#
|
|
SetDevDvarIfUninitialized( "launcher_viewangle", 0 );
|
|
playerviewpos = ( 0, 0, 0 );
|
|
while ( 1 )
|
|
{
|
|
while ( ! GetDvarInt( "launcher_viewangle", 0 ) )
|
|
wait .05;
|
|
SetDevDvar( "launcher_viewangle", "0" );
|
|
playerviewangle = level.player GetPlayerAngles();
|
|
launcher_write_clipboard( playerviewangle[ 0 ] + ", " + playerviewangle[ 1 ] + ", " + playerviewangle[ 2 ] );
|
|
|
|
//this part doesn't do anything for radiant. gonna have to make it work sometime.
|
|
// + " " + playerviewangle[0] + " " + playerviewangle[1]
|
|
}
|
|
#/
|
|
}
|
|
|
|
window_destroy()
|
|
{
|
|
Assert( IsDefined( self.target ) );
|
|
|
|
glassID = GetGlass( self.target );
|
|
|
|
// this can happen with myMapEnts
|
|
//assertex( IsDefined( glassID ), "couldn't find glass for ent with targetname \"window_poster\" at "+ self GetOrigin() );
|
|
if ( !isDefined( glassID ) )
|
|
{
|
|
PrintLn( "Warning: Couldn't find glass with targetname \"" + self.target + "\" for ent with targetname \"window_poster\" at " + self.origin );
|
|
return;
|
|
}
|
|
|
|
level waittillmatch( "glass_destroyed", glassID );
|
|
self Delete();
|
|
}
|
|
|
|
global_empty_callback( empty1, empty2, empty3, empty4, empty5 )
|
|
{
|
|
AssertMsg( "a _stealth or _idle related function was called in a global script without being initilized by the stealth system. If you've already initilized those scripts, then this is a bug for Mo." );
|
|
}
|
|
|
|
trigger_multiple_compass( trigger )
|
|
{
|
|
minimap_image = trigger.script_parameters;
|
|
AssertEx( IsDefined( minimap_image ), "trigger_multiple_compass has no script_parameters for its minimap_image." );
|
|
|
|
if ( !isdefined( level.minimap_image ) )
|
|
level.minimap_image = "";
|
|
for ( ;; )
|
|
{
|
|
trigger waittill( "trigger" );
|
|
if ( level.minimap_image != minimap_image )
|
|
{
|
|
maps\_compass::setupMiniMap( minimap_image );
|
|
}
|
|
}
|
|
}
|
|
|
|
weapon_list_debug()
|
|
{
|
|
create_dvar( "weaponlist", "0" );
|
|
if ( !getdvarint( "weaponlist" ) )
|
|
return;
|
|
|
|
ents = GetEntArray();
|
|
list = [];
|
|
foreach ( ent in ents )
|
|
{
|
|
if ( !isdefined( ent.code_classname ) )
|
|
continue;
|
|
if ( IsSubStr( ent.code_classname, "weapon" ) )
|
|
{
|
|
list[ ent.classname ] = true;
|
|
}
|
|
}
|
|
|
|
PrintLn( "Placed weapons list: " );
|
|
foreach ( weapon, _ in list )
|
|
{
|
|
PrintLn( weapon );
|
|
}
|
|
|
|
spawners = GetSpawnerArray();
|
|
classes = [];
|
|
foreach ( spawner in spawners )
|
|
{
|
|
classes[ spawner.code_classname ] = true;
|
|
}
|
|
|
|
PrintLn( "" );
|
|
PrintLn( "Spawner classnames: " );
|
|
|
|
foreach ( class, _ in classes )
|
|
{
|
|
PrintLn( class );
|
|
}
|
|
}
|
|
|
|
slowmo_system_init()
|
|
{
|
|
level.slowmo = spawnstruct();
|
|
|
|
slowmo_system_defaults();
|
|
|
|
notifyOnCommand( "_cheat_player_press_slowmo", "+melee" );
|
|
notifyOnCommand( "_cheat_player_press_slowmo", "+melee_breath" );
|
|
}
|
|
|
|
slowmo_system_defaults()
|
|
{
|
|
level.slowmo.lerp_time_in = 0.0;
|
|
level.slowmo.lerp_time_out = .25;
|
|
level.slowmo.speed_slow = 0.4;
|
|
level.slowmo.speed_norm = 1.0;
|
|
}
|