init
This commit is contained in:
331
maps/mp/alien/_achievement.gsc
Normal file
331
maps/mp/alien/_achievement.gsc
Normal file
@ -0,0 +1,331 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
GOAL_KILL_WITH_TRAP = 50;
|
||||
GOAL_ESCAPE_IN_TIME = 90000; // 1 minute and 30 second in ms
|
||||
GOAL_ESCAPE_1ST_TIME = 1;
|
||||
GOAL_ESCAPE_ALL_CHALLENGE = 1;
|
||||
GOAL_ESCAPE_ALL_PLAYERS = 4;
|
||||
GOAL_ESCAPE_WITH_NERF_ON = 1;
|
||||
GOAL_SCAVENGE_ITEM = 40;
|
||||
|
||||
init_player_achievement()
|
||||
{
|
||||
self.achievement_list = [];
|
||||
|
||||
if ( isDefined( level.achievement_registration_func ) )
|
||||
[[level.achievement_registration_func]]();
|
||||
|
||||
if ( maps\mp\alien\_utility::is_true( level.include_default_achievements ) )
|
||||
register_default_achievements();
|
||||
}
|
||||
|
||||
register_default_achievements()
|
||||
{
|
||||
// reference goal init_func should_update_func is_goal_reached_func complete_in_casual
|
||||
register_achievement( "KILL_WITH_TRAP" , GOAL_KILL_WITH_TRAP, ::default_init , ::should_update_kill_with_trap , ::equal_to_goal );
|
||||
register_achievement( "ESCAPE_ALL_PLAYERS" , GOAL_ESCAPE_ALL_PLAYERS, ::default_init , ::default_should_update , ::at_least_goal );
|
||||
register_achievement( "ESCAPE_IN_TIME" , GOAL_ESCAPE_IN_TIME, ::default_init , ::default_should_update , ::at_least_goal );
|
||||
register_achievement( "ESCAPE_1ST_TIME" , GOAL_ESCAPE_1ST_TIME, ::default_init , ::default_should_update , ::at_least_goal );
|
||||
register_achievement( "ESCAPE_ALL_CHALLENGE" , GOAL_ESCAPE_ALL_CHALLENGE, ::default_init , ::should_update_all_challenge , ::at_least_goal );
|
||||
register_achievement( "ESCAPE_WITH_NERF_ON" , GOAL_ESCAPE_WITH_NERF_ON, ::default_init , ::default_should_update , ::at_least_goal );
|
||||
register_achievement( "REACH_CITY" , 1, ::default_init , ::default_should_update , ::at_least_goal );
|
||||
register_achievement( "REACH_CABIN" , 1, ::default_init , ::default_should_update , ::at_least_goal );
|
||||
register_achievement( "SCAVENGE_ITEM" , GOAL_SCAVENGE_ITEM, ::default_init , ::default_should_update , ::equal_to_goal );
|
||||
}
|
||||
|
||||
register_achievement( reference, goal, init_func, should_update_func, is_goal_reached_func, complete_in_casual )
|
||||
{
|
||||
achievement = spawnStruct();
|
||||
achievement [[init_func]]( goal, should_update_func, is_goal_reached_func, complete_in_casual );
|
||||
self.achievement_list[reference] = achievement;
|
||||
}
|
||||
|
||||
default_init( goal, should_update_func, is_goal_reached_func, complete_in_casual )
|
||||
{
|
||||
self.progress = 0;
|
||||
self.goal = goal;
|
||||
self.should_update_func = should_update_func;
|
||||
self.is_goal_reached_func = is_goal_reached_func;
|
||||
self.achievement_completed = false;
|
||||
if( isDefined( complete_in_casual ) )
|
||||
self.complete_in_casual =complete_in_casual;
|
||||
}
|
||||
|
||||
default_should_update( unused_1, unused_2, unused_3, unused_4, unused_5, unused_6, unused_7, unused_8, unused_9, unused_10 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
update_progress( progress_amount )
|
||||
{
|
||||
self.progress += progress_amount;
|
||||
}
|
||||
|
||||
at_least_goal()
|
||||
{
|
||||
return ( self.progress >= self.goal );
|
||||
}
|
||||
|
||||
equal_to_goal()
|
||||
{
|
||||
return ( self.progress == self.goal );
|
||||
}
|
||||
|
||||
is_completed()
|
||||
{
|
||||
return ( self.achievement_completed );
|
||||
}
|
||||
|
||||
can_complete_in_causal()
|
||||
{
|
||||
return ( maps\mp\alien\_utility::is_true( self.complete_in_casual ) );
|
||||
}
|
||||
|
||||
mark_completed()
|
||||
{
|
||||
self.achievement_completed = true;
|
||||
}
|
||||
|
||||
is_valid_achievement( achievement )
|
||||
{
|
||||
return ( isDefined ( achievement ) );
|
||||
}
|
||||
|
||||
update_achievement( reference, progress_amt, param_1, param_2, param_3, param_4, param_5, param_6, param_7, param_8, param_9, param_10 )
|
||||
{
|
||||
achievement = self.achievement_list[reference];
|
||||
|
||||
/#//<TODO J.C.> Move this back into release build
|
||||
if(maps\mp\alien\_utility::is_chaos_mode())
|
||||
return;
|
||||
#/
|
||||
|
||||
if ( !is_valid_achievement( achievement ) )
|
||||
return;
|
||||
|
||||
if ( achievement is_completed() )
|
||||
return;
|
||||
|
||||
if ( maps\mp\alien\_utility::is_casual_mode() && !achievement can_complete_in_causal() )
|
||||
return;
|
||||
|
||||
if ( achievement [[achievement.should_update_func]]( param_1, param_2, param_3, param_4, param_5, param_6, param_7, param_8, param_9, param_10 ) )
|
||||
{
|
||||
achievement update_progress( progress_amt );
|
||||
|
||||
if ( achievement [[achievement.is_goal_reached_func]]() )
|
||||
{
|
||||
/#
|
||||
maps\mp\alien\_debug::debug_print_achievement_unlocked( reference, progress_amt );
|
||||
//self IPrintLnBold( "ACHIEVEMENT: " + reference );
|
||||
#/
|
||||
self giveAchievement( reference );
|
||||
|
||||
achievement mark_completed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Related to aliens killed
|
||||
/////////////////////////////////////////
|
||||
update_alien_kill_achievements( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration )
|
||||
{
|
||||
if ( isdefined( level.update_alien_kill_achievements_func ) )
|
||||
[[ level.update_alien_kill_achievements_func ]]( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration );
|
||||
|
||||
if ( !isDefined( eAttacker ) || !isPlayer( eAttacker ) )
|
||||
return;
|
||||
|
||||
eAttacker update_achievement( "KILL_WITH_TRAP", 1, eInflictor );
|
||||
}
|
||||
|
||||
should_update_kill_with_trap( eInflictor, unused_2, unused_3, unused_4, unused_5, unused_6, unused_7, unused_8, unused_9, unused_10 )
|
||||
{
|
||||
if ( maps\mp\alien\_utility::is_trap( eInflictor ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Related to escape
|
||||
///////////////////////////////////////
|
||||
update_escape_achievements( players_escaped, escape_time_remains )
|
||||
{
|
||||
escape_player_count = players_escaped.size;
|
||||
|
||||
foreach ( player in players_escaped )
|
||||
{
|
||||
times_escaped = player maps\mp\alien\_persistence::get_player_escaped();
|
||||
num_nerf_selected = player maps\mp\alien\_prestige::get_num_nerf_selected();
|
||||
player update_personal_escape_achievements( escape_player_count, escape_time_remains, times_escaped, num_nerf_selected );
|
||||
}
|
||||
}
|
||||
|
||||
update_personal_escape_achievements( escape_player_count, escape_time_remains, times_escaped, num_nerf_selected )
|
||||
{
|
||||
self update_achievement( "ESCAPE_ALL_PLAYERS" , escape_player_count );
|
||||
self update_achievement( "ESCAPE_IN_TIME" , escape_time_remains );
|
||||
self update_achievement( "ESCAPE_1ST_TIME" , times_escaped );
|
||||
self update_achievement( "ESCAPE_ALL_CHALLENGE", 1 );
|
||||
self update_achievement( "ESCAPE_WITH_NERF_ON" , num_nerf_selected );
|
||||
}
|
||||
|
||||
should_update_all_challenge( unused_1, unused_2, unused_3, unused_4, unused_5, unused_6, unused_7, unused_8, unused_9, unused_10 )
|
||||
{
|
||||
return level.all_challenge_completed;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Related to kill blocker hive
|
||||
/////////////////////////////////////////
|
||||
update_blocker_hive_achievements( hive_name )
|
||||
{
|
||||
switch( hive_name )
|
||||
{
|
||||
case "lodge_lung_3":
|
||||
update_achievement_all_players( "REACH_CITY", 1 );
|
||||
break;
|
||||
|
||||
case "city_lung_5":
|
||||
update_achievement_all_players( "REACH_CABIN", 1 );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
update_achievement_all_players( reference, progress_amt )
|
||||
{
|
||||
foreach( player in level.players )
|
||||
{
|
||||
player update_achievement( reference, progress_amt );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Related to scavenge item
|
||||
/////////////////////////////////////////
|
||||
update_scavenge_achievement()
|
||||
{
|
||||
self update_achievement( "SCAVENGE_ITEM", 1 );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Kill alien based on weapon
|
||||
/////////////////////////////////////////
|
||||
update_achievement_damage_weapon( sWeapon )
|
||||
{
|
||||
if ( isdefined( level.update_achievement_damage_weapon_func ) )
|
||||
self [[ level.update_achievement_damage_weapon_func ]] ( sWeapon );
|
||||
}
|
||||
|
||||
|
||||
// packNum is 0-indexed
|
||||
eggAllFoundForPack( packNum )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
println( "calculating eggstra xp..." );
|
||||
|
||||
//wait until the first hive is killed to give any awards.`
|
||||
level waittill_any( "regular_hive_destroyed", "obelisk_destroyed", "outpost_encounter_completed" );
|
||||
|
||||
//legacy variable - if its equal to 1015 then we have already awarded xp for packNum 0.
|
||||
legacyState = self GetCoopPlayerData( "alienPlayerStats", "deaths" );
|
||||
|
||||
eggState = self GetCoopPlayerDataReservedInt( "eggstra_state_flags" );
|
||||
packEggState = ( eggState >> ( packnum * 4 ) ) & 15;
|
||||
|
||||
if ( packEggstate == 15 )
|
||||
{
|
||||
//if we got here then the player has found all the eggs for packNum.
|
||||
eggstra_award_flags = self GetCoopPlayerDataReservedInt( "eggstra_award_flags" );
|
||||
hasModifiedFlags = false;
|
||||
|
||||
//update the new flags to reflect the legacy state
|
||||
//if we already awarded pack 0 xp, change eggstra_award_flags to reflect this
|
||||
if ( legacyState == 1015 && (( eggstra_award_flags & ( 1 << 0 )) != 1 ))
|
||||
{
|
||||
//mark the xp award as already given out. This is pack 0, so or a 1 into the 0th slot of the award_flags
|
||||
eggstra_award_flags |= ( 1 << 0 );
|
||||
hasModifiedFlags = true;
|
||||
}
|
||||
|
||||
// checks if we have given the xp award yet.
|
||||
if (( eggstra_award_flags & ( 1 << packNum )) == 0 )
|
||||
{
|
||||
//if we got here we have not awarded it yet.
|
||||
eggstra_award_flags |= ( 1 << packNum );
|
||||
hasModifiedFlags = true;
|
||||
|
||||
self SetClientOmnvar( "ui_alien_eggstra_xp", true );
|
||||
self thread maps\mp\alien\_persistence::wait_and_give_player_xp ( 10000, 5.0 ); //Give player 10,000 Egg-stra XP
|
||||
|
||||
}
|
||||
|
||||
//update the award flags
|
||||
if ( hasModifiedFlags == true )
|
||||
self SetCoopPlayerDataReservedInt( "eggstra_award_flags", eggstra_award_flags );
|
||||
|
||||
//needs updated to be a generic call.
|
||||
self update_mp_eggs_achievement( packnum );
|
||||
}
|
||||
}
|
||||
|
||||
update_mp_eggs_achievement( dlc_num )
|
||||
{
|
||||
switch ( dlc_num )
|
||||
{
|
||||
case 0:
|
||||
self update_achievement( "GOT_THEEGGSTRA_XP", 1 );
|
||||
break;
|
||||
case 1:
|
||||
self update_achievement( "GOT_THEEGGSTRA_XP_DLC2", 1 );
|
||||
break;
|
||||
case 2:
|
||||
self update_achievement( "GOT_THEEGGSTRA_XP_DLC3", 1 );
|
||||
break;
|
||||
case 3:
|
||||
self update_achievement( "GOT_THEEGGSTRA_XP_DLC4", 1 );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Related to scavenge item
|
||||
update_intel_achievement(dlc_num)
|
||||
{
|
||||
dlc_num = 0;
|
||||
map_name = getdvar("ui_mapname" );
|
||||
if(map_name == "mp_alien_armory")
|
||||
dlc_num = 1;
|
||||
if(map_name == "mp_alien_beacon")
|
||||
dlc_num = 2;
|
||||
if(map_name == "mp_alien_dlc3")
|
||||
dlc_num = 3;
|
||||
if(map_name == "mp_alien_last")
|
||||
dlc_num = 4;
|
||||
switch ( dlc_num )
|
||||
{
|
||||
case 1:
|
||||
self update_achievement( "FOUND_ALL_INTELS", 1 );
|
||||
break;
|
||||
case 2:
|
||||
self update_achievement( "FOUND_ALL_INTELS_MAYDAY", 1 );
|
||||
break;
|
||||
case 3:
|
||||
self update_achievement( "AWAKENING_ALL_INTEL", 1 );
|
||||
break;
|
||||
case 4:
|
||||
self update_achievement( "LAST_ALL_INTEL", 1 );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
2052
maps/mp/alien/_airdrop.gsc
Normal file
2052
maps/mp/alien/_airdrop.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1510
maps/mp/alien/_alien_class_skills_main.gsc
Normal file
1510
maps/mp/alien/_alien_class_skills_main.gsc
Normal file
File diff suppressed because it is too large
Load Diff
89
maps/mp/alien/_alien_fx.gsc
Normal file
89
maps/mp/alien/_alien_fx.gsc
Normal file
@ -0,0 +1,89 @@
|
||||
#include maps\mp\alien\_utility;
|
||||
|
||||
main()
|
||||
{
|
||||
init_fx();
|
||||
}
|
||||
|
||||
init_fx()
|
||||
{
|
||||
level._effect[ "vfx_scrnfx_alien_spitter_mist" ] = LoadFX("vfx/gameplay/screen_effects/vfx_scrnfx_alien_spitter_mist");
|
||||
level._effect[ "vfx_scrnfx_alien_blood" ] = LoadFX("vfx/gameplay/screen_effects/vfx_scrnfx_alien_blood" );
|
||||
level._effect[ "vfx_scrnfx_tocam_slidedust_m" ] = LoadFX( "vfx/gameplay/screen_effects/vfx_scrnfx_tocam_slidedust_m" );
|
||||
level._effect[ "vfx_melee_blood_spray" ] = LoadFX( "vfx/gameplay/screen_effects/vfx_melee_blood_spray" );
|
||||
level._effect[ "vfx_blood_hit_left" ] = LoadFX( "vfx/gameplay/screen_effects/vfx_blood_hit_left" );
|
||||
level._effect[ "vfx_blood_hit_right" ] = LoadFX( "vfx/gameplay/screen_effects/vfx_blood_hit_right" );
|
||||
level._effect[ "vfx_alien_spitter_hit_left" ] = LoadFX( "vfx/gameplay/screen_effects/vfx_alien_spitter_hit_left" );
|
||||
level._effect[ "vfx_alien_spitter_hit_right" ] = LoadFX( "vfx/gameplay/screen_effects/vfx_alien_spitter_hit_right" );
|
||||
level._effect[ "vfx_alien_spitter_hit_center" ] = LoadFX( "vfx/gameplay/screen_effects/vfx_alien_spitter_hit_center" );
|
||||
|
||||
}
|
||||
|
||||
alien_fire_on()
|
||||
{
|
||||
if ( !isDefined( self.is_burning ) )
|
||||
{
|
||||
self.is_burning = 0;
|
||||
}
|
||||
self.is_burning++;
|
||||
|
||||
if ( self.is_burning == 1 )
|
||||
{
|
||||
self SetScriptablePartState( "body", "burning" );
|
||||
//self thread disable_fire_on_death();
|
||||
}
|
||||
}
|
||||
|
||||
alien_fire_off()
|
||||
{
|
||||
self.is_burning--;
|
||||
if ( self.is_burning > 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.is_burning = undefined;
|
||||
self notify( "fire_off" );
|
||||
self SetScriptablePartState( "body", "normal" );
|
||||
}
|
||||
|
||||
disable_fx_on_death()
|
||||
{
|
||||
self SetScriptablePartState( "body", "normal" );
|
||||
}
|
||||
|
||||
fx_stun_damage()
|
||||
{
|
||||
// Minion does not have stun scriptable state
|
||||
if ( self get_alien_type() == "minion" )
|
||||
return;
|
||||
|
||||
self endon ("death");
|
||||
self SetScriptablePartState("body", "shocked");
|
||||
wait 0.5;
|
||||
if ( IsAlive(self) )
|
||||
self SetScriptablePartState("body", "normal");
|
||||
|
||||
}
|
||||
|
||||
alien_cloak_fx_on()
|
||||
{
|
||||
if ( !isDefined( self.is_cloaking ) )
|
||||
self.is_cloaking = 0;
|
||||
|
||||
self playsound( "alien_teleport" );
|
||||
self.is_cloaking++;
|
||||
|
||||
if ( self.is_cloaking == 1 )
|
||||
self SetScriptablePartState( "body", "normal" );
|
||||
}
|
||||
|
||||
alien_cloak_fx_off()
|
||||
{
|
||||
self.is_cloaking--;
|
||||
if ( self.is_cloaking > 0 )
|
||||
return;
|
||||
self playsound( "alien_teleport_appear" );
|
||||
|
||||
self.is_cloaking = undefined;
|
||||
self SetScriptablePartState( "body", "normal" );
|
||||
}
|
406
maps/mp/alien/_alien_matchdata.gsc
Normal file
406
maps/mp/alien/_alien_matchdata.gsc
Normal file
@ -0,0 +1,406 @@
|
||||
MAX_NUM_ALIEN_HIVES = 25; // match the value defined as "MaxNumAliensHives" in matchdata.def
|
||||
MAX_NUM_PERKS_BOUGHT = 50; // match the value defined as "MaxNumAliensPerksBought" in matchdata.def
|
||||
MAX_NUM_UPGRADES = 32; // match the value defined as "MaxNumAliensUpgrades" in matchdata.def
|
||||
|
||||
CONST_MAX_BYTE = 127;
|
||||
CONST_MAX_SHORT = 32767;
|
||||
CONST_MAX_INT = 2147483647;
|
||||
|
||||
start_game_type()
|
||||
{
|
||||
init();
|
||||
|
||||
set_is_private_match();
|
||||
|
||||
override_gametype();
|
||||
|
||||
register_upgrade_types();
|
||||
|
||||
level thread wait_set_initial_player_count();
|
||||
}
|
||||
|
||||
set_is_private_match()
|
||||
{
|
||||
setMatchData( "aliensIsPrivateMatch", getDvarInt( "xblive_privatematch" ) );
|
||||
}
|
||||
|
||||
override_gametype() // We are overriding the matchdata "gametype" which is set from the MP logic at line 15 and 19 in _matchdata.gsc
|
||||
{
|
||||
setMatchData( "gametype", get_alien_game_type() );
|
||||
}
|
||||
|
||||
get_alien_game_type()
|
||||
{
|
||||
CONST_CHAOS_MODE = "aliens ch";
|
||||
CONST_HARDCORE_MODE = "aliens hc";
|
||||
CONST_CASUAL_MODE = "aliens ca";
|
||||
CONST_NORMAL_MODE = "aliens";
|
||||
|
||||
if ( maps\mp\alien\_utility::is_chaos_mode() )
|
||||
return CONST_CHAOS_MODE;
|
||||
|
||||
if ( maps\mp\alien\_utility::is_hardcore_mode() )
|
||||
return CONST_HARDCORE_MODE;
|
||||
else if ( maps\mp\alien\_utility::is_casual_mode() )
|
||||
return CONST_CASUAL_MODE;
|
||||
else
|
||||
return CONST_NORMAL_MODE;
|
||||
}
|
||||
|
||||
init()
|
||||
{
|
||||
alien_matchData = spawnStruct();
|
||||
|
||||
single_value_stats = [];
|
||||
single_value_stats["aliensTotalDrillDamage"] = get_single_value_struct( 0, "short" );
|
||||
alien_matchData.single_value_stats = single_value_stats;
|
||||
|
||||
challenge_results = [];
|
||||
alien_matchData.challenge_results = challenge_results;
|
||||
|
||||
level.alien_matchData = alien_matchData;
|
||||
}
|
||||
|
||||
wait_set_initial_player_count()
|
||||
{
|
||||
level endon( "gameEnded" );
|
||||
level waittill("prematch_over");
|
||||
setMatchData( "aliensInitialPlayerCount", validate_byte( level.players.size ) );
|
||||
}
|
||||
|
||||
on_player_connect()
|
||||
{
|
||||
player_init();
|
||||
|
||||
set_max_player_count();
|
||||
set_split_screen();
|
||||
set_alien_loadout();
|
||||
set_join_in_progress();
|
||||
set_relics_selected();
|
||||
set_upgrades_purchased();
|
||||
set_upgrades_enabled();
|
||||
}
|
||||
|
||||
player_init()
|
||||
{
|
||||
alien_matchData = spawnStruct();
|
||||
|
||||
single_value_stats = [];
|
||||
single_value_stats["aliensCashSpentOnWeapon"] = get_single_value_struct( 0, "int" );
|
||||
single_value_stats["aliensCashSpentOnAbility"] = get_single_value_struct( 0, "int" );
|
||||
single_value_stats["aliensCashSpentOnTrap"] = get_single_value_struct( 0, "int" );
|
||||
alien_matchData.single_value_stats = single_value_stats;
|
||||
|
||||
perk_upgraded = [];
|
||||
alien_matchData.perk_upgraded = perk_upgraded;
|
||||
|
||||
lastStand_record = [];
|
||||
lastStand_record["aliensTimesDowned"] = [];
|
||||
lastStand_record["aliensTimesRevived"] = [];
|
||||
lastStand_record["aliensTimesBledOut"] = [];
|
||||
alien_matchData.lastStand_record = lastStand_record;
|
||||
|
||||
self.alien_matchData = alien_matchData;
|
||||
}
|
||||
|
||||
set_max_player_count()
|
||||
{
|
||||
if ( !isDefined( level.max_player_count ) )
|
||||
level.max_player_count = 0;
|
||||
|
||||
if ( ( level.players.size + 1 ) > level.max_player_count )
|
||||
{
|
||||
level.max_player_count++;
|
||||
setMatchData( "aliensMaxPlayerCount", validate_byte( level.max_player_count ) );
|
||||
}
|
||||
}
|
||||
|
||||
set_split_screen()
|
||||
{
|
||||
setMatchData( "players", self.clientid, "isSplitscreen", self isSplitscreenPlayer() );
|
||||
}
|
||||
|
||||
set_join_in_progress()
|
||||
{
|
||||
if ( prematch_over() )
|
||||
setMatchData( "players", self.clientid, "aliensJIP", true );
|
||||
}
|
||||
|
||||
prematch_over()
|
||||
{
|
||||
if ( isDefined( level.startTime ) ) // level.startTime is defined after the prematch period is done
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
set_alien_loadout()
|
||||
{
|
||||
setMatchData( "players", self.clientid, "aliensLoadOut", 0, maps\mp\alien\_persistence::get_selected_perk_0() );
|
||||
setMatchData( "players", self.clientid, "aliensLoadOut", 1, maps\mp\alien\_persistence::get_selected_perk_1() );
|
||||
setMatchData( "players", self.clientid, "aliensLoadOut", 2, maps\mp\alien\_persistence::get_selected_dpad_up() );
|
||||
setMatchData( "players", self.clientid, "aliensLoadOut", 3, maps\mp\alien\_persistence::get_selected_dpad_down() );
|
||||
setMatchData( "players", self.clientid, "aliensLoadOut", 4, maps\mp\alien\_persistence::get_selected_dpad_left() );
|
||||
setMatchData( "players", self.clientid, "aliensLoadOut", 5, maps\mp\alien\_persistence::get_selected_dpad_right() );
|
||||
}
|
||||
|
||||
set_relics_selected()
|
||||
{
|
||||
num_enabled_nerfs = 0;
|
||||
|
||||
foreach( nerf in level.nerf_list )
|
||||
{
|
||||
if ( self alienscheckisrelicenabled( nerf ) )
|
||||
{
|
||||
setMatchData( "players", self.clientid, "aliensRelics", num_enabled_nerfs, nerf );
|
||||
num_enabled_nerfs++;
|
||||
}
|
||||
}
|
||||
|
||||
for( i = num_enabled_nerfs; i < level.nerf_list.size; i++ )
|
||||
setMatchData( "players", self.clientid, "aliensRelics", i, "none" );
|
||||
}
|
||||
|
||||
set_upgrades_purchased()
|
||||
{
|
||||
num_upgrade_purchased = 0;
|
||||
|
||||
foreach( upgrade_ref in level.alien_upgrades )
|
||||
{
|
||||
if( self maps\mp\alien\_persistence::is_upgrade_purchased( upgrade_ref ) )
|
||||
{
|
||||
setMatchData( "players", self.clientid, "aliensUpgradePurchased", num_upgrade_purchased, upgrade_ref );
|
||||
num_upgrade_purchased++;
|
||||
}
|
||||
}
|
||||
|
||||
for( index = num_upgrade_purchased; index < MAX_NUM_UPGRADES; index++ )
|
||||
setMatchData( "players", self.clientid, "aliensUpgradePurchased", index, "none" );
|
||||
}
|
||||
|
||||
set_upgrades_enabled()
|
||||
{
|
||||
num_upgrade_enabled = 0;
|
||||
|
||||
foreach( upgrade_ref in level.alien_upgrades )
|
||||
{
|
||||
if( self maps\mp\alien\_persistence::is_upgrade_enabled( upgrade_ref ) )
|
||||
{
|
||||
setMatchData( "players", self.clientid, "aliensUpgradeEnabled", num_upgrade_enabled, upgrade_ref );
|
||||
num_upgrade_enabled++;
|
||||
}
|
||||
}
|
||||
|
||||
for( index = num_upgrade_enabled; index < MAX_NUM_UPGRADES; index++ )
|
||||
setMatchData( "players", self.clientid, "aliensUpgradeEnabled", index, "none" );
|
||||
}
|
||||
|
||||
inc_drill_heli_damages( damage_amt )
|
||||
{
|
||||
level.alien_matchData.single_value_stats["aliensTotalDrillDamage"].value += damage_amt;
|
||||
}
|
||||
|
||||
set_escape_time_remaining( escape_time_remains )
|
||||
{
|
||||
setMatchData( "aliensEscapeTimeRemaining" , validate_int( escape_time_remains ) );
|
||||
}
|
||||
|
||||
update_challenges_status( challenge_name, result )
|
||||
{
|
||||
if ( level.alien_matchData.challenge_results.size > MAX_NUM_ALIEN_HIVES )
|
||||
return;
|
||||
|
||||
challenge_status = spawnStruct();
|
||||
challenge_status.challenge_name = challenge_name;
|
||||
challenge_status.result = result;
|
||||
|
||||
level.alien_matchData.challenge_results[level.alien_matchData.challenge_results.size] = challenge_status;
|
||||
}
|
||||
|
||||
record_perk_upgrade( perk_name )
|
||||
{
|
||||
if ( self.alien_matchData.perk_upgraded.size > MAX_NUM_PERKS_BOUGHT )
|
||||
return;
|
||||
|
||||
self.alien_matchData.perk_upgraded[self.alien_matchData.perk_upgraded.size] = perk_name;
|
||||
}
|
||||
|
||||
inc_downed_counts()
|
||||
{
|
||||
inc_lastStand_record( "aliensTimesDowned" );
|
||||
}
|
||||
|
||||
inc_revived_counts()
|
||||
{
|
||||
inc_lastStand_record( "aliensTimesRevived" );
|
||||
}
|
||||
|
||||
inc_bleedout_counts()
|
||||
{
|
||||
inc_lastStand_record( "aliensTimesBledOut" );
|
||||
}
|
||||
|
||||
inc_lastStand_record( field_name )
|
||||
{
|
||||
if ( !isDefined( self.alien_matchData.lastStand_record[field_name][level.num_hive_destroyed] ) )
|
||||
self.alien_matchData.lastStand_record[field_name][level.num_hive_destroyed] = 0;
|
||||
|
||||
self.alien_matchData.lastStand_record[field_name][level.num_hive_destroyed]++;
|
||||
}
|
||||
|
||||
update_spending_type( amount_spent, spending_type )
|
||||
{
|
||||
switch( spending_type )
|
||||
{
|
||||
case "weapon":
|
||||
self.alien_matchData.single_value_stats["aliensCashSpentOnWeapon"].value += amount_spent;
|
||||
break;
|
||||
|
||||
case "ability":
|
||||
self.alien_matchData.single_value_stats["aliensCashSpentOnAbility"].value += amount_spent;
|
||||
break;
|
||||
|
||||
case "trap":
|
||||
self.alien_matchData.single_value_stats["aliensCashSpentOnTrap"].value += amount_spent;
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertMsg( "Spending type: " + spending_type + " is not recognized." );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EndGame( end_condition, play_time )
|
||||
{
|
||||
set_game_data( end_condition, play_time );
|
||||
|
||||
foreach( player in level.players )
|
||||
player set_player_game_data();
|
||||
|
||||
sendMatchData();
|
||||
}
|
||||
|
||||
set_game_data( end_condition, play_time )
|
||||
{
|
||||
CONST_CHALLENGES_COMPLETED = "aliensChallengesCompleted";
|
||||
|
||||
setMatchData( "aliensFinalPlayerCount" , validate_byte( level.players.size ) );
|
||||
setMatchData( "aliensHivesDestroyed" , validate_byte( level.num_hive_destroyed ) );
|
||||
setMatchData( "aliensGameOverCondition", end_condition );
|
||||
setMatchData( "aliensTotalTimeElapsed" , validate_int( play_time ) );
|
||||
|
||||
alien_matchData = level.alien_matchData;
|
||||
|
||||
foreach( matchData_field, value_struct in alien_matchData.single_value_stats )
|
||||
{
|
||||
value = validate_value( value_struct.value, value_struct.value_type );
|
||||
setMatchData( matchData_field , value );
|
||||
}
|
||||
|
||||
foreach( index, challenge_status in alien_matchData.challenge_results )
|
||||
{
|
||||
setMatchData( CONST_CHALLENGES_COMPLETED, index, "challengeId", challenge_status.challenge_name );
|
||||
setMatchData( CONST_CHALLENGES_COMPLETED, index, "success" , challenge_status.result );
|
||||
}
|
||||
}
|
||||
|
||||
set_player_game_data()
|
||||
{
|
||||
copy_from_playerData();
|
||||
set_perk_upgraded();
|
||||
set_lastStand_stats();
|
||||
set_single_value_stats();
|
||||
}
|
||||
|
||||
copy_from_playerData()
|
||||
{
|
||||
// Those fields are already tracked in the alienSession section in player data
|
||||
setMatchData( "players", self.clientid, "aliensFinalScore" , validate_int( self GetCoopPlayerData( "alienSession", "score" ) ) );
|
||||
setMatchData( "players", self.clientid, "aliensDrillRepairs", validate_byte( self GetCoopPlayerData( "alienSession", "repairs" ) ) );
|
||||
setMatchData( "players", self.clientid, "aliensXpEarned" , validate_int( self GetCoopPlayerData( "alienSession", "experience" ) ) );
|
||||
}
|
||||
|
||||
set_perk_upgraded()
|
||||
{
|
||||
foreach( index, perk_name in self.alien_matchData.perk_upgraded )
|
||||
setMatchData( "players", self.clientid, "aliensPerksBought", index, perk_name );
|
||||
}
|
||||
|
||||
set_lastStand_stats()
|
||||
{
|
||||
foreach( stat_type, info_array in self.alien_matchData.lastStand_record )
|
||||
{
|
||||
foreach( hive_index, counts in info_array )
|
||||
setMatchData( "players", self.clientid, stat_type, hive_index, validate_byte( counts ) );
|
||||
}
|
||||
}
|
||||
|
||||
set_single_value_stats()
|
||||
{
|
||||
foreach( field_name, value_struct in self.alien_matchData.single_value_stats )
|
||||
{
|
||||
value = validate_value( value_struct.value, value_struct.value_type );
|
||||
setMatchData( "players", self.clientid, field_name, value );
|
||||
}
|
||||
}
|
||||
|
||||
validate_value( value, data_type )
|
||||
{
|
||||
switch( data_type )
|
||||
{
|
||||
case "byte":
|
||||
return validate_byte( value );
|
||||
|
||||
case "short":
|
||||
return validate_short( value );
|
||||
|
||||
case "int":
|
||||
return validate_int( value );
|
||||
|
||||
default:
|
||||
AssertMsg( "Value type: " + data_type + " is not supported" );
|
||||
}
|
||||
}
|
||||
|
||||
validate_byte( value )
|
||||
{
|
||||
return int( min( value, CONST_MAX_BYTE ) );
|
||||
}
|
||||
|
||||
validate_short( value )
|
||||
{
|
||||
return int( min( value, CONST_MAX_SHORT ) );
|
||||
}
|
||||
|
||||
validate_int( value )
|
||||
{
|
||||
return int( min( value, CONST_MAX_INT ) );
|
||||
}
|
||||
|
||||
get_single_value_struct( initial_value, value_type )
|
||||
{
|
||||
value_struct = spawnStruct();
|
||||
value_struct.value = initial_value;
|
||||
value_struct.value_type = value_type;
|
||||
|
||||
return value_struct;
|
||||
}
|
||||
|
||||
register_upgrade_types()
|
||||
{
|
||||
UPGRADE_TABLE = "mp/alien/alien_purchasable_items.csv";
|
||||
TABLE_INDEX_COLUMN = 0;
|
||||
UPGRADE_REF_COLUMN = 1;
|
||||
|
||||
upgrades = [];
|
||||
for ( index = 0; index < MAX_NUM_UPGRADES; index++ )
|
||||
{
|
||||
upgrade_ref = tablelookup( UPGRADE_TABLE, TABLE_INDEX_COLUMN, index, UPGRADE_REF_COLUMN );
|
||||
if ( maps\mp\agents\alien\_alien_agents::is_empty_string( upgrade_ref ) )
|
||||
break;
|
||||
|
||||
upgrades[upgrades.size] = upgrade_ref;
|
||||
}
|
||||
|
||||
level.alien_upgrades = upgrades;
|
||||
}
|
1848
maps/mp/alien/_autosentry_alien.gsc
Normal file
1848
maps/mp/alien/_autosentry_alien.gsc
Normal file
File diff suppressed because it is too large
Load Diff
407
maps/mp/alien/_challenge.gsc
Normal file
407
maps/mp/alien/_challenge.gsc
Normal file
@ -0,0 +1,407 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\alien\_utility;
|
||||
#include maps\mp\alien\_challenge_function;
|
||||
|
||||
init_challenge()
|
||||
{
|
||||
//set up the challenge table automatically
|
||||
map_name = getdvar("ui_mapname" );
|
||||
level.alien_challenge_table = "mp/alien/" + map_name + "_challenges.csv";
|
||||
|
||||
if ( maps\mp\alien\_utility::is_hardcore_mode() )
|
||||
{
|
||||
level.alien_challenge_table = "mp/alien/" + map_name + "_hardcore_challenges.csv";
|
||||
if ( !TableExists( level.alien_challenge_table ) )
|
||||
level.alien_challenge_table = "mp/alien/" + map_name + "_challenges.csv";
|
||||
}
|
||||
|
||||
init_challenge_type();
|
||||
}
|
||||
|
||||
spawn_challenge()
|
||||
{
|
||||
if ( !alien_mode_has( "challenge" ) )
|
||||
return;
|
||||
|
||||
level.current_challenge_index = undefined;
|
||||
level thread spawn_challenge_internal();
|
||||
}
|
||||
|
||||
spawn_challenge_internal()
|
||||
{
|
||||
challenge = get_valid_challenge();
|
||||
if ( !isDefined ( challenge ) )
|
||||
{
|
||||
println( "***CHALLENGE_ERROR*** - no challenge found" );
|
||||
return;
|
||||
}
|
||||
/#
|
||||
if ( GetDvar( "scr_setactivechallenge" ) != "" )
|
||||
{
|
||||
challenge = GetDvar( "scr_setactivechallenge" );
|
||||
SetDvar( "scr_setactivechallenge" ,"" );
|
||||
}
|
||||
#/
|
||||
activate_new_challenge ( challenge );
|
||||
}
|
||||
|
||||
update_challenge ( challenge_name, param_1, param_2, param_3, param_4, param_5, param_6, param_7, param_8, param_9 )
|
||||
{
|
||||
if ( !current_challenge_is ( challenge_name ) || !alien_mode_has( "challenge" ) )
|
||||
return;
|
||||
|
||||
if ( level.pre_challenge_active )
|
||||
return;
|
||||
|
||||
current_challenge = level.challenge_data [ level.current_challenge ];
|
||||
current_challenge [[ current_challenge.updateFunc ]]( param_1, param_2, param_3, param_4, param_5, param_6, param_7, param_8, param_9 );
|
||||
}
|
||||
|
||||
end_current_challenge()
|
||||
{
|
||||
if ( current_challenge_exist() && alien_mode_has( "challenge" ) )
|
||||
deactivate_current_challenge();
|
||||
}
|
||||
|
||||
remove_all_challenge_cases()
|
||||
{
|
||||
level notify ( "remove_all_challenge_case" );
|
||||
}
|
||||
|
||||
get_valid_challenge()
|
||||
{
|
||||
valid_challenges = [];
|
||||
|
||||
foreach ( challenge in level.challenge_data )
|
||||
{
|
||||
if ( isDefined ( challenge.already_issued ) ) //don't repeat the challenges
|
||||
continue;
|
||||
if ( level.players.size == 1 && !is_true(challenge.allowedinsolo) ) //challenge not allowed in solo
|
||||
continue;
|
||||
|
||||
if ( !isDefined ( challenge.allowed_cycles ) )
|
||||
continue;
|
||||
|
||||
allowed_cycles = strTok( challenge.allowed_cycles, " " );
|
||||
|
||||
foreach ( cycle in allowed_cycles ) //see if this challenge is allowed
|
||||
{
|
||||
if ( level.cycle_count - 1 == int( cycle ) )
|
||||
{
|
||||
current_hive = maps\mp\alien\_spawn_director::get_current_encounter();
|
||||
if ( !isDefined ( current_hive ) )
|
||||
{
|
||||
println("***CHALLENGE ERROR*** - no current hive found" );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( should_skip_challenge( challenge ) )
|
||||
continue;
|
||||
|
||||
allowed_hives = StrTok( challenge.allowed_hives," " );
|
||||
foreach ( hive in allowed_hives ) //see if this challenge is allowed for this hive
|
||||
{
|
||||
if ( hive == current_hive )
|
||||
{
|
||||
valid_challenges[ valid_challenges.size ] = challenge;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( valid_challenges.size > 0 )
|
||||
{
|
||||
valid_challenge = valid_challenges[randomint( valid_challenges.size )];
|
||||
valid_challenge.already_issued = true;
|
||||
|
||||
return valid_challenge.ref;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
should_skip_challenge( challenge )
|
||||
{
|
||||
is_weapon_challenge = (challenge.ref == "ar_only" ||
|
||||
challenge.ref == "smg_only" ||
|
||||
challenge.ref == "lmgs_only" ||
|
||||
challenge.ref == "shotguns_only" ||
|
||||
challenge.ref == "2_weapons_only" ||
|
||||
challenge.ref == "semi_autos_only" ||
|
||||
challenge.ref == "new_weapon" ||
|
||||
challenge.ref == "snipers_only" );
|
||||
|
||||
if( !is_weapon_challenge )
|
||||
return false;
|
||||
|
||||
num_pistol_prestige_players = 0;
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( player maps\mp\alien\_prestige::prestige_getPistolsOnly() == 1 )
|
||||
num_pistol_prestige_players++;
|
||||
}
|
||||
|
||||
if ( challenge.ref == "new_weapon" && num_pistol_prestige_players > 0 ) //skip this challenge if any single person has the nerf
|
||||
return true;
|
||||
|
||||
if ( num_pistol_prestige_players >= level.players.size - 1 ) //skip this challenge if the majority of the players have the nerf
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
deactivate_current_challenge()
|
||||
{
|
||||
if ( !current_challenge_exist() )
|
||||
return;
|
||||
|
||||
current_challenge = level.challenge_data [ level.current_challenge ];
|
||||
|
||||
unset_current_challenge();
|
||||
if ( current_challenge [[ current_challenge.isSuccessFunc ]]() )
|
||||
{
|
||||
display_challenge_message ( "challenge_success",false );
|
||||
current_challenge [[ current_challenge.rewardFunc ]]();
|
||||
maps\mp\alien\_gamescore::update_players_encounter_performance( maps\mp\alien\_gamescore::get_challenge_score_component_name(), "challenge_complete" );
|
||||
maps\mp\alien\_persistence::update_LB_alienSession_challenge( true );
|
||||
maps\mp\alien\_alien_matchdata::update_challenges_status( current_challenge.ref, true );
|
||||
level.num_challenge_completed++;
|
||||
|
||||
if ( !is_casual_mode() )
|
||||
{
|
||||
if ( level.num_challenge_completed == 10 )
|
||||
{
|
||||
foreach( player in level.players )
|
||||
player maps\mp\alien\_persistence::give_player_tokens( 2, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
display_challenge_message ( "challenge_failed",false );
|
||||
current_challenge [[ current_challenge.failFunc ]]();
|
||||
level.all_challenge_completed = false;
|
||||
maps\mp\alien\_persistence::update_LB_alienSession_challenge( false );
|
||||
maps\mp\alien\_alien_matchdata::update_challenges_status( current_challenge.ref, false );
|
||||
}
|
||||
|
||||
current_challenge [[ current_challenge.deactivateFunc ]]();
|
||||
}
|
||||
|
||||
activate_new_challenge ( challenge_name )
|
||||
{
|
||||
assert( IsDefined( challenge_name ) && isDefined ( level.challenge_data [ challenge_name ] ) );
|
||||
|
||||
new_challenge = level.challenge_data [ challenge_name ];
|
||||
|
||||
if ( new_challenge [[ new_challenge.canActivateFunc ]]() )
|
||||
{
|
||||
|
||||
scalar = get_challenge_scalar( challenge_name );
|
||||
if ( isDefined ( scalar ) )
|
||||
{
|
||||
level.challenge_data[ challenge_name ].goal = scalar;
|
||||
level.current_challenge_scalar = scalar;
|
||||
}
|
||||
else
|
||||
level.current_challenge_scalar = -1;
|
||||
|
||||
display_challenge_message ( challenge_name, true, scalar ); //get_challenge_activate_string( new_challenge ) );
|
||||
set_current_challenge ( challenge_name );
|
||||
|
||||
level.pre_challenge_active = true;
|
||||
challenge_countdown();
|
||||
level.pre_challenge_active = false;
|
||||
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
player setClientOmnvar ( "ui_intel_prechallenge", 0 );
|
||||
}
|
||||
|
||||
level.current_challenge_pre_challenge = 0;
|
||||
new_challenge [[ new_challenge.activateFunc ]]();
|
||||
}
|
||||
else
|
||||
{
|
||||
new_challenge [[ new_challenge.failActivateFunc ]]();
|
||||
}
|
||||
}
|
||||
|
||||
challenge_countdown()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
new_challenge_time = int ( gettime() + 5000 );
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
player SetClientOmnvar( "ui_intel_timer",new_challenge_time );
|
||||
player SetClientOmnvar ( "ui_intel_title", 1 );
|
||||
}
|
||||
level.current_challenge_title = 1;
|
||||
wait ( 5 );
|
||||
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
player SetClientOmnvar( "ui_intel_timer",-1 );
|
||||
player SetClientOmnvar ( "ui_intel_title", -1 );
|
||||
}
|
||||
level.current_challenge_title = -1;
|
||||
wait ( .5 );
|
||||
}
|
||||
|
||||
|
||||
can_pick_up_challenge ( player )
|
||||
{
|
||||
if ( !IsPlayer(player) )
|
||||
return false;
|
||||
|
||||
if ( isAI( player ) )
|
||||
return false;
|
||||
|
||||
if ( !isAlive( player ) || ( isDefined( player.fauxDead ) && player.fauxDead ) ) //there is a time when you kill your self with remote that this will pass
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
display_challenge_message ( message, activate , scalar )
|
||||
{
|
||||
index = TableLookup(level.alien_challenge_table, 1, message, 0 );
|
||||
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
|
||||
if ( activate )
|
||||
{
|
||||
if ( isDefined ( scalar ) )
|
||||
{
|
||||
player SetClientOmnvar( "ui_intel_challenge_scalar", scalar );
|
||||
}
|
||||
else
|
||||
{
|
||||
player SetClientOmnvar( "ui_intel_challenge_scalar",-1 );
|
||||
}
|
||||
player setClientOmnvar ( "ui_intel_prechallenge", 1 );
|
||||
player SetClientOmnvar( "ui_intel_active_index", int( index ) );
|
||||
level.current_challenge_index = int( index );
|
||||
level.current_challenge_pre_challenge = 1;
|
||||
player PlayLocalSound( "mp_intel_received" );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
player SetClientOmnvar( "ui_intel_active_index", -1 );
|
||||
player SetClientOmnvar ( "ui_intel_progress_current",-1 );
|
||||
player setClientOmnvar ( "ui_intel_progress_max",-1 );
|
||||
player setClientOmnvar ( "ui_intel_percent",-1 );
|
||||
player SetClientOmnvar ( "ui_intel_target_player" , -1 );
|
||||
player setClientOmnvar ( "ui_intel_prechallenge", 0 );
|
||||
player SetClientOmnvar( "ui_intel_timer",-1 );
|
||||
player SetClientOmnvar( "ui_intel_challenge_scalar" ,-1);
|
||||
|
||||
level.current_challenge_index = -1;
|
||||
level.current_challenge_progress_max = -1;
|
||||
level.current_challenge_progress_current = -1;
|
||||
level.current_challenge_percent = -1;
|
||||
level.current_challenge_target_player = -1;
|
||||
level.current_challenge_timer = -1;
|
||||
level.current_challenge_scalar = -1;
|
||||
level.current_challenge_pre_challenge = 0;
|
||||
}
|
||||
}
|
||||
if ( activate )
|
||||
return;
|
||||
|
||||
level thread show_challenge_outcome( message, index );
|
||||
|
||||
}
|
||||
|
||||
show_challenge_outcome( message, challenge_message_index )
|
||||
{
|
||||
level endon("game_ended");
|
||||
wait ( 1 );
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( message == "challenge_failed" )
|
||||
{
|
||||
player SetClientOmnvar("ui_intel_active_index", int( challenge_message_index ) );
|
||||
player PlayLocalSound( "mp_intel_fail" );
|
||||
}
|
||||
else
|
||||
{
|
||||
player SetClientOmnvar("ui_intel_active_index", int ( challenge_message_index ) );
|
||||
player PlayLocalSound( "mp_intel_success" );
|
||||
}
|
||||
}
|
||||
wait ( 4 );
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
player SetClientOmnvar("ui_intel_active_index",-1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
current_challenge_exist() { return isDefined ( level.current_challenge ); }
|
||||
current_challenge_is ( challenge_name ) { return ( current_challenge_exist() && level.current_challenge == challenge_name ); }
|
||||
unset_current_challenge() { level.current_challenge = undefined; }
|
||||
set_current_challenge ( challenge_name ) { level.current_challenge = challenge_name; }
|
||||
|
||||
|
||||
handle_challenge_hotjoin()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
self setClientOmnvar ( "ui_intel_prechallenge", level.current_challenge_pre_challenge );
|
||||
|
||||
if ( current_challenge_exist() )
|
||||
{
|
||||
|
||||
self SetClientOmnvar( "ui_intel_active_index", int( level.current_challenge_index ) );
|
||||
self SetClientOmnvar ( "ui_intel_progress_current", int ( level.current_challenge_progress_current ) );
|
||||
self setClientOmnvar ( "ui_intel_progress_max", int ( level.current_challenge_progress_max ) );
|
||||
self setClientOmnvar ( "ui_intel_percent", int ( level.current_challenge_percent ) );
|
||||
self SetClientOmnvar ( "ui_intel_target_player" , int ( level.current_challenge_target_player ) );
|
||||
self setclientOmnvar ( "ui_intel_title", int ( level.current_challenge_title ) );
|
||||
if ( level.current_challenge_timer > 0 )
|
||||
self SetClientOmnvar( "ui_intel_timer", int ( gettime() + ( level.current_challenge_timer * 1000) ) );
|
||||
|
||||
self SetClientOmnvar( "ui_intel_challenge_scalar", level.current_challenge_scalar );
|
||||
}
|
||||
|
||||
if ( level.current_challenge == "50_percent_accuracy" || level.current_challenge == "75_percent_accuracy" )// accuracy challenges
|
||||
{
|
||||
challenge = level.challenge_data[ level.current_challenge ];
|
||||
self thread track_percent_accuracy_shots_fired_internal( challenge );
|
||||
}
|
||||
else if ( level.current_challenge == "no_reloads" ) //no reloads
|
||||
{
|
||||
self thread wait_for_reload();
|
||||
}
|
||||
else if ( level.current_challenge == "no_abilities" ) // use no abilities
|
||||
{
|
||||
self thread wait_for_ability_use();
|
||||
}
|
||||
|
||||
if ( isDefined ( level.current_drill_health ) )
|
||||
{
|
||||
SetOmnvar( "ui_alien_drill_health_text", int( level.current_drill_health ) );
|
||||
}
|
||||
if ( isDefined ( level.current_drill_time ) )
|
||||
{
|
||||
SetOmnvar( "ui_alien_drill_end_milliseconds", int( level.current_drill_time ) );
|
||||
}
|
||||
}
|
||||
|
||||
get_num_challenge_completed()
|
||||
{
|
||||
if ( !isDefined( level.num_challenge_completed ) )
|
||||
return 0;
|
||||
else
|
||||
return level.num_challenge_completed;
|
||||
}
|
1722
maps/mp/alien/_challenge_function.gsc
Normal file
1722
maps/mp/alien/_challenge_function.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1383
maps/mp/alien/_chaos.gsc
Normal file
1383
maps/mp/alien/_chaos.gsc
Normal file
File diff suppressed because it is too large
Load Diff
135
maps/mp/alien/_chaos_laststand.gsc
Normal file
135
maps/mp/alien/_chaos_laststand.gsc
Normal file
@ -0,0 +1,135 @@
|
||||
#include maps\mp\alien\_laststand;
|
||||
|
||||
CONST_CHAOS_SELF_REVIVE_TIME = 15;
|
||||
CONST_CHAOS_REVIVE_TIME = 3000; // in ms
|
||||
CONST_CHAOS_INITIAL_LASTSTANDS = 3;
|
||||
|
||||
chaos_PlayerLastStand( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, bleedOutSpawnEntity )
|
||||
{
|
||||
gameShouldEnd = chaos_gameShouldEnd( self );
|
||||
|
||||
if ( gameShouldEnd )
|
||||
maps\mp\alien\_chaos_utility::chaos_end_game();
|
||||
|
||||
if ( is_killed_by_kill_trigger( bleedOutSpawnEntity ) )
|
||||
return process_killed_by_kill_trigger( bleedOutSpawnEntity );
|
||||
|
||||
chaos_dropIntoLastStand( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, bleedOutSpawnEntity, gameShouldEnd );
|
||||
}
|
||||
|
||||
process_killed_by_kill_trigger( bleedOutSpawnEntity )
|
||||
{
|
||||
self setOrigin( bleedOutSpawnEntity.origin );
|
||||
maps\mp\alien\_death::set_kill_trigger_event_processed( self, false );
|
||||
|
||||
if ( !self.inLastStand )
|
||||
self DoDamage( 1000, self.origin ); // Do enough damage so code will drop player into laststand.
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
chaos_dropIntoLastStand( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, bleedOutSpawnEntity, gameShouldEnd )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
self notify( "last_stand" );
|
||||
|
||||
enter_GamemodeSpecificAction();
|
||||
|
||||
enter_laststand();
|
||||
|
||||
if ( get_last_stand_count() > 0 )
|
||||
chaos_self_revive( gameShouldEnd );
|
||||
else
|
||||
wait_to_be_revived( self, self.origin, undefined, undefined, true, CONST_CHAOS_REVIVE_TIME, ( 0.33, 0.75, 0.24 ), undefined, false, gameShouldEnd, true );
|
||||
|
||||
self notify( "revive" );
|
||||
|
||||
exit_laststand();
|
||||
|
||||
exit_GamemodeSpecificAction();
|
||||
}
|
||||
|
||||
chaos_self_revive( gameShouldEnd )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "revive");
|
||||
level endon( "game_ended" );
|
||||
|
||||
/#
|
||||
if ( self maps\mp\alien\_debug::shouldSelfRevive() )
|
||||
return debug_self_revive();
|
||||
#/
|
||||
|
||||
self set_in_chaos_self_revive( self, true );
|
||||
self take_lastStand( self, 1 );
|
||||
self register_laststand_ammo();
|
||||
|
||||
return ( wait_for_chaos_self_revive( gameShouldEnd, CONST_CHAOS_SELF_REVIVE_TIME ) );
|
||||
}
|
||||
|
||||
wait_for_chaos_self_revive( gameShouldEnd, duration )
|
||||
{
|
||||
if ( gameShouldEnd )
|
||||
{
|
||||
level waittill( "forever" ); //<NOTE J.C.> When this happens, the "game_ended" notify will already happen. Wait here is to make sure the player stays in this state until game fully ended.
|
||||
return false; // Returning a false here is to be logically consistent of always returning true/false from this function
|
||||
}
|
||||
|
||||
maps\mp\alien\_hud::set_last_stand_timer( self, duration );
|
||||
self common_scripts\utility::waittill_any_timeout( duration, "revive_success" );
|
||||
maps\mp\alien\_hud::clear_last_stand_timer( self );
|
||||
return true;
|
||||
}
|
||||
|
||||
chaos_gameShouldEnd( player_just_down )
|
||||
{
|
||||
return ( get_team_self_revive_count() == 0 && everyone_else_all_in_lastStand( player_just_down ) && no_one_else_in_chaos_self_revive( player_just_down ) );
|
||||
}
|
||||
|
||||
no_one_else_in_chaos_self_revive( player_just_down )
|
||||
{
|
||||
foreach( player in level.players )
|
||||
{
|
||||
if ( player == player_just_down )
|
||||
continue;
|
||||
|
||||
if ( is_in_chaos_self_revive( player ) )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
get_team_self_revive_count()
|
||||
{
|
||||
total_self_revive_count = 0;
|
||||
|
||||
foreach( player in level.players )
|
||||
total_self_revive_count += player get_last_stand_count();
|
||||
|
||||
return total_self_revive_count;
|
||||
}
|
||||
|
||||
CONST_PRE_GAME_IS_OVER_FLAG = "chaos_pre_game_is_over";
|
||||
|
||||
chaos_player_init_laststand()
|
||||
{
|
||||
if ( common_scripts\utility::flag( CONST_PRE_GAME_IS_OVER_FLAG ) )
|
||||
return;
|
||||
|
||||
set_last_stand_count( self, CONST_CHAOS_INITIAL_LASTSTANDS );
|
||||
self thread init_selfrevive_icon( CONST_CHAOS_INITIAL_LASTSTANDS );
|
||||
}
|
||||
|
||||
chaos_exit_GamemodeSpecificAction( player )
|
||||
{
|
||||
player maps\mp\alien\_damage::setBodyArmor( level.deployablebox_vest_max );
|
||||
player notify( "enable_armor" );
|
||||
player set_in_chaos_self_revive( self, false );
|
||||
maps\mp\alien\_chaos::process_chaos_event( "refill_combo_meter" );
|
||||
}
|
||||
|
||||
set_in_chaos_self_revive( player, value ) { player.in_chaos_self_revive = value; }
|
||||
should_instant_revive( attacker ) { return ( isDefined( attacker ) && is_in_chaos_self_revive( attacker ) ); }
|
||||
is_in_chaos_self_revive( player ) { return maps\mp\alien\_utility::is_true( player.in_chaos_self_revive ); }
|
542
maps/mp/alien/_chaos_utility.gsc
Normal file
542
maps/mp/alien/_chaos_utility.gsc
Normal file
@ -0,0 +1,542 @@
|
||||
init_chaos_score_components()
|
||||
{
|
||||
level.combo_counter = 0;
|
||||
level.score_streak = 0;
|
||||
level.running_score_base = 0;
|
||||
level.total_score = 0;
|
||||
}
|
||||
|
||||
calculate_total_score()
|
||||
{
|
||||
level.total_score = level.running_score_base + level.combo_counter * level.score_streak;
|
||||
maps\mp\alien\_hud::set_total_score( level.total_score );
|
||||
return level.total_score;
|
||||
}
|
||||
|
||||
keep_running_score()
|
||||
{
|
||||
level.running_score_base += get_combo_counter() * get_score_streak();
|
||||
}
|
||||
|
||||
reset_combo_counter() { level.combo_counter = 0; }
|
||||
add_combo_counter( increment ) { level.combo_counter += increment ; }
|
||||
add_score_streak( increment ) { level.score_streak += increment; }
|
||||
get_combo_counter() { return level.combo_counter; }
|
||||
get_score_streak() { return level.score_streak; }
|
||||
get_total_score() { return level.total_score; }
|
||||
|
||||
TABLE_INDEX_COLUMN = 0;
|
||||
|
||||
CHAOS_EVENT_TABLE = "mp/alien/chaos_events.csv";
|
||||
GSC_ID_COLUMN = 1;
|
||||
LUA_EVENT_ID_COLUMN = 2;
|
||||
COMBO_INC_COLUMN = 4;
|
||||
SCORE_INC_COLUMN = 5;
|
||||
MAX_EVENT_INDEX = 100;
|
||||
|
||||
register_chaos_events()
|
||||
{
|
||||
level.chaos_events = [];
|
||||
|
||||
for ( entryIndex = 1; entryIndex <= MAX_EVENT_INDEX; entryIndex++ )
|
||||
{
|
||||
event_ID = table_look_up( CHAOS_EVENT_TABLE, entryIndex, GSC_ID_COLUMN );
|
||||
if ( maps\mp\agents\alien\_alien_agents::is_empty_string( event_ID ) )
|
||||
break;
|
||||
|
||||
event_info = [];
|
||||
event_info["LUA_event_ID"] = int( table_look_up( CHAOS_EVENT_TABLE, entryIndex, LUA_EVENT_ID_COLUMN ) );
|
||||
event_info["combo_inc"] = int( table_look_up( CHAOS_EVENT_TABLE, entryIndex, COMBO_INC_COLUMN ) );
|
||||
event_info["score_inc"] = int( table_look_up( CHAOS_EVENT_TABLE, entryIndex, SCORE_INC_COLUMN ) );
|
||||
|
||||
level.chaos_events[event_ID] = event_info;
|
||||
}
|
||||
}
|
||||
|
||||
WEAPON_START_INDEX = 1000;
|
||||
WEAPON_END_INDEX = 1099;
|
||||
|
||||
add_chaos_weapon( world_item_list )
|
||||
{
|
||||
for( index = WEAPON_START_INDEX; index <= WEAPON_END_INDEX; index++ )
|
||||
{
|
||||
if( is_empty_value( index ) )
|
||||
break;
|
||||
|
||||
weapon_struct = make_weapon_struct( index );
|
||||
world_item_list[world_item_list.size] = weapon_struct;
|
||||
}
|
||||
|
||||
return world_item_list;
|
||||
}
|
||||
|
||||
make_weapon_struct( index )
|
||||
{
|
||||
weapon_struct = spawnStruct();
|
||||
|
||||
weapon_struct.script_noteworthy = get_weapon_ref( index );
|
||||
weapon_struct.origin = get_weapon_origin( index );
|
||||
weapon_struct.angles = get_weapon_angles( index );
|
||||
|
||||
return weapon_struct;
|
||||
}
|
||||
|
||||
WEAPON_REF_COLUMN = 1;
|
||||
WEAPON_ORIGIN_COLUMN = 2;
|
||||
WEAPON_ANGLES_COLUMN = 3;
|
||||
|
||||
is_empty_value( index ) { return ( table_look_up( level.alien_cycle_table, index, WEAPON_REF_COLUMN ) == "" ); }
|
||||
get_weapon_ref( index ) { return get_weapon_info( index, WEAPON_REF_COLUMN ); }
|
||||
get_weapon_origin( index ) { return transform_to_coordinate( get_weapon_info( index, WEAPON_ORIGIN_COLUMN ) ); }
|
||||
get_weapon_angles( index ) { return transform_to_coordinate( get_weapon_info( index, WEAPON_ANGLES_COLUMN ) ); }
|
||||
get_weapon_info( index, column ) { return table_look_up( level.alien_cycle_table, index, column ); }
|
||||
|
||||
register_perk( perk_ref, activate_func, deactivate_func )
|
||||
{
|
||||
perk_info = [];
|
||||
perk_info["perk_ref"] = perk_ref;
|
||||
perk_info["activate_func"] = activate_func;
|
||||
perk_info["deactivate_func"] = deactivate_func;
|
||||
perk_info["LUA_perk_ID"] = get_LUA_perk_ID( perk_ref );
|
||||
perk_info["is_activated"] = false;
|
||||
|
||||
level.perk_progression[get_activation_level( perk_ref )] = perk_info;
|
||||
}
|
||||
|
||||
CHAOS_PERK_TABLE = "mp/alien/chaos_perks.csv";
|
||||
ACTIVATION_LEVEL_COLUMN = 1;
|
||||
LUA_PERK_ID_COLUMN = 2;
|
||||
|
||||
get_LUA_perk_ID( perk_ref ) { return int( table_look_up( CHAOS_PERK_TABLE, perk_ref, LUA_PERK_ID_COLUMN ) ); }
|
||||
get_activation_level( perk_ref ) { return int( table_look_up( CHAOS_PERK_TABLE, perk_ref, ACTIVATION_LEVEL_COLUMN ) ); }
|
||||
|
||||
DROP_LOC_START_INDEX = 4000;
|
||||
DROP_LOC_END_INDEX = 4099;
|
||||
DROP_LOC_COLUMN = 1;
|
||||
|
||||
register_drop_locations()
|
||||
{
|
||||
level.chaos_bonus_loc = [];
|
||||
level.chaos_bonus_loc_used = [];
|
||||
|
||||
for( index = DROP_LOC_START_INDEX; index <= DROP_LOC_END_INDEX; index++ )
|
||||
{
|
||||
drop_loc = table_look_up( level.alien_cycle_table, index, DROP_LOC_COLUMN );
|
||||
|
||||
if( maps\mp\agents\alien\_alien_agents::is_empty_string( drop_loc ) )
|
||||
break;
|
||||
|
||||
level.chaos_bonus_loc[level.chaos_bonus_loc.size] = transform_to_coordinate( drop_loc );
|
||||
}
|
||||
}
|
||||
|
||||
PROGRESSION_START_INDEX = 5000;
|
||||
PROGRESSION_END_INDEX = 5099;
|
||||
WAIT_DURATION_COLUMN = 1;
|
||||
NUM_OF_DROPS_COLUMN = 2;
|
||||
GROUP_TYPE_COLUMN = 3;
|
||||
GROUP_CHANCE_COLUMN = 4;
|
||||
ITEM_CHANCE_COLUMN = 5;
|
||||
|
||||
register_bonus_progression()
|
||||
{
|
||||
level.chaos_bonus_progression = [];
|
||||
max_num_of_drops = 0;
|
||||
|
||||
for( index = PROGRESSION_START_INDEX; index <= PROGRESSION_END_INDEX; index++ )
|
||||
{
|
||||
wait_duration = table_look_up( level.alien_cycle_table, index, WAIT_DURATION_COLUMN );
|
||||
|
||||
if( maps\mp\agents\alien\_alien_agents::is_empty_string( wait_duration ) )
|
||||
break;
|
||||
|
||||
bonus_info = [];
|
||||
bonus_info["wait_duration"] = int( wait_duration );
|
||||
bonus_info["num_of_drops"] = int( table_look_up( level.alien_cycle_table, index, NUM_OF_DROPS_COLUMN ) );
|
||||
bonus_info["package_group_type"] = strTok( table_look_up( level.alien_cycle_table, index, GROUP_TYPE_COLUMN ), " " );
|
||||
bonus_info["package_group_chance"] = convert_array_to_int( strTok( table_look_up( level.alien_cycle_table, index, GROUP_CHANCE_COLUMN ), " " ) );
|
||||
bonus_info["item_chance"] = strTok( table_look_up( level.alien_cycle_table, index, ITEM_CHANCE_COLUMN ), " " );
|
||||
AssertEx( bonus_info["num_of_drops"] <= bonus_info["package_group_type"].size, "For wait duration: " + wait_duration + ", there is not enough bonus packages to support " + bonus_info["num_of_drops"] + " drops." );
|
||||
|
||||
if ( bonus_info["num_of_drops"] > max_num_of_drops )
|
||||
max_num_of_drops = bonus_info["num_of_drops"];
|
||||
|
||||
level.chaos_bonus_progression[level.chaos_bonus_progression.size] = bonus_info;
|
||||
}
|
||||
|
||||
level.chaos_max_used_loc_stored = level.chaos_bonus_loc.size - max_num_of_drops;
|
||||
}
|
||||
|
||||
convert_array_to_int( string_array )
|
||||
{
|
||||
int_array = [];
|
||||
|
||||
foreach( string in string_array )
|
||||
int_array[int_array.size] = int( string );
|
||||
|
||||
return int_array;
|
||||
}
|
||||
|
||||
transform_to_coordinate( text_string )
|
||||
{
|
||||
tokenized = StrTok( text_string, "," );
|
||||
return ( int( tokenized[0] ), int( tokenized[1] ), int( tokenized[2] ) );
|
||||
}
|
||||
|
||||
init_chaos_deployable( boxType, iconName, onUseCallback )
|
||||
{
|
||||
boxConfig = SpawnStruct();
|
||||
boxConfig.modelBase = "mp_weapon_alien_crate";
|
||||
boxConfig.hintString = &"ALIEN_CHAOS_BONUS_PICKUP";
|
||||
boxConfig.capturingString = &"ALIEN_CHAOS_BONUS_TAKING";
|
||||
boxConfig.headIconOffset = 25;
|
||||
boxConfig.lifeSpan = 90.0;
|
||||
boxConfig.useXP = 0;
|
||||
boxConfig.voDestroyed = "ballistic_vest_destroyed";
|
||||
boxConfig.onUseSfx = "ammo_crate_use";
|
||||
boxConfig.onUseCallback = onUseCallback;
|
||||
boxConfig.canUseCallback = maps\mp\alien\_deployablebox::default_canUseDeployable;
|
||||
boxConfig.useTime = 500;
|
||||
boxConfig.maxHealth = 150;
|
||||
boxConfig.damageFeedback = "deployable_bag";
|
||||
boxConfig.maxUses = 1;
|
||||
boxConfig.icon_name = iconName;
|
||||
|
||||
add_to_chaos_bonus_package_type( boxType );
|
||||
maps\mp\alien\_deployablebox::init_deployable( boxType, boxConfig );
|
||||
}
|
||||
|
||||
get_random_player() { return level.players[ randomint( level.players.size ) ]; }
|
||||
table_look_up( table, index, target_column ) { return tableLookup( table, TABLE_INDEX_COLUMN, index, target_column ); }
|
||||
|
||||
get_drop_location_rated( desired_dir, base_pos )
|
||||
{
|
||||
MIN_DIST_SQD_FROM_ALL_PLAYER = 22500; // 150 * 150
|
||||
MAX_DIST_SQD_FROM_ALL_PLAYER = 90000; // 300 * 300
|
||||
|
||||
DIST_FROM_ALL_PLAYER_WEIGHT = 1.0;
|
||||
DESIRED_DIR_WEIGHT = 1.0;
|
||||
RANDOM_WEIGHT = 2.0;
|
||||
|
||||
best_location_rating = -1000.0;
|
||||
best_location = ( 0, 0, 0 );
|
||||
|
||||
foreach( location in level.chaos_bonus_loc )
|
||||
{
|
||||
if ( location_recently_used( location ) )
|
||||
continue;
|
||||
|
||||
rating = 0.0;
|
||||
|
||||
foreach( player in level.players )
|
||||
{
|
||||
player_to_location_distanceSquared = DistanceSquared( player.origin, location );
|
||||
|
||||
if ( player_to_location_distanceSquared > MIN_DIST_SQD_FROM_ALL_PLAYER )
|
||||
rating += DIST_FROM_ALL_PLAYER_WEIGHT;
|
||||
|
||||
if ( player_to_location_distanceSquared < MAX_DIST_SQD_FROM_ALL_PLAYER )
|
||||
rating += DIST_FROM_ALL_PLAYER_WEIGHT;
|
||||
}
|
||||
|
||||
base_pos_to_location = vectorNormalize( ( 0, vectorToYaw( location - base_pos ), 0 ) );
|
||||
rating += VectorDot( base_pos_to_location, desired_dir ) * DESIRED_DIR_WEIGHT;
|
||||
|
||||
rating += randomFloat( RANDOM_WEIGHT );
|
||||
|
||||
if ( rating > best_location_rating )
|
||||
{
|
||||
best_location_rating = rating;
|
||||
best_location = location;
|
||||
}
|
||||
}
|
||||
|
||||
register_location( best_location );
|
||||
return best_location;
|
||||
}
|
||||
|
||||
register_location( location )
|
||||
{
|
||||
if( level.chaos_bonus_loc_used.size == level.chaos_max_used_loc_stored )
|
||||
{
|
||||
for( i = 0; i < level.chaos_max_used_loc_stored - 1; i++ )
|
||||
level.chaos_bonus_loc_used[i] = level.chaos_bonus_loc_used[i+1];
|
||||
|
||||
level.chaos_bonus_loc_used[level.chaos_max_used_loc_stored - 1] = location;
|
||||
}
|
||||
else
|
||||
{
|
||||
level.chaos_bonus_loc_used[level.chaos_bonus_loc_used.size] = location;
|
||||
}
|
||||
}
|
||||
|
||||
location_recently_used( location )
|
||||
{
|
||||
return common_scripts\utility::array_contains( level.chaos_bonus_loc_used, location );
|
||||
}
|
||||
|
||||
reset_alien_kill_streak() { level.current_alien_kill_streak = 0; }
|
||||
inc_alien_kill_streak() { level.current_alien_kill_streak++; }
|
||||
get_alien_kill_streak() { return level.current_alien_kill_streak; }
|
||||
|
||||
play_FX_on_package( package_loc, owner_angles )
|
||||
{
|
||||
CONST_XY_OFFSET = ( -0.5, 5.6, 0 ); // To correct the fact that tag_origin is not placed at the center for the model "mp_weapon_alien_crate"
|
||||
CONST_Z_OFFSET = ( 0, 0, 5 ); // To raise the FX up a little above the ground
|
||||
|
||||
XY_offset = RotateVector( CONST_XY_OFFSET, owner_angles );
|
||||
FX_loc = package_loc + XY_offset;
|
||||
FX_loc += CONST_Z_OFFSET;
|
||||
fx= SpawnFX( common_scripts\utility::getfx( "chaos_pre_bonus_drop" ), FX_loc );
|
||||
TriggerFx( fx );
|
||||
|
||||
return fx;
|
||||
}
|
||||
|
||||
clean_up_monitor( fx, box )
|
||||
{
|
||||
box waittill( "death" );
|
||||
fx delete();
|
||||
}
|
||||
|
||||
init_highest_combo() { level.highest_combo = 0; }
|
||||
|
||||
record_highest_combo( combo_counter )
|
||||
{
|
||||
if ( combo_counter <= level.highest_combo )
|
||||
return;
|
||||
|
||||
level.highest_combo = combo_counter ;
|
||||
foreach ( player in level.players )
|
||||
player maps\mp\alien\_persistence::LB_player_update_stat( "hits", combo_counter, true ); // In Chaos, we are using session data "hits" to record the highest combo
|
||||
}
|
||||
|
||||
CYCLE_PARAMETER_START_INDEX = 500;
|
||||
CYCLE_PARAMETER_END_INDEX = 599;
|
||||
CYCLE_NUMBER_COLUMN = 1;
|
||||
CYCLE_DURATION_COLUMN = 6;
|
||||
|
||||
register_cycle_duration()
|
||||
{
|
||||
level.chaos_cycle_duration = [];
|
||||
|
||||
for( index = CYCLE_PARAMETER_START_INDEX; index <= CYCLE_PARAMETER_END_INDEX; index++ )
|
||||
{
|
||||
cycle_number = table_look_up( level.alien_cycle_table, index, CYCLE_NUMBER_COLUMN );
|
||||
|
||||
if( maps\mp\agents\alien\_alien_agents::is_empty_string( cycle_number ) )
|
||||
break;
|
||||
|
||||
level.chaos_cycle_duration[level.chaos_cycle_duration.size] = int( table_look_up( level.alien_cycle_table, index, CYCLE_DURATION_COLUMN ) );
|
||||
}
|
||||
}
|
||||
|
||||
SPAWN_LOC_START_INDEX = 6000;
|
||||
SPAWN_LOC_END_INDEX = 6099;
|
||||
SPAWN_LOC_ORIGIN_COLUMN = 1;
|
||||
SPAWN_LOC_ANGLES_COLUMN = 2;
|
||||
SPAWN_LOC_LINKTO_COLUMN = 3;
|
||||
SPAWN_LOC_NOTEWORTHY_COLUMN = 4;
|
||||
|
||||
add_extra_spawn_locations()
|
||||
{
|
||||
extra_spawn_locations = [];
|
||||
|
||||
for( index = SPAWN_LOC_START_INDEX; index <= SPAWN_LOC_END_INDEX; index++ )
|
||||
{
|
||||
spawn_loc_origin = table_look_up( level.alien_cycle_table, index, SPAWN_LOC_ORIGIN_COLUMN );
|
||||
|
||||
if( maps\mp\agents\alien\_alien_agents::is_empty_string( spawn_loc_origin ) )
|
||||
break;
|
||||
|
||||
spawn_location = spawnStruct();
|
||||
spawn_location.origin = transform_to_coordinate( spawn_loc_origin );
|
||||
spawn_location.angles = transform_to_coordinate( table_look_up( level.alien_cycle_table, index, SPAWN_LOC_ANGLES_COLUMN ) );
|
||||
spawn_location.script_linkto = translate_to_actual_zone_name( table_look_up( level.alien_cycle_table, index, SPAWN_LOC_LINKTO_COLUMN ) );
|
||||
spawn_location.script_noteworthy = table_look_up( level.alien_cycle_table, index, SPAWN_LOC_NOTEWORTHY_COLUMN );
|
||||
|
||||
extra_spawn_locations[extra_spawn_locations.size] = spawn_location;
|
||||
}
|
||||
|
||||
maps\mp\alien\_spawn_director::put_spawnLocations_into_cycle_data( extra_spawn_locations, level.cycle_data );
|
||||
}
|
||||
|
||||
DEFAULT_INIT_COMBO_DURATION = 4.0; // Time (in sec) after a combo action / event that the player has to do another action to keep the combo going
|
||||
|
||||
init_combo_duration()
|
||||
{
|
||||
if ( !isDefined( level.combo_duration ) )
|
||||
level.combo_duration = DEFAULT_INIT_COMBO_DURATION;
|
||||
}
|
||||
|
||||
get_combo_duration() { return level.combo_duration; }
|
||||
adjust_combo_duration( delta ) { level.combo_duration += delta; }
|
||||
|
||||
COMBO_DURATION_START_INDEX = 7000;
|
||||
COMBO_DURATION_END_INDEX = 7099;
|
||||
COMBO_DURATION_PRE_DELTA_INTERVAL_COLUMN = 1;
|
||||
COMBO_DURATION_DELTA_COLUMN = 2;
|
||||
|
||||
register_combo_duration_schedule()
|
||||
{
|
||||
level.combo_duration_schedule = [];
|
||||
|
||||
for( index = COMBO_DURATION_START_INDEX; index <= COMBO_DURATION_END_INDEX; index++ )
|
||||
{
|
||||
pre_delta_interval = table_look_up( level.alien_cycle_table, index, COMBO_DURATION_PRE_DELTA_INTERVAL_COLUMN );
|
||||
|
||||
if( maps\mp\agents\alien\_alien_agents::is_empty_string( pre_delta_interval ) )
|
||||
break;
|
||||
|
||||
duration_delta = [];
|
||||
duration_delta["pre_delta_interval"] = float( pre_delta_interval );
|
||||
duration_delta["delta"] = float( table_look_up( level.alien_cycle_table, index, COMBO_DURATION_DELTA_COLUMN ) );
|
||||
|
||||
level.combo_duration_schedule[level.combo_duration_schedule.size] = duration_delta;
|
||||
}
|
||||
}
|
||||
|
||||
DEFAULT_BONUS_PACKAGE_CAP = 3;
|
||||
|
||||
init_bonus_package_cap()
|
||||
{
|
||||
if ( !isDefined( level.chaos_bonus_package_cap ) )
|
||||
level.chaos_bonus_package_cap = DEFAULT_BONUS_PACKAGE_CAP;
|
||||
}
|
||||
|
||||
get_bonus_package_cap() { return level.chaos_bonus_package_cap; }
|
||||
init_chaos_bonus_package_type() { level.chaos_bonus_package_type = []; }
|
||||
add_to_chaos_bonus_package_type( package_type ) { level.chaos_bonus_package_type[level.chaos_bonus_package_type.size] = package_type; }
|
||||
|
||||
get_current_num_bonus_package()
|
||||
{
|
||||
result = 0;
|
||||
|
||||
foreach ( package_type in level.chaos_bonus_package_type )
|
||||
result += level.deployable_box[package_type].size;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
chaos_end_game()
|
||||
{
|
||||
if ( chaos_should_end() )
|
||||
level thread maps\mp\gametypes\aliens::AlienEndGame( "axis", maps\mp\alien\_hud::get_end_game_string_index( "kia" ) );
|
||||
}
|
||||
|
||||
CONST_IN_HOST_MIGRATION_FLAG = "in_host_migration";
|
||||
|
||||
chaos_should_end()
|
||||
{
|
||||
/#
|
||||
if ( getDvarInt( "chaos_no_fail", 0 ) == 1 )
|
||||
return false;
|
||||
#/
|
||||
if ( common_scripts\utility::flag( CONST_IN_HOST_MIGRATION_FLAG ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/#
|
||||
reset_chaos_no_fail() { setDvar( "chaos_no_fail", 0 ); }
|
||||
#/
|
||||
|
||||
should_process_alien_killed_event( attacker )
|
||||
{
|
||||
return ( isPlayer( attacker ) || ( isDefined( attacker.owner ) && isPlayer( attacker.owner ) ) || ( isDefined( attacker.team ) && attacker.team == "allies" ) );
|
||||
}
|
||||
|
||||
should_process_alien_damaged_event( sWeapon )
|
||||
{
|
||||
if ( isDefined( sWeapon ) && sWeapon == "alien_minion_explosion" )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unset_player_perks( player )
|
||||
{
|
||||
foreach( perk_info in level.perk_progression )
|
||||
{
|
||||
if ( perk_info["is_activated"] )
|
||||
[[perk_info["deactivate_func"]]]( player, perk_info["perk_ref"] );
|
||||
}
|
||||
player PlayLocalSound( "mp_splash_screen_default" );
|
||||
}
|
||||
|
||||
give_activated_perks( player )
|
||||
{
|
||||
foreach( perk_info in level.perk_progression )
|
||||
{
|
||||
if ( perk_info["is_activated"] )
|
||||
[[perk_info["activate_func"]]]( player, perk_info["perk_ref"] );
|
||||
}
|
||||
}
|
||||
|
||||
set_all_perks_inactivated()
|
||||
{
|
||||
foreach( perk_info in level.perk_progression )
|
||||
perk_info["is_activated"] = false;
|
||||
}
|
||||
|
||||
get_attacker_as_player( attacker )
|
||||
{
|
||||
if ( isPlayer( attacker ) )
|
||||
return attacker;
|
||||
|
||||
if ( isDefined( attacker.owner ) && isPlayer( attacker.owner ) )
|
||||
return attacker.owner;
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
MAX_EVENT_COUNT = 18; // How many choas events are listed in the chaos_events.csv
|
||||
|
||||
init_event_counts()
|
||||
{
|
||||
level.chaos_event_counts = [];
|
||||
|
||||
for( i = 1; i <= MAX_EVENT_COUNT; i++ )
|
||||
level.chaos_event_counts[i] = 0;
|
||||
}
|
||||
|
||||
update_HUD_event_counts()
|
||||
{
|
||||
for( i = 1; i <= MAX_EVENT_COUNT; i++ )
|
||||
maps\mp\alien\_hud::set_event_count( i, level.chaos_event_counts[i] );
|
||||
}
|
||||
|
||||
inc_event_count( event_ID ) { level.chaos_event_counts[event_ID]++; }
|
||||
register_pre_end_game_display_func() { level.pre_end_game_display_func = ::update_HUD_event_counts; }
|
||||
|
||||
translate_to_actual_zone_name( zone_name_list )
|
||||
{
|
||||
actual_zone_name_list = [];
|
||||
|
||||
zone_name_list = StrTok( zone_name_list, " " );
|
||||
foreach ( zone_name in zone_name_list )
|
||||
{
|
||||
foreach ( actual_zone_name, spawn_data in level.cycle_data.spawn_zones )
|
||||
{
|
||||
if ( IsSubStr( actual_zone_name, zone_name ) )
|
||||
actual_zone_name_list[actual_zone_name_list.size] = actual_zone_name;
|
||||
}
|
||||
}
|
||||
|
||||
/# AssertEx( actual_zone_name_list.size == zone_name_list.size, "Unable to find the actual zone name for some zones." ); #/
|
||||
|
||||
if ( actual_zone_name_list.size == 0 )
|
||||
{
|
||||
result_actual_name_string = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
result_actual_name_string = actual_zone_name_list[0];
|
||||
|
||||
for( i = 1; i < actual_zone_name_list.size; i++ )
|
||||
result_actual_name_string = result_actual_name_string + " " + actual_zone_name_list[i];
|
||||
}
|
||||
|
||||
return result_actual_name_string;
|
||||
}
|
1794
maps/mp/alien/_collectibles.gsc
Normal file
1794
maps/mp/alien/_collectibles.gsc
Normal file
File diff suppressed because it is too large
Load Diff
2739
maps/mp/alien/_combat_resources.gsc
Normal file
2739
maps/mp/alien/_combat_resources.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1284
maps/mp/alien/_damage.gsc
Normal file
1284
maps/mp/alien/_damage.gsc
Normal file
File diff suppressed because it is too large
Load Diff
716
maps/mp/alien/_death.gsc
Normal file
716
maps/mp/alien/_death.gsc
Normal file
@ -0,0 +1,716 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\alien\_utility;
|
||||
|
||||
//=======================================================
|
||||
// onPlayerKilled
|
||||
//=======================================================
|
||||
onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId)
|
||||
{
|
||||
if ( level.gameEnded == true )
|
||||
return;
|
||||
|
||||
if ( kill_trigger_event_was_processed() )
|
||||
return;
|
||||
|
||||
set_kill_trigger_event_processed( self, true );
|
||||
|
||||
maps\mp\alien\_laststand::Callback_PlayerLastStandAlien( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, getKillTriggerSpawnLoc() );
|
||||
}
|
||||
|
||||
kill_trigger_event_was_processed() { return is_true( self.kill_trigger_event_processed ); }
|
||||
set_kill_trigger_event_processed( player, value ) { self.kill_trigger_event_processed = value; }
|
||||
|
||||
//=======================================================
|
||||
// onNormalDeath
|
||||
//=======================================================
|
||||
onNormalDeath( victim, attacker, lifeId )
|
||||
{
|
||||
if ( game["state"] == "postgame" && game["teamScores"][attacker.team] > game["teamScores"][level.otherTeam[attacker.team]] )
|
||||
attacker.finalKill = true;
|
||||
}
|
||||
|
||||
|
||||
CONST_DANGEROUS_RADIUS = 256;
|
||||
CONST_DANGEROUS_DURATION = 10;
|
||||
CONST_DANGEROUS_DURATION_TRAP = 3;
|
||||
CONST_KILLS_PER_TOKEN_AWARD = 300;
|
||||
|
||||
//=======================================================
|
||||
// onAlienAgentKilled
|
||||
//=======================================================
|
||||
onAlienAgentKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration )
|
||||
{
|
||||
// scene aliens suicide skips all regular alien dying logic
|
||||
if ( isdefined( sMeansOfDeath ) && sMeansOfDeath == "MOD_SUICIDE" && isdefined( self.scene ) && self.scene )
|
||||
return;
|
||||
|
||||
self.isActive = false;
|
||||
self.hasDied = false;
|
||||
self.owner = undefined;
|
||||
type = self.alien_type;
|
||||
pet_spawned = false;
|
||||
|
||||
if ( !isDefined ( vDir ) )
|
||||
vDir = anglesToForward( self.angles );
|
||||
|
||||
self maps\mp\alien\_alien_fx::disable_fx_on_death();
|
||||
|
||||
if ( sMeansOfDeath == "MOD_TRIGGER_HURT" )
|
||||
return; // died by hurt trigger
|
||||
|
||||
// Mark nearby nodes as dangerous - less for traps
|
||||
dangerous_duration = CONST_DANGEROUS_DURATION;
|
||||
if ( maps\mp\alien\_utility::is_trap( eInflictor ) )
|
||||
{
|
||||
dangerous_duration = CONST_DANGEROUS_DURATION_TRAP;
|
||||
}
|
||||
level thread maps\mp\alien\_utility::mark_dangerous_nodes( self.origin, CONST_DANGEROUS_RADIUS, dangerous_duration );
|
||||
|
||||
isPetTrapKill = is_pettrap_kill( eInflictor );
|
||||
|
||||
//if killed with a special weapon then turn the alien into a pet
|
||||
if ( sWeapon == "alienthrowingknife_mp" && sMeansofDeath == "MOD_IMPACT" || isPetTrapKill || is_true( self.hypnoknifed ) )
|
||||
{
|
||||
if ( self maps\mp\alien\_utility::can_hypno( eAttacker, isPetTrapKill ) )
|
||||
{
|
||||
thread maps\mp\gametypes\aliens::spawnAllyPet( type, 1, self.origin, eAttacker, self.angles , isPetTrapKill );
|
||||
pet_spawned = true;
|
||||
if ( type == "elite" && isPetTrapKill && isDefined( level.update_achievement_hypno_trap_func ) )
|
||||
eAttacker [[level.update_achievement_hypno_trap_func]]();
|
||||
}
|
||||
//don't delete the pet trap!
|
||||
if ( !isPetTrapKill )
|
||||
eInflictor delete();
|
||||
}
|
||||
|
||||
should_do_custom_death = false;
|
||||
if ( isDefined( level.custom_alien_death_func ) )
|
||||
should_do_custom_death = self [[level.custom_alien_death_func]]( eInflictor, eAttacker,iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc );
|
||||
|
||||
if ( should_do_pipebomb_death( sWeapon ) )
|
||||
{
|
||||
self thread do_pipebomb_death();
|
||||
}
|
||||
else if ( self should_play_death() && sMeansOfDeath != "MOD_SUICIDE" && !pet_spawned && !should_do_custom_death )
|
||||
play_death_anim_and_ragdoll( eInflictor, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc );
|
||||
|
||||
self on_alien_type_killed( pet_spawned );
|
||||
|
||||
self maps\mp\agents\alien\_alien_think::OnEnterAnimState( self.currentAnimState, "death" ); // we don't need to enter death so much as exit currentAnimState.
|
||||
|
||||
//notify for dlc vo
|
||||
eAttacker notify("dlc_vo_notify", get_alien_type() + "_killed", eAttacker);
|
||||
|
||||
switch ( get_alien_type() )
|
||||
{
|
||||
case "mammoth":
|
||||
self PlaySoundOnMovingEnt( "queen_death" );
|
||||
break;
|
||||
case "elite":
|
||||
self PlaySoundOnMovingEnt( "queen_death" );
|
||||
break;
|
||||
case "minion":
|
||||
self PlaySoundOnMovingEnt( "alien_minion_explode" );
|
||||
break;
|
||||
case "spitter":
|
||||
self PlaySoundOnMovingEnt( "spitter_death" );
|
||||
break;
|
||||
default:
|
||||
self PlaySoundOnMovingEnt( "alien_death" );
|
||||
break;
|
||||
}
|
||||
|
||||
// chopper reward
|
||||
if ( isdefined( level.attack_heli ) && eAttacker == level.attack_heli )
|
||||
{
|
||||
reward_point = self maps\mp\alien\_gamescore::get_reward_point_for_kill();
|
||||
|
||||
assertex( isdefined( eAttacker.reward_pool ) );
|
||||
reward_unit = reward_point / eAttacker.reward_pool.size;
|
||||
|
||||
// reset
|
||||
foreach ( player in eAttacker.reward_pool )
|
||||
{
|
||||
if ( isdefined( player ) )
|
||||
player.chopper_reward = 0;
|
||||
}
|
||||
|
||||
// add
|
||||
foreach ( player in eAttacker.reward_pool )
|
||||
{
|
||||
if ( isdefined( player ) )
|
||||
player.chopper_reward += reward_unit;
|
||||
}
|
||||
|
||||
// give
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( isdefined( player ) && isdefined( player.chopper_reward ) )
|
||||
maps\mp\alien\_gamescore::giveKillReward( player, int( player.chopper_reward ), "large" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( Isdefined( eAttacker.pet ) && ( eAttacker.pet == 1 ) )
|
||||
{
|
||||
maps\mp\alien\_gamescore::give_attacker_kill_rewards( eAttacker.owner );
|
||||
}
|
||||
else
|
||||
{
|
||||
maps\mp\alien\_gamescore::give_attacker_kill_rewards( eAttacker, sHitLoc );
|
||||
}
|
||||
|
||||
// weaponstats tracking: register weapon shot hit
|
||||
eAttacker thread maps\mp\alien\_persistence::update_weaponstats_kills( sWeapon, 1 );
|
||||
}
|
||||
|
||||
//update any challenges related to aliens being killed
|
||||
maps\mp\alien\_challenge_function::update_alien_death_challenges( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration );
|
||||
|
||||
//update any achievements related to aliens being killed
|
||||
maps\mp\alien\_achievement::update_alien_kill_achievements( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration );
|
||||
|
||||
//update alien session stats related to aliens being killed
|
||||
maps\mp\alien\_persistence::update_alien_kill_sessionStats( eInflictor, eAttacker );
|
||||
|
||||
if ( is_chaos_mode() )
|
||||
maps\mp\alien\_chaos::update_alien_killed_event( get_alien_type(), self.origin, eAttacker );
|
||||
|
||||
blackBox_alienKilled( eAttacker );
|
||||
|
||||
attacker_as_player = get_attacker_as_player( eAttacker );
|
||||
|
||||
if( IsDefined( attacker_as_player ) )
|
||||
{
|
||||
record_player_kills( attacker_as_player );
|
||||
check_award_token_for_kill( attacker_as_player );
|
||||
}
|
||||
|
||||
level notify( "alien_killed",self.origin, sMeansOfDeath, eAttacker );
|
||||
|
||||
}
|
||||
|
||||
get_attacker_as_player( eAttacker )
|
||||
{
|
||||
if( IsPlayer( eAttacker ) )
|
||||
return eAttacker;
|
||||
|
||||
if ( IsDefined( eAttacker.owner ) && IsPlayer( eAttacker.owner ) )
|
||||
return eAttacker.owner;
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
record_player_kills( player )
|
||||
{
|
||||
player maps\mp\alien\_persistence::set_player_kills();
|
||||
|
||||
player maps\mp\alien\_persistence::eog_player_update_stat( "kills", 1 );
|
||||
}
|
||||
|
||||
check_award_token_for_kill( player )
|
||||
{
|
||||
killCount = player maps\mp\alien\_persistence::get_player_kills();
|
||||
if ( killCount % CONST_KILLS_PER_TOKEN_AWARD == 0 )
|
||||
{
|
||||
player maps\mp\alien\_persistence::give_player_tokens( 1, true );
|
||||
}
|
||||
}
|
||||
|
||||
on_alien_type_killed( pet_spawned )
|
||||
{
|
||||
switch ( self get_alien_type() )
|
||||
{
|
||||
case "minion":
|
||||
level thread maps\mp\agents\alien\_alien_minion::minion_explode_on_death( self.origin );
|
||||
break;
|
||||
|
||||
case "spitter":
|
||||
maps\mp\agents\alien\_alien_spitter::spitter_death();
|
||||
break;
|
||||
|
||||
default:
|
||||
// Check for level specific overrides
|
||||
if( isDefined( level.dlc_alien_death_override_func ))
|
||||
self [[level.dlc_alien_death_override_func]]( pet_spawned );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
should_play_death()
|
||||
{
|
||||
switch( get_alien_type() )
|
||||
{
|
||||
case "minion":
|
||||
case "seeder":
|
||||
case "bomber":
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
play_death_anim_and_ragdoll( eInflictor, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc )
|
||||
{
|
||||
ORIENTED_DEATH_OFFSET = 24;
|
||||
APEX_TRAVERSAL_DEATH_OFFSET = 30;
|
||||
|
||||
if ( GetDvarInt( "alien_easter_egg" ) > 0 || ( isdefined( level.easter_egg_lodge_sign_active ) && level.easter_egg_lodge_sign_active ) )
|
||||
{
|
||||
PlayFX( level._effect[ "arcade_death" ], self.origin );
|
||||
//self thread alien_toy_death();
|
||||
}
|
||||
else
|
||||
{
|
||||
primary_animState = get_primary_death_anim_state();
|
||||
|
||||
if ( !is_normal_upright( AnglesToUp( self.angles ) ) )
|
||||
move_away_from_surface( AnglesToUp( self.angles ), ORIENTED_DEATH_OFFSET );
|
||||
|
||||
if ( isDefined( self.apexTraversalDeathVector ) )
|
||||
move_away_from_surface( self.apexTraversalDeathVector, APEX_TRAVERSAL_DEATH_OFFSET );
|
||||
|
||||
play_death_anim_and_ragdoll_internal( primary_animState, eInflictor, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc );
|
||||
}
|
||||
}
|
||||
|
||||
should_do_immediate_ragdoll( deathAnimState )
|
||||
{
|
||||
if ( IsDefined( level.dlc_alien_should_immediate_ragdoll_on_death_override_func ) )
|
||||
{
|
||||
should_immediate_ragdoll = [[level.dlc_alien_should_immediate_ragdoll_on_death_override_func]]( deathAnimState );
|
||||
if ( IsDefined( should_immediate_ragdoll ) )
|
||||
return should_immediate_ragdoll;
|
||||
}
|
||||
|
||||
switch ( deathAnimState )
|
||||
{
|
||||
case "jump":
|
||||
case "traverse":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
play_death_anim_and_ragdoll_internal( primary_animState, eInflictor, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc )
|
||||
{
|
||||
if ( is_special_death( primary_animState ) )
|
||||
{
|
||||
animState = "special_death";
|
||||
animIndex = self maps\mp\agents\alien\_alien_anim_utils::getSpecialDeathAnimIndex( primary_animState );
|
||||
}
|
||||
else
|
||||
{
|
||||
animState = self maps\mp\agents\alien\_alien_anim_utils::getDeathAnimState( ( primary_animState + "_death" ), iDamage );
|
||||
animIndex = self maps\mp\agents\alien\_alien_anim_utils::getDeathAnimIndex( primary_animState , vDir, sHitLoc );
|
||||
}
|
||||
|
||||
do_immediate_ragdoll = should_do_immediate_ragdoll( primary_animState );
|
||||
|
||||
self ScrAgentSetPhysicsMode( get_death_anim_physics_mode( animState ) );
|
||||
self SetAnimState( animState, animIndex );
|
||||
|
||||
self.body = get_clone_agent( animState, animIndex );
|
||||
|
||||
self thread handle_ragdoll( self.body, animState, do_immediate_ragdoll );
|
||||
}
|
||||
|
||||
move_away_from_surface( direction, offset_length )
|
||||
{
|
||||
offsetLocation = self.origin + direction * offset_length;
|
||||
self SetOrigin( offsetLocation );
|
||||
}
|
||||
|
||||
get_primary_death_anim_state()
|
||||
{
|
||||
// special death case
|
||||
if ( isdefined( self.shocked ) && self.shocked ) //for electric fence, shock backwards anim
|
||||
return "electric_shock_death";
|
||||
|
||||
switch ( self.currentAnimState )
|
||||
{
|
||||
case "scripted":
|
||||
{
|
||||
return "idle";
|
||||
}
|
||||
case "move":
|
||||
{
|
||||
if ( self.trajectoryActive )
|
||||
return "jump";
|
||||
else
|
||||
return "run";
|
||||
}
|
||||
case "idle":
|
||||
{
|
||||
return "idle";
|
||||
}
|
||||
case "melee":
|
||||
{
|
||||
if ( self.trajectoryActive )
|
||||
return "jump";
|
||||
if ( self.melee_in_move_back || self.melee_in_posture )
|
||||
return "idle";
|
||||
else
|
||||
return "run";
|
||||
}
|
||||
case "traverse":
|
||||
{
|
||||
if ( self.trajectoryActive )
|
||||
return "jump";
|
||||
else
|
||||
return "traverse";
|
||||
}
|
||||
default:
|
||||
{
|
||||
AssertMsg( "currentAnimState: " + self.currentAnimState + " does not have a death anim mapping." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is_special_death( primary_animState )
|
||||
{
|
||||
switch ( primary_animState )
|
||||
{
|
||||
case "traverse":
|
||||
case "electric_shock_death":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
get_death_anim_physics_mode( anim_state )
|
||||
{
|
||||
switch ( anim_state )
|
||||
{
|
||||
case "electric_shock": // so alien doesn't get stuck on electric fence geo
|
||||
return "noclip";
|
||||
default:
|
||||
return "gravity";
|
||||
}
|
||||
}
|
||||
|
||||
get_clone_agent( animState, animIndex )
|
||||
{
|
||||
animEntry = self GetAnimEntry( animState, animIndex );
|
||||
animLength = GetAnimLength( animEntry );
|
||||
if ( AnimHasNotetrack( animEntry, "start_ragdoll" ) )
|
||||
{
|
||||
notetracks = GetNotetrackTimes( animEntry, "start_ragdoll" );
|
||||
assert( notetracks.size > 0 );
|
||||
animLength *= notetracks[0];
|
||||
}
|
||||
|
||||
deathAnimDuration = int( animLength * 1000 ); // duration in milliseconds
|
||||
|
||||
return ( self CloneAgent( deathAnimDuration ) );
|
||||
}
|
||||
|
||||
handle_ragdoll( corpse, animState, do_immediate_ragdoll )
|
||||
{
|
||||
deathAnim = corpse getcorpseanim();
|
||||
|
||||
if ( !should_do_ragdoll( corpse, deathAnim ) )
|
||||
return;
|
||||
|
||||
if ( do_immediate_ragdoll )
|
||||
{
|
||||
corpse startragdoll();
|
||||
|
||||
if ( corpse isRagdoll() ) //Immediate ragdoll succeed
|
||||
return;
|
||||
|
||||
/#
|
||||
println( "Corpse failed immediate ragdoll at " + corpse.origin );
|
||||
#/
|
||||
}
|
||||
|
||||
delayStartRagdoll( corpse, deathAnim );
|
||||
|
||||
if ( !isDefined( corpse ) )
|
||||
return;
|
||||
|
||||
// electric fence shock does physics to send aliens flying
|
||||
// TODO: Remove once death animation for shock_death does this
|
||||
if ( animState == "shock_death" )
|
||||
{
|
||||
self notify( "in_ragdoll", corpse.origin );
|
||||
}
|
||||
}
|
||||
|
||||
delayStartRagdoll( corpse, deathAnim )
|
||||
{
|
||||
totalAnimTime = getanimlength( deathAnim );
|
||||
if ( animhasnotetrack( deathAnim, "start_ragdoll" ) )
|
||||
{
|
||||
times = getnotetracktimes( deathAnim, "start_ragdoll" );
|
||||
startFrac = times[ 0 ];
|
||||
waitTime = startFrac * totalAnimTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
waitTime = 0.2;
|
||||
}
|
||||
|
||||
wait( waitTime );
|
||||
|
||||
if ( !isDefined( corpse ) ) // Corpse can be deleted during host migration
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
corpse startragdoll();
|
||||
|
||||
if ( corpse isRagdoll() )
|
||||
return;
|
||||
}
|
||||
|
||||
/#
|
||||
println( "Corpse failed first ragdoll at " + corpse.origin );
|
||||
#/
|
||||
|
||||
// Ragdoll failed, do a final attempt
|
||||
if ( waitTime < totalAnimTime )
|
||||
{
|
||||
wait ( totalAnimTime - waitTime );
|
||||
|
||||
if ( !isDefined( corpse ) ) // Corpse can be deleted during host migration
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
corpse startragdoll();
|
||||
|
||||
if ( corpse isRagdoll() )
|
||||
return;
|
||||
}
|
||||
/#
|
||||
println( "Corpse failed second ragdoll at " + corpse.origin );
|
||||
#/
|
||||
}
|
||||
|
||||
// If final attempt failed, delete the corpse
|
||||
if ( isDefined( corpse ) )
|
||||
corpse delete();
|
||||
}
|
||||
|
||||
should_do_ragdoll( ent, deathAnim )
|
||||
{
|
||||
if ( ent isRagDoll() )
|
||||
return false;
|
||||
|
||||
if ( animhasnotetrack( deathAnim, "ignore_ragdoll" ) )
|
||||
return false;
|
||||
|
||||
if ( IsDefined( level.noRagdollEnts ) && level.noRagdollEnts.size )
|
||||
{
|
||||
foreach( noRag in level.noRagdollEnts )
|
||||
{
|
||||
if ( distanceSquared( ent.origin, noRag.origin ) < 65536 ) //256^2
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
blackBox_alienKilled( eAttacker )
|
||||
{
|
||||
// black box data tracking
|
||||
if ( isPlayer( eAttacker )
|
||||
|| ( isDefined( eAttacker.pet ) && ( eAttacker.pet == 1 ) && isPlayer( eAttacker.petowner ) )
|
||||
|| ( IsDefined( eAttacker.owner ) && IsPlayer( eAttacker.owner ) )
|
||||
)
|
||||
{
|
||||
level.alienBBData[ "aliens_killed" ]++;
|
||||
}
|
||||
|
||||
self notify( "alien_killed" );
|
||||
|
||||
// black box data tracking
|
||||
// =========================== blackbox print [START] ===========================
|
||||
// self is agent victim that died
|
||||
|
||||
// attacker_is_agent
|
||||
attacker_is_agent = IsAgent( eAttacker );
|
||||
|
||||
// attacker_alive_time, attacker_agent_type, attacker_name
|
||||
if ( attacker_is_agent )
|
||||
{
|
||||
attacker_alive_time = ( gettime() - eAttacker.birthtime ) / 1000;
|
||||
attacker_agent_type = "unknown agent";
|
||||
attacker_name = "none";
|
||||
|
||||
if ( isdefined( eAttacker.agent_type ) )
|
||||
{
|
||||
attacker_agent_type = eAttacker.agent_type;
|
||||
if ( isdefined( eAttacker.alien_type ) )
|
||||
attacker_agent_type = eAttacker.alien_type;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
attacker_alive_time = 0;
|
||||
attacker_name = "none";
|
||||
|
||||
if ( isplayer( eAttacker ) )
|
||||
{
|
||||
attacker_agent_type = "player";
|
||||
|
||||
if ( isdefined( eAttacker.name ) )
|
||||
attacker_name = eAttacker.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
attacker_agent_type = "nonagent";
|
||||
}
|
||||
}
|
||||
|
||||
// attacker origin
|
||||
attackerx = 0.0;
|
||||
attackery = 0.0;
|
||||
attackerz = 0.0;
|
||||
if ( isdefined( eAttacker ) && ( IsAgent( eAttacker ) || isPlayer( eAttacker ) ) )
|
||||
{
|
||||
attackerx = eAttacker.origin[ 0 ];
|
||||
attackery = eAttacker.origin[ 1 ];
|
||||
attackerz = eAttacker.origin[ 2 ];
|
||||
}
|
||||
|
||||
victim_alive_time = 0;
|
||||
if ( isdefined( self.birthtime ) )
|
||||
victim_alive_time = ( gettime() - self.birthtime ) / 1000;
|
||||
|
||||
victim_spawn_origin = ( 0, 0, 0 );
|
||||
if ( isdefined( self.spawnorigin ) )
|
||||
victim_spawn_origin = self.spawnorigin;
|
||||
|
||||
victim_dist_from_spawn = 0;
|
||||
if ( isdefined( self.spawnorigin ) )
|
||||
victim_dist_from_spawn = distance( self.origin, self.spawnorigin );
|
||||
|
||||
victim_damage_done = 0;
|
||||
if ( isdefined( self.damage_done ) )
|
||||
victim_damage_done = self.damage_done;
|
||||
|
||||
victim_agent_type = "unknown agent";
|
||||
if ( isdefined( self.agent_type ) )
|
||||
{
|
||||
victim_agent_type = self.agent_type;
|
||||
if ( isdefined( self.alien_type ) )
|
||||
victim_agent_type = self.alien_type;
|
||||
}
|
||||
|
||||
current_enemy_population = 0;
|
||||
foreach ( agent in level.agentArray )
|
||||
{
|
||||
if ( !IsDefined( agent.isActive ) || !agent.isActive )
|
||||
continue;
|
||||
|
||||
if ( isdefined( agent.team ) && agent.team == "axis" )
|
||||
current_enemy_population++;
|
||||
}
|
||||
|
||||
current_player_population = 0;
|
||||
if ( isdefined( level.players ) )
|
||||
current_player_population = level.players.size;
|
||||
|
||||
/#
|
||||
if ( GetDvarInt( "alien_bbprint_debug" ) > 0 )
|
||||
{
|
||||
IPrintLnBold( "^8bbprint: alienkilled (1/2)\n" +
|
||||
" attackerisagent=" + attacker_is_agent +
|
||||
" attackeralivetime=" + attacker_alive_time +
|
||||
" attackeragenttype=" + attacker_agent_type +
|
||||
" attackername=" + attacker_name +
|
||||
" attackerx=" + eAttacker.origin[ 0 ] +
|
||||
" attackery=" + eAttacker.origin[ 1 ] +
|
||||
" attackerz=" + eAttacker.origin[ 2 ] +
|
||||
" victimalivetime=" + victim_alive_time );
|
||||
|
||||
IPrintLnBold( "^8bbprint: alienkilled (2/2)\n" +
|
||||
" victimspawnoriginx=" + victim_spawn_origin[ 0 ] +
|
||||
" victimspawnoriginy=" + victim_spawn_origin[ 1 ] +
|
||||
" victimspawnoriginz=" + victim_spawn_origin[ 2 ] +
|
||||
" victimdistfromspawn=" + victim_dist_from_spawn +
|
||||
" victimdamagedone=" + victim_damage_done +
|
||||
" victimagenttype=" + victim_agent_type +
|
||||
" currentenemypopulation=" + current_enemy_population +
|
||||
" currentplayerpopulation=" + current_player_population );
|
||||
}
|
||||
#/
|
||||
|
||||
bbprint( "alienkilled",
|
||||
"attackerisagent %i attackeralivetime %f attackeragenttype %s attackername %s attackerx %f attackery %f attackerz %f victimalivetime %f victimspawnoriginx %f victimspawnoriginy %f victimspawnoriginz %f victimdistfromspawn %i victimdamagedone %i victimagenttype %s currentenemypopulation %i currentplayerpopulation %i ",
|
||||
attacker_is_agent,
|
||||
attacker_alive_time,
|
||||
attacker_agent_type,
|
||||
attacker_name,
|
||||
eAttacker.origin[ 0 ],
|
||||
eAttacker.origin[ 1 ],
|
||||
eAttacker.origin[ 2 ],
|
||||
victim_alive_time,
|
||||
victim_spawn_origin[ 0 ],
|
||||
victim_spawn_origin[ 1 ],
|
||||
victim_spawn_origin[ 2 ],
|
||||
victim_dist_from_spawn,
|
||||
victim_damage_done,
|
||||
victim_agent_type,
|
||||
current_enemy_population,
|
||||
current_player_population );
|
||||
|
||||
// =========================== [END] blackbox print ===========================
|
||||
}
|
||||
|
||||
KILL_TRIGGER_SPAWN_STRUCT_TARGET_NAME = "respawn_edge";
|
||||
kill_trigger_spawn_init()
|
||||
{
|
||||
level.killTriggerSpawnLocs = getstructArray( KILL_TRIGGER_SPAWN_STRUCT_TARGET_NAME, "targetname" );
|
||||
}
|
||||
|
||||
getKillTriggerSpawnLoc()
|
||||
{
|
||||
AssertEx( level.killTriggerSpawnLocs.size > 0, "Need to put script struct around kill triggers with KVP: 'targetname', '" + KILL_TRIGGER_SPAWN_STRUCT_TARGET_NAME + "'" );
|
||||
|
||||
return ( getClosest ( self.origin, level.killTriggerSpawnLocs ) );
|
||||
}
|
||||
|
||||
should_do_pipebomb_death( sWeapon )
|
||||
{
|
||||
alientype = self get_alien_type();
|
||||
|
||||
//minions already explode, and the Rhino/Elite aliens shouldn't gib
|
||||
if ( alientype == "minion" || alientype == "elite" || alientype == "mammoth" )
|
||||
return false;
|
||||
|
||||
return ( isDefined( sWeapon ) && sWeapon == "iw6_aliendlc22_mp" ); //pipe bomb
|
||||
}
|
||||
|
||||
do_pipebomb_death()
|
||||
{
|
||||
PlayFx( level._effect[ "alien_gib" ], self.origin + (0,0,32) );
|
||||
}
|
||||
|
||||
is_pettrap_kill( eInflictor )
|
||||
{
|
||||
return ( isDefined( eInflictor ) && isDefined( eInflictor.is_pet_trap ) );
|
||||
}
|
||||
|
||||
general_alien_custom_death( eInflictor, eAttacker,iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc )
|
||||
{
|
||||
is_player = IsDefined( eAttacker ) && isPlayer ( eAttacker );
|
||||
|
||||
if ( is_player && isDefined ( sWeapon ) && weapon_has_alien_attachment( sWeapon ) && sMeansOfDeath != "MOD_MELEE" && !is_true ( level.easter_egg_lodge_sign_active ) )
|
||||
{
|
||||
PlayFx( level._effect[ "alien_ark_gib" ], self.origin + (0,0,32) );
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
1168
maps/mp/alien/_debug.gsc
Normal file
1168
maps/mp/alien/_debug.gsc
Normal file
File diff suppressed because it is too large
Load Diff
989
maps/mp/alien/_deployablebox.gsc
Normal file
989
maps/mp/alien/_deployablebox.gsc
Normal file
@ -0,0 +1,989 @@
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include maps\mp\alien\_utility;
|
||||
|
||||
/*
|
||||
Deployable box killstreaks: the player will be able to place a box in the world and teammates can grab items from it
|
||||
this will be used on multiple killstreaks where you can place a box in the world with something in it
|
||||
*/
|
||||
|
||||
BOX_TIMEOUT_UPDATE_INTERVAL = 1.0;
|
||||
DEFAULT_USE_TIME = 3000;
|
||||
BOX_DEFAULT_HEALTH = 999999; // so that boxes aren't killed in code
|
||||
|
||||
init()
|
||||
{
|
||||
if ( !IsDefined( level.boxSettings ) )
|
||||
{
|
||||
level.boxSettings = [];
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// MARKER FUNCTIONS
|
||||
// 2012-06-21 wallace
|
||||
// Stole an updated version from _uplink.gsc. Should probably unify all these funcs eventually
|
||||
//////////////////////////////////////////////////
|
||||
beginDeployableViaMarker( lifeId, boxType )
|
||||
{
|
||||
self thread watchDeployableMarkerCancel( boxType );
|
||||
self thread watchDeployableMarkerPlacement( boxType, lifeId );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
result = self waittill_any_return( "deployable_canceled", "deployable_deployed", "death", "disconnect" );
|
||||
|
||||
return ( result == "deployable_deployed" );
|
||||
}
|
||||
}
|
||||
|
||||
tryUseDeployable( lifeId, boxType ) // self == player
|
||||
{
|
||||
self thread watchDeployableMarkerCancel( boxType );
|
||||
self thread watchDeployableMarkerPlacement( boxType, lifeId );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
result = self waittill_any_return( "deployable_canceled", "deployable_deployed", "death", "disconnect" );
|
||||
|
||||
return ( result == "deployable_deployed" );
|
||||
}
|
||||
}
|
||||
|
||||
watchDeployableMarkerCancel( boxType )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "deployable_deployed" );
|
||||
|
||||
boxConfig = level.boxSettings[ boxType ];
|
||||
currentWeapon = self getCurrentWeapon();
|
||||
|
||||
while( currentWeapon == boxConfig.weaponInfo )
|
||||
{
|
||||
self waittill( "weapon_change", currentWeapon );
|
||||
}
|
||||
|
||||
self notify( "deployable_canceled" );
|
||||
}
|
||||
|
||||
watchDeployableMarkerPlacement( boxType, lifeId )
|
||||
{
|
||||
self endon( "spawned_player" ); // you shouldn't do endon( "death" ) here because this thread needs to run
|
||||
self endon( "disconnect" );
|
||||
self endon( "deployable_canceled" );
|
||||
|
||||
while( true )
|
||||
{
|
||||
self waittill( "grenade_fire", marker, weaponName );
|
||||
|
||||
if( isReallyAlive(self) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
marker Delete();
|
||||
}
|
||||
}
|
||||
|
||||
self notify( "deployable_deployed" );
|
||||
|
||||
marker.owner = self;
|
||||
marker.weaponName = weaponName;
|
||||
self.marker = marker;
|
||||
|
||||
marker PlaySoundToPlayer( level.boxSettings[ boxType ].deployedSfx, self );
|
||||
|
||||
marker thread markerActivate( lifeId, boxType, ::box_setActive );
|
||||
}
|
||||
|
||||
override_box_moving_platform_death( data )
|
||||
{
|
||||
self notify( "death" ); // we're doing this here instead of letting the mover code just delete us so that we can run our necessary clean-up functionality (like removal of the objective marker from the minimap)
|
||||
}
|
||||
|
||||
markerActivate( lifeId, boxType, usedCallback ) // self == marker
|
||||
{
|
||||
self notify( "markerActivate" );
|
||||
self endon( "markerActivate" );
|
||||
//self waittill( "explode", position );
|
||||
self waittill( "missile_stuck" );
|
||||
owner = self.owner;
|
||||
position = self.origin;
|
||||
|
||||
if ( !isDefined( owner ) )
|
||||
return;
|
||||
|
||||
box = createBoxForPlayer( boxType, position, owner );
|
||||
|
||||
// For moving platforms.
|
||||
data = SpawnStruct();
|
||||
data.linkParent = self GetLinkedParent();
|
||||
|
||||
//fixes wall hack exploit with linked items
|
||||
if ( isDefined( data.linkParent ) && isDefined( data.linkParent.model ) && DeployableExclusion( data.linkParent.model ) )
|
||||
{
|
||||
box.origin = data.linkParent.origin;
|
||||
|
||||
grandParent = data.linkParent GetLinkedParent();
|
||||
|
||||
if ( isDefined( grandParent ) )
|
||||
data.linkParent = grandParent;
|
||||
else
|
||||
data.linkParent = undefined;
|
||||
}
|
||||
|
||||
data.deathOverrideCallback = ::override_box_moving_platform_death;
|
||||
box thread maps\mp\_movers::handle_moving_platforms( data );
|
||||
|
||||
box.moving_platform = data.linkParent;
|
||||
|
||||
box SetOtherEnt(owner);
|
||||
|
||||
// ES - 2/24/14 - This waitframe is causing an issue where, when deployed on a moving platform, the "death" notification is sent instantly, but is never caught.
|
||||
wait 0.05;
|
||||
|
||||
//self playSound( "sentry_gun_beep" );
|
||||
box thread [[ usedCallback ]]();
|
||||
|
||||
self delete();
|
||||
|
||||
if( IsDefined(box) && (box touchingBadTrigger()) )
|
||||
{
|
||||
box notify( "death" );
|
||||
}
|
||||
}
|
||||
|
||||
DeployableExclusion( parentModel )
|
||||
{
|
||||
if ( parentModel == "weapon_alien_laser_drill" )
|
||||
return true;
|
||||
else if ( IsSubStr( parentModel, "crafting" ) )
|
||||
return true;
|
||||
else if ( IsSubStr( parentModel, "scorpion_body" ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
isHoldingDeployableBox()
|
||||
{
|
||||
curWeap = self GetCurrentWeapon();
|
||||
if ( IsDefined( curWeap ) )
|
||||
{
|
||||
foreach( deplBoxWeap in level.boxSettings )
|
||||
{
|
||||
if ( curWeap == deplBoxWeap.weaponInfo )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
///////////////////////////////////////////////////
|
||||
// END MARKER FUNCTIONS
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// BOX HANDLER FUNCTIONS
|
||||
//////////////////////////////////////////////////
|
||||
get_box_icon( resourceType, dpadName, upgrade_rank )
|
||||
{
|
||||
return level.alien_combat_resources[ resourceType][ dpadName ].upgrades[upgrade_rank].dpad_icon;
|
||||
}
|
||||
|
||||
get_resource_type( dpadName )
|
||||
{
|
||||
if( !isDefined( dpadName ) )
|
||||
return undefined;
|
||||
|
||||
foreach ( resource_type_name, resource_type in level.alien_combat_resources )
|
||||
{
|
||||
if ( IsDefined( resource_type[ dpadName ] ) )
|
||||
{
|
||||
return resource_type_name;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
createBoxForPlayer( boxType, position, owner )
|
||||
{
|
||||
assertEx( isDefined( owner ), "createBoxForPlayer() called without owner specified" );
|
||||
|
||||
boxConfig = level.boxSettings[ boxType ];
|
||||
|
||||
box = Spawn( "script_model", position );
|
||||
box setModel( boxConfig.modelBase );
|
||||
box.health = BOX_DEFAULT_HEALTH;
|
||||
box.maxHealth = boxConfig.maxHealth;
|
||||
box.angles = owner.angles;
|
||||
box.boxType = boxType;
|
||||
box.owner = owner;
|
||||
box.team = owner.team;
|
||||
if ( IsDefined( boxConfig.dpadName ) )
|
||||
{
|
||||
box.dpadName = boxConfig.dpadName;
|
||||
}
|
||||
if ( IsDefined( boxConfig.maxUses ) )
|
||||
{
|
||||
box.usesRemaining = boxConfig.maxUses;
|
||||
}
|
||||
|
||||
player = box.owner;
|
||||
resource_type = get_resource_type( box.dpadName );
|
||||
|
||||
if ( is_combat_resource( resource_type ) )
|
||||
{
|
||||
box.upgrade_rank = player maps\mp\alien\_persistence::get_upgrade_level( resource_type );
|
||||
box.icon_name = get_box_icon( resource_type, box.dpadName, box.upgrade_rank );
|
||||
}
|
||||
else
|
||||
{
|
||||
AssertEx( isDefined( boxConfig.icon_name ), "For non-combat-resource box, the .icon_name must be specified in the boxConfig struct" );
|
||||
|
||||
box.upgrade_rank = 0;
|
||||
box.icon_name = boxConfig.icon_name;
|
||||
}
|
||||
|
||||
// black box data tracking
|
||||
level.alienBBData[ "team_item_deployed" ]++;
|
||||
player maps\mp\alien\_persistence::eog_player_update_stat( "deployables", 1 );
|
||||
|
||||
/*
|
||||
ownername = "";
|
||||
if ( isdefined( owner.name ) )
|
||||
ownername = owner.name;
|
||||
|
||||
itemname = boxType;
|
||||
if ( isdefined( box.dpadName ) )
|
||||
itemname = box.dpadName;
|
||||
|
||||
/#
|
||||
if ( GetDvarInt( "alien_bbprint_debug" ) > 0 )
|
||||
{
|
||||
IPrintLnBold( "^8bbprint: aliendeployabledeployed \n" +
|
||||
" itemname=" + itemname +
|
||||
" itemlevel=" + box.upgrade_rank +
|
||||
" itemx,y,z=" + position +
|
||||
" ownername=" + ownername );
|
||||
}
|
||||
#/
|
||||
|
||||
bbprint( "aliendeployabledeployed",
|
||||
"itemname %s itemlevel %s itemx %f itemy %f itemz %f ownername %s ",
|
||||
itemname,
|
||||
box.upgrade_rank,
|
||||
position[0],
|
||||
position[1],
|
||||
position[2],
|
||||
ownername );
|
||||
*/
|
||||
|
||||
box box_setInactive();
|
||||
box thread box_handleOwnerDisconnect();
|
||||
box addBoxToLevelArray();
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
is_combat_resource( resource_type ) { return isDefined( resource_type ); }
|
||||
|
||||
box_setActive( skipOwnerUse ) // self == box
|
||||
{
|
||||
self setCursorHint( "HINT_NOICON" );
|
||||
boxConfig = level.boxSettings[ self.boxType ];
|
||||
self setHintString( boxConfig.hintString );
|
||||
|
||||
self.inUse = false;
|
||||
|
||||
curObjID = maps\mp\gametypes\_gameobjects::getNextObjID();
|
||||
Objective_Add( curObjID, "invisible", (0,0,0) );
|
||||
Objective_Position( curObjID, self.origin );
|
||||
Objective_State( curObjID, "active" );
|
||||
|
||||
if( isDefined( boxConfig.shaderName ) )
|
||||
Objective_Icon( curObjID, boxConfig.shaderName );
|
||||
|
||||
self.objIdFriendly = curObjID;
|
||||
|
||||
// use the deployable on the owner once
|
||||
if ( ( !IsDefined( skipOwnerUse ) || !skipOwnerUse ) && IsDefined( boxConfig.onuseCallback )
|
||||
&& ( !IsDefined( boxconfig.canUseCallback ) || (self.owner [[ boxConfig.canUseCallback ]]() ) )
|
||||
)
|
||||
{
|
||||
if( isReallyAlive( self.owner ) )
|
||||
self.owner [[ boxConfig.onUseCallback ]]( self );
|
||||
}
|
||||
|
||||
if ( level.teamBased )
|
||||
{
|
||||
Objective_Team( curObjID, self.team );
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( self.team == player.team
|
||||
&& (!IsDefined(boxConfig.canUseCallback) || player [[ boxConfig.canUseCallback ]](self) )
|
||||
)
|
||||
{
|
||||
self box_SetIcon( player, boxConfig.streakName, boxConfig.headIconOffset );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Objective_Player( curObjID, self.owner GetEntityNumber() );
|
||||
|
||||
if( !IsDefined(boxConfig.canUseCallback) || self.owner [[ boxConfig.canUseCallback ]](self) )
|
||||
{
|
||||
self box_SetIcon( self.owner, boxConfig.streakName, boxConfig.headIconOffset );
|
||||
}
|
||||
}
|
||||
|
||||
self MakeUsable();
|
||||
self.isUsable = true;
|
||||
self SetCanDamage( true );
|
||||
self thread box_handleDamage();
|
||||
self thread box_handleDeath();
|
||||
self thread box_timeOut();
|
||||
|
||||
self make_entity_sentient_mp( self.team, true );
|
||||
|
||||
if ( IsDefined( self.owner ) )
|
||||
self.owner notify( "new_deployable_box", self );
|
||||
|
||||
if (level.teamBased)
|
||||
{
|
||||
foreach ( player in level.participants )
|
||||
{
|
||||
_box_setActiveHelper( player, self.team == player.team, boxConfig.canUseCallback );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( player in level.participants )
|
||||
{
|
||||
_box_setActiveHelper( player, IsDefined( self.owner ) && self.owner == player, boxConfig.canUseCallback );
|
||||
}
|
||||
}
|
||||
|
||||
if( ( !isdefined( self.air_dropped ) || !self.air_dropped ) && !isPlayingSolo() )
|
||||
level thread teamPlayerCardSplash( boxConfig.splashName, self.owner, self.team );
|
||||
|
||||
self thread box_playerConnected();
|
||||
self thread box_agentConnected();
|
||||
}
|
||||
|
||||
_box_setActiveHelper( player, bActivate, canUseFunc )
|
||||
{
|
||||
if ( bActivate )
|
||||
{
|
||||
if ( !IsDefined( canUseFunc ) || player [[ canUseFunc ]](self) )
|
||||
{
|
||||
self box_enablePlayerUse( player );
|
||||
}
|
||||
else
|
||||
{
|
||||
self box_disablePlayerUse( player );
|
||||
// if this player is already a juggernaut then when they die, let them use the box
|
||||
self thread doubleDip( player );
|
||||
}
|
||||
self thread boxThink( player );
|
||||
}
|
||||
else
|
||||
{
|
||||
self box_disablePlayerUse( player );
|
||||
}
|
||||
}
|
||||
|
||||
box_playerConnected() // self == box
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
// when new players connect they need a boxthink thread run on them
|
||||
while( true )
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
self childthread box_waittill_player_spawn_and_add_box( player );
|
||||
}
|
||||
}
|
||||
|
||||
box_agentConnected() // self == box
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
// when new agents connect they need a boxthink thread run on them
|
||||
while( true )
|
||||
{
|
||||
level waittill( "spawned_agent_player", agent );
|
||||
self box_addBoxForPlayer( agent );
|
||||
}
|
||||
}
|
||||
|
||||
box_waittill_player_spawn_and_add_box( player ) // self == box
|
||||
{
|
||||
player waittill( "spawned_player" );
|
||||
if ( level.teamBased )
|
||||
{
|
||||
self box_addBoxForPlayer( player );
|
||||
}
|
||||
}
|
||||
|
||||
box_playerJoinedTeam( player ) // self == box
|
||||
{
|
||||
self endon( "death" );
|
||||
player endon( "disconnect" );
|
||||
|
||||
// when new players connect they need a boxthink thread run on them
|
||||
while( true )
|
||||
{
|
||||
player waittill( "joined_team" );
|
||||
if ( level.teamBased )
|
||||
{
|
||||
self box_addBoxForPlayer( player );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
box_addBoxForPlayer( player ) // self == box
|
||||
{
|
||||
if ( self.team == player.team )
|
||||
{
|
||||
self box_enablePlayerUse( player );
|
||||
self thread boxThink( player );
|
||||
self box_SetIcon( player, level.boxSettings[ self.boxType ].streakName, level.boxSettings[ self.boxType ].headIconOffset );
|
||||
}
|
||||
else
|
||||
{
|
||||
self box_disablePlayerUse( player );
|
||||
self maps\mp\_entityheadIcons::setHeadIcon( player, "", (0,0,0) );
|
||||
}
|
||||
}
|
||||
|
||||
box_SetIcon( player, streakName, vOffset )
|
||||
{
|
||||
self maps\mp\_entityheadIcons::setHeadIcon( player, self.icon_name, (0, 0, vOffset), 14, 14, undefined, undefined, undefined, undefined, undefined, false );
|
||||
}
|
||||
|
||||
box_enablePlayerUse( player ) // self == box
|
||||
{
|
||||
if ( IsPlayer(player) )
|
||||
self EnablePlayerUse( player );
|
||||
|
||||
self.disabled_use_for[player GetEntityNumber()] = false;
|
||||
}
|
||||
|
||||
box_disablePlayerUse( player ) // self == box
|
||||
{
|
||||
if ( IsPlayer(player) )
|
||||
self DisablePlayerUse( player );
|
||||
|
||||
self.disabled_use_for[player GetEntityNumber()] = true;
|
||||
}
|
||||
|
||||
box_setInactive()
|
||||
{
|
||||
self makeUnusable();
|
||||
self.isUsable = false;
|
||||
self maps\mp\_entityheadIcons::setHeadIcon( "none", "", (0,0,0) );
|
||||
if ( isDefined( self.objIdFriendly ) )
|
||||
_objective_delete( self.objIdFriendly );
|
||||
}
|
||||
|
||||
box_handleDamage() // self == box
|
||||
{
|
||||
boxConfig = level.boxSettings[ self.boxType ];
|
||||
|
||||
self maps\mp\gametypes\_damage::monitorDamage(
|
||||
boxConfig.maxHealth,
|
||||
boxConfig.damageFeedback,
|
||||
::boxModifyDamage,
|
||||
::boxHandleDeathDamage,
|
||||
true // isKillstreak
|
||||
);
|
||||
}
|
||||
|
||||
boxModifyDamage( attacker, weapon, type, damage )
|
||||
{
|
||||
modifiedDamage = damage;
|
||||
|
||||
if( IsExplosiveDamageMOD( type ) )
|
||||
{
|
||||
modifiedDamage = damage * 1.5;
|
||||
}
|
||||
|
||||
modifiedDamage = self maps\mp\gametypes\_damage::handleMeleeDamage( weapon, type, modifiedDamage );
|
||||
modifiedDamage = self maps\mp\gametypes\_damage::handleMissileDamage( weapon, type, modifiedDamage );
|
||||
modifiedDamage = self maps\mp\gametypes\_damage::handleAPDamage( weapon, type, modifiedDamage, attacker );
|
||||
|
||||
return modifiedDamage;
|
||||
}
|
||||
|
||||
boxHandleDeathDamage( attacker, weapon, type, damage )
|
||||
{
|
||||
boxConfig = level.boxSettings[ self.boxType ];
|
||||
self maps\mp\gametypes\_damage::onKillstreakKilled( attacker, weapon, type, damage, boxConfig.xpPopup, boxConfig.voDestroyed );
|
||||
}
|
||||
|
||||
box_handleDeath()
|
||||
{
|
||||
self waittill ( "death" );
|
||||
|
||||
// this handles cases of deletion
|
||||
if ( !isDefined( self ) )
|
||||
return;
|
||||
|
||||
self box_setInactive();
|
||||
self removeBoxFromLevelArray();
|
||||
|
||||
boxConfig = level.boxSettings[ self.boxType ];
|
||||
PlayFX( getfx( "deployablebox_crate_destroy" ), self.origin );
|
||||
// 2013-03-08 wsh: whould probably validate all the used fields...
|
||||
if ( IsDefined( boxConfig.deathDamageMax ) )
|
||||
{
|
||||
owner = undefined;
|
||||
if ( IsDefined(self.owner) )
|
||||
owner = self.owner;
|
||||
|
||||
// somewhat hacky:
|
||||
// shift the origin of the damage because it'll collide with the box otherwise
|
||||
// we could also apply the damage after we delete the item?
|
||||
RadiusDamage( self.origin + (0, 0, boxConfig.headIconOffset),
|
||||
boxConfig.deathDamageRadius,
|
||||
boxConfig.deathDamageMax,
|
||||
boxConfig.deathDamageMin,
|
||||
owner,
|
||||
"MOD_EXPLOSIVE",
|
||||
boxConfig.deathWeaponInfo
|
||||
);
|
||||
}
|
||||
|
||||
wait( 0.1 );
|
||||
|
||||
self notify( "deleting" );
|
||||
|
||||
self delete();
|
||||
}
|
||||
|
||||
box_handleOwnerDisconnect() // self == box
|
||||
{
|
||||
self endon ( "death" );
|
||||
level endon ( "game_ended" );
|
||||
|
||||
self notify ( "box_handleOwner" );
|
||||
self endon ( "box_handleOwner" );
|
||||
|
||||
old_owner = self.owner;
|
||||
self.owner waittill( "killstreak_disowned" );
|
||||
|
||||
// special case for air dropped box to stay when fake owner leaves ( owner was randomly picked )
|
||||
if ( isdefined( self.air_dropped ) && self.air_dropped )
|
||||
{
|
||||
// reassign owner to next avaliable player
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( !isdefined( player ) || ( isdefined( old_owner ) && old_owner == player ) )
|
||||
continue;
|
||||
|
||||
self.owner = player;
|
||||
self thread box_handleOwnerDisconnect(); // recurse
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// removed if not air dropped or if no host player found (which shouldn't happen)
|
||||
self notify( "death" );
|
||||
}
|
||||
|
||||
boxThink( player )
|
||||
{
|
||||
self endon ( "death" );
|
||||
|
||||
self thread boxCaptureThink( player );
|
||||
|
||||
if ( !IsDefined(player.boxes) )
|
||||
{
|
||||
player.boxes = [];
|
||||
}
|
||||
player.boxes[player.boxes.size] = self;
|
||||
|
||||
boxConfig = level.boxSettings[ self.boxType ];
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill ( "captured", capturer );
|
||||
|
||||
if (capturer == player)
|
||||
{
|
||||
player PlayLocalSound( boxConfig.onUseSfx );
|
||||
|
||||
if ( IsDefined( boxConfig.onuseCallback ) )
|
||||
{
|
||||
player [[ boxConfig.onUseCallback ]]( self );
|
||||
|
||||
if ( maps\mp\alien\_utility::is_chaos_mode() )
|
||||
maps\mp\alien\_chaos::update_pickup_deployable_box_event();
|
||||
}
|
||||
|
||||
// if this is not the owner then give the owner some xp
|
||||
if( IsDefined( self.owner ) && player != self.owner )
|
||||
{
|
||||
self.owner thread maps\mp\gametypes\_rank::xpEventPopup( boxConfig.event );
|
||||
self.owner thread maps\mp\gametypes\_rank::giveRankXP( "support", boxConfig.useXP );
|
||||
}
|
||||
|
||||
if ( IsDefined( self.usesRemaining ) )
|
||||
{
|
||||
self.usesRemaining--;
|
||||
if ( self.usesRemaining == 0)
|
||||
{
|
||||
self box_leave();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
self maps\mp\_entityheadIcons::setHeadIcon( player, "", (0,0,0) );
|
||||
self box_disablePlayerUse( player );
|
||||
self thread doubleDip( player );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doubleDip( player ) // self == box
|
||||
{
|
||||
self endon( "death" );
|
||||
player endon( "disconnect" );
|
||||
|
||||
// air dropped rewards can not be double dipped
|
||||
if( isdefined( self.air_dropped ) && self.air_dropped )
|
||||
return;
|
||||
|
||||
// once they die, let them take from the box again
|
||||
player waittill( "death" );
|
||||
|
||||
if( level.teamBased )
|
||||
{
|
||||
if( self.team == player.team )
|
||||
{
|
||||
self box_SetIcon( player, level.boxSettings[ self.boxType ].streakName, level.boxSettings[ self.boxType ].headIconOffset );
|
||||
self box_enablePlayerUse( player );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( IsDefined( self.owner ) && self.owner == player )
|
||||
{
|
||||
self box_SetIcon( player, level.boxSettings[ self.boxType ].streakName, level.boxSettings[ self.boxType ].headIconOffset );
|
||||
self box_enablePlayerUse( player );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boxCaptureThink( player ) // self == box
|
||||
{
|
||||
while( isDefined( self ) )
|
||||
{
|
||||
self waittill( "trigger", tiggerer );
|
||||
if ( is_aliens() )
|
||||
{
|
||||
if ( [[level.boxCaptureThink_alien_func]]( tiggerer ) )
|
||||
continue;
|
||||
}
|
||||
if ( is_chaos_mode() )
|
||||
{
|
||||
switch ( self.boxType )
|
||||
{
|
||||
case "medic_skill":
|
||||
case "specialist_skill":
|
||||
case "tank_skill":
|
||||
case "engineer_skill":
|
||||
if( is_true( tiggerer.hasChaosClassSkill ) )
|
||||
{
|
||||
tiggerer maps\mp\_utility::setLowerMessage( "cant_use", &"ALIEN_CHAOS_CANT_PICKUP_BONUS", 3 );
|
||||
continue;
|
||||
}
|
||||
else if ( is_true( tiggerer.chaosClassSkillInUse ) )
|
||||
{
|
||||
tiggerer maps\mp\_utility::setLowerMessage( "skill_in_use", &"ALIEN_CHAOS_SKILL_IN_USE", 3 );
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case "combo_freeze":
|
||||
if( is_true( tiggerer.hasComboFreeze ) )
|
||||
{
|
||||
tiggerer maps\mp\_utility::setLowerMessage( "cant_use", &"ALIEN_CHAOS_CANT_PICKUP_BONUS", 3 );
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tiggerer == player
|
||||
&& self useHoldThink( player, level.boxSettings[ self.boxType ].useTime )
|
||||
)
|
||||
{
|
||||
self notify( "captured", player );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isFriendlyToBox( box )
|
||||
{
|
||||
return ( level.teamBased
|
||||
&& self.team == box.team );
|
||||
}
|
||||
|
||||
box_timeOut() // self == box
|
||||
{
|
||||
self endon( "death" );
|
||||
level endon ( "game_ended" );
|
||||
|
||||
if ( box_should_leave_immediately() )
|
||||
{
|
||||
wait 0.05;
|
||||
}
|
||||
else
|
||||
{
|
||||
lifeSpan = level.boxSettings[ self.boxType ].lifeSpan;
|
||||
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( lifeSpan );
|
||||
}
|
||||
|
||||
self box_leave();
|
||||
}
|
||||
|
||||
box_should_leave_immediately()
|
||||
{
|
||||
if ( ( self.boxtype == "deployable_ammo" && self.upgrade_rank == 4 ) || ( self.boxtype == "deployable_specialammo_comb" && self.upgrade_rank == 4 ) ) // stay to regen ammo
|
||||
return false;
|
||||
|
||||
if ( maps\mp\alien\_utility::isPlayingSolo() && ( !isdefined( self.air_dropped ) || !self.air_dropped ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
box_leave()
|
||||
{
|
||||
// TODO: get sound for this
|
||||
//if ( isDefined( self.owner ) )
|
||||
// self.owner thread leaderDialogOnPlayer( "sentry_gone" );
|
||||
PlayFX( getfx( "deployablebox_crate_destroy" ), self.origin );
|
||||
|
||||
wait( 0.05 );
|
||||
|
||||
self notify( "death" );
|
||||
}
|
||||
|
||||
deleteOnOwnerDeath( owner ) // self == box.friendlyModel or box.enemyModel, owner == box
|
||||
{
|
||||
wait ( 0.25 );
|
||||
self linkTo( owner, "tag_origin", (0,0,0), (0,0,0) );
|
||||
|
||||
owner waittill ( "death" );
|
||||
|
||||
box_leave();
|
||||
}
|
||||
|
||||
box_ModelTeamUpdater( showForTeam ) // self == box model (enemy or friendly)
|
||||
{
|
||||
self endon ( "death" );
|
||||
|
||||
self hide();
|
||||
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( player.team == showForTeam )
|
||||
self showToPlayer( player );
|
||||
}
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill ( "joined_team" );
|
||||
|
||||
self hide();
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( player.team == showForTeam )
|
||||
self showToPlayer( player );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useHoldThink( player, useTime )
|
||||
{
|
||||
if ( IsPlayer(player) )
|
||||
player playerLinkTo( self );
|
||||
else
|
||||
player LinkTo( self );
|
||||
player playerLinkedOffsetEnable();
|
||||
|
||||
player.boxParams = SpawnStruct();
|
||||
player.boxParams.curProgress = 0;
|
||||
player.boxParams.inUse = true;
|
||||
player.boxParams.useRate = 0;
|
||||
|
||||
if ( isDefined( useTime ) )
|
||||
{
|
||||
player.boxParams.useTime = useTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
player.boxParams.useTime = DEFAULT_USE_TIME;
|
||||
}
|
||||
|
||||
//player _disableWeapon();
|
||||
player disable_weapon_timeout( ( useTime + 0.05 ), "deployable_weapon_management" );
|
||||
|
||||
if ( IsPlayer(player) )
|
||||
player thread personalUseBar( self );
|
||||
|
||||
result = useHoldThinkLoop( player );
|
||||
assert ( isDefined( result ) );
|
||||
|
||||
if ( isAlive( player ) )
|
||||
{
|
||||
//player _enableWeapon();
|
||||
player enable_weapon_wrapper( "deployable_weapon_management" );
|
||||
player unlink();
|
||||
}
|
||||
|
||||
if ( !isDefined( self ) )
|
||||
return false;
|
||||
|
||||
player.boxParams.inUse = false;
|
||||
player.boxParams.curProgress = 0;
|
||||
|
||||
return ( result );
|
||||
}
|
||||
|
||||
personalUseBar( object ) // self == player
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
useBar = createPrimaryProgressBar( 0, 25 );
|
||||
useBarText = createPrimaryProgressBarText( 0, 25 );
|
||||
useBarText setText( level.boxSettings[ object.boxType ].capturingString );
|
||||
|
||||
lastRate = -1;
|
||||
while ( isReallyAlive( self ) && isDefined( object ) && self.boxParams.inUse && object.isUsable && !level.gameEnded )
|
||||
{
|
||||
if ( lastRate != self.boxParams.useRate )
|
||||
{
|
||||
if( self.boxParams.curProgress > self.boxParams.useTime)
|
||||
self.boxParams.curProgress = self.boxParams.useTime;
|
||||
|
||||
useBar updateBar( self.boxParams.curProgress / self.boxParams.useTime, (1000 / self.boxParams.useTime) * self.boxParams.useRate );
|
||||
|
||||
if ( !self.boxParams.useRate )
|
||||
{
|
||||
useBar hideElem();
|
||||
useBarText hideElem();
|
||||
}
|
||||
else
|
||||
{
|
||||
useBar showElem();
|
||||
useBarText showElem();
|
||||
}
|
||||
}
|
||||
lastRate = self.boxParams.useRate;
|
||||
wait ( 0.05 );
|
||||
}
|
||||
|
||||
useBar destroyElem();
|
||||
useBarText destroyElem();
|
||||
}
|
||||
|
||||
useHoldThinkLoop( player )
|
||||
{
|
||||
while( !level.gameEnded && isDefined( self ) && isReallyAlive( player ) && player useButtonPressed() && player.boxParams.curProgress < player.boxParams.useTime )
|
||||
{
|
||||
player.boxParams.curProgress += (50 * player.boxParams.useRate);
|
||||
|
||||
if ( isDefined( player.objectiveScaler ) )
|
||||
player.boxParams.useRate = 1 * player.objectiveScaler;
|
||||
else
|
||||
player.boxParams.useRate = 1;
|
||||
|
||||
if ( player.boxParams.curProgress >= player.boxParams.useTime )
|
||||
return ( isReallyAlive( player ) );
|
||||
|
||||
wait 0.05;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
disableWhenJuggernaut() // self == box
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
self endon( "death" );
|
||||
|
||||
while( true )
|
||||
{
|
||||
level waittill( "juggernaut_equipped", player );
|
||||
self maps\mp\_entityheadIcons::setHeadIcon( player, "", (0,0,0) );
|
||||
self box_disablePlayerUse( player );
|
||||
self thread doubleDip( player );
|
||||
}
|
||||
}
|
||||
|
||||
addBoxToLevelArray() // self == box
|
||||
{
|
||||
// put the newly created box in the level array for the box type
|
||||
level.deployable_box[ self.boxType ][ self GetEntityNumber() ] = self;
|
||||
}
|
||||
|
||||
removeBoxFromLevelArray() // self == box
|
||||
{
|
||||
level.deployable_box[ self.boxType ][ self GetEntityNumber() ] = undefined;
|
||||
}
|
||||
|
||||
|
||||
default_canUseDeployable( boxEnt ) // self == player
|
||||
{
|
||||
if( ( isDefined( boxEnt ) && boxEnt.owner == self || self maps\mp\alien\_prestige::prestige_getNoDeployables() == 1.0 ) && !isdefined( boxEnt.air_dropped ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
default_OnUseDeployable( boxent ) //self =a player
|
||||
{
|
||||
self thread maps\mp\alien\_persistence::deployablebox_used_track( boxEnt );
|
||||
maps\mp\alien\_utility::deployable_box_onuse_message( boxent );
|
||||
}
|
||||
|
||||
default_tryUseDeployable( lifeId, BOX_TYPE ) // self == player
|
||||
{
|
||||
result = self maps\mp\alien\_combat_resources::alien_beginDeployableViaMarker( lifeId, BOX_TYPE );
|
||||
|
||||
if( ( !IsDefined( result ) || !result ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
init_deployable( BOX_TYPE, boxconfig )
|
||||
{
|
||||
if ( !IsDefined( level.boxSettings ) )
|
||||
{
|
||||
level.boxSettings = [];
|
||||
}
|
||||
|
||||
level.boxSettings[ BOX_TYPE ] = boxConfig;
|
||||
|
||||
if ( !IsDefined( level.killStreakFuncs ) )
|
||||
{
|
||||
level.killStreakFuncs = [];
|
||||
}
|
||||
|
||||
//level.killStreakFuncs[ BOX_TYPE ] = ::default_tryUseDeployable;
|
||||
|
||||
level.deployable_box[ BOX_TYPE ] = []; // storing each created box in their own array
|
||||
}
|
1620
maps/mp/alien/_deployablebox_functions.gsc
Normal file
1620
maps/mp/alien/_deployablebox_functions.gsc
Normal file
File diff suppressed because it is too large
Load Diff
65
maps/mp/alien/_dev.gsc
Normal file
65
maps/mp/alien/_dev.gsc
Normal file
@ -0,0 +1,65 @@
|
||||
|
||||
/#
|
||||
init()
|
||||
{
|
||||
SetDevDvarIfUninitialized( "debug_reflection", "0" );
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
player thread updateReflectionProbe();
|
||||
}
|
||||
}
|
||||
|
||||
updateReflectionProbe()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
if ( GetDvarInt( "debug_reflection" ) == 1 )
|
||||
{
|
||||
if ( !IsDefined( self.debug_reflectionobject ) )
|
||||
{
|
||||
self.debug_reflectionobject = spawn( "script_model", self geteye() + ( ( anglestoforward( self.angles ) * 100 ) ) );
|
||||
self.debug_reflectionobject setmodel( "test_sphere_silver" );
|
||||
self.debug_reflectionobject.origin = self geteye() + ( ( anglestoforward( self getplayerangles() ) * 100 ) );
|
||||
self thread reflectionProbeButtons();
|
||||
}
|
||||
}
|
||||
else if ( GetDvarInt( "debug_reflection" ) == 0 )
|
||||
{
|
||||
if ( IsDefined( self.debug_reflectionobject ) )
|
||||
self.debug_reflectionobject delete();
|
||||
}
|
||||
|
||||
wait( 0.05 );
|
||||
}
|
||||
}
|
||||
|
||||
reflectionProbeButtons()
|
||||
{
|
||||
offset = 100;
|
||||
offsetinc = 50;
|
||||
|
||||
while ( GetDvarInt( "debug_reflection" ) == 1 )
|
||||
{
|
||||
if ( self buttonpressed( "BUTTON_X" ) )
|
||||
offset += offsetinc;
|
||||
if ( self buttonpressed( "BUTTON_Y" ) )
|
||||
offset -= offsetinc;
|
||||
if ( offset > 1000 )
|
||||
offset = 1000;
|
||||
if ( offset < 64 )
|
||||
offset = 64;
|
||||
|
||||
self.debug_reflectionobject.origin = self GetEye() + ( ( AnglesToForward( self GetPlayerAngles() ) * offset ) );
|
||||
|
||||
wait .05;
|
||||
}
|
||||
}
|
||||
#/
|
210
maps/mp/alien/_director.gsc
Normal file
210
maps/mp/alien/_director.gsc
Normal file
@ -0,0 +1,210 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\agents\_agent_utility;
|
||||
#include maps\mp\alien\_utility;
|
||||
|
||||
|
||||
// ================================================================
|
||||
// Alien Attribute Table
|
||||
// ================================================================
|
||||
|
||||
ATTRIBUTE_TABLE = "mp/alien/default_alien_definition.csv";
|
||||
|
||||
TABLE_COL_INDEX = 0;
|
||||
TABLE_COL_ATTRIBUTE = 1;
|
||||
TABLE_COL_AI_TYPE_BEGIN = 2;
|
||||
TABLE_COL_AI_TYPE_MAX_TYPES = 16;
|
||||
|
||||
alien_attribute_table_init()
|
||||
{
|
||||
// to be updated with default_alien_definition.csv
|
||||
// value variable type is defined in index values
|
||||
|
||||
if ( !isdefined( level.default_alien_definition ) )
|
||||
level.default_alien_definition = ATTRIBUTE_TABLE;
|
||||
|
||||
att_idx = [];
|
||||
att_idx[ "ref" ] = "0"; // string value
|
||||
att_idx[ "name" ] = "1";
|
||||
att_idx[ "model" ] = "2";
|
||||
att_idx[ "desc" ] = "3";
|
||||
att_idx[ "boss" ] = 4; // int value
|
||||
att_idx[ "animclass" ] = "5"; // string value
|
||||
|
||||
att_idx[ "health" ] = 10;
|
||||
att_idx[ "min_cumulative_pain_threshold" ] = 11;
|
||||
att_idx[ "min_cumulative_pain_buffer_time" ] = 12.0;
|
||||
att_idx[ "accuracy" ] = 13.0; // float value
|
||||
att_idx[ "speed" ] = 14.0;
|
||||
att_idx[ "scale" ] = 15.0;
|
||||
att_idx[ "xp" ] = 16;
|
||||
att_idx[ "attacker_difficulty" ] = 17.0;
|
||||
att_idx[ "attacker_priority" ] = 18;
|
||||
att_idx[ "jump_cost" ] = 19.0;
|
||||
att_idx[ "traverse_cost" ] = 20.0;
|
||||
att_idx[ "run_cost" ] = 21.0;
|
||||
att_idx[ "wall_run_cost" ] = 29.0;
|
||||
att_idx[ "heavy_damage_threshold" ] = 22.0;
|
||||
att_idx[ "pain_interval" ] = 23.0;
|
||||
att_idx[ "emissive_default" ] = 24.0;
|
||||
att_idx[ "emissive_max" ] = 25.0;
|
||||
att_idx[ "weight_scale" ] = 26.0;
|
||||
att_idx[ "reward" ] = 27.0;
|
||||
att_idx[ "view_height" ] = 28.0;
|
||||
|
||||
att_idx[ "behavior_cloak" ] = 100;
|
||||
att_idx[ "behavior_spit" ] = 101;
|
||||
att_idx[ "behavior_lead" ] = 102;
|
||||
att_idx[ "behavior_hives" ] = 103;
|
||||
|
||||
att_idx[ "swipe_min_damage" ] = 2000;
|
||||
att_idx[ "swipe_max_damage" ] = 2001;
|
||||
att_idx[ "leap_min_damage" ] = 2002;
|
||||
att_idx[ "leap_max_damage" ] = 2003;
|
||||
att_idx[ "wall_min_damage" ] = 2004;
|
||||
att_idx[ "wall_max_damage" ] = 2005;
|
||||
att_idx[ "charge_min_damage" ] = 2006;
|
||||
att_idx[ "charge_max_damage" ] = 2007;
|
||||
att_idx[ "explode_min_damage" ] = 2008;
|
||||
att_idx[ "explode_max_damage" ] = 2009;
|
||||
att_idx[ "slam_min_damage" ] = 2010;
|
||||
att_idx[ "slam_max_damage" ] = 2011;
|
||||
att_idx[ "synch_min_damage_per_second" ] = 2012;
|
||||
att_idx[ "synch_max_damage_per_second" ] = 2013;
|
||||
|
||||
// loots - float values
|
||||
loot_index = 1000;
|
||||
loot_index_max = 1100;
|
||||
for( i = loot_index; i < loot_index_max; i++ )
|
||||
{
|
||||
loot_ref = TableLookup( level.default_alien_definition, TABLE_COL_INDEX, i, TABLE_COL_ATTRIBUTE );
|
||||
if ( loot_ref == "" )
|
||||
break;
|
||||
|
||||
att_idx[ loot_ref ] = i * 1.00; // float
|
||||
}
|
||||
|
||||
level.alien_types = [];
|
||||
|
||||
// get types from table
|
||||
|
||||
maxIndex = TABLE_COL_AI_TYPE_BEGIN + TABLE_COL_AI_TYPE_MAX_TYPES;
|
||||
for ( typeIndex = TABLE_COL_AI_TYPE_BEGIN; typeIndex < maxIndex; typeIndex++ )
|
||||
setup_alien_type( att_idx, typeIndex );
|
||||
|
||||
if ( IsDefined( level.custom_alien_attribute_table_init ) )
|
||||
[[level.custom_alien_attribute_table_init]]();
|
||||
}
|
||||
|
||||
setup_alien_type( att_idx, type )
|
||||
{
|
||||
type_ref = TableLookup( level.default_alien_definition, TABLE_COL_INDEX, att_idx[ "ref" ], type );
|
||||
|
||||
// return if type does not exist
|
||||
if ( type_ref == "" )
|
||||
return;
|
||||
|
||||
level.alien_types[ type_ref ] = SpawnStruct();
|
||||
//level.alien_types[ type_ref ].attribute_index = att_idx;
|
||||
level.alien_types[ type_ref ].attributes = [];
|
||||
level.alien_types[ type_ref ].loots = [];
|
||||
|
||||
foreach( key, index in att_idx )
|
||||
{
|
||||
value = TableLookup( level.default_alien_definition, TABLE_COL_INDEX, index, type );
|
||||
|
||||
// cast the correct variable type
|
||||
if ( !isString( index ) )
|
||||
{
|
||||
if ( !IsSubStr( value, "." ) )
|
||||
value = int( value );
|
||||
else
|
||||
value = float( value );
|
||||
}
|
||||
|
||||
level.alien_types[ type_ref ].attributes[ key ] = value;
|
||||
|
||||
// loot!
|
||||
if ( IsSubStr( key, "loot_" ) && value > 0.0 )
|
||||
{
|
||||
level.alien_types[ type_ref ].loots[ key ] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============== Alien cloaking ==============
|
||||
CONST_DECLOAK_DIST = 800;
|
||||
CONST_CLOCK_CHANCE = 1;
|
||||
|
||||
alien_cloak()
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
self thread near_player_notify();
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
if( any_player_nearby( self.origin, CONST_DECLOAK_DIST ) )
|
||||
{
|
||||
wait 0.05;
|
||||
continue;
|
||||
}
|
||||
|
||||
self waittill( "jump_launching" );
|
||||
|
||||
|
||||
wait 0.20;
|
||||
|
||||
original_model = self.model;
|
||||
self maps\mp\alien\_alien_fx::alien_cloak_fx_on();
|
||||
self cloak_fx();
|
||||
self setmodel( original_model + "_cloak" ); // this _cloak model must exist
|
||||
|
||||
waittill_any_timeout( 1, "jump_finished", "damage" ); //, "near_player" );
|
||||
|
||||
|
||||
wait 0.20;
|
||||
|
||||
//self Show();
|
||||
self maps\mp\alien\_alien_fx::alien_cloak_fx_off();
|
||||
self uncloak_fx();
|
||||
self setmodel( original_model );
|
||||
}
|
||||
}
|
||||
|
||||
// WIP: SP>MP
|
||||
near_player_notify()
|
||||
{
|
||||
self endon( "death" );
|
||||
while ( 1 )
|
||||
{
|
||||
if ( any_player_nearby( self.origin, CONST_DECLOAK_DIST ) )
|
||||
self notify( "near_player" );
|
||||
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
cloak_fx()
|
||||
{
|
||||
PlayFXOnTag( level._effect[ "alien_cloaking" ], self, "j_neck" );
|
||||
}
|
||||
|
||||
uncloak_fx()
|
||||
{
|
||||
PlayFXOnTag( level._effect[ "alien_uncloaking" ], self, "j_neck" );
|
||||
}
|
||||
|
||||
|
||||
smoke_puff()
|
||||
{
|
||||
PlayFXOnTag( level._effect[ "alien_teleport" ], self, "tag_origin" );
|
||||
|
||||
// somehow in MP the tags are not valid assets???
|
||||
|
||||
//PlayFXOnTag( level._effect[ "alien_teleport" ], self, "j_spineupper" );
|
||||
//PlayFXOnTag( level._effect[ "alien_teleport" ], self, "j_mainroot" );
|
||||
//PlayFXOnTag( level._effect[ "alien_teleport" ], self, "j_tail_3" );
|
||||
|
||||
PlayFXOnTag( level._effect[ "alien_teleport_dist" ], self, "tag_origin" );
|
||||
}
|
2164
maps/mp/alien/_drill.gsc
Normal file
2164
maps/mp/alien/_drill.gsc
Normal file
File diff suppressed because it is too large
Load Diff
21
maps/mp/alien/_ffotd.gsc
Normal file
21
maps/mp/alien/_ffotd.gsc
Normal file
@ -0,0 +1,21 @@
|
||||
// FFOTD scripts for aliens
|
||||
|
||||
init()
|
||||
{
|
||||
}
|
||||
|
||||
onStartGameType()
|
||||
{
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
}
|
||||
|
||||
onSpawnPlayer()
|
||||
{
|
||||
}
|
||||
|
||||
onSpawnAlien()
|
||||
{
|
||||
}
|
918
maps/mp/alien/_gamescore.gsc
Normal file
918
maps/mp/alien/_gamescore.gsc
Normal file
@ -0,0 +1,918 @@
|
||||
#include maps\mp\alien\_utility;
|
||||
|
||||
SCORE_TO_CASH_CONVERSION = 0.1; // the conversion rate from hive score( without prestige nerf bonus) to cash
|
||||
PRESTIGE_RELIC_SCORE_BONUS = 0.2; // The extra percentage of hive score that player will earn for each prestige relic on
|
||||
|
||||
// LUA uses the index to lookup the actual string from scoreboard_string_lookup.csv
|
||||
CONST_UI_STRING_INDEX_DRILL_PROTECT = 1; // "ALIEN_COLLECTIBLES_DRILL_PROTECT";
|
||||
CONST_UI_STRING_INDEX_TEAMWORK = 2; // "ALIEN_COLLECTIBLES_TEAMWORK";
|
||||
CONST_UI_STRING_INDEX_PERSONAL_SKILL = 3; // "ALIEN_COLLECTIBLES_PERSONAL_SKILL";
|
||||
CONST_UI_STRING_INDEX_CHALLENGE = 4; // "ALIEN_COLLECTIBLES_CHALLENGE_COMP";
|
||||
CONST_UI_STRING_INDEX_RELIC_BONUS = 5; // "ALIEN_COLLECTIBLES_PRESTIGE_BONUS";
|
||||
CONST_UI_STRING_INDEX_TOTAL_SCORE = 6; // "ALIEN_COLLECTIBLES_HIVE_SCORE_EARNED";
|
||||
CONST_UI_STRING_INDEX_BONUS_MONEY = 7; // "ALIEN_COLLECTIBLES_BONUS_MONEY_EARNED";
|
||||
CONST_UI_STRING_INDEX_HIVE = 8; // "ALIEN_COLLECTIBLES_TOTAL_HIVE_SCORE";
|
||||
CONST_UI_STRING_INDEX_ESCAPE = 9; // "ALIEN_COLLECTIBLES_ESCAPE_TIME_BONUS";
|
||||
CONST_UI_STRING_INDEX_EOG_TOTAL_SCORE = 10; // "ALIEN_COLLECTIBLES_END_GAME_SCORE";
|
||||
|
||||
// Encounter score
|
||||
CONST_NAME_REF_CHALLENGE = "challenge";
|
||||
CONST_NAME_REF_DRILL = "drill";
|
||||
CONST_NAME_REF_TEAM = "team";
|
||||
CONST_NAME_REF_PERSONAL = "personal";
|
||||
CONST_NAME_REF_ESCAPE = "escape";
|
||||
CONST_NAME_REF_TEAM_BLK = "team_blocker";
|
||||
CONST_NAME_REF_PERSONAL_BLK = "personal_blocker";
|
||||
|
||||
// EOG score
|
||||
CONST_NAME_REF_EOG_HIVE = "hive";
|
||||
CONST_NAME_REF_EOG_ESCAPE = "escape";
|
||||
CONST_NAME_REF_EOG_RELICS = "relics";
|
||||
|
||||
init_gamescore()
|
||||
{
|
||||
register_scoring_mode();
|
||||
}
|
||||
|
||||
init_eog_score_components( component_name_list )
|
||||
{
|
||||
level.eog_score_components = [];
|
||||
|
||||
foreach( component_name in component_name_list )
|
||||
{
|
||||
switch( component_name )
|
||||
{
|
||||
case CONST_NAME_REF_EOG_HIVE:
|
||||
register_eog_score_component( CONST_NAME_REF_EOG_HIVE, CONST_UI_STRING_INDEX_HIVE );
|
||||
break;
|
||||
|
||||
case CONST_NAME_REF_EOG_ESCAPE:
|
||||
register_eog_score_component( CONST_NAME_REF_EOG_ESCAPE, CONST_UI_STRING_INDEX_ESCAPE );
|
||||
break;
|
||||
|
||||
case CONST_NAME_REF_EOG_RELICS:
|
||||
register_eog_score_component( CONST_NAME_REF_EOG_RELICS, CONST_UI_STRING_INDEX_RELIC_BONUS );
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertMsg( "'" + component_name + "' is not a supported end-of-game score component." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init_encounter_score_components( component_name_list )
|
||||
{
|
||||
level.encounter_score_components = [];
|
||||
|
||||
foreach( component_name in component_name_list )
|
||||
{
|
||||
switch( component_name )
|
||||
{
|
||||
case CONST_NAME_REF_CHALLENGE:
|
||||
init_challenge_score_component();
|
||||
break;
|
||||
|
||||
case CONST_NAME_REF_DRILL:
|
||||
init_drill_score_component();
|
||||
break;
|
||||
|
||||
case CONST_NAME_REF_TEAM:
|
||||
init_teamwork_score_component();
|
||||
break;
|
||||
|
||||
case CONST_NAME_REF_TEAM_BLK:
|
||||
init_blocker_hive_teamwork_score_component();
|
||||
break;
|
||||
|
||||
case CONST_NAME_REF_PERSONAL:
|
||||
init_personal_score_component();
|
||||
break;
|
||||
|
||||
case CONST_NAME_REF_PERSONAL_BLK:
|
||||
init_blocker_hive_personal_score_component();
|
||||
break;
|
||||
|
||||
case CONST_NAME_REF_ESCAPE:
|
||||
init_escape_score_component();
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertMsg( "'" + component_name + "' is not a supported round score component." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init_player_score()
|
||||
{
|
||||
if ( is_scoring_disabled() )
|
||||
return;
|
||||
|
||||
self.encounter_performance = [];
|
||||
self.end_game_score = [];
|
||||
|
||||
component_specific_init( self );
|
||||
reset_player_encounter_performance( self );
|
||||
reset_end_game_score();
|
||||
}
|
||||
|
||||
reset_encounter_performance()
|
||||
{
|
||||
foreach( component_name, score_component in level.encounter_score_components )
|
||||
{
|
||||
if ( isDefined( score_component.reset_team_performance_func ) )
|
||||
[[score_component.reset_team_performance_func]]( score_component );
|
||||
}
|
||||
|
||||
reset_players_encounter_performance_and_LUA();
|
||||
}
|
||||
|
||||
reset_players_encounter_performance_and_LUA()
|
||||
{
|
||||
foreach( player in level.players )
|
||||
{
|
||||
reset_player_encounter_performance( player );
|
||||
maps\mp\alien\_hud::reset_player_encounter_LUA_omnvars( player );
|
||||
}
|
||||
}
|
||||
|
||||
component_specific_init( player )
|
||||
{
|
||||
foreach( component_name, score_component in level.encounter_score_components )
|
||||
{
|
||||
if ( isDefined( score_component.player_init_func ) )
|
||||
[[score_component.player_init_func]]( player );
|
||||
}
|
||||
}
|
||||
|
||||
reset_player_encounter_performance( player )
|
||||
{
|
||||
foreach( component_name, score_component in level.encounter_score_components )
|
||||
{
|
||||
if ( isDefined( score_component.reset_player_performance_func ) )
|
||||
[[score_component.reset_player_performance_func]]( player );
|
||||
}
|
||||
}
|
||||
|
||||
reset_end_game_score()
|
||||
{
|
||||
foreach( eog_component_name, score_component in level.eog_score_components )
|
||||
self.end_game_score[eog_component_name] = 0;
|
||||
}
|
||||
|
||||
calculate_total_end_game_score( player )
|
||||
{
|
||||
row_number = 1;
|
||||
total_end_game_score = 0;
|
||||
|
||||
foreach( eog_score_name, eog_score_component_struct in level.eog_score_components )
|
||||
{
|
||||
eog_score_value = player.end_game_score[eog_score_name];
|
||||
maps\mp\alien\_hud::set_LUA_EoG_score_row( player, row_number, eog_score_component_struct.lua_string_index, eog_score_value );
|
||||
row_number++;
|
||||
|
||||
total_end_game_score += eog_score_value;
|
||||
}
|
||||
|
||||
maps\mp\alien\_hud::set_LUA_EoG_score_row( player, row_number, CONST_UI_STRING_INDEX_EOG_TOTAL_SCORE, total_end_game_score );
|
||||
}
|
||||
|
||||
calculate_players_total_end_game_score()
|
||||
{
|
||||
if ( is_scoring_disabled() )
|
||||
return;
|
||||
|
||||
if ( common_scripts\utility::flag_exist( "drill_drilling" ) && common_scripts\utility::flag( "drill_drilling" ) )
|
||||
calculate_encounter_scores( level.players, get_partial_hive_score_component_list() ); // Partial hive
|
||||
|
||||
foreach ( player in level.players )
|
||||
calculate_total_end_game_score( player );
|
||||
}
|
||||
|
||||
get_partial_hive_score_component_list()
|
||||
{
|
||||
if ( isDefined( level.partial_hive_score_component_list_func ) )
|
||||
return [[level.partial_hive_score_component_list_func]]();
|
||||
|
||||
return [ CONST_NAME_REF_CHALLENGE, CONST_NAME_REF_TEAM ];
|
||||
}
|
||||
|
||||
update_players_encounter_performance( score_component_name, performance_type, amount )
|
||||
{
|
||||
foreach ( player in level.players )
|
||||
player update_personal_encounter_performance( score_component_name, performance_type, amount );
|
||||
}
|
||||
|
||||
calculate_and_show_encounter_scores( players_list, score_component_name_list )
|
||||
{
|
||||
calculate_encounter_scores( players_list, score_component_name_list );
|
||||
|
||||
maps\mp\alien\_hud::show_encounter_scores();
|
||||
}
|
||||
|
||||
calculate_encounter_scores( players_list, score_component_name_list )
|
||||
{
|
||||
foreach( player in players_list )
|
||||
calculate_player_encounter_scores( player, score_component_name_list );
|
||||
}
|
||||
|
||||
calculate_player_encounter_scores( player, score_component_name_list )
|
||||
{
|
||||
/#
|
||||
maps\mp\alien\_debug::debug_print_encounter_performance( player );
|
||||
#/
|
||||
|
||||
row_number = 1;
|
||||
total_score = 0;
|
||||
|
||||
foreach ( score_component_name in score_component_name_list )
|
||||
{
|
||||
AssertEx( isDefined( level.encounter_score_components[score_component_name] ), "'" + score_component_name + "' is not a initialized score component" );
|
||||
score_component_struct = level.encounter_score_components[score_component_name];
|
||||
|
||||
encounter_score = [[score_component_struct.calculate_func]]( player, score_component_struct );
|
||||
encounter_score *= level.cycle_score_scalar;
|
||||
encounter_score = int( encounter_score );
|
||||
player.end_game_score[score_component_struct.end_game_score_component_ref] += encounter_score; // Update the corresponding EoG score field
|
||||
maps\mp\alien\_hud::set_LUA_encounter_score_row( player, row_number, score_component_struct.lua_string_index, encounter_score );
|
||||
|
||||
total_score += encounter_score;
|
||||
row_number++;
|
||||
}
|
||||
|
||||
// Relics bonus score
|
||||
num_relic_selected = player maps\mp\alien\_prestige::get_num_nerf_selected();
|
||||
relics_bonus_score = int( total_score * num_relic_selected * PRESTIGE_RELIC_SCORE_BONUS );
|
||||
AssertEx( has_eog_score_component( CONST_NAME_REF_EOG_RELICS ), "'relics' needs to be initialized as one of the end-of-game score components" );
|
||||
player.end_game_score["relics"] += relics_bonus_score;
|
||||
maps\mp\alien\_hud::set_LUA_encounter_score_row( player, row_number, CONST_UI_STRING_INDEX_RELIC_BONUS, relics_bonus_score );
|
||||
row_number++;
|
||||
|
||||
// Total encounter score
|
||||
total_score += relics_bonus_score;
|
||||
player maps\mp\alien\_persistence::eog_player_update_stat( "score", total_score ); // For in-game pause menu
|
||||
maps\mp\alien\_hud::set_LUA_encounter_score_row( player, row_number, CONST_UI_STRING_INDEX_TOTAL_SCORE, total_score );
|
||||
row_number++;
|
||||
|
||||
// Bonus cash earned
|
||||
perk_currency_scalar = player maps\mp\alien\_perk_utility::perk_GetCurrencyScalePerHive();
|
||||
prestige_currency_scalar = player maps\mp\alien\_prestige::prestige_getMoneyEarnedScalar();
|
||||
bonus_cash_earned = int( total_score * perk_currency_scalar * prestige_currency_scalar * SCORE_TO_CASH_CONVERSION / level.cycle_score_scalar );
|
||||
bonus_cash_earned = round_up_to_nearest( bonus_cash_earned, 10 );
|
||||
maps\mp\alien\_hud::set_LUA_encounter_score_row( player, row_number, CONST_UI_STRING_INDEX_BONUS_MONEY, bonus_cash_earned );
|
||||
|
||||
player.encounter_score_earned = total_score;
|
||||
player.encounter_cash_earned = bonus_cash_earned;
|
||||
}
|
||||
|
||||
/////////////////////////////////////
|
||||
// Challenge //
|
||||
/////////////////////////////////////
|
||||
COOP_CONST_MAX_SCORE_COMPLETE_CHALLENGE = 1000;
|
||||
SOLO_CONST_MAX_SCORE_COMPLETE_CHALLENGE = 1500;
|
||||
|
||||
CONST_DEFAULT_CHALLENGE_COMPONENT_NAME = "challenge";
|
||||
|
||||
init_challenge_score_component()
|
||||
{
|
||||
register_encounter_score_component( CONST_NAME_REF_CHALLENGE,
|
||||
::init_challenge_score,
|
||||
undefined,
|
||||
::reset_player_challenge_performance,
|
||||
::calculate_challenge_score,
|
||||
CONST_UI_STRING_INDEX_CHALLENGE,
|
||||
CONST_NAME_REF_EOG_HIVE );
|
||||
}
|
||||
|
||||
init_challenge_score( score_component_struct )
|
||||
{
|
||||
if ( isPlayingSolo() )
|
||||
score_component_struct.max_score = SOLO_CONST_MAX_SCORE_COMPLETE_CHALLENGE;
|
||||
else
|
||||
score_component_struct.max_score = COOP_CONST_MAX_SCORE_COMPLETE_CHALLENGE;
|
||||
|
||||
return score_component_struct;
|
||||
}
|
||||
|
||||
reset_player_challenge_performance( player )
|
||||
{
|
||||
player.encounter_performance["challenge_complete"] = 0;
|
||||
}
|
||||
|
||||
calculate_challenge_score( player, score_component_struct )
|
||||
{
|
||||
return int( player.encounter_performance["challenge_complete"] * score_component_struct.max_score );
|
||||
}
|
||||
|
||||
get_challenge_score_component_name() { return common_scripts\utility::ter_op( isDefined( level.challenge_score_component_name ), level.challenge_score_component_name, CONST_DEFAULT_CHALLENGE_COMPONENT_NAME ); }
|
||||
set_challenge_score_component_name( challenge_score_component_name ) { level.challenge_score_component_name = challenge_score_component_name; }
|
||||
|
||||
/////////////////////////////////////
|
||||
// Drill //
|
||||
/////////////////////////////////////
|
||||
COOP_CONST_MAX_SCORE_DRILL_DAMAGE = 3500;
|
||||
SOLO_CONST_MAX_SCORE_DRILL_DAMAGE = 4500;
|
||||
|
||||
COOP_CONST_DRILL_DAMAGE_LIMIT = 750; // if the drill takes more damage than this, no score from drill damage taken ( 60% of max health )
|
||||
SOLO_CONST_DRILL_DAMAGE_LIMIT = 1200; // if the drill takes more damage than this, no score from drill damage taken ( 60% of max health )
|
||||
|
||||
CONST_DEFAULT_DRILL_COMPONENT_NAME = "drill";
|
||||
|
||||
init_drill_score_component()
|
||||
{
|
||||
register_encounter_score_component( CONST_NAME_REF_DRILL,
|
||||
::init_drill_score,
|
||||
::reset_team_drill_performance,
|
||||
undefined,
|
||||
::calculate_drill_protection_score,
|
||||
CONST_UI_STRING_INDEX_DRILL_PROTECT,
|
||||
CONST_NAME_REF_EOG_HIVE );
|
||||
}
|
||||
|
||||
init_drill_score( score_component_struct )
|
||||
{
|
||||
if ( isPlayingSolo() )
|
||||
{
|
||||
score_component_struct.max_score_damage_damage = SOLO_CONST_MAX_SCORE_DRILL_DAMAGE;
|
||||
score_component_struct.max_drill_damage_limit = SOLO_CONST_DRILL_DAMAGE_LIMIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
score_component_struct.max_score_damage_damage = COOP_CONST_MAX_SCORE_DRILL_DAMAGE;
|
||||
score_component_struct.max_drill_damage_limit = COOP_CONST_DRILL_DAMAGE_LIMIT;
|
||||
}
|
||||
|
||||
return score_component_struct;
|
||||
}
|
||||
|
||||
reset_team_drill_performance( score_component_struct )
|
||||
{
|
||||
score_component_struct.team_encounter_performance["drill_damage_taken"] = 0;
|
||||
|
||||
return score_component_struct;
|
||||
}
|
||||
|
||||
calculate_drill_protection_score( player, score_component_struct )
|
||||
{
|
||||
damage_penalty = get_team_encounter_performance( score_component_struct, "drill_damage_taken" ) / score_component_struct.max_drill_damage_limit ;
|
||||
damage_score_percent_earned = max( 0, 1 - damage_penalty );
|
||||
max_score_drill_damage = score_component_struct.max_score_damage_damage;
|
||||
damage_score_earned = max_score_drill_damage * damage_score_percent_earned;
|
||||
|
||||
/#
|
||||
maps\mp\alien\_debug::debug_print_drill_protection_score( damage_score_earned );
|
||||
#/
|
||||
|
||||
return int( damage_score_earned );
|
||||
}
|
||||
|
||||
get_drill_score_component_name() { return common_scripts\utility::ter_op( isDefined( level.drill_score_component_name ), level.drill_score_component_name, CONST_DEFAULT_DRILL_COMPONENT_NAME ); }
|
||||
set_drill_score_component_name( drill_score_component_name ) { level.drill_score_component_name = drill_score_component_name; }
|
||||
|
||||
/////////////////////////////////////
|
||||
// Team //
|
||||
/////////////////////////////////////
|
||||
COOP_CONST_MAX_SCORE_DEPLOY_SUPPORT = 1000;
|
||||
COOP_CONST_MAX_SCORE_REVIVE_TEAMMATE = 1000;
|
||||
COOP_CONST_MAX_SCORE_DAMAGE_DONE = 1000;
|
||||
COOP_CONST_DEPLOY_SUPPORT = 100; // player gains this many point every time deploy a team support item
|
||||
COOP_CONST_PENALTY_PER_DOWN = 200; // all players loses this many point every time a teammate goes down
|
||||
|
||||
CONST_DEFAULT_TEAM_COMPONENT_NAME = "team";
|
||||
|
||||
init_teamwork_score_component()
|
||||
{
|
||||
register_encounter_score_component( CONST_NAME_REF_TEAM,
|
||||
::init_teamwork_score,
|
||||
::reset_team_score_performance,
|
||||
::reset_player_teamwork_score_performance,
|
||||
::calculate_teamwork_score,
|
||||
CONST_UI_STRING_INDEX_TEAMWORK,
|
||||
CONST_NAME_REF_EOG_HIVE );
|
||||
}
|
||||
|
||||
init_teamwork_score( score_component_struct )
|
||||
{
|
||||
score_component_struct.max_score_deploy = COOP_CONST_MAX_SCORE_DEPLOY_SUPPORT;
|
||||
score_component_struct.max_score_revive = COOP_CONST_MAX_SCORE_REVIVE_TEAMMATE;
|
||||
score_component_struct.max_score_damage = COOP_CONST_MAX_SCORE_DAMAGE_DONE;
|
||||
|
||||
reset_team_score_performance( score_component_struct );
|
||||
|
||||
return score_component_struct;
|
||||
}
|
||||
|
||||
reset_team_score_performance( score_component_struct )
|
||||
{
|
||||
score_component_struct.team_encounter_performance["damage_done_on_alien"] = 0;
|
||||
score_component_struct.team_encounter_performance["num_players_enter_laststand"] = 0;
|
||||
score_component_struct.team_encounter_performance["num_players_bleed_out"] = 0;
|
||||
|
||||
return score_component_struct;
|
||||
}
|
||||
|
||||
reset_player_teamwork_score_performance( player )
|
||||
{
|
||||
player.encounter_performance["damage_done_on_alien"] = 0;
|
||||
player.encounter_performance["team_support_deploy"] = 0;
|
||||
}
|
||||
|
||||
calculate_teamwork_score( player, score_component_struct )
|
||||
{
|
||||
max_score_deploy_support = score_component_struct.max_score_deploy;
|
||||
deploy_supply_score_earned = min( max_score_deploy_support, get_player_encounter_performance( player, "team_support_deploy" ) * COOP_CONST_DEPLOY_SUPPORT );
|
||||
|
||||
if ( get_team_encounter_performance( score_component_struct, "num_players_bleed_out" ) )
|
||||
{
|
||||
revive_teammate_score_earned = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
max_score_revive = score_component_struct.max_score_revive;
|
||||
total_penalty = get_team_encounter_performance( score_component_struct, "num_players_enter_laststand" ) * COOP_CONST_PENALTY_PER_DOWN;
|
||||
revive_teammate_score_earned = max ( 0, ( max_score_revive - total_penalty ) );
|
||||
}
|
||||
|
||||
team_damage_done_on_alien = get_team_encounter_performance( score_component_struct, "damage_done_on_alien" );
|
||||
if ( team_damage_done_on_alien == 0 )
|
||||
team_damage_done_on_alien = 1;
|
||||
|
||||
damage_done_ratio = get_player_encounter_performance( player, "damage_done_on_alien" ) / team_damage_done_on_alien;
|
||||
max_score_damage_done = score_component_struct.max_score_damage;
|
||||
damage_score_team_pool = max_score_damage_done * level.players.size;
|
||||
damage_done_score_earned = min( max_score_damage_done, damage_done_ratio * damage_score_team_pool );
|
||||
|
||||
/#
|
||||
maps\mp\alien\_debug::debug_print_teamwork_score( deploy_supply_score_earned, revive_teammate_score_earned, damage_done_score_earned );
|
||||
#/
|
||||
|
||||
return int( deploy_supply_score_earned + revive_teammate_score_earned + damage_done_score_earned );
|
||||
}
|
||||
|
||||
get_team_score_component_name() { return common_scripts\utility::ter_op( isDefined( level.team_score_component_name ), level.team_score_component_name, CONST_DEFAULT_TEAM_COMPONENT_NAME ); }
|
||||
set_team_score_component_name( team_score_component_name ) { level.team_score_component_name = team_score_component_name; }
|
||||
|
||||
/////////////////////////////////////
|
||||
// Blocker Hive: Team //
|
||||
/////////////////////////////////////
|
||||
COOP_CONST_MAX_BLOCKER_SCORE_DEPLOY_SUPPORT = 2000;
|
||||
COOP_CONST_MAX_BLOCKER_SCORE_REVIVE_TEAMMATE = 1000;
|
||||
COOP_CONST_MAX_BLOCKER_SCORE_DAMAGE_DONE = 2500;
|
||||
|
||||
init_blocker_hive_teamwork_score_component()
|
||||
{
|
||||
register_encounter_score_component( CONST_NAME_REF_TEAM_BLK,
|
||||
::init_blocker_teamwork_score,
|
||||
::reset_team_score_performance,
|
||||
::reset_player_teamwork_score_performance,
|
||||
::calculate_teamwork_score,
|
||||
CONST_UI_STRING_INDEX_TEAMWORK,
|
||||
CONST_NAME_REF_EOG_HIVE );
|
||||
}
|
||||
|
||||
init_blocker_teamwork_score( score_component_struct )
|
||||
{
|
||||
score_component_struct.max_score_deploy = COOP_CONST_MAX_BLOCKER_SCORE_DEPLOY_SUPPORT;
|
||||
score_component_struct.max_score_revive = COOP_CONST_MAX_BLOCKER_SCORE_REVIVE_TEAMMATE;
|
||||
score_component_struct.max_score_damage = COOP_CONST_MAX_BLOCKER_SCORE_DAMAGE_DONE;
|
||||
|
||||
reset_team_score_performance( score_component_struct );
|
||||
|
||||
return score_component_struct;
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
// Personal //
|
||||
////////////////////////////////////////
|
||||
COOP_CONST_MAX_SCORE_DAMAGE_TAKEN = 1500;
|
||||
COOP_CONST_MAX_SCORE_ACCURACY = 1000;
|
||||
|
||||
SOLO_CONST_MAX_SCORE_DAMAGE_TAKEN = 2500;
|
||||
SOLO_CONST_MAX_SCORE_ACCURACY = 1500;
|
||||
|
||||
CONST_PLAYER_DAMAGE_LIMIT = 500; // if player takes this much damage, no skill score from avoid damage
|
||||
|
||||
CONST_DEFAULT_PERSONAL_COMPONENT_NAME = "personal";
|
||||
|
||||
init_personal_score_component()
|
||||
{
|
||||
register_encounter_score_component( CONST_NAME_REF_PERSONAL,
|
||||
::init_personal_score,
|
||||
undefined,
|
||||
::reset_player_personal_score_performance,
|
||||
::calculate_personal_skill_score,
|
||||
CONST_UI_STRING_INDEX_PERSONAL_SKILL,
|
||||
CONST_NAME_REF_EOG_HIVE );
|
||||
}
|
||||
|
||||
init_personal_score( score_component_struct )
|
||||
{
|
||||
if( isPlayingSolo() )
|
||||
{
|
||||
score_component_struct.max_score_damage_taken = SOLO_CONST_MAX_SCORE_DAMAGE_TAKEN;
|
||||
score_component_struct.max_score_accuracy = SOLO_CONST_MAX_SCORE_ACCURACY;
|
||||
}
|
||||
else
|
||||
{
|
||||
score_component_struct.max_score_damage_taken = COOP_CONST_MAX_SCORE_DAMAGE_TAKEN;
|
||||
score_component_struct.max_score_accuracy = COOP_CONST_MAX_SCORE_ACCURACY;
|
||||
}
|
||||
|
||||
return score_component_struct;
|
||||
}
|
||||
|
||||
reset_player_personal_score_performance( player )
|
||||
{
|
||||
player.encounter_performance["damage_taken"] = 0;
|
||||
player.encounter_performance["shots_hit"] = 0;
|
||||
player.encounter_performance["shots_fired"] = 0;
|
||||
}
|
||||
|
||||
calculate_personal_skill_score( player, score_component_struct )
|
||||
{
|
||||
damage_penalty = get_player_encounter_performance( player, "damage_taken" ) / CONST_PLAYER_DAMAGE_LIMIT;
|
||||
damage_score_percent_earned = max( 0, 1 - damage_penalty );
|
||||
max_score_demage_taken = score_component_struct.max_score_damage_taken;
|
||||
damage_score_earned = max_score_demage_taken * damage_score_percent_earned;
|
||||
|
||||
if ( get_player_encounter_performance( player, "shots_fired" ) == 0 )
|
||||
accuracy_ratio = 1.0;
|
||||
else
|
||||
accuracy_ratio = get_player_encounter_performance( player, "shots_hit" ) / get_player_encounter_performance( player, "shots_fired" );
|
||||
|
||||
//AssertEx( accuracy_ratio <= 1.0, "Personal accuracy is greater than 100%. Need to exclude weapons that we cannot track misses." );
|
||||
accuracy_ratio = min( 1.0, accuracy_ratio );
|
||||
max_score_accuracy = score_component_struct.max_score_accuracy;
|
||||
accuracy_score_earned = max_score_accuracy * accuracy_ratio;
|
||||
|
||||
/#
|
||||
maps\mp\alien\_debug::debug_print_personal_skill_score( damage_score_earned, accuracy_score_earned );
|
||||
#/
|
||||
|
||||
return int( damage_score_earned + accuracy_score_earned );
|
||||
}
|
||||
|
||||
get_personal_score_component_name() { return common_scripts\utility::ter_op( isDefined( level.personal_score_component_name ), level.personal_score_component_name, CONST_DEFAULT_PERSONAL_COMPONENT_NAME ); }
|
||||
set_personal_score_component_name( personal_score_component_name ) { level.personal_score_component_name = personal_score_component_name; }
|
||||
|
||||
////////////////////////////////////////
|
||||
// Blocker Hive: Personal //
|
||||
////////////////////////////////////////
|
||||
COOP_CONST_MAX_BLOCKER_SCORE_DAMAGE_TAKEN = 2500;
|
||||
COOP_CONST_MAX_BLOCKER_SCORE_ACCURACY = 2000;
|
||||
|
||||
SOLO_CONST_MAX_BLOCKER_SCORE_DAMAGE_TAKEN = 5500;
|
||||
SOLO_CONST_MAX_BLOCKER_SCORE_ACCURACY = 4500;
|
||||
|
||||
init_blocker_hive_personal_score_component()
|
||||
{
|
||||
register_encounter_score_component( CONST_NAME_REF_PERSONAL_BLK,
|
||||
::init_blocker_personal_score,
|
||||
undefined,
|
||||
::reset_player_personal_score_performance,
|
||||
::calculate_personal_skill_score,
|
||||
CONST_UI_STRING_INDEX_PERSONAL_SKILL,
|
||||
CONST_NAME_REF_EOG_HIVE );
|
||||
}
|
||||
|
||||
init_blocker_personal_score( score_component_struct )
|
||||
{
|
||||
if( isPlayingSolo() )
|
||||
{
|
||||
score_component_struct.max_score_damage_taken = SOLO_CONST_MAX_BLOCKER_SCORE_DAMAGE_TAKEN;
|
||||
score_component_struct.max_score_accuracy = SOLO_CONST_MAX_BLOCKER_SCORE_ACCURACY;
|
||||
}
|
||||
else
|
||||
{
|
||||
score_component_struct.max_score_damage_taken = COOP_CONST_MAX_BLOCKER_SCORE_DAMAGE_TAKEN;
|
||||
score_component_struct.max_score_accuracy = COOP_CONST_MAX_BLOCKER_SCORE_ACCURACY;
|
||||
}
|
||||
|
||||
return score_component_struct;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Escape //
|
||||
/////////////////////////////////////////
|
||||
CONST_TOTAL_ESCAPE_TIME_IN_MS = 240000;
|
||||
CONST_MAX_ESCAPE_SCORE = 15000;
|
||||
CONST_ESCAPE_BASE_BONUS = 15000;
|
||||
|
||||
init_escape_score_component()
|
||||
{
|
||||
register_encounter_score_component( CONST_NAME_REF_ESCAPE,
|
||||
::init_escape_score,
|
||||
undefined,
|
||||
undefined,
|
||||
::calculate_escape_score,
|
||||
CONST_UI_STRING_INDEX_ESCAPE,
|
||||
CONST_NAME_REF_EOG_ESCAPE );
|
||||
}
|
||||
|
||||
init_escape_score( score_component_struct )
|
||||
{
|
||||
score_component_struct.team_encounter_performance["time_remain_ms"] = 0;
|
||||
score_component_struct.team_encounter_performance["escape_player_ratio"] = 0;
|
||||
|
||||
return score_component_struct;
|
||||
}
|
||||
|
||||
calculate_escape_score( player, score_component_struct )
|
||||
{
|
||||
time_left_as_total_time = get_team_encounter_performance( score_component_struct, "time_remain_ms" ) / CONST_TOTAL_ESCAPE_TIME_IN_MS;
|
||||
prestige_score_buff_scalar = 1 + ( player maps\mp\alien\_prestige::get_num_nerf_selected() + 1 ) * PRESTIGE_RELIC_SCORE_BONUS;
|
||||
escape_time_score = int( CONST_ESCAPE_BASE_BONUS + CONST_MAX_ESCAPE_SCORE * time_left_as_total_time * get_team_encounter_performance( score_component_struct, "escape_player_ratio" ) * prestige_score_buff_scalar );
|
||||
|
||||
return escape_time_score;
|
||||
}
|
||||
|
||||
process_end_game_score_escaped( escape_time_remains, players_escaped )
|
||||
{
|
||||
escape_player_ratio = players_escaped.size / level.players.size;
|
||||
|
||||
update_team_encounter_performance( "escape", "time_remain_ms", escape_time_remains );
|
||||
update_team_encounter_performance( "escape", "escape_player_ratio", escape_player_ratio );
|
||||
|
||||
calculate_encounter_scores( players_escaped, [ CONST_NAME_REF_ESCAPE ] );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Common helper funcs //
|
||||
/////////////////////////////////////////
|
||||
|
||||
update_personal_encounter_performance( score_component_name, performance_type, amount )
|
||||
{
|
||||
if ( !has_encounter_score_component( score_component_name ) )
|
||||
return;
|
||||
|
||||
if ( !isPlayer( self ) )
|
||||
return;
|
||||
|
||||
self.encounter_performance = update_encounter_performance_internal( self.encounter_performance, performance_type, amount );
|
||||
}
|
||||
|
||||
update_team_encounter_performance( score_component_name, performance_type, amount )
|
||||
{
|
||||
if ( !has_encounter_score_component( score_component_name ) )
|
||||
return;
|
||||
|
||||
if ( !isDefined( amount ) )
|
||||
amount = 1;
|
||||
|
||||
level.encounter_score_components[score_component_name].team_encounter_performance[performance_type] += amount;
|
||||
}
|
||||
|
||||
update_encounter_performance_internal( performance_list, performance_type, amount )
|
||||
{
|
||||
AssertEx( isDefined( performance_list ), "Performance list is not defined" );
|
||||
AssertEx( isDefined( performance_list[performance_type] ), "Unknown performance type: " + performance_type );
|
||||
|
||||
if ( !isDefined( amount ) )
|
||||
amount = 1;
|
||||
|
||||
performance_list[performance_type] += amount;
|
||||
|
||||
return performance_list;
|
||||
}
|
||||
|
||||
register_scoring_mode()
|
||||
{
|
||||
if ( isPlayingSolo() )
|
||||
SetOmnvar( "ui_alien_is_solo", true );
|
||||
else
|
||||
SetOmnvar( "ui_alien_is_solo", false );
|
||||
}
|
||||
|
||||
get_team_encounter_performance( score_component_struct, performance_type )
|
||||
{
|
||||
return score_component_struct.team_encounter_performance[performance_type];
|
||||
}
|
||||
|
||||
get_player_encounter_performance( player, performance_type )
|
||||
{
|
||||
return player.encounter_performance[performance_type];
|
||||
}
|
||||
|
||||
has_encounter_score_component( score_component_name )
|
||||
{
|
||||
return has_score_component_internal( level.encounter_score_components, score_component_name );
|
||||
}
|
||||
|
||||
has_eog_score_component( score_component_name )
|
||||
{
|
||||
return has_score_component_internal( level.eog_score_components, score_component_name );
|
||||
}
|
||||
|
||||
has_score_component_internal( score_component_list, score_component_name )
|
||||
{
|
||||
if ( is_scoring_disabled() )
|
||||
return false;
|
||||
|
||||
return isDefined( score_component_list[score_component_name] );
|
||||
}
|
||||
|
||||
register_eog_score_component( name_ref, lua_string_index )
|
||||
{
|
||||
score_component = spawnStruct();
|
||||
|
||||
score_component.lua_string_index = lua_string_index;
|
||||
|
||||
level.eog_score_components[name_ref] = score_component;
|
||||
}
|
||||
|
||||
register_encounter_score_component( name_ref, init_func, reset_team_performance_func, reset_player_performance_func, calculate_func, lua_string_index, end_game_score_component_ref, player_init_func )
|
||||
{
|
||||
AssertEx( has_eog_score_component( end_game_score_component_ref ), "'" + end_game_score_component_ref + "' eog game component has not been registered." );
|
||||
|
||||
score_component = spawnStruct();
|
||||
|
||||
score_component = [[init_func]]( score_component );
|
||||
score_component.reset_team_performance_func = reset_team_performance_func;
|
||||
score_component.reset_player_performance_func = reset_player_performance_func;
|
||||
score_component.calculate_func = calculate_func;
|
||||
score_component.lua_string_index = lua_string_index;
|
||||
score_component.end_game_score_component_ref = end_game_score_component_ref;
|
||||
|
||||
if ( isDefined( player_init_func ) )
|
||||
score_component.player_init_func = player_init_func;
|
||||
|
||||
level.encounter_score_components[name_ref] = score_component;
|
||||
}
|
||||
|
||||
update_performance_alien_damage( eAttacker, iDamage, sMeansOfDeath )
|
||||
{
|
||||
if ( !isDefined( eAttacker ) )
|
||||
return;
|
||||
|
||||
if ( isDefined( eAttacker.classname ) && eAttacker.classname == "script_vehicle" ) // Friendly helicopter
|
||||
return;
|
||||
|
||||
if ( sMeansOfDeath == "MOD_TRIGGER_HURT" ) // Kill trigger
|
||||
return;
|
||||
|
||||
update_team_encounter_performance( get_team_score_component_name(), "damage_done_on_alien", iDamage );
|
||||
|
||||
personal_score_component_name = get_personal_score_component_name();
|
||||
|
||||
if ( isPlayer( eAttacker ) )
|
||||
eAttacker update_personal_encounter_performance( personal_score_component_name, "damage_done_on_alien", iDamage );
|
||||
else if ( isDefined( eAttacker.owner ) )
|
||||
eAttacker.owner update_personal_encounter_performance( personal_score_component_name, "damage_done_on_alien", iDamage );
|
||||
}
|
||||
|
||||
give_attacker_kill_rewards( attacker, sHitloc )
|
||||
{
|
||||
// if ( alien_mode_has( "nogame" ) )
|
||||
// return;
|
||||
|
||||
if ( self.agentteam == "allies" )
|
||||
return;
|
||||
|
||||
// For the elite, give all players the kill reward
|
||||
if ( self get_alien_type() == "elite" || self get_alien_type() == "mammoth" )
|
||||
{
|
||||
reward_point = get_reward_point_for_kill();
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
self giveKillReward( player, reward_point, "large" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Give assist bonuses
|
||||
if ( isDefined( self.attacker_damage ) )
|
||||
{
|
||||
MIN_ASSIST_BONUS_DAMAGE_RATIO = 0.1;
|
||||
min_assist_damage = self.max_health * MIN_ASSIST_BONUS_DAMAGE_RATIO;
|
||||
assist_bonus_amount = self getAssistBonusAmount();
|
||||
foreach ( attacker_struct in self.attacker_damage )
|
||||
{
|
||||
if ( attacker_struct.player == attacker ||( isDefined( attacker.owner ) && attacker_struct.player == attacker.owner ) )
|
||||
continue;
|
||||
|
||||
if ( attacker_struct.damage >= min_assist_damage )
|
||||
{
|
||||
if ( IsDefined( attacker_struct.player ) && attacker_struct.player != attacker )
|
||||
{
|
||||
assertex( isplayer( attacker_struct.player ), "Tried to give non-player rewards" );
|
||||
|
||||
// EoG tracking: assists
|
||||
attacker_struct.player maps\mp\alien\_persistence::eog_player_update_stat( "assists", 1 );
|
||||
|
||||
self giveKillReward( attacker_struct.player, assist_bonus_amount );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isDefined( attacker ) )
|
||||
return;
|
||||
|
||||
if ( !isPlayer( attacker ) && ( !isDefined( attacker.owner ) || !isPlayer( attacker.owner ) ) )
|
||||
return;
|
||||
|
||||
isEquipmentKill = false;
|
||||
if ( isDefined( attacker.owner ) )
|
||||
{
|
||||
attacker = attacker.owner;
|
||||
isEquipmentKill = true;
|
||||
}
|
||||
reward_point = get_reward_point_for_kill();
|
||||
if ( isDefined ( sHitloc ) && sHitloc == "soft" && !isEquipmentKill )
|
||||
reward_point = int( reward_point * 1.5 );
|
||||
giveKillReward( attacker, reward_point, "large", sHitloc );
|
||||
}
|
||||
|
||||
giveKillReward( attacker, amount, size, sHitloc )
|
||||
{
|
||||
currency_reward = amount * level.cycle_reward_scalar;
|
||||
attacker maps\mp\alien\_persistence::give_player_currency( currency_reward, size, sHitloc );
|
||||
|
||||
// give xp
|
||||
if( isdefined( level.alien_xp ) )
|
||||
{
|
||||
attacker maps\mp\alien\_persistence::give_player_xp( int( currency_reward ) );
|
||||
}
|
||||
|
||||
// Add to cortex charge if applicable
|
||||
if ( common_scripts\utility::flag_exist( "cortex_started" ) && common_scripts\utility::flag( "cortex_started" ) )
|
||||
{
|
||||
if ( IsDefined( level.add_cortex_charge_func ) )
|
||||
{
|
||||
[[level.add_cortex_charge_func]]( amount );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
giveAssistBonus( attacker, damage )
|
||||
{
|
||||
if ( !isDefined( attacker ) )
|
||||
return;
|
||||
|
||||
if ( !isPlayer( attacker ) && ( !isDefined( attacker.owner ) || !isPlayer( attacker.owner ) ) )
|
||||
return;
|
||||
|
||||
if ( isDefined( attacker.owner ) )
|
||||
attacker = attacker.owner;
|
||||
|
||||
if ( !IsDefined( self.attacker_damage ) )
|
||||
{
|
||||
self.attacker_damage = [];
|
||||
}
|
||||
|
||||
foreach ( attacker_struct in self.attacker_damage )
|
||||
{
|
||||
if ( attacker_struct.player == attacker )
|
||||
{
|
||||
attacker_struct.damage += damage;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
new_attacker_struct = spawnstruct();
|
||||
new_attacker_struct.player = attacker;
|
||||
new_attacker_struct.damage = damage;
|
||||
self.attacker_damage[ self.attacker_damage.size ] = new_attacker_struct;
|
||||
}
|
||||
|
||||
getAssistBonusAmount()
|
||||
{
|
||||
return level.alien_types[ self get_alien_type() ].attributes["reward"] * 0.5;
|
||||
}
|
||||
|
||||
get_reward_point_for_kill()
|
||||
{
|
||||
return level.alien_types[ self get_alien_type() ].attributes["reward"];
|
||||
}
|
||||
|
||||
round_up_to_nearest( cash_amount, base )
|
||||
{
|
||||
temp_value = cash_amount / base;
|
||||
temp_value = ceil( temp_value );
|
||||
return int( temp_value * base );
|
||||
}
|
||||
|
||||
is_scoring_disabled()
|
||||
{
|
||||
/#
|
||||
if ( alien_mode_has( "nogame" ) )
|
||||
return true;
|
||||
|
||||
if ( maps\mp\alien\_debug::spawn_test_enable() )
|
||||
return true;
|
||||
#/
|
||||
if ( is_chaos_mode() )
|
||||
return true; // Chaos has its own scoring system
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// Helper //
|
||||
////////////////////////////////
|
||||
|
||||
// The more under the max limit, the higher the score
|
||||
calculate_under_max_score( performance, max_limit, max_score )
|
||||
{
|
||||
under_max_limit = clamp( max_limit - performance, 0, max_limit );
|
||||
return int ( under_max_limit / max_limit * max_score );
|
||||
}
|
268
maps/mp/alien/_globallogic.gsc
Normal file
268
maps/mp/alien/_globallogic.gsc
Normal file
@ -0,0 +1,268 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include common_scripts\utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level.splitscreen = isSplitScreen();
|
||||
set_console_status();
|
||||
|
||||
level.onlineGame = getDvarInt( "onlinegame" );
|
||||
level.rankedMatch = ( ( level.onlineGame && !getDvarInt( "xblive_privatematch" ) ) || GetDvarInt( "force_ranking" ) ); // System link games are no longer ranked games
|
||||
|
||||
/#
|
||||
if ( getdvarint( "scr_forcerankedmatch" ) == 1 )
|
||||
{
|
||||
level.onlineGame = true;
|
||||
level.rankedMatch = true;
|
||||
}
|
||||
#/
|
||||
|
||||
level.script = toLower( getDvar( "mapname" ) );
|
||||
level.gametype = toLower( getDvar( "g_gametype" ) );
|
||||
|
||||
//default team list, use this for team algos, overwrite it for Multiteam games
|
||||
level.teamNameList = ["axis", "allies"];
|
||||
|
||||
level.otherTeam["allies"] = "axis";
|
||||
level.otherTeam["axis"] = "allies";
|
||||
|
||||
level.multiTeamBased = false;
|
||||
|
||||
level.teamBased = false;
|
||||
|
||||
level.objectiveBased = false;
|
||||
|
||||
level.endGameOnTimeLimit = true;
|
||||
|
||||
level.showingFinalKillcam = false;
|
||||
|
||||
level.tiSpawnDelay = getDvarInt( "scr_tispawndelay" );
|
||||
|
||||
// hack to allow maps with no scripts to run correctly
|
||||
if ( !isDefined( level.tweakablesInitialized ) )
|
||||
maps\mp\gametypes\_tweakables::init();
|
||||
|
||||
level.halftimeType = "halftime";
|
||||
level.halftimeSubCaption = &"MP_SWITCHING_SIDES";
|
||||
|
||||
level.lastStatusTime = 0;
|
||||
level.wasWinning = "none";
|
||||
|
||||
level.lastSlowProcessFrame = 0;
|
||||
|
||||
level.placement["allies"] = [];
|
||||
level.placement["axis"] = [];
|
||||
level.placement["all"] = [];
|
||||
|
||||
level.postRoundTime = 5.0;
|
||||
|
||||
level.playersLookingForSafeSpawn = [];
|
||||
|
||||
registerDvars();
|
||||
|
||||
mapLeaderboard = " LB_" + getdvar( "ui_mapname" );
|
||||
if(GetDvarInt( "scr_chaos_mode") == 1)
|
||||
mapLeaderboard += "_CHAOS";
|
||||
if( getDvarInt ( "sv_maxclients" ) == 1 )
|
||||
mapLeaderboard += "_SOLO";
|
||||
else
|
||||
mapLeaderboard += "_COOP";
|
||||
|
||||
mapEscapesLeaderboard = " LB_" + getdvar( "ui_mapname" ) + "_ESCAPES";
|
||||
|
||||
if( getDvarInt( "scr_aliens_hardcore" ) )
|
||||
mapLeaderboard += "_HC";
|
||||
|
||||
if(GetDvarInt( "scr_chaos_mode") == 1)
|
||||
{
|
||||
globalLeaderboard = "LB_GB_ALIEN_CHAOS";
|
||||
if( getDvarInt ( "sv_maxclients" ) == 1 )
|
||||
globalLeaderboard += "_SOLO";
|
||||
else
|
||||
globalLeaderboard += "_COOP";
|
||||
precacheLeaderboards( globalLeaderboard + mapLeaderboard);
|
||||
}
|
||||
else
|
||||
precacheLeaderboards( "LB_GB_ALIEN_HIVES LB_GB_ALIEN_KILLS LB_GB_ALIEN_REVIVES LB_GB_ALIEN_DOWNED LB_GB_ALIEN_XP LB_GB_ALIEN_SCORE LB_GB_ALIEN_CHALLENGES LB_GB_ALIEN_CASHFLOW" + mapLeaderboard + mapEscapesLeaderboard);
|
||||
|
||||
|
||||
level.teamCount["allies"] = 0;
|
||||
level.teamCount["axis"] = 0;
|
||||
level.teamCount["spectator"] = 0;
|
||||
|
||||
level.aliveCount["allies"] = 0;
|
||||
level.aliveCount["axis"] = 0;
|
||||
level.aliveCount["spectator"] = 0;
|
||||
|
||||
level.livesCount["allies"] = 0;
|
||||
level.livesCount["axis"] = 0;
|
||||
|
||||
level.oneLeftTime = [];
|
||||
|
||||
level.hasSpawned["allies"] = 0;
|
||||
level.hasSpawned["axis"] = 0;
|
||||
|
||||
/#
|
||||
if ( getdvarint( "scr_runlevelandquit" ) == 1 )
|
||||
{
|
||||
thread runLevelAndQuit();
|
||||
}
|
||||
#/
|
||||
|
||||
max_possible_teams = 9;
|
||||
init_multiTeamData( max_possible_teams );
|
||||
}
|
||||
|
||||
init_multiTeamData( max_num_teams )
|
||||
{
|
||||
for( i = 0; i < max_num_teams; i++ )
|
||||
{
|
||||
team_name = "team_" + i;
|
||||
|
||||
level.placement[team_name] = [];
|
||||
|
||||
level.teamCount[team_name] = 0;
|
||||
level.aliveCount[team_name] = 0;
|
||||
level.livesCount[team_name] = 0;
|
||||
level.hasSpawned[team_name] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/#
|
||||
runLevelAndQuit()
|
||||
{
|
||||
wait 1;
|
||||
while ( level.players.size < 1 )
|
||||
{
|
||||
wait 0.5;
|
||||
}
|
||||
wait 0.5;
|
||||
level notify( "game_ended" );
|
||||
exitLevel();
|
||||
}
|
||||
#/
|
||||
|
||||
|
||||
registerDvars()
|
||||
{
|
||||
SetOmnvar( "ui_bomb_timer", 0 );
|
||||
if( getDvar( "r_reflectionProbeGenerate" ) != "1" )
|
||||
{
|
||||
SetOmnvar( "ui_nuke_end_milliseconds", 0 );
|
||||
}
|
||||
SetDvar( "ui_danger_team", "" );
|
||||
SetDvar( "ui_inhostmigration", 0 );
|
||||
SetDvar( "ui_inprematch", 0 );
|
||||
SetDvar( "ui_override_halftime", 0 );
|
||||
SetDvar( "camera_thirdPerson", getDvarInt( "scr_thirdPerson" ) );
|
||||
SetDvar( "scr_alien_intel_pillage", 0 );
|
||||
}
|
||||
|
||||
SetupCallbacks()
|
||||
{
|
||||
level.onXPEvent = ::onXPEvent;
|
||||
|
||||
level.getSpawnPoint = ::blank;
|
||||
level.onSpawnPlayer = ::blank;
|
||||
level.onRespawnDelay = ::blank;
|
||||
|
||||
level.onTimeLimit = maps\mp\gametypes\_gamelogic::default_onTimeLimit;
|
||||
level.onHalfTime = maps\mp\gametypes\_gamelogic::default_onHalfTime;
|
||||
level.onDeadEvent = maps\mp\gametypes\_gamelogic::default_onDeadEvent;
|
||||
level.onOneLeftEvent = maps\mp\gametypes\_gamelogic::default_onOneLeftEvent;
|
||||
|
||||
level.onPrecacheGametype = ::blank;
|
||||
level.onStartGameType = ::blank;
|
||||
level.onPlayerKilled = ::blank;
|
||||
|
||||
level.killStreakInit = ::blank;
|
||||
level.matchEventsInit = ::blank;
|
||||
level.intelInit = ::blank;
|
||||
|
||||
/#
|
||||
level.devInit = maps\mp\alien\_dev::init;
|
||||
#/
|
||||
}
|
||||
|
||||
|
||||
|
||||
blank( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/#
|
||||
xpRateThread()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
level endon ( "game_ended" );
|
||||
|
||||
gameFlagWait( "prematch_done" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait ( 5.0 );
|
||||
if ( level.players[0].pers["team"] == "allies" || level.players[0].pers["team"] == "axis" )
|
||||
self maps\mp\gametypes\_rank::giveRankXP( "kill", int(min( getDvarInt( "scr_xprate" ), 50 )) );
|
||||
}
|
||||
}
|
||||
#/
|
||||
|
||||
testMenu()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait ( 10.0 );
|
||||
|
||||
notifyData = spawnStruct();
|
||||
notifyData.titleText = &"MP_CHALLENGE_COMPLETED";
|
||||
notifyData.notifyText = "wheee";
|
||||
notifyData.sound = "mp_challenge_complete";
|
||||
|
||||
self thread maps\mp\gametypes\_hud_message::notifyMessage( notifyData );
|
||||
}
|
||||
}
|
||||
|
||||
testShock()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait ( 3.0 );
|
||||
|
||||
numShots = randomInt( 6 );
|
||||
|
||||
for ( i = 0; i < numShots; i++ )
|
||||
{
|
||||
iPrintLnBold( numShots );
|
||||
self shellShock( "frag_grenade_mp", 0.2 );
|
||||
wait ( 0.1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onXPEvent( event )
|
||||
{
|
||||
//self thread maps\mp\_loot::giveMoney( event, 10 );
|
||||
self thread maps\mp\gametypes\_rank::giveRankXP( event );
|
||||
}
|
||||
|
||||
|
||||
debugLine( start, end )
|
||||
{
|
||||
for ( i = 0; i < 50; i++ )
|
||||
{
|
||||
line( start, end );
|
||||
wait .05;
|
||||
}
|
||||
}
|
1148
maps/mp/alien/_hive.gsc
Normal file
1148
maps/mp/alien/_hive.gsc
Normal file
File diff suppressed because it is too large
Load Diff
597
maps/mp/alien/_hud.gsc
Normal file
597
maps/mp/alien/_hud.gsc
Normal file
@ -0,0 +1,597 @@
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\alien\_persistence;
|
||||
#include maps\mp\alien\_perk_utility;
|
||||
|
||||
//<TODO JC> When ship, all of those HUD elements should be replaced/handled by LUA
|
||||
|
||||
CREDIT_GAIN_DEFAULT_FONT_SIZE = 1.38;
|
||||
SPLITSCREEN_CREDIT_GAIN_DEFAULT_FONT_SIZE = 1.2;
|
||||
|
||||
init()
|
||||
{
|
||||
register_end_game_string_index();
|
||||
}
|
||||
|
||||
playPainOverlay( attacker, weapon_name, direction )
|
||||
{
|
||||
// No pain overlay for the player while in Vanguard
|
||||
if ( isUsingRemote() && maps\mp\alien\_utility::is_true( self.vanguard_num ) )
|
||||
return;
|
||||
|
||||
damage_direction = get_damage_direction( direction );
|
||||
|
||||
if ( is_spitter_spit( weapon_name ) ) {
|
||||
self play_spitter_pain_overlay(damage_direction);
|
||||
} else if ( is_spitter_gas( weapon_name ) ) {
|
||||
self play_spitter_pain_overlay( "center" );
|
||||
} else if ( is_elite_attack( attacker ) ) {
|
||||
// play_slash_pain_overlay( damage_direction );
|
||||
PlayFXOnTagForClients( level._effect[ "vfx_melee_blood_spray" ], self, "tag_eye", self );
|
||||
} else {
|
||||
self play_basic_pain_overlay( damage_direction );
|
||||
}
|
||||
}
|
||||
|
||||
get_damage_direction( direction )
|
||||
{
|
||||
COS_15 = 0.965;
|
||||
|
||||
possible_directions = ["left", "center", "right"];
|
||||
|
||||
if ( !isDefined( direction ) )
|
||||
return possible_directions[randomInt( possible_directions.size )];
|
||||
|
||||
direction *= -1; //change direction to be based on the player's view
|
||||
|
||||
self_forward = anglesToForward( self.angles );
|
||||
forward_dot_product = VectorDot( direction, self_forward );
|
||||
|
||||
if ( forward_dot_product > COS_15 )
|
||||
return "center";
|
||||
|
||||
self_right = anglesToRight( self.angles );
|
||||
right_dot_product = VectorDot( direction, self_right );
|
||||
|
||||
if ( right_dot_product > 0 )
|
||||
return "right";
|
||||
else
|
||||
return "left";
|
||||
}
|
||||
|
||||
play_basic_pain_overlay( damage_direction )
|
||||
{
|
||||
if ( damage_direction == "left" )
|
||||
PlayFXOnTagForClients( level._effect[ "vfx_blood_hit_left" ], self, "tag_eye", self );
|
||||
else if ( damage_direction == "center" )
|
||||
PlayFXOnTagForClients( level._effect[ "vfx_melee_blood_spray" ], self, "tag_eye", self );
|
||||
else if ( damage_direction == "right" )
|
||||
PlayFXOnTagForClients( level._effect[ "vfx_blood_hit_right" ], self, "tag_eye", self );
|
||||
else
|
||||
AssertMsg( "Unknown damage_direction: " + damage_direction );
|
||||
}
|
||||
|
||||
play_spitter_pain_overlay( damage_direction )
|
||||
{
|
||||
if ( damage_direction == "left" )
|
||||
PlayFXOnTagForClients( level._effect[ "vfx_alien_spitter_hit_left" ], self, "tag_eye", self );
|
||||
else if ( damage_direction == "center" )
|
||||
PlayFXOnTagForClients( level._effect[ "vfx_alien_spitter_hit_center" ], self, "tag_eye", self );
|
||||
else if ( damage_direction == "right" )
|
||||
PlayFXOnTagForClients( level._effect[ "vfx_alien_spitter_hit_right" ], self, "tag_eye", self );
|
||||
else
|
||||
AssertMsg( "Unknown damage_direction: " + damage_direction );
|
||||
}
|
||||
|
||||
play_slash_pain_overlay( damage_direction )
|
||||
{
|
||||
if ( damage_direction == "center" ) // We currently do not have a center HUD overlay for slash center
|
||||
damage_direction = random_pick_R_or_L();
|
||||
|
||||
if ( damage_direction == "left" )
|
||||
PlayFXOnTagForClients( level._effect[ "vfx_blood_hit_left" ], self, "tag_eye", self );
|
||||
else if ( damage_direction == "right" )
|
||||
PlayFXOnTagForClients( level._effect[ "vfx_blood_hit_right" ], self, "tag_eye", self );
|
||||
else
|
||||
AssertMsg( "Unknown damage_direction: " + damage_direction );
|
||||
}
|
||||
|
||||
play_goo_pain_overlay( damage_direction )
|
||||
{
|
||||
if ( damage_direction == "left" )
|
||||
PlayFXOnTagForClients( level._effect[ "vfx_alien_spitter_hit_left" ], self, "tag_eye", self );
|
||||
else if ( damage_direction == "center" )
|
||||
PlayFXOnTagForClients( level._effect[ "vfx_alien_spitter_hit_center" ], self, "tag_eye", self );
|
||||
else if ( damage_direction == "right" )
|
||||
PlayFXOnTagForClients( level._effect[ "vfx_alien_spitter_hit_right" ], self, "tag_eye", self );
|
||||
else
|
||||
AssertMsg( "Unknown damage_direction: " + damage_direction );
|
||||
}
|
||||
|
||||
random_pick_R_or_L()
|
||||
{
|
||||
if ( cointoss() )
|
||||
return "right";
|
||||
else
|
||||
return "left";
|
||||
}
|
||||
|
||||
is_spitter_spit( weapon_name )
|
||||
{
|
||||
if ( !isDefined( weapon_name ) )
|
||||
return false;
|
||||
|
||||
return ( weapon_name == "alienspit_mp" );
|
||||
}
|
||||
|
||||
is_spitter_gas( weapon_name )
|
||||
{
|
||||
if ( !isDefined( weapon_name ) )
|
||||
return false;
|
||||
|
||||
return ( weapon_name == "alienspit_gas_mp" );
|
||||
}
|
||||
|
||||
|
||||
is_elite_attack( attacker )
|
||||
{
|
||||
if ( !isDefined( attacker ) || !attacker maps\mp\alien\_utility::is_alien_agent() )
|
||||
return false;
|
||||
|
||||
return ( attacker maps\mp\alien\_utility::get_alien_type() == "elite" );
|
||||
}
|
||||
|
||||
//===========================================
|
||||
// lastStandUpdateReviveIconColorAlien
|
||||
//===========================================
|
||||
lastStandUpdateReviveIconColorAlien( bleedOutTime )
|
||||
{
|
||||
self endon( "death" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
wait bleedOutTime / 3;
|
||||
self.color = (1.0, 0.64, 0.0);
|
||||
|
||||
wait bleedOutTime / 3;
|
||||
self.color = (1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
makeReviveIcon( owner, color, bleedOutTime )
|
||||
{
|
||||
reviveIcon = newTeamHudElem( owner.team );
|
||||
reviveIcon setShader( "waypoint_alien_revive", 8, 8 );
|
||||
reviveIcon setWaypoint( true, true );
|
||||
reviveIcon SetTargetEnt( self );
|
||||
reviveIcon.color = color;
|
||||
|
||||
reviveIcon thread deleteReviveIcon( owner );
|
||||
|
||||
if ( isDefined ( bleedOutTime ) )
|
||||
reviveIcon thread lastStandUpdateReviveIconColorAlien( bleedOutTime );
|
||||
|
||||
return reviveIcon;
|
||||
}
|
||||
|
||||
deleteReviveIcon( owner )
|
||||
{
|
||||
self endon ( "death" );
|
||||
|
||||
owner waittill_any( "disconnect", "revive", "death" );
|
||||
self destroy();
|
||||
}
|
||||
|
||||
hideHudElementOnGameEnd( hudElement )
|
||||
{
|
||||
level waittill("game_ended");
|
||||
if ( isDefined( hudElement ) )
|
||||
hudElement.alpha = 0;
|
||||
}
|
||||
|
||||
blocker_hive_hp_bar()
|
||||
{
|
||||
submitted_health = 100000; // initial large value to get through initial delta comparison
|
||||
while ( isdefined( self ) && self.health > 0 )
|
||||
{
|
||||
self waittill_notify_or_timeout( "damage", 2 );
|
||||
|
||||
if ( !isDefined ( self ) || self.health <= 0 )
|
||||
break;
|
||||
|
||||
hp_ratio = max( 0.005, self.health / self.maxhealth );
|
||||
inverse_health = 100 - hp_ratio * 100;
|
||||
|
||||
// omnvar throttle
|
||||
throttle = 0.5;
|
||||
if ( abs( abs( submitted_health ) - abs( inverse_health ) ) > throttle )
|
||||
{
|
||||
// inverse_health is ( max - health remaining ) for LUI
|
||||
SetOmnvar ( "ui_alien_boss_progression", inverse_health );
|
||||
submitted_health = inverse_health;
|
||||
}
|
||||
}
|
||||
SetOmnvar ( "ui_alien_boss_status", 0 );
|
||||
}
|
||||
|
||||
blocker_hive_chopper_hp_bar()
|
||||
{
|
||||
while ( isdefined( self ) && self.health > 0 )
|
||||
{
|
||||
self waittill_notify_or_timeout( "damage", 2 );
|
||||
|
||||
if ( !isDefined ( self ) || self.health <= 0 )
|
||||
break;
|
||||
|
||||
hp_ratio = self.health / self.maxhealth;
|
||||
health_remaining = hp_ratio * 100;
|
||||
}
|
||||
}
|
||||
|
||||
init_player_hud_onconnect()
|
||||
{
|
||||
VisionSetPain( "near_death_mp" );
|
||||
/#
|
||||
self.hud_laststand_count = self create_hud_laststand_count( 0, -20, 1.0 );
|
||||
#/
|
||||
}
|
||||
|
||||
/#
|
||||
// Temp HUD for displaying the number of times the player drops into last stand
|
||||
create_hud_laststand_count( xpos, ypos, scale )
|
||||
{
|
||||
self.hud_laststand_counter = 0;
|
||||
|
||||
hud_score = self maps\mp\gametypes\_hud_util::createFontString( "objective", scale );
|
||||
hud_score maps\mp\gametypes\_hud_util::setPoint( "BOTTOM LEFT", "BOTTOM LEFT", xpos, ypos );
|
||||
hud_score.color = ( 1, 1, 0 );
|
||||
hud_score.glowAlpha = 1;
|
||||
hud_score.sort = 1;
|
||||
hud_score.hideWhenInMenu = true;
|
||||
hud_score.archived = true;
|
||||
hud_score.label = &"";
|
||||
hud_score setValue( 0 );
|
||||
|
||||
if ( getDvarInt( "debug_alien_laststand_hud", 0 ) == 1 )
|
||||
hud_score.alpha = 1;
|
||||
else
|
||||
hud_score.alpha = 0;
|
||||
|
||||
return hud_score;
|
||||
}
|
||||
|
||||
update_hud_laststand_count()
|
||||
{
|
||||
self.hud_laststand_counter++;
|
||||
self.hud_laststand_count setValue( self.hud_laststand_counter );
|
||||
}
|
||||
#/
|
||||
|
||||
createSpendHintHUD( resource, rank ,message )
|
||||
{
|
||||
if ( !isDefined ( message ) )
|
||||
self setLowerMessage( "spend_hint", &"ALIEN_COLLECTIBLES_PULL_TO_SPEND" );
|
||||
else
|
||||
self setLowerMessage( "spend_hint", message );
|
||||
self thread hideSpendHintIcon();
|
||||
}
|
||||
|
||||
hideSpendHintIcon()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
self waittill_any_timeout( 3, "action_finish_used","player_action_slot_restart", "kill_spendhint" );
|
||||
self clearLowerMessage( "spend_hint" );
|
||||
|
||||
}
|
||||
|
||||
intro_black_screen()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "stop_intro" );
|
||||
|
||||
self.introscreen_overlay = newClientHudElem( self );
|
||||
|
||||
self.introscreen_overlay.x = 0;
|
||||
self.introscreen_overlay.y = 0;
|
||||
self.introscreen_overlay setshader( "black", 640, 480 );
|
||||
self.introscreen_overlay.alignX = "left";
|
||||
self.introscreen_overlay.alignY = "top";
|
||||
self.introscreen_overlay.sort = 1;
|
||||
self.introscreen_overlay.horzAlign = "fullscreen";
|
||||
self.introscreen_overlay.vertAlign = "fullscreen";
|
||||
self.introscreen_overlay.alpha = 1;
|
||||
self.introscreen_overlay.foreground = true;
|
||||
level waittill( "introscreen_over" );
|
||||
self.introscreen_overlay FadeOverTime( 3 );
|
||||
self.introscreen_overlay.alpha = 0;
|
||||
wait ( 3.5);
|
||||
self.introscreen_overlay Destroy();
|
||||
|
||||
}
|
||||
|
||||
|
||||
introscreen_corner_line( string, index_key )
|
||||
{
|
||||
if ( !IsDefined( level.intro_offset ) )
|
||||
level.intro_offset = 0;
|
||||
else
|
||||
level.intro_offset++;
|
||||
|
||||
y = cornerline_height();
|
||||
|
||||
font_scale = 1.6;
|
||||
if ( level.splitscreen )
|
||||
font_scale = 2;
|
||||
|
||||
hudelem = NewHudElem();
|
||||
hudelem.x = 20;
|
||||
hudelem.y = y;
|
||||
hudelem.alignX = "left";
|
||||
hudelem.alignY = "bottom";
|
||||
hudelem.horzAlign = "left";
|
||||
hudelem.vertAlign = "bottom";
|
||||
hudelem.sort = 3;// force to draw after the background
|
||||
hudelem.foreground = true;
|
||||
hudelem SetText( string );
|
||||
hudelem.alpha = 1;
|
||||
hudelem.hidewheninmenu = true;
|
||||
hudelem.fontScale = font_scale;// was 1.6 and 2.4, larger font change
|
||||
hudelem.color = ( 0.8, 1.0, 0.8 );
|
||||
hudelem.font = "default";
|
||||
hudelem.glowColor = ( 0.3, 0.6, 0.3 );
|
||||
hudelem.glowAlpha = 1;
|
||||
hudelem setPulseFX( 35, 4000, 1000 );
|
||||
return hudelem;
|
||||
}
|
||||
|
||||
cornerline_height()
|
||||
{
|
||||
offset = -92;
|
||||
|
||||
if ( level.splitscreen )
|
||||
offset = -110;
|
||||
|
||||
return( ( ( level.intro_offset ) * 20 ) - 92 );
|
||||
}
|
||||
|
||||
displayAlienGameEnd( winner, endReasonTextIndex )
|
||||
{
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( isDefined( player.connectedPostGame ) || player.pers["team"] == "spectator" )
|
||||
continue;
|
||||
|
||||
player thread alienOutcomeNotify( winner, endReasonTextIndex );
|
||||
player thread freezeControlsWrapper( true );
|
||||
}
|
||||
|
||||
level notify ( "game_win", winner );
|
||||
|
||||
maps\mp\gametypes\_gamelogic::roundEndWait( level.postRoundTime, true );
|
||||
}
|
||||
|
||||
alienOutcomeNotify( winner, end_reason_text_index )
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
self notify ( "reset_outcome" );
|
||||
|
||||
wait ( 0.5 );
|
||||
|
||||
team = self.pers["team"];
|
||||
if ( !IsDefined( team ) || (team != "allies" && team != "axis") )
|
||||
team = "allies";
|
||||
|
||||
// wait for notifies to finish
|
||||
while ( self maps\mp\gametypes\_hud_message::isDoingSplash() )
|
||||
wait 0.05;
|
||||
|
||||
self endon ( "reset_outcome" );
|
||||
|
||||
if ( IsDefined( self.pers["team"] ) && winner == team )
|
||||
outcome_title_index = get_end_game_string_index( "win" );
|
||||
else
|
||||
outcome_title_index = get_end_game_string_index( "fail" );
|
||||
|
||||
self setClientOmnvar( "ui_round_end_title" , outcome_title_index );
|
||||
self setClientOmnvar( "ui_round_end_reason" , end_reason_text_index );
|
||||
self setClientOmnvar( "ui_alien_show_eog_score", true );
|
||||
}
|
||||
|
||||
register_end_game_string_index()
|
||||
{
|
||||
if ( isDefined( level.end_game_string_override ) )
|
||||
[[ level.end_game_string_override ]]();
|
||||
else
|
||||
register_default_end_game_string_index();
|
||||
}
|
||||
|
||||
register_default_end_game_string_index()
|
||||
{
|
||||
level.end_game_string_index = [];
|
||||
|
||||
//<NOTE J.C.> When LUA is ready to take over, those string references will be changed into indexes and set via
|
||||
// proper omnvar. The actual string references are in RoundEndHud.lua
|
||||
|
||||
// for ui_round_end_title
|
||||
level.end_game_string_index["win"] = 1; // &"ALIEN_COLLECTIBLES_MISSION_WIN";
|
||||
level.end_game_string_index["fail"] = 2; // &"ALIEN_COLLECTIBLES_MISSION_FAIL";
|
||||
|
||||
// for ui_round_end_reason
|
||||
level.end_game_string_index["all_escape"] = 1; // &"ALIEN_COLLECTIBLES_MISSION_WIN_ALL_ESCAPE";
|
||||
level.end_game_string_index["some_escape"] = 2; // &"ALIEN_COLLECTIBLES_MISSION_WIN_CASUALTY";
|
||||
level.end_game_string_index["fail_escape"] = 3; // &"ALIEN_COLLECTIBLES_MISSION_FAIL_ESCAPE";
|
||||
level.end_game_string_index["drill_destroyed"] = 4; // &"ALIEN_COLLECTIBLES_MISSION_FAIL_DRILL_DESTROYED";
|
||||
level.end_game_string_index["kia"] = 5; // &"ALIEN_COLLECTIBLES_MISSION_FAIL_KILLED_IN_ACTION";
|
||||
level.end_game_string_index["host_end"] = 6; // &"ALIEN_COLLECTIBLES_MISSION_FAIL_HOST_END";
|
||||
level.end_game_string_index["gas_fail"] = 7; // &"ALIEN_PICKUPS_BEACON_GAS_FAIL";
|
||||
level.end_game_string_index["generator_destroyed"] = 8; // &"MP_ALIEN_LAST_GENERATOR_DESTROYED";
|
||||
}
|
||||
|
||||
get_end_game_string_index( key )
|
||||
{
|
||||
return level.end_game_string_index[key];
|
||||
}
|
||||
|
||||
show_encounter_scores()
|
||||
{
|
||||
level endon( "game_ended " );
|
||||
|
||||
SetOmnvar( "ui_alien_show_encounter_score", true );
|
||||
wait 1.0; // Allow LUI to catch the change notification
|
||||
SetOmnvar( "ui_alien_show_encounter_score", false );
|
||||
}
|
||||
|
||||
reset_player_encounter_LUA_omnvars( player )
|
||||
{
|
||||
CONST_ENCOUNTER_SCORE_MAX_NUM_ROW = 8;
|
||||
|
||||
for ( row_number = 1; row_number <= CONST_ENCOUNTER_SCORE_MAX_NUM_ROW; row_number++ )
|
||||
{
|
||||
title_omnvar_name = "ui_alien_encounter_title_row_" + row_number;
|
||||
score_omnvar_name = "ui_alien_encounter_score_row_" + row_number;
|
||||
player setClientOmnvar( title_omnvar_name, 0 );
|
||||
player setClientOmnvar( score_omnvar_name, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
set_LUA_encounter_score_row( player, row_number, row_title, row_score )
|
||||
{
|
||||
omnvar_title_name = "ui_alien_encounter_title_row_" + row_number;
|
||||
omnvar_score_name = "ui_alien_encounter_score_row_" + row_number;
|
||||
player setClientOmnvar( omnvar_title_name, row_title );
|
||||
player setClientOmnvar( omnvar_score_name, row_score );
|
||||
}
|
||||
|
||||
set_LUA_EoG_score_row( player, row_number, row_title, row_score )
|
||||
{
|
||||
omnvar_title_name = "ui_alien_eog_title_row_" + row_number;
|
||||
omnvar_score_name = "ui_alien_eog_score_row_" + row_number;
|
||||
player setClientOmnvar( omnvar_title_name, row_title );
|
||||
player setClientOmnvar( omnvar_score_name, row_score );
|
||||
}
|
||||
|
||||
make_wayPoint( shader, icon_width, icon_height, icon_alpha, location )
|
||||
{
|
||||
icon = NewHudElem();
|
||||
icon SetShader( shader, icon_width, icon_height );
|
||||
icon.alpha = icon_alpha;
|
||||
icon SetWayPoint( true, true );
|
||||
icon.x = location[0];
|
||||
icon.y = location[1];
|
||||
icon.z = location[2];
|
||||
return icon;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Chaos HUD external interface
|
||||
///////////////////////////////////////////////////////
|
||||
chaos_HUD_init()
|
||||
{
|
||||
level.last_combo_meter_reset_time = 0;
|
||||
}
|
||||
|
||||
set_combo_counter( value )
|
||||
{
|
||||
SetOmnvar( "ui_alien_chaos_combo_counter", value );
|
||||
}
|
||||
|
||||
set_score_streak( value )
|
||||
{
|
||||
SetOmnvar( "ui_alien_chaos_score_streak", value );
|
||||
}
|
||||
|
||||
set_total_score( value )
|
||||
{
|
||||
SetOmnvar( "ui_alien_chaos_total_score", value );
|
||||
}
|
||||
|
||||
reset_combo_meter( combo_duration )
|
||||
{
|
||||
if ( is_combo_meter_reset_this_frame() )
|
||||
return;
|
||||
|
||||
foreach( player in level.players )
|
||||
{
|
||||
now = gettime();
|
||||
player SetClientOmnvar( "ui_alien_chaos_combo_meter_start", now );
|
||||
player SetClientOmnvar( "ui_alien_chaos_combo_meter_end", now + int ( combo_duration * 1000 ) );
|
||||
}
|
||||
}
|
||||
|
||||
is_combo_meter_reset_this_frame()
|
||||
{
|
||||
current_time = getTime();
|
||||
previous_time = level.last_combo_meter_reset_time;
|
||||
level.last_combo_meter_reset_time = current_time;
|
||||
|
||||
return ( current_time == previous_time );
|
||||
}
|
||||
|
||||
set_grace_period_clock( grace_period_end_time )
|
||||
{
|
||||
setOmnvar( "ui_alien_chaos_grace_period", grace_period_end_time );
|
||||
}
|
||||
|
||||
unset_grace_period_clock()
|
||||
{
|
||||
setOmnvar( "ui_alien_chaos_grace_period", 0 );
|
||||
}
|
||||
|
||||
set_has_combo_freeze( player, has_combo_freeze )
|
||||
{
|
||||
player setClientOmnvar( "ui_alien_chaos_has_meter_freeze", has_combo_freeze );
|
||||
}
|
||||
|
||||
freeze_combo_meter( duration )
|
||||
{
|
||||
current_time = gettime();
|
||||
SetOmnvar( "ui_alien_chaos_meter_freeze_start", current_time );
|
||||
SetOmnvar( "ui_alien_chaos_meter_freeze_end", current_time + duration * 1000 );
|
||||
}
|
||||
|
||||
unfreeze_combo_meter()
|
||||
{
|
||||
SetOmnvar( "ui_alien_chaos_meter_freeze_start", 0 );
|
||||
SetOmnvar( "ui_alien_chaos_meter_freeze_end", 0 );
|
||||
}
|
||||
|
||||
set_event_count( event_id, event_count )
|
||||
{
|
||||
foreach( player in level.players )
|
||||
player SetClientOmnvar( "ui_alien_eog_score_row_" + event_id, event_count );
|
||||
}
|
||||
|
||||
set_has_chaos_class_skill_bonus( player, class_index )
|
||||
{
|
||||
player setClientOmnvar( "ui_alien_chaos_class_skill_bonus", class_index );
|
||||
}
|
||||
unset_has_chaos_class_skill_bonus( player )
|
||||
{
|
||||
player setClientOmnvar( "ui_alien_chaos_class_skill_bonus", 0 );
|
||||
}
|
||||
|
||||
set_last_stand_timer( player, duration )
|
||||
{
|
||||
player setClientOmnvar( "ui_laststand_end_milliseconds", gettime() + ( duration * 1000 ) );
|
||||
}
|
||||
|
||||
clear_last_stand_timer( player )
|
||||
{
|
||||
player setClientOmnvar( "ui_laststand_end_milliseconds", 0 );
|
||||
}
|
||||
|
||||
turn_on_drill_meter_HUD( drill_duration_sec )
|
||||
{
|
||||
// Make drill meter move
|
||||
SetOmnvar( "ui_alien_drill_state", 1 );
|
||||
|
||||
// Set UI drill end time
|
||||
drill_end_time_ms = int ( gettime() + drill_duration_sec * 1000 );
|
||||
SetOmnvar ( "ui_alien_drill_start_milliseconds" , gettime() );
|
||||
SetOmnvar( "ui_alien_drill_end_milliseconds", drill_end_time_ms );
|
||||
}
|
||||
|
||||
update_drill_health( drill_health )
|
||||
{
|
||||
SetOmnvar( "ui_alien_drill_health_text", drill_health );
|
||||
}
|
209
maps/mp/alien/_intro_sequence.gsc
Normal file
209
maps/mp/alien/_intro_sequence.gsc
Normal file
@ -0,0 +1,209 @@
|
||||
#include common_scripts\utility;
|
||||
|
||||
intro_sequence_precache()
|
||||
{
|
||||
flag_init( "intro_sequence_complete" );
|
||||
|
||||
switch( level.script )
|
||||
{
|
||||
case "mp_alien_town":
|
||||
town_intro_precache();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
play_intro_sequence( player )
|
||||
{
|
||||
switch( level.script )
|
||||
{
|
||||
case "mp_alien_town":
|
||||
level thread alien_town_intro( player );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// mp_alien_town
|
||||
////////////////////////////////////////////////////////////
|
||||
town_intro_precache()
|
||||
{
|
||||
alien_town_intro_precache_props();
|
||||
|
||||
alien_town_intro_precache_characters();
|
||||
}
|
||||
|
||||
#using_animtree("multiplayer");
|
||||
alien_town_intro_precache_characters()
|
||||
{
|
||||
PrecacheMpAnim( "alien_town_intro_boss" );
|
||||
PrecacheMpAnim( "alien_town_intro_pilot" );
|
||||
}
|
||||
|
||||
#using_animtree("animated_props");
|
||||
alien_town_intro_precache_props()
|
||||
{
|
||||
PrecacheMpAnim( "alien_town_intro_chopper" );
|
||||
//PrecacheMpAnim( "alien_town_intro_chopper_idle" );
|
||||
//PrecacheMpAnim( "alien_town_intro_chopper_leave" );
|
||||
PrecacheMpAnim( "alien_town_intro_drill" );
|
||||
}
|
||||
|
||||
alien_town_intro( player )
|
||||
{
|
||||
level waittill( "introscreen_over" );
|
||||
CHOPPER_START_POSITION = ( 2830.455, -398.027, 707.026 ); //<TODO J.C.> Maybe mark this position in map with script struct?
|
||||
// Thay way, we can eliminate the need for helibrush.
|
||||
//CHOPPER_IDLE_LOOP_TIMES = 1;
|
||||
|
||||
//add helicopter collision
|
||||
helibrush = GetEnt( "helicoptercoll", "targetname" );
|
||||
|
||||
heli = SpawnHelicopter( player, CHOPPER_START_POSITION, helibrush.angles + (0,180,0) , "nh90_alien_intro", "tag_origin_vehicle" );
|
||||
assert( IsDefined( heli ) );
|
||||
|
||||
//spawn helicopter
|
||||
IntroHeli = spawn("script_model", CHOPPER_START_POSITION );
|
||||
IntroHeli.angles = helibrush.angles;
|
||||
IntroHeli SetModel( "vehicle_nh90_interior2" );
|
||||
thread sfx_intro_heli_takeoff(heli);
|
||||
heli setmodel( "tag_origin_vehicle" );
|
||||
|
||||
level.intro_heli = IntroHeli;
|
||||
|
||||
//spawn and setup models
|
||||
boss_model = spawn_model( "mp_body_us_rangers_assault_a_urban", IntroHeli, "TAG_GUY1", ( 0, 0, 0 ) );
|
||||
boss_model SetModel( "mp_body_us_rangers_assault_a_urban" );
|
||||
boss_head = spawn_model( "head_mp_head_a", boss_model, "J_spine4", ( 0, 0, 0 ) );
|
||||
pilot_model = spawn_model( "mp_body_us_rangers_assault_a_urban", IntroHeli, "tag_driver", ( 0, 0, 0 ) );
|
||||
pilot_head = spawn_model( "head_mp_head_a", pilot_model, "J_spine4", ( 0, 0, 0 ) );
|
||||
drill_model = spawn_model( "mp_laser_drill", IntroHeli, "TAG_GUY1", ( 0, 0, 0 ) );
|
||||
|
||||
thread sfx_intro_npc_foley(boss_model);
|
||||
|
||||
//play helicopter intro animations
|
||||
IntroHeli ScriptModelPlayAnimDeltaMotion("alien_town_intro_chopper");
|
||||
pilot_model ScriptModelPlayAnim("alien_town_intro_pilot");
|
||||
pilot_head ScriptModelPlayAnim("alien_town_intro_pilot");
|
||||
boss_model ScriptModelPlayAnim("alien_town_intro_boss");
|
||||
boss_head ScriptModelPlayAnim("alien_town_intro_boss");
|
||||
drill_model ScriptModelPlayAnim("alien_town_intro_drill");
|
||||
|
||||
thread sfx_intro_heli_drop_drill(drill_model);
|
||||
|
||||
helibrush thread wait_to_delete();
|
||||
|
||||
wait( GetAnimLength( %alien_town_intro_drill ) );
|
||||
|
||||
drill_model ScriptModelClearAnim();
|
||||
drill_model Delete();
|
||||
|
||||
level thread mp_alien_town_intro_drill_setup();
|
||||
|
||||
//<TODO J.C.> Waiting for final asset here. Will spawn the actual drill to match the end position of the drill anim.
|
||||
|
||||
//play helicopter loop anim
|
||||
/*
|
||||
for( i = 0; i < CHOPPER_IDLE_LOOP_TIMES; i++ )
|
||||
{
|
||||
IntroHeli ScriptModelPlayAnimDeltaMotion("alien_town_intro_chopper_idle");
|
||||
wait( GetAnimLength( %alien_town_intro_chopper_idle ) );
|
||||
}
|
||||
*/
|
||||
|
||||
//play helicopter leaving anim
|
||||
//IntroHeli ScriptModelPlayAnimDeltaMotion("alien_town_intro_chopper_leave");
|
||||
level thread kill_heli ( heli );
|
||||
wait( GetAnimLength( %alien_town_intro_chopper) );
|
||||
|
||||
//clear the anim before deletion
|
||||
pilot_model ScriptModelClearAnim();
|
||||
pilot_head ScriptModelClearAnim();
|
||||
boss_model ScriptModelClearAnim();
|
||||
boss_head ScriptModelClearAnim();
|
||||
IntroHeli ScriptModelClearAnim();
|
||||
|
||||
//clean up
|
||||
boss_model Delete();
|
||||
boss_head Delete();
|
||||
pilot_model Delete();
|
||||
pilot_head Delete();
|
||||
IntroHeli Delete();
|
||||
}
|
||||
|
||||
wait_to_delete()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
CONST_HELI_COLLISION_DELETE_TIME = 16.5; // wait for heli to leave the ground high enough
|
||||
|
||||
wait ( CONST_HELI_COLLISION_DELETE_TIME );
|
||||
self delete();
|
||||
}
|
||||
|
||||
kill_heli ( heli )
|
||||
{
|
||||
wait ( 10 );
|
||||
heli Vehicle_SetSpeed( 50,10 );
|
||||
heli SetVehGoalPos ( heli.origin + (0,0,1600 ));
|
||||
wait ( 10 );
|
||||
heli delete();
|
||||
}
|
||||
|
||||
|
||||
spawn_model( model_name, attach_to_entity, tag_name, spawn_angle_offset )
|
||||
{
|
||||
new_model = spawn( "script_model", ( 0, 0, 0 ) );
|
||||
new_model SetModel( model_name );
|
||||
new_model.origin = attach_to_entity GetTagOrigin( tag_name );
|
||||
new_model.angles = attach_to_entity GetTagAngles( tag_name ) + spawn_angle_offset;
|
||||
new_model LinkTo( attach_to_entity, tag_name );
|
||||
|
||||
return new_model;
|
||||
}
|
||||
|
||||
intro_sequence_enabled()
|
||||
{
|
||||
/#
|
||||
if ( maps\mp\alien\_debug::StartPointEnabled() )
|
||||
return false;
|
||||
#/
|
||||
if ( maps\mp\alien\_utility::is_chaos_mode() )
|
||||
return false;
|
||||
|
||||
return ( getDvarInt( "scr_alien_intro", 1 ) == 1 );
|
||||
}
|
||||
|
||||
mp_alien_town_intro_drill_setup()
|
||||
{
|
||||
level.initial_drill_origin = ( 2834.272, -243.002, 524.068 );
|
||||
level.initial_drill_angles = ( 0.995, -103.877, 1.287 );
|
||||
|
||||
level notify ( "spawn_intro_drill" );
|
||||
|
||||
wait( 8 );
|
||||
|
||||
flag_set( "intro_sequence_complete" );
|
||||
}
|
||||
|
||||
sfx_intro_heli_takeoff(heli)
|
||||
{
|
||||
heli Vehicle_TurnEngineOff();
|
||||
heli PlaySound("alien_heli_intro_takeoff");
|
||||
}
|
||||
|
||||
sfx_intro_heli_drop_drill(drill)
|
||||
{
|
||||
//wait 8;
|
||||
wait( GetAnimLength( %alien_town_intro_drill ) - 0.5);
|
||||
//IPrintLnBold("Drill");
|
||||
drill PlaySound("alien_heli_drill_drop");
|
||||
}
|
||||
|
||||
sfx_intro_npc_foley(npc)
|
||||
{
|
||||
wait 2.53;
|
||||
npc PlaySound("alien_heli_npc_foley");
|
||||
}
|
351
maps/mp/alien/_lasedstrike_alien.gsc
Normal file
351
maps/mp/alien/_lasedstrike_alien.gsc
Normal file
@ -0,0 +1,351 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include common_scripts\utility;
|
||||
|
||||
CONST_SOFLAM_AMMO = 3;
|
||||
|
||||
init()
|
||||
{
|
||||
level.lasedStrikeGlow = loadfx("fx/misc/laser_glow");
|
||||
level.lasedStrikeExplode = LoadFX( "fx/explosions/uav_advanced_death" );
|
||||
|
||||
thread onPlayerConnect();
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill("connected", player);
|
||||
player thread onPlayerSpawned();
|
||||
player.soflamAmmoUsed = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
self thread watch_alien_soflam_usage();
|
||||
self thread watch_alien_soflam_weaponswitch();
|
||||
}
|
||||
}
|
||||
|
||||
watch_alien_soflam_weaponswitch()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon("death");
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "weapon_change",newWeapon );
|
||||
|
||||
if ( newWeapon == "aliensoflam_mp" )
|
||||
self SetWeaponAmmoClip ( "aliensoflam_mp", CONST_SOFLAM_AMMO - self.soflamAmmoUsed );
|
||||
}
|
||||
}
|
||||
|
||||
watch_alien_soflam_usage()
|
||||
{
|
||||
self notify( "watchaliensoflamusage" );
|
||||
self endon( "watchaliensoflamusage" );
|
||||
|
||||
level endon( "game_ended" );
|
||||
self endon( "disconnect" );
|
||||
|
||||
while( self isChangingWeapon() )
|
||||
wait ( 0.05 );
|
||||
|
||||
for(;;)
|
||||
{
|
||||
|
||||
if ( self AttackButtonPressed() && self GetCurrentWeapon() == "aliensoflam_mp" && self AdsButtonPressed() && !self IsUsingTurret() )
|
||||
{
|
||||
//self WeaponLockNoClearance( false );
|
||||
self WeaponLockTargetTooClose( false );
|
||||
self WeaponLockFree();
|
||||
|
||||
targetInfo = getTargetPoint();
|
||||
|
||||
if( !isDefined( targetInfo ) )
|
||||
{
|
||||
wait 0.05;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !isDefined( targetInfo[0] ) )
|
||||
{
|
||||
wait 0.05;
|
||||
continue;
|
||||
}
|
||||
|
||||
targPoint = targetInfo[0];
|
||||
|
||||
self attackLasedTarget( targPoint );
|
||||
}
|
||||
|
||||
wait( 0.05 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
playLockSound()
|
||||
{
|
||||
if ( isDefined( self.playingLockSound ) && self.playingLockSound )
|
||||
return;
|
||||
|
||||
self PlayLocalSound( "javelin_clu_lock" );
|
||||
self.playingLockSound = true;
|
||||
|
||||
wait( .75 );
|
||||
|
||||
self StopLocalSound( "javelin_clu_lock" );
|
||||
self.playingLockSound = false;
|
||||
}
|
||||
|
||||
playLockErrorSound()
|
||||
{
|
||||
if ( isDefined( self.playingLockSound ) && self.playingLockSound )
|
||||
return;
|
||||
|
||||
self PlayLocalSound( "javelin_clu_aquiring_lock" );
|
||||
self.playingLockSound = true;
|
||||
|
||||
wait( .75 );
|
||||
|
||||
self StopLocalSound( "javelin_clu_aquiring_lock" );
|
||||
self.playingLockSound = false;
|
||||
}
|
||||
|
||||
|
||||
attackLasedTarget( targPoint )
|
||||
{
|
||||
finalTargetEnt = undefined;
|
||||
midTargetEnt = undefined;
|
||||
|
||||
upQuantity = 6000;
|
||||
upVector = (0, 0, upQuantity );
|
||||
backDist = 3000;
|
||||
forward = AnglesToForward( self.angles );
|
||||
ownerOrigin = self.origin;
|
||||
startpos = ownerOrigin + upVector + forward * backDist * -1;
|
||||
|
||||
foundAngle = false;
|
||||
|
||||
//straight down
|
||||
|
||||
skyTrace = bulletTrace( targPoint + (0,0,upQuantity), targPoint , false );
|
||||
if( skyTrace["fraction"] > .99 )
|
||||
{
|
||||
foundAngle = true;
|
||||
startPos = targPoint + (0,0,upQuantity);
|
||||
}
|
||||
//self thread drawLine( targPoint, targPoint + (0,0,upQuantity), 25, (1,0,0) );
|
||||
|
||||
|
||||
if( !foundAngle )
|
||||
{
|
||||
skyTrace = bulletTrace( targPoint + (300,0,upQuantity), targPoint , false );
|
||||
if( skyTrace["fraction"] > .99 )
|
||||
{
|
||||
foundAngle = true;
|
||||
startPos = targPoint + (300,0,upQuantity);
|
||||
}
|
||||
//self thread drawLine( targPoint, targPoint + (300,0,upQuantity), 25, (1,0,0) );
|
||||
}
|
||||
|
||||
if( !foundAngle )
|
||||
{
|
||||
skyTrace = bulletTrace( targPoint + (0,300,upQuantity), targPoint , false );
|
||||
if( skyTrace["fraction"] > .99 )
|
||||
{
|
||||
foundAngle = true;
|
||||
startPos = targPoint + (0,300,upQuantity);
|
||||
}
|
||||
//self thread drawLine( targPoint, targPoint + (0,300,upQuantity), 25, (1,0,0) );
|
||||
}
|
||||
|
||||
if( !foundAngle )
|
||||
{
|
||||
skyTrace = bulletTrace( targPoint + (0,-300,upQuantity), targPoint , false );
|
||||
if( skyTrace["fraction"] > .99 )
|
||||
{
|
||||
foundAngle = true;
|
||||
startPos = targPoint + (0,-300,upQuantity);
|
||||
}
|
||||
//self thread drawLine( targPoint, targPoint + (0,-300,upQuantity), 25, (1,0,0) );
|
||||
}
|
||||
|
||||
if( !foundAngle )
|
||||
{
|
||||
skyTrace = bulletTrace( targPoint + (300,300,upQuantity), targPoint , false );
|
||||
if( skyTrace["fraction"] > .99 )
|
||||
{
|
||||
foundAngle = true;
|
||||
startPos = targPoint + (300,300,upQuantity);
|
||||
}
|
||||
//self thread drawLine( targPoint, targPoint + (300,300,upQuantity), 25, (1,0,0) );
|
||||
}
|
||||
|
||||
if( !foundAngle )
|
||||
{
|
||||
skyTrace = bulletTrace( targPoint + (-300,0,upQuantity), targPoint , false );
|
||||
if( skyTrace["fraction"] > .99 )
|
||||
{
|
||||
foundAngle = true;
|
||||
startPos = targPoint + (-300,0,upQuantity);
|
||||
}
|
||||
//self thread drawLine( targPoint, targPoint + (-300,0,upQuantity), 25, (1,0,0) );
|
||||
}
|
||||
|
||||
if( !foundAngle )
|
||||
{
|
||||
skyTrace = bulletTrace( targPoint + (-300,-300,upQuantity), targPoint , false );
|
||||
if( skyTrace["fraction"] > .99 )
|
||||
{
|
||||
foundAngle = true;
|
||||
startPos = targPoint + (-300,-300,upQuantity);
|
||||
}
|
||||
//self thread drawLine( targPoint, targPoint + (-300,-300,upQuantity), 25, (1,0,0) );
|
||||
}
|
||||
|
||||
if( !foundAngle )
|
||||
{
|
||||
skyTrace = bulletTrace( targPoint + (300,-300,upQuantity), targPoint , false );
|
||||
if( skyTrace["fraction"] > .99 )
|
||||
{
|
||||
foundAngle = true;
|
||||
startPos = targPoint + (300,-300,upQuantity);
|
||||
}
|
||||
//self thread drawLine( targPoint, targPoint + (300,-300,upQuantity), 25, (1,0,0) );
|
||||
}
|
||||
|
||||
//backwards vector from player over target area
|
||||
if( !foundAngle )
|
||||
{
|
||||
for ( i = 0; i < 5; i++ )
|
||||
{
|
||||
upQuantity = upQuantity / 2;
|
||||
upVector = (0, 0, upQuantity );
|
||||
startpos = self.origin + upVector + forward * backDist * -1;
|
||||
|
||||
targetSkyCheck = BulletTrace( targPoint, startpos, false );
|
||||
if ( targetSkyCheck["fraction"] > .99 )
|
||||
{
|
||||
foundAngle = true;
|
||||
break;
|
||||
}
|
||||
wait( 0.05 );
|
||||
}
|
||||
}
|
||||
|
||||
//check increased angle to try to get it over large objects
|
||||
if( !foundAngle )
|
||||
{
|
||||
for ( i = 0; i < 5; i++ )
|
||||
{
|
||||
upQuantity = upQuantity * 2.5;
|
||||
|
||||
upVector = (0, 0, upQuantity );
|
||||
startpos = self.origin + upVector + forward * backDist * -1;
|
||||
|
||||
targetSkyCheck = BulletTrace( targPoint, startpos, false );
|
||||
if ( targetSkyCheck["fraction"] > .99 )
|
||||
{
|
||||
foundAngle = true;
|
||||
break;
|
||||
}
|
||||
wait( 0.05 );
|
||||
}
|
||||
}
|
||||
|
||||
if( !foundAngle )
|
||||
{
|
||||
self thread cantHitTarget();
|
||||
return false;
|
||||
}
|
||||
|
||||
//finalTargetEnt = Spawn( "script_origin", targPoint );
|
||||
finalTargetEnt = SpawnFx( level.lasedStrikeGlow, targPoint );
|
||||
|
||||
self thread playLockSound();
|
||||
self WeaponLockFinalize( targPoint, (0,0,0), false );
|
||||
self thread update_soflam_ammocount();
|
||||
|
||||
missile = MagicBullet("aliensoflam_missle_mp", startPos, targPoint, self);
|
||||
missile Missile_SetTargetEnt( finalTargetEnt );
|
||||
|
||||
self thread loopTriggeredeffect( finalTargetEnt, missile );
|
||||
|
||||
self WeaponLockFree();
|
||||
missile waittill( "death" );
|
||||
|
||||
if( isDefined( finalTargetEnt ) )
|
||||
{
|
||||
finalTargetEnt delete();
|
||||
}
|
||||
|
||||
Earthquake(.4,1,targPoint,850 );
|
||||
return true;
|
||||
}
|
||||
|
||||
loopTriggeredEffect( effect, missile )
|
||||
{
|
||||
missile endon( "death" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
TriggerFX( effect );
|
||||
wait ( 0.5 );
|
||||
}
|
||||
}
|
||||
|
||||
cantHitTarget()
|
||||
{
|
||||
self thread playLockErrorSound();
|
||||
//self WeaponLockNoClearance( true );
|
||||
self WeaponLockTargetTooClose( true );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
getTargetPoint()
|
||||
{
|
||||
origin = self GetEye();
|
||||
angles = self GetPlayerAngles();
|
||||
forward = AnglesToForward( angles );
|
||||
endpoint = origin + forward * 15000;
|
||||
|
||||
res = BulletTrace( origin, endpoint, false, undefined );
|
||||
|
||||
if ( res["surfacetype"] == "none" )
|
||||
return undefined;
|
||||
if ( res["surfacetype"] == "default" )
|
||||
return undefined;
|
||||
|
||||
results = [];
|
||||
results[0] = res["position"];
|
||||
results[1] = res["normal"];
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
update_soflam_ammocount()
|
||||
{
|
||||
self.soflamAmmoUsed++;
|
||||
self SetWeaponAmmoClip ( "aliensoflam_mp", CONST_SOFLAM_AMMO - self.soflamAmmoUsed );
|
||||
if( self.soflamAmmoUsed >= CONST_SOFLAM_AMMO )
|
||||
{
|
||||
self.soflamAmmoUsed = 0;
|
||||
self takeweapon( "aliensoflam_mp" );
|
||||
if ( !maps\mp\alien\_utility::is_true( self.has_special_weapon ) && !maps\mp\alien\_utility::is_true( self.is_holding_deployable ) )
|
||||
self SwitchToWeapon( self GetWeaponsListPrimaries()[0] );
|
||||
}
|
||||
|
||||
}
|
1039
maps/mp/alien/_laststand.gsc
Normal file
1039
maps/mp/alien/_laststand.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1631
maps/mp/alien/_music_and_dialog.gsc
Normal file
1631
maps/mp/alien/_music_and_dialog.gsc
Normal file
File diff suppressed because it is too large
Load Diff
291
maps/mp/alien/_nuke.gsc
Normal file
291
maps/mp/alien/_nuke.gsc
Normal file
@ -0,0 +1,291 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
|
||||
// the nuke ended the game in MW2, for MW3 it will be an MOAB, not end the game but kill the other team and emp them for 60 seconds, it will also change the visionset for the level
|
||||
|
||||
init()
|
||||
{
|
||||
level.nukeVisionSet = "alien_nuke";
|
||||
level.nukeVisionSetFailed = "alien_nuke_blast";
|
||||
|
||||
if ( level.script == "mp_alien_last" )
|
||||
{
|
||||
level._effect[ "nuke_flash" ] = loadfx( "vfx/moments/alien/player_nuke_flash_alien_last" );
|
||||
}
|
||||
else
|
||||
{
|
||||
level._effect[ "nuke_flash" ] = loadfx( "fx/explosions/player_death_nuke_flash_alien" );
|
||||
}
|
||||
|
||||
SetDvarIfUninitialized( "scr_nukeTimer", 10 );
|
||||
SetDvarIfUninitialized( "scr_nukeCancelMode", 0 );
|
||||
|
||||
level.nukeTimer = getDvarInt( "scr_nukeTimer" );
|
||||
level.cancelMode = getDvarInt( "scr_nukeCancelMode" );
|
||||
|
||||
level.nukeInfo = spawnStruct();
|
||||
level.nukeInfo.xpScalar = 2;
|
||||
level.nukeDetonated = undefined;
|
||||
|
||||
level thread onPlayerConnect();
|
||||
}
|
||||
|
||||
delaythread_nuke( delay, func )
|
||||
{
|
||||
level endon ( "nuke_cancelled" );
|
||||
|
||||
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( delay );
|
||||
|
||||
thread [[ func ]]();
|
||||
}
|
||||
|
||||
// used in aliens mode
|
||||
doNukeSimple()
|
||||
{
|
||||
level.nukeInfo.player = self;
|
||||
level.nukeInfo.team = self.pers["team"];
|
||||
level.nukeIncoming = true;
|
||||
|
||||
level thread delaythread_nuke( (level.nukeTimer - 3.3), ::nukeSoundIncoming );
|
||||
level thread delaythread_nuke( level.nukeTimer, ::nukeSoundExplosion );
|
||||
level thread delaythread_nuke( level.nukeTimer, ::nukeSlowMo );
|
||||
level thread delaythread_nuke( level.nukeTimer, ::nukeEffects );
|
||||
level thread delaythread_nuke( (level.nukeTimer + 0.25), ::nukeVision );
|
||||
level thread delaythread_nuke( (level.nukeTimer + 1.5), ::nukeDeath );
|
||||
//level thread delaythread_nuke( (level.nukeTimer + 1.5), ::nukeEarthquake );
|
||||
|
||||
// need objects to play sound off of, i'm keeping them on level so we don't spawn them more than once if multiple nukes get called in a match
|
||||
if( !IsDefined( level.nuke_soundObject ) )
|
||||
{
|
||||
level.nuke_soundObject = Spawn( "script_origin", (0,0,1) );
|
||||
level.nuke_soundObject hide();
|
||||
}
|
||||
}
|
||||
|
||||
nukeDeath()
|
||||
{
|
||||
level notify( "nuke_death" );
|
||||
}
|
||||
|
||||
nukeSoundIncoming()
|
||||
{
|
||||
level endon ( "nuke_cancelled" );
|
||||
|
||||
if( IsDefined( level.nuke_soundObject ) )
|
||||
level.nuke_soundObject PlaySound( "nuke_incoming" );
|
||||
}
|
||||
|
||||
nukeSoundExplosion()
|
||||
{
|
||||
level endon ( "nuke_cancelled" );
|
||||
|
||||
if( IsDefined( level.nuke_soundObject ) )
|
||||
{
|
||||
level.nuke_soundObject PlaySound( "nuke_explosion" );
|
||||
level.nuke_soundObject PlaySound( "nuke_wave" );
|
||||
}
|
||||
}
|
||||
|
||||
nukeEffects()
|
||||
{
|
||||
level endon ( "nuke_cancelled" );
|
||||
|
||||
level.nukeDetonated = true;
|
||||
|
||||
foreach( player in level.players )
|
||||
{
|
||||
playerForward = anglestoforward( player.angles );
|
||||
playerForward = ( playerForward[0], playerForward[1], 0 );
|
||||
playerForward = VectorNormalize( playerForward );
|
||||
|
||||
nukeDistance = 5000;
|
||||
|
||||
nukeLoc = player.origin + ( playerForward * nukeDistance );
|
||||
// nuke location override: from aliens
|
||||
if ( isdefined( level.nukeLoc ) )
|
||||
nukeLoc = level.nukeLoc;
|
||||
|
||||
nukeAngles = ( 0, (player.angles[1] + 180), 90 );
|
||||
// nuke angle override: from aliens
|
||||
if ( IsDefined( level.nukeAngles ) )
|
||||
nukeAngles = level.nukeAngles;
|
||||
|
||||
nukeEnt = Spawn( "script_model", nukeLoc );
|
||||
nukeEnt setModel( "tag_origin" );
|
||||
nukeEnt.angles = nukeAngles;
|
||||
|
||||
nukeEnt thread nukeEffect( player );
|
||||
}
|
||||
}
|
||||
|
||||
nukeEffect( player )
|
||||
{
|
||||
level endon ( "nuke_cancelled" );
|
||||
|
||||
player endon( "disconnect" );
|
||||
|
||||
waitframe();
|
||||
PlayFXOnTagForClients( level._effect[ "nuke_flash" ], self, "tag_origin", player );
|
||||
}
|
||||
|
||||
nukeSlowMo()
|
||||
{
|
||||
level endon ( "nuke_cancelled" );
|
||||
|
||||
//SetSlowMotion( <startTimescale>, <endTimescale>, <deltaTime> )
|
||||
SetSlowMotion( 1.0, 0.25, 0.5 );
|
||||
level waittill( "nuke_death" );
|
||||
SetSlowMotion( 0.25, 1, 2.0 );
|
||||
}
|
||||
|
||||
nukeVision()
|
||||
{
|
||||
level endon ( "nuke_cancelled" );
|
||||
|
||||
level.nukeVisionInProgress = true;
|
||||
|
||||
// level waittill( "nuke_death" );
|
||||
|
||||
transition_time = 0.75;
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
// if spectating player is spectating someone who escaped
|
||||
if ( isdefined( player.sessionstate ) && player.sessionstate == "spectator" )
|
||||
{
|
||||
spectated_player = player GetSpectatingPlayer();
|
||||
if ( isdefined( spectated_player ) )
|
||||
{
|
||||
// go with what spectated player is using
|
||||
if ( ( isdefined( spectated_player.nuke_escaped ) && spectated_player.nuke_escaped ) )
|
||||
player set_vision_for_nuke_escaped( transition_time );
|
||||
else
|
||||
player set_vision_for_nuke_failed( transition_time );
|
||||
}
|
||||
else
|
||||
{
|
||||
// use failed vision if player isnt spectating anyone, meaning he could be looking at nuke from bad angle
|
||||
player set_vision_for_nuke_failed( transition_time );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ( isdefined( player.nuke_escaped ) && player.nuke_escaped ) )
|
||||
player set_vision_for_nuke_escaped( transition_time );
|
||||
else
|
||||
player set_vision_for_nuke_failed( transition_time );
|
||||
}
|
||||
}
|
||||
|
||||
fog_nuke(transition_time);
|
||||
// restore_fog( 0 );
|
||||
// VisionSetPain( level.nukeVisionSet );
|
||||
}
|
||||
|
||||
// Julian - Kyle, you may use the following functions to replace vision change with your fx
|
||||
set_vision_for_nuke_escaped( transition_time )
|
||||
{
|
||||
self VisionSetNakedForPlayer( level.nukeVisionSet, transition_time );
|
||||
self VisionSetPainForPlayer( level.nukeVisionSet );
|
||||
}
|
||||
|
||||
set_vision_for_nuke_failed( transition_time )
|
||||
{
|
||||
PlayFXOnTagForClients( level._effect[ "vfx/moments/alien/nuke_fail_screen_flash" ], self, "tag_eye",self);
|
||||
self VisionSetNakedForPlayer( level.nukeVisionSetFailed, transition_time );
|
||||
self VisionSetPainForPlayer( level.nukeVisionSetFailed );
|
||||
}
|
||||
|
||||
|
||||
fog_nuke(transition_time)
|
||||
{
|
||||
if ( !isdefined( level.nuke_fog_setting ) )
|
||||
return;
|
||||
|
||||
ent = level.nuke_fog_setting;
|
||||
|
||||
SetExpFog(
|
||||
ent.startDist,
|
||||
ent.halfwayDist,
|
||||
ent.red,
|
||||
ent.green,
|
||||
ent.blue,
|
||||
ent.HDRColorIntensity,
|
||||
ent.maxOpacity,
|
||||
transition_time,
|
||||
ent.sunRed,
|
||||
ent.sunGreen,
|
||||
ent.sunBlue,
|
||||
ent.HDRSunColorIntensity,
|
||||
ent.sunDir,
|
||||
ent.sunBeginFadeAngle,
|
||||
ent.sunEndFadeAngle,
|
||||
ent.normalFogScale,
|
||||
ent.skyFogIntensity,
|
||||
ent.skyFogMinAngle,
|
||||
ent.skyFogMaxAngle );
|
||||
}
|
||||
|
||||
restore_fog( transition_time )
|
||||
{
|
||||
if ( !isdefined( level.restore_fog_setting ) )
|
||||
return;
|
||||
|
||||
ent = level.restore_fog_setting;
|
||||
|
||||
SetExpFog(
|
||||
ent.startDist,
|
||||
ent.halfwayDist,
|
||||
ent.red,
|
||||
ent.green,
|
||||
ent.blue,
|
||||
ent.HDRColorIntensity,
|
||||
ent.maxOpacity,
|
||||
transition_time,
|
||||
ent.sunRed,
|
||||
ent.sunGreen,
|
||||
ent.sunBlue,
|
||||
ent.HDRSunColorIntensity,
|
||||
ent.sunDir,
|
||||
ent.sunBeginFadeAngle,
|
||||
ent.sunEndFadeAngle,
|
||||
ent.normalFogScale,
|
||||
ent.skyFogIntensity,
|
||||
ent.skyFogMinAngle,
|
||||
ent.skyFogMaxAngle );
|
||||
}
|
||||
|
||||
nukeEarthquake()
|
||||
{
|
||||
level endon ( "nuke_cancelled" );
|
||||
|
||||
level waittill( "nuke_death" );
|
||||
|
||||
// TODO: need to get a different position to call this on
|
||||
//earthquake( 0.6, 10, nukepos, 100000 );
|
||||
|
||||
//foreach( player in level.players )
|
||||
//player PlayRumbleOnEntity( "damage_heavy" );
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
level waittill("connected", player);
|
||||
player thread onPlayerSpawned();
|
||||
}
|
||||
}
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
// make sure the vision set stays on between deaths
|
||||
if( IsDefined( level.nukeDetonated ) )
|
||||
self VisionSetNakedForPlayer( level.nukeVisionSet, 0 );
|
||||
}
|
||||
}
|
577
maps/mp/alien/_outline_proto.gsc
Normal file
577
maps/mp/alien/_outline_proto.gsc
Normal file
@ -0,0 +1,577 @@
|
||||
#include maps\mp\alien\_utility;
|
||||
#include common_scripts\utility;
|
||||
/*
|
||||
* Outline color index:
|
||||
* 0 - white
|
||||
* 1 - red
|
||||
* 2 - green
|
||||
* 3 - cyan
|
||||
* 4 - orange
|
||||
* 5 - yellow
|
||||
* 7 - magenta
|
||||
*/
|
||||
|
||||
CONST_MIN_PLAYER_OUTLINE_ENABLE_DIST_SQUARED = 2250000; // 1500 * 1500
|
||||
CONST_MAX_ITEM_OUTLINE_ENABLE_DIST_SQUARED = 122500; // 350 * 350
|
||||
CONST_MAX_PILLAGE_OUTLINE_ENABLE_DIST_SQUARED = 27225; // 165 * 165
|
||||
CONST_MAX_WEAPON_OUTLINE_ENABLE_DIST_SQUARED = 1000000; // 1000 * 1000
|
||||
CONST_MAX_DRILL_OUTLINE_ENABLE_DIST_SQUARED = 1000000; // 1000 * 1000
|
||||
PLAYER_COLOR_INDEX_BOOSTED_HEALTH = 0;
|
||||
PLAYER_COLOR_INDEX_GOOD_HEALTH = 3;
|
||||
PLAYER_COLOR_INDEX_OKAY_HEALTH = 5;
|
||||
PLAYER_COLOR_INDEX_BAD_HEALTH = 4;
|
||||
ITEM_COLOR_INDEX_ENOUGH_MONEY = 3;
|
||||
ITEM_COLOR_INDEX_NOT_ENOUGH_MONEY = 4;
|
||||
CONST_HEALTH_INVULNERABLE = 20000;
|
||||
CONST_OUTLINE_COLOR_RED = 4;
|
||||
CONST_OUTLINE_COLOR_GREEN = 3;
|
||||
CONST_OUTLINE_COLOR_NONE = 0;
|
||||
|
||||
outline_init()
|
||||
{
|
||||
level.outline_watch_list = [];
|
||||
level.outline_pillage_watch_list = [];
|
||||
level.outline_weapon_watch_list = [];
|
||||
level.outline_drill_watch_list = [];
|
||||
level.outline_hive_watch_list = [];
|
||||
level.outline_drill_preplant_watch_list = [];
|
||||
}
|
||||
|
||||
outline_monitor()
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
level endon ( "game_ended" );
|
||||
|
||||
self waittill ( "spawned" );
|
||||
self childthread outline_monitor_think();
|
||||
|
||||
}
|
||||
|
||||
outline_monitor_think()
|
||||
{
|
||||
|
||||
while ( true )
|
||||
{
|
||||
prof_begin( "outline_monitor" );
|
||||
|
||||
self player_outline();
|
||||
waitframe();
|
||||
self item_outline();
|
||||
waitframe();
|
||||
self item_outline_pillage();
|
||||
waitframe();
|
||||
self intel_outline();
|
||||
waitframe();
|
||||
self item_outline_weapon_monitor();
|
||||
waitframe();
|
||||
self item_outline_drill_monitor();
|
||||
waitframe();
|
||||
self hive_outline_monitor();
|
||||
waitframe();
|
||||
self drill_preplant_outline_monitor();
|
||||
waitframe();
|
||||
|
||||
prof_end( "outline_monitor" );
|
||||
}
|
||||
}
|
||||
|
||||
update_drill_outline()
|
||||
{
|
||||
level waittill_any_timeout( 1, "drill_spawned" );
|
||||
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
outline_color = player get_item_outline_color( level.drill );
|
||||
|
||||
if ( outline_color == CONST_OUTLINE_COLOR_GREEN || outline_color == CONST_OUTLINE_COLOR_RED )
|
||||
enable_outline_for_player( level.drill, player, outline_color, false, "high" );
|
||||
else
|
||||
disable_outline_for_player( level.drill, player );
|
||||
}
|
||||
}
|
||||
|
||||
player_outline()
|
||||
{
|
||||
self endon( "refresh_outline" );
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( self == player )
|
||||
continue;
|
||||
|
||||
if ( should_put_player_outline_on ( player ) )
|
||||
enable_outline_for_player( player, self, get_color_index_player ( player ), false, "high" );
|
||||
else
|
||||
disable_outline_for_player( player, self );
|
||||
}
|
||||
}
|
||||
|
||||
set_alien_outline()
|
||||
{
|
||||
self endon( "unset_adrenaline" );
|
||||
self endon( "switchblade_over" );
|
||||
self endon ( "disconnect" );
|
||||
self endon( "death" );
|
||||
level endon ( "game_ended" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
foreach ( alien in maps\mp\alien\_spawnlogic::get_alive_enemies() )
|
||||
{
|
||||
if(isdefined(level.kraken) && alien == level.kraken)
|
||||
continue;
|
||||
if(IsDefined(alien.agent_type) && alien.agent_type == "kraken_tentacle")
|
||||
continue;
|
||||
if ( isDefined( alien.damaged_by_players ) ) // this is set by a challenge that uses outlines, so don't mess with the outlines for these guys
|
||||
continue;
|
||||
|
||||
if ( isDefined( alien.marked_for_challenge ) ) // this is set by a challenge that uses outlines, so don't mess with the outlines for these guys
|
||||
continue;
|
||||
|
||||
if ( isDefined( alien.pet) )
|
||||
continue;
|
||||
else
|
||||
{
|
||||
if( !isdefined( alien.no_outline_on_alien ) )
|
||||
{
|
||||
if( IsDefined( alien.feral_occludes ) )
|
||||
{
|
||||
enable_outline_for_player( alien, self, 4, true, "high" );
|
||||
}
|
||||
else
|
||||
{
|
||||
enable_outline_for_player( alien, self, 4, false, "high" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
wait ( 0.5 );
|
||||
}
|
||||
}
|
||||
|
||||
unset_alien_outline()
|
||||
{
|
||||
foreach ( alien in maps\mp\alien\_spawnlogic::get_alive_enemies() )
|
||||
{
|
||||
if ( isDefined( alien.damaged_by_players ) ) // this is set by a challenge that uses outlines, so don't mess with the outlines for these guys
|
||||
continue;
|
||||
|
||||
if ( isDefined( alien.marked_for_challenge ) ) // this is set by a challenge that uses outlines, so don't mess with the outlines for these guys
|
||||
continue;
|
||||
|
||||
if ( !isDefined( alien.pet) )
|
||||
disable_outline_for_player( alien, self );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
hive_outline_monitor()
|
||||
{
|
||||
self endon( "refresh_outline" );
|
||||
foreach (index, item in level.outline_hive_watch_list )
|
||||
{
|
||||
enable_outline_for_player( item, self, 4, true, "medium" );
|
||||
if ( index%10 == 0 )
|
||||
waitframe();
|
||||
}
|
||||
}
|
||||
|
||||
drill_preplant_outline_monitor()
|
||||
{
|
||||
self endon( "refresh_outline" );
|
||||
foreach ( index, item in level.outline_drill_preplant_watch_list )
|
||||
{
|
||||
if ( !isdefined ( item ) )
|
||||
continue;
|
||||
|
||||
if( should_put_drill_outline_on ( item ) )
|
||||
enable_outline_for_player( item, self, 3, false, "high" );
|
||||
else
|
||||
disable_outline_for_player( item, self );
|
||||
|
||||
if( index%6 == 0 )
|
||||
waitframe();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
item_outline()
|
||||
{
|
||||
self endon( "refresh_outline" );
|
||||
foreach (index, item in level.outline_watch_list )
|
||||
{
|
||||
if ( !isDefined ( item ) )
|
||||
continue;
|
||||
|
||||
outline_color = get_item_outline_color( item );
|
||||
|
||||
if ( outline_color == CONST_OUTLINE_COLOR_GREEN )
|
||||
enable_outline_for_player( item, self, get_color_index_item ( item ), true, "low" );
|
||||
else if ( outline_color == CONST_OUTLINE_COLOR_RED ) //player is holding an item and cant' search this spot
|
||||
enable_outline_for_player( item, self, 4, true, "low" );
|
||||
else
|
||||
disable_outline_for_player( item, self );
|
||||
|
||||
if( index%6 == 0 )
|
||||
waitframe();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
item_outline_pillage()
|
||||
{
|
||||
self endon( "refresh_outline" );
|
||||
foreach (index, item in level.outline_pillage_watch_list )
|
||||
{
|
||||
if ( !isDefined ( item ) )
|
||||
continue;
|
||||
|
||||
outline_color = get_pillage_item_outline_color( item );
|
||||
|
||||
if ( outline_color == CONST_OUTLINE_COLOR_GREEN )
|
||||
enable_outline_for_player( item, self, 3, false, "low" );
|
||||
else if ( outline_color == CONST_OUTLINE_COLOR_RED ) //player is holding an item and cant' search this spot
|
||||
enable_outline_for_player( item, self, CONST_OUTLINE_COLOR_RED, false, "low" );
|
||||
else
|
||||
disable_outline_for_player( item, self );
|
||||
|
||||
if ( index%10 == 0 )
|
||||
waitframe();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
intel_outline()
|
||||
{
|
||||
if(IsDefined(level.intel_outline_func))
|
||||
[[level.intel_outline_func]]();
|
||||
|
||||
}
|
||||
|
||||
item_outline_weapon_monitor()
|
||||
{
|
||||
self endon( "refresh_outline" );
|
||||
foreach ( index, item in level.outline_weapon_watch_list )
|
||||
{
|
||||
if ( !isdefined ( item ) )
|
||||
continue;
|
||||
weapon_flag = true;
|
||||
outline_color = get_weapon_outline_color( item );
|
||||
|
||||
if ( outline_color == CONST_OUTLINE_COLOR_GREEN )
|
||||
enable_outline_for_player( item, self, get_color_index_item ( item, weapon_flag ), true, "low" );
|
||||
else if ( outline_color == CONST_OUTLINE_COLOR_RED ) //player is holding an item and cant' buy a weapon
|
||||
enable_outline_for_player( item, self, 4, true, "low" );
|
||||
else
|
||||
disable_outline_for_player( item, self );
|
||||
|
||||
if( index%6 == 0 )
|
||||
waitframe();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
item_outline_drill_monitor()
|
||||
{
|
||||
if( isDefined( level.item_outline_drill_monitor_override ) )
|
||||
{
|
||||
[[level.item_outline_drill_monitor_override]]();
|
||||
return;
|
||||
}
|
||||
self endon( "refresh_outline" );
|
||||
last_used_index = undefined;
|
||||
|
||||
foreach ( drill in level.outline_drill_watch_list )
|
||||
{
|
||||
ratio = ( level.drill.health - CONST_HEALTH_INVULNERABLE ) / (level.drill.maxhealth - CONST_HEALTH_INVULNERABLE );
|
||||
|
||||
if ( ratio < 0.75 )
|
||||
{
|
||||
if ( should_put_drill_outline_on( drill ) )
|
||||
enable_outline_for_player( drill, self, get_drill_widget_color ( drill ), false, "high" );
|
||||
else
|
||||
disable_outline_for_player( drill, self );
|
||||
}
|
||||
else
|
||||
disable_outline_for_player( drill, self );
|
||||
if ( isDefined( level.drill) && drill == level.drill )
|
||||
{
|
||||
index = get_drill_widget_color ( drill );
|
||||
|
||||
if ( isDefined ( last_used_index ) && last_used_index == index ) //don't spam the omnvar
|
||||
continue;
|
||||
last_used_index = index;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
get_drill_widget_color( drill )
|
||||
{
|
||||
ratio = ( level.drill.health - CONST_HEALTH_INVULNERABLE ) / (level.drill.maxhealth - CONST_HEALTH_INVULNERABLE );
|
||||
|
||||
if ( ratio <= 0.30 )
|
||||
return PLAYER_COLOR_INDEX_BAD_HEALTH;
|
||||
else if ( ratio <= 0.75 )
|
||||
return PLAYER_COLOR_INDEX_OKAY_HEALTH;
|
||||
else if ( ratio <= 1 )
|
||||
return PLAYER_COLOR_INDEX_GOOD_HEALTH;
|
||||
else
|
||||
return PLAYER_COLOR_INDEX_BOOSTED_HEALTH;
|
||||
}
|
||||
|
||||
get_color_index_item ( item, weapon_flag )
|
||||
{
|
||||
if ( self has_pistols_only_relic_and_no_deployables() && is_true( weapon_flag ) )
|
||||
cost = level.pistol_ammo_cost;
|
||||
else
|
||||
cost = item.cost;
|
||||
|
||||
if ( maps\mp\alien\_persistence::player_has_enough_currency( cost ) || is_true ( item.enabled ) )
|
||||
return ITEM_COLOR_INDEX_ENOUGH_MONEY;
|
||||
else
|
||||
return ITEM_COLOR_INDEX_NOT_ENOUGH_MONEY;
|
||||
}
|
||||
|
||||
get_color_index_player( player )
|
||||
{
|
||||
health_ratio = player.health / 100;
|
||||
|
||||
if ( health_ratio <= 0.33 || player.inlaststand )
|
||||
return PLAYER_COLOR_INDEX_BAD_HEALTH;
|
||||
else if ( health_ratio <= 0.66 )
|
||||
return PLAYER_COLOR_INDEX_OKAY_HEALTH;
|
||||
else if ( health_ratio <= 1.0 )
|
||||
return PLAYER_COLOR_INDEX_GOOD_HEALTH;
|
||||
else
|
||||
return PLAYER_COLOR_INDEX_BOOSTED_HEALTH;
|
||||
}
|
||||
|
||||
get_item_outline_color ( item )
|
||||
{
|
||||
if ( isDefined ( item.classname ) && item.classname == "misc_turret" && isDefined( item.owner ) )
|
||||
{
|
||||
return CONST_OUTLINE_COLOR_NONE;
|
||||
}
|
||||
|
||||
in_close_proximity = distanceSquared ( self.origin, item.origin ) < CONST_MAX_ITEM_OUTLINE_ENABLE_DIST_SQUARED;
|
||||
if ( !in_close_proximity )
|
||||
return CONST_OUTLINE_COLOR_NONE;
|
||||
|
||||
if ( self has_special_weapon() )
|
||||
{
|
||||
if( isDefined ( item.targetname ) && ( item.targetname == "fire_trap_barrel" || item.targetname == "puddle_generator" || item.targetname == "fence_generator" ) )
|
||||
return CONST_OUTLINE_COLOR_GREEN;
|
||||
else if ( isDefined ( item.classname ) && item.classname == "misc_turret" )
|
||||
return CONST_OUTLINE_COLOR_GREEN;
|
||||
else
|
||||
return CONST_OUTLINE_COLOR_RED;
|
||||
}
|
||||
else if ( self is_holding_deployable() )
|
||||
{
|
||||
return CONST_OUTLINE_COLOR_RED;
|
||||
}
|
||||
|
||||
return CONST_OUTLINE_COLOR_GREEN;
|
||||
}
|
||||
|
||||
|
||||
get_pillage_item_outline_color ( item )
|
||||
{
|
||||
if ( !isdefined( item ) )
|
||||
{
|
||||
return CONST_OUTLINE_COLOR_NONE;
|
||||
}
|
||||
|
||||
in_close_proximity = distanceSquared ( self.origin, item.origin ) < CONST_MAX_PILLAGE_OUTLINE_ENABLE_DIST_SQUARED;
|
||||
if ( !in_close_proximity )
|
||||
return CONST_OUTLINE_COLOR_NONE;
|
||||
|
||||
if(IsDefined(item.is_locker) && item.is_locker && !IsDefined(self.locker_key))
|
||||
return CONST_OUTLINE_COLOR_NONE;
|
||||
|
||||
if ( self is_holding_deployable() || self has_special_weapon() )
|
||||
{
|
||||
return CONST_OUTLINE_COLOR_RED;
|
||||
}
|
||||
|
||||
return CONST_OUTLINE_COLOR_GREEN;
|
||||
}
|
||||
|
||||
get_weapon_outline_color ( item )
|
||||
{
|
||||
in_close_proximity = distanceSquared ( self.origin, item.origin ) < CONST_MAX_WEAPON_OUTLINE_ENABLE_DIST_SQUARED;
|
||||
if ( !in_close_proximity )
|
||||
return CONST_OUTLINE_COLOR_NONE;
|
||||
|
||||
if ( is_chaos_mode() && maps\mp\alien\_chaos::is_weapon_recently_picked_up( self, item.weapon_ref ) )
|
||||
return CONST_OUTLINE_COLOR_RED;
|
||||
|
||||
if( self is_holding_deployable() )
|
||||
{
|
||||
return CONST_OUTLINE_COLOR_RED;
|
||||
}
|
||||
|
||||
if ( !is_true ( item.is_recipe_table) && self maps\mp\alien\_prestige::prestige_getPistolsOnly() == 1 && !self maps\mp\alien\_prestige::prestige_getNoDeployables() == 1 )
|
||||
{
|
||||
return CONST_OUTLINE_COLOR_RED;
|
||||
}
|
||||
|
||||
if ( isDefined( level.get_custom_weapon_outline_func ) && [[ level.get_custom_weapon_outline_func ]]( item ) )
|
||||
{
|
||||
return CONST_OUTLINE_COLOR_RED;
|
||||
}
|
||||
|
||||
if ( self has_special_weapon() && !is_true ( item.is_recipe_table ))
|
||||
{
|
||||
if( isDefined ( level.drill) && item == level.drill )
|
||||
return CONST_OUTLINE_COLOR_GREEN;
|
||||
else
|
||||
return CONST_OUTLINE_COLOR_RED;
|
||||
}
|
||||
|
||||
return CONST_OUTLINE_COLOR_GREEN;
|
||||
}
|
||||
|
||||
should_put_drill_outline_on ( item )
|
||||
{
|
||||
in_close_proximity = distanceSquared ( self.origin, item.origin ) < CONST_MAX_WEAPON_OUTLINE_ENABLE_DIST_SQUARED;
|
||||
if ( !in_close_proximity )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
should_put_player_outline_on ( player )
|
||||
{
|
||||
if ( !isAlive ( player ) || !isDefined ( player.maxhealth ) || !player.maxhealth )
|
||||
return false;
|
||||
|
||||
not_close_proximity = distanceSquared ( self.origin, player.origin ) > CONST_MIN_PLAYER_OUTLINE_ENABLE_DIST_SQUARED;
|
||||
if ( not_close_proximity )
|
||||
return true;
|
||||
|
||||
not_in_LOS = !BulletTracePassed ( self getEye(), player getEye(), false, self );
|
||||
return ( not_in_LOS );
|
||||
}
|
||||
|
||||
add_to_outline_watch_list ( item, cost )
|
||||
{
|
||||
item.cost = cost;
|
||||
level.outline_watch_list [ level.outline_watch_list.size ] = item;
|
||||
}
|
||||
|
||||
remove_from_outline_watch_list ( item )
|
||||
{
|
||||
level.outline_watch_list = common_scripts\utility::array_remove( level.outline_watch_list, item );
|
||||
thread remove_outline( item );
|
||||
}
|
||||
|
||||
add_to_drill_preplant_watch_list ( item )
|
||||
{
|
||||
level.outline_drill_preplant_watch_list [ level.outline_drill_preplant_watch_list.size ] = item;
|
||||
}
|
||||
|
||||
remove_from_drill_preplant_watch_list ( item )
|
||||
{
|
||||
level.outline_drill_preplant_watch_list = common_scripts\utility::array_remove( level.outline_drill_preplant_watch_list, item );
|
||||
thread remove_outline( item );
|
||||
}
|
||||
|
||||
|
||||
add_to_outline_hive_watch_list ( item )
|
||||
{
|
||||
level.outline_hive_watch_list [ level.outline_hive_watch_list.size ] = item;
|
||||
}
|
||||
|
||||
remove_from_outline_hive_watch_list ( item )
|
||||
{
|
||||
level.outline_hive_watch_list = common_scripts\utility::array_remove( level.outline_hive_watch_list, item );
|
||||
thread remove_outline( item );
|
||||
}
|
||||
|
||||
add_to_outline_pillage_watch_list ( item, cost )
|
||||
{
|
||||
if ( !array_contains(level.outline_pillage_watch_list, item ) )
|
||||
{
|
||||
item.cost = cost;
|
||||
level.outline_pillage_watch_list [ level.outline_pillage_watch_list.size ] = item;
|
||||
}
|
||||
}
|
||||
|
||||
remove_from_outline_pillage_watch_list ( item )
|
||||
{
|
||||
level.outline_pillage_watch_list = common_scripts\utility::array_remove( level.outline_pillage_watch_list, item );
|
||||
thread remove_outline( item );
|
||||
}
|
||||
|
||||
add_to_outline_weapon_watch_list ( item, cost )
|
||||
{
|
||||
item.cost = cost;
|
||||
level.outline_weapon_watch_list [ level.outline_weapon_watch_list.size ] = item;
|
||||
|
||||
}
|
||||
|
||||
remove_from_outline_weapon_watch_list ( item )
|
||||
{
|
||||
level.outline_weapon_watch_list = common_scripts\utility::array_remove( level.outline_weapon_watch_list, item );
|
||||
thread remove_outline( item );
|
||||
}
|
||||
|
||||
add_to_outline_drill_watch_list ( item, cost )
|
||||
{
|
||||
item.cost = cost;
|
||||
level.outline_drill_watch_list [ level.outline_drill_watch_list.size ] = item;
|
||||
}
|
||||
|
||||
remove_from_outline_drill_watch_list ( item )
|
||||
{
|
||||
level.outline_drill_watch_list = common_scripts\utility::array_remove( level.outline_drill_watch_list, item );
|
||||
thread remove_outline( item );
|
||||
}
|
||||
|
||||
remove_outline( item )
|
||||
{
|
||||
if ( !isdefined( item ) )
|
||||
return;
|
||||
|
||||
foreach( player in level.players )
|
||||
{
|
||||
if ( isdefined( player ) )
|
||||
{
|
||||
player notify( "refresh_outline" );
|
||||
disable_outline_for_player( item, player );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enable_outline_for_players( item, players, color_index, depth_enable, priority )
|
||||
{
|
||||
item HudOutlineEnableForClients( players, color_index, depth_enable );
|
||||
}
|
||||
|
||||
enable_outline_for_player( item, player, color_index, depth_enable, priority )
|
||||
{
|
||||
item HudOutlineEnableForClient( player, color_index, depth_enable );
|
||||
}
|
||||
|
||||
disable_outline_for_players( item, players )
|
||||
{
|
||||
item HudOutlineDisableForClients( players );
|
||||
}
|
||||
|
||||
disable_outline_for_player( item, player )
|
||||
{
|
||||
item HudOutlineDisableForClient( player );
|
||||
}
|
||||
|
||||
enable_outline( item, color_index, depth_enable )
|
||||
{
|
||||
item HudOutlineEnable( color_index, depth_enable );
|
||||
}
|
||||
|
||||
disable_outline( item )
|
||||
{
|
||||
item HudOutlineDisable();
|
||||
}
|
||||
|
||||
outline_proto_enabled() { return ( GetDvarInt ( "enable_outline_proto" ) == 1 ); }
|
||||
is_host( player ) { return player isHost(); }
|
95
maps/mp/alien/_perk_utility.gsc
Normal file
95
maps/mp/alien/_perk_utility.gsc
Normal file
@ -0,0 +1,95 @@
|
||||
#include maps\mp\alien\_perkfunctions;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// This file contains perk interface function for other components of the game mode //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
init_each_perk()
|
||||
{
|
||||
self.perk_data = [];
|
||||
|
||||
self.perk_data[ "health" ] = init_perk_health();
|
||||
self.perk_data[ "damagemod" ] = init_perk_bullet_damage();
|
||||
self.perk_data[ "medic" ] = init_perk_medic();
|
||||
self.perk_data[ "rigger" ] = init_perk_rigger();
|
||||
self.perk_data[ "pistol" ] = init_perk_pistol();
|
||||
self.perk_data[ "none" ] = init_perk_none();
|
||||
}
|
||||
|
||||
// === perk_health ===
|
||||
perk_GetMeleeScalar() { return self.perk_data[ "health" ].melee_scalar; }
|
||||
perk_GetMaxHealth() { return self.perk_data[ "health" ].max_health; }
|
||||
|
||||
// === perk_bullet_damage ===
|
||||
perk_GetBulletDamageScalar() { return self.perk_data[ "damagemod" ].bullet_damage_scalar; }
|
||||
|
||||
// === perk_medic ===
|
||||
perk_GetReviveTimeScalar() { return self.perk_data[ "medic" ].revive_time_scalar; }
|
||||
perk_GetGasDamageScalar() { return self.perk_data[ "medic" ].gas_damage_scalar; }
|
||||
perk_GetMoveSpeedScalar() { return self.perk_data[ "medic" ].move_speed_scalar; }
|
||||
perk_GetReviveDamageScalar() { return self.perk_data[ "medic" ].revive_damage_scalar; }
|
||||
|
||||
// === perk_rigger ===
|
||||
perk_GetDrillHealthScalar() { return self.perk_data[ "rigger" ].drill_health_scalar; }
|
||||
perk_GetDrillTimeScalar() { return self.perk_data[ "rigger" ].drill_time_scalar; }
|
||||
perk_GetTrapCostScalar() { return self.perk_data[ "rigger" ].trap_cost_scalar; }
|
||||
perk_GetTrapDamageScalar() { return self.perk_data[ "rigger" ].trap_damage_scalar; }
|
||||
perk_GetTrapDurationScalar() { return self.perk_data[ "rigger" ].trap_duration_scalar; }
|
||||
perk_GetCurrencyScalePerHive() { return self.perk_data[ "rigger" ].currency_scale_per_hive; }
|
||||
perk_GetExplosiveDamageScalar() { return self.perk_data[ "rigger" ].explosive_damage_scalar; }
|
||||
perk_GetRepairDamageScalar() { return self.perk_data[ "rigger" ].repair_damage_scalar; }
|
||||
|
||||
// === perk_pistol ===
|
||||
perk_GetPistolRegen() { return self.perk_data[ "pistol" ].pistol_regen; }
|
||||
perk_GetPistolOverkill() { return self.perk_data[ "pistol" ].pistol_overkill; }
|
||||
|
||||
/*
|
||||
=============
|
||||
///ScriptDocBegin
|
||||
"Name: has_perk( <required> perk name, <optional> perk level list )"
|
||||
"Summary: Returns true if the player has the specified perk (at one of the specified level) at either Perk 0 slot or Perk 1 slot"
|
||||
"Module: Alien"
|
||||
"Example: if ( player has_perk( "perk_medic", [3, 4] )"
|
||||
"SPMP: multiplayer"
|
||||
///ScriptDocEnd
|
||||
=============
|
||||
*/
|
||||
has_perk( perk_name, perk_level_list )
|
||||
{
|
||||
AssertEx( is_valid_perk( perk_name ), perk_name + " is not a valid perk." );
|
||||
|
||||
selected_perk_0 = maps\mp\alien\_persistence::get_selected_perk_0();
|
||||
perk_0_level = maps\mp\alien\_persistence::get_perk_0_level();
|
||||
|
||||
selected_perk_1 = maps\mp\alien\_persistence::get_selected_perk_1();
|
||||
perk_1_level = maps\mp\alien\_persistence::get_perk_1_level();
|
||||
|
||||
selected_perk_0_secondary = "perk_none";
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "multi_class" ))
|
||||
{
|
||||
selected_perk_0_secondary = maps\mp\alien\_persistence::get_selected_perk_0_secondary();
|
||||
}
|
||||
|
||||
if ( !isDefined( perk_level_list ) )
|
||||
{
|
||||
return ( perk_name == selected_perk_0 || perk_name == selected_perk_1 || perk_name == selected_perk_0_secondary );
|
||||
}
|
||||
else
|
||||
{
|
||||
is_selected_perk_0_at_level = ( perk_name == selected_perk_0 && common_scripts\utility::array_contains( perk_level_list, perk_0_level ) );
|
||||
is_selected_perk_1_at_level = ( perk_name == selected_perk_1 && common_scripts\utility::array_contains( perk_level_list, perk_1_level ) );
|
||||
is_selected_perk_0_secondary_at_level = ( perk_name == selected_perk_0_secondary && common_scripts\utility::array_contains( perk_level_list, perk_0_level ) );
|
||||
return ( is_selected_perk_0_at_level || is_selected_perk_1_at_level || is_selected_perk_0_secondary_at_level );
|
||||
}
|
||||
}
|
||||
|
||||
is_valid_perk( perk_name )
|
||||
{
|
||||
perk_0_list = GetArrayKeys( level.alien_perks["perk_0"] );
|
||||
|
||||
if ( common_scripts\utility::array_contains( perk_0_list, perk_name ) )
|
||||
return true;
|
||||
|
||||
perk_1_list = GetArrayKeys( level.alien_perks["perk_1"] );
|
||||
return common_scripts\utility::array_contains( perk_1_list, perk_name );
|
||||
}
|
963
maps/mp/alien/_perkfunctions.gsc
Normal file
963
maps/mp/alien/_perkfunctions.gsc
Normal file
@ -0,0 +1,963 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\alien\_utility;
|
||||
#include maps\mp\alien\_perk_utility;
|
||||
|
||||
init_perk_none()
|
||||
{
|
||||
perk_data = spawnStruct();
|
||||
return perk_data;
|
||||
}
|
||||
|
||||
|
||||
set_perk_none()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
unset_perk_none()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
/// Tank Perks ///
|
||||
////////////////////////////////////////
|
||||
|
||||
DEFAULT_MAX_HEALTH = 100;
|
||||
LEVEL_0_MAX_HEALTH = 125;
|
||||
LEVEL_1_MAX_HEALTH = 125;
|
||||
LEVEL_2_MAX_HEALTH = 150;
|
||||
LEVEL_3_MAX_HEALTH = 175;
|
||||
LEVEL_4_MAX_HEALTH = 200;
|
||||
|
||||
DEFAULT_MELEE_SCALAR = 1.0;
|
||||
LEVEL_1_MELEE_SCALAR = 1.25;
|
||||
LEVEL_3_MELEE_SCALAR = 1.5;
|
||||
LEVEL_4_MELEE_SCALAR = 2.0;
|
||||
|
||||
init_perk_health()
|
||||
{
|
||||
perk_data = spawnStruct();
|
||||
|
||||
perk_data.melee_scalar = DEFAULT_MELEE_SCALAR;
|
||||
|
||||
return perk_data;
|
||||
}
|
||||
|
||||
set_perk_health_level_0()
|
||||
{
|
||||
self.perk_data[ "health" ].max_health = LEVEL_0_MAX_HEALTH;
|
||||
self.perk_data[ "health" ].melee_scalar = DEFAULT_MELEE_SCALAR;
|
||||
}
|
||||
|
||||
unset_perk_health_level_0()
|
||||
{
|
||||
self.perk_data[ "health" ].melee_scalar = DEFAULT_MELEE_SCALAR;
|
||||
}
|
||||
|
||||
set_perk_health_level_1()
|
||||
{
|
||||
self.perk_data[ "health" ].max_health = LEVEL_1_MAX_HEALTH;
|
||||
self.maxhealth = self.perk_data[ "health" ].max_health;
|
||||
self notify( "health_perk_upgrade" );
|
||||
self.perk_data[ "health" ].melee_scalar = LEVEL_1_MELEE_SCALAR;
|
||||
}
|
||||
|
||||
unset_perk_health_level_1()
|
||||
{
|
||||
self.perk_data[ "health" ].melee_scalar = DEFAULT_MELEE_SCALAR;
|
||||
}
|
||||
|
||||
set_perk_health_level_2()
|
||||
{
|
||||
self.perk_data[ "health" ].max_health = LEVEL_2_MAX_HEALTH;
|
||||
self.maxhealth = self.perk_data[ "health" ].max_health;
|
||||
self notify( "health_perk_upgrade" );
|
||||
self.perk_data[ "health" ].melee_scalar = LEVEL_1_MELEE_SCALAR;
|
||||
}
|
||||
|
||||
unset_perk_health_level_2()
|
||||
{
|
||||
self.perk_data[ "health" ].melee_scalar = DEFAULT_MELEE_SCALAR;
|
||||
}
|
||||
|
||||
set_perk_health_level_3()
|
||||
{
|
||||
self.perk_data[ "health" ].max_health = LEVEL_3_MAX_HEALTH;
|
||||
self.maxhealth = self.perk_data[ "health" ].max_health;
|
||||
self notify( "health_perk_upgrade" );
|
||||
self.perk_data[ "health" ].melee_scalar = LEVEL_3_MELEE_SCALAR;
|
||||
}
|
||||
|
||||
unset_perk_health_level_3()
|
||||
{
|
||||
self.perk_data[ "health" ].melee_scalar = DEFAULT_MELEE_SCALAR;
|
||||
}
|
||||
|
||||
set_perk_health_level_4()
|
||||
{
|
||||
self.perk_data[ "health" ].max_health = LEVEL_4_MAX_HEALTH;
|
||||
self.maxhealth = self.perk_data[ "health" ].max_health;
|
||||
self notify( "health_perk_upgrade" );
|
||||
self.perk_data[ "health" ].melee_scalar = LEVEL_4_MELEE_SCALAR;
|
||||
}
|
||||
|
||||
unset_perk_health_level_4()
|
||||
{
|
||||
self.perk_data[ "health" ].melee_scalar = DEFAULT_MELEE_SCALAR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
/// Weapon Specialist Perks ///
|
||||
//////////////////////////////////////
|
||||
|
||||
DEFAULT_BULLET_DAMAGE_SCALAR = 1.0;
|
||||
LEVEL_0_BULLET_DAMAGE_SCALAR = 1.2;
|
||||
|
||||
LEVEL_2_BULLET_DAMAGE_SCALAR = 1.3;
|
||||
LEVEL_3_BULLET_DAMAGE_SCALAR = 1.4;
|
||||
LEVEL_4_BULLET_DAMAGE_SCALAR = 1.5;
|
||||
|
||||
|
||||
init_perk_bullet_damage()
|
||||
{
|
||||
perk_data = spawnStruct();
|
||||
|
||||
perk_data.bullet_damage_scalar = DEFAULT_BULLET_DAMAGE_SCALAR;
|
||||
|
||||
return perk_data;
|
||||
}
|
||||
|
||||
set_perk_bullet_damage_0()
|
||||
{
|
||||
self.perk_data[ "damagemod" ].bullet_damage_scalar = LEVEL_0_BULLET_DAMAGE_SCALAR;
|
||||
}
|
||||
|
||||
unset_perk_bullet_damage_0()
|
||||
{
|
||||
self.perk_data[ "damagemod" ].bullet_damage_scalar = DEFAULT_BULLET_DAMAGE_SCALAR;
|
||||
}
|
||||
|
||||
set_perk_bullet_damage_1()
|
||||
{
|
||||
self.perk_data[ "damagemod" ].bullet_damage_scalar = LEVEL_0_BULLET_DAMAGE_SCALAR;
|
||||
self givePerk( "specialty_quickswap", false );
|
||||
self givePerk( "specialty_stalker", false );
|
||||
self givePerk( "specialty_fastoffhand", false );
|
||||
}
|
||||
|
||||
unset_perk_bullet_damage_1()
|
||||
{
|
||||
self.perk_data[ "damagemod" ].bullet_damage_scalar = DEFAULT_BULLET_DAMAGE_SCALAR;
|
||||
self _unsetPerk( "specialty_quickswap" );
|
||||
self _unsetPerk( "specialty_stalker" );
|
||||
self _unsetPerk( "specialty_fastoffhand" );
|
||||
}
|
||||
|
||||
set_perk_bullet_damage_2()
|
||||
{
|
||||
self.perk_data[ "damagemod" ].bullet_damage_scalar = LEVEL_0_BULLET_DAMAGE_SCALAR;
|
||||
self givePerk( "specialty_quickswap", false );
|
||||
self givePerk( "specialty_stalker", false );
|
||||
self givePerk( "specialty_fastoffhand", false );
|
||||
self givePerk( "specialty_quickdraw", false );
|
||||
}
|
||||
|
||||
unset_perk_bullet_damage_2()
|
||||
{
|
||||
self.perk_data[ "damagemod" ].bullet_damage_scalar = DEFAULT_BULLET_DAMAGE_SCALAR;
|
||||
self _unsetPerk( "specialty_quickswap" );
|
||||
self _unsetPerk( "specialty_stalker" );
|
||||
self _unsetPerk( "specialty_fastoffhand" );
|
||||
self _unsetPerk( "specialty_quickdraw" );
|
||||
}
|
||||
|
||||
set_perk_bullet_damage_3()
|
||||
{
|
||||
self.perk_data[ "damagemod" ].bullet_damage_scalar = LEVEL_0_BULLET_DAMAGE_SCALAR;
|
||||
self givePerk( "specialty_quickswap", false );
|
||||
self givePerk( "specialty_stalker", false );
|
||||
self givePerk( "specialty_fastoffhand", false );
|
||||
self givePerk( "specialty_quickdraw", false );
|
||||
self givePerk( "specialty_fastreload", false );
|
||||
}
|
||||
|
||||
unset_perk_bullet_damage_3()
|
||||
{
|
||||
self.perk_data[ "damagemod" ].bullet_damage_scalar = DEFAULT_BULLET_DAMAGE_SCALAR;
|
||||
self _unsetPerk( "specialty_quickswap" );
|
||||
self _unsetPerk( "specialty_stalker" );
|
||||
self _unsetPerk( "specialty_fastoffhand" );
|
||||
self _unsetPerk( "specialty_quickdraw" );
|
||||
self givePerk( "specialty_fastreload", false );
|
||||
}
|
||||
|
||||
set_perk_bullet_damage_4()
|
||||
{
|
||||
self.perk_data[ "damagemod" ].bullet_damage_scalar = LEVEL_4_BULLET_DAMAGE_SCALAR;
|
||||
self givePerk( "specialty_quickswap", false );
|
||||
self givePerk( "specialty_stalker", false );
|
||||
self givePerk( "specialty_fastoffhand", false );
|
||||
self givePerk( "specialty_quickdraw", false );
|
||||
self setaimspreadmovementscale( 0.5 );
|
||||
|
||||
self givePerk( "specialty_fastreload", false );
|
||||
}
|
||||
|
||||
unset_perk_bullet_damage_4()
|
||||
{
|
||||
self.perk_data[ "damagemod" ].bullet_damage_scalar = DEFAULT_BULLET_DAMAGE_SCALAR;
|
||||
self _unsetPerk( "specialty_quickswap" );
|
||||
self _unsetPerk( "specialty_stalker" );
|
||||
self _unsetPerk( "specialty_fastoffhand" );
|
||||
self _unsetPerk( "specialty_quickdraw" );
|
||||
self setaimspreadmovementscale( 1.0 );
|
||||
|
||||
self _unsetPerk( "specialty_fastreload" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
/// perk_medic ///
|
||||
////////////////////////////////////////
|
||||
|
||||
DEFAULT_GAS_DAMAGE_SCALAR = 1.0;
|
||||
LEVEL_1_MEDIC_GAS_DAMAGE_SCALAR = 0.0;
|
||||
|
||||
DEFAULT_REVIVE_TIME_SCALAR = 1.0;
|
||||
LEVEL_0_MEDIC_REVIVE_TIME_SCALAR = 1.5;
|
||||
LEVEL_2_MEDIC_REGEN_RATE = 5.0; // 5 points per second to nearby allies
|
||||
LEVEL_2_MEDIC_HEALTH_REGEN_DIST_SQR = 65536.0; // 256.0 * 256.0
|
||||
|
||||
LEVEL_4_MEDIC_HEALTH_REGEN_DIST_SQR = 0.0; // Infinite distance
|
||||
|
||||
DEFAULT_MOVE_SPEED_SCALAR = 1.0;
|
||||
LEVEL_2_MOVE_SPEED_SCALAR = 1.06;
|
||||
LEVEL_4_MOVE_SPEED_SCALAR = 1.12;
|
||||
|
||||
DEFAULT_REVIVE_DAMAGE_SCALAR = 1.0;
|
||||
LEVEL_3_REVIVE_DAMAGE_SCALAR = 0.75;
|
||||
|
||||
init_perk_medic()
|
||||
{
|
||||
perk_data = spawnStruct();
|
||||
|
||||
perk_data.revive_time_scalar = DEFAULT_REVIVE_TIME_SCALAR;
|
||||
perk_data.gas_damage_scalar = DEFAULT_GAS_DAMAGE_SCALAR;
|
||||
perk_data.move_speed_scalar = DEFAULT_MOVE_SPEED_SCALAR;
|
||||
perk_data.revive_damage_scalar = DEFAULT_REVIVE_DAMAGE_SCALAR;
|
||||
|
||||
return perk_data;
|
||||
}
|
||||
|
||||
set_perk_medic_0()
|
||||
{
|
||||
self.perk_data[ "medic" ].revive_time_scalar = LEVEL_0_MEDIC_REVIVE_TIME_SCALAR;
|
||||
self.moveSpeedScaler = self maps\mp\alien\_prestige::prestige_getMoveSlowScalar();
|
||||
self.perk_data[ "medic" ].move_speed_scalar = self.moveSpeedScaler;
|
||||
}
|
||||
|
||||
unset_perk_medic_0()
|
||||
{
|
||||
self.perk_data[ "medic" ].revive_time_scalar = DEFAULT_REVIVE_TIME_SCALAR;
|
||||
self.moveSpeedScaler = DEFAULT_MOVE_SPEED_SCALAR * self maps\mp\alien\_prestige::prestige_getMoveSlowScalar();
|
||||
self.perk_data[ "medic" ].move_speed_scalar = self.moveSpeedScaler;
|
||||
|
||||
}
|
||||
|
||||
set_perk_medic_1()
|
||||
{
|
||||
self.perk_data[ "medic" ].revive_time_scalar = LEVEL_0_MEDIC_REVIVE_TIME_SCALAR;
|
||||
self.moveSpeedScaler = LEVEL_2_MOVE_SPEED_SCALAR * self maps\mp\alien\_prestige::prestige_getMoveSlowScalar();
|
||||
self.perk_data[ "medic" ].move_speed_scalar = self.moveSpeedScaler;
|
||||
self.perk_data[ "medic" ].revive_damage_scalar = LEVEL_3_REVIVE_DAMAGE_SCALAR;
|
||||
}
|
||||
|
||||
unset_perk_medic_1()
|
||||
{
|
||||
self.perk_data[ "medic" ].revive_time_scalar = DEFAULT_REVIVE_TIME_SCALAR;
|
||||
self.moveSpeedScaler = DEFAULT_MOVE_SPEED_SCALAR * self maps\mp\alien\_prestige::prestige_getMoveSlowScalar();
|
||||
self.perk_data[ "medic" ].move_speed_scalar = self.moveSpeedScaler;
|
||||
self.perk_data[ "medic" ].revive_damage_scalar = DEFAULT_REVIVE_DAMAGE_SCALAR;
|
||||
|
||||
}
|
||||
|
||||
set_perk_medic_2()
|
||||
{
|
||||
self givePerk( "specialty_longersprint", false );
|
||||
self thread medic_health_regen( LEVEL_2_MEDIC_HEALTH_REGEN_DIST_SQR );
|
||||
self.perk_data[ "medic" ].revive_time_scalar = LEVEL_0_MEDIC_REVIVE_TIME_SCALAR;
|
||||
self.moveSpeedScaler = LEVEL_2_MOVE_SPEED_SCALAR * self maps\mp\alien\_prestige::prestige_getMoveSlowScalar();
|
||||
self.perk_data[ "medic" ].move_speed_scalar = self.moveSpeedScaler;
|
||||
self.perk_data[ "medic" ].revive_damage_scalar = LEVEL_3_REVIVE_DAMAGE_SCALAR;
|
||||
}
|
||||
|
||||
unset_perk_medic_2()
|
||||
{
|
||||
self _unsetPerk( "specialty_longersprint" );
|
||||
self notify( "end_medic_health_regen" );
|
||||
self.perk_data[ "medic" ].revive_time_scalar = DEFAULT_REVIVE_TIME_SCALAR;
|
||||
self.moveSpeedScaler = DEFAULT_MOVE_SPEED_SCALAR * self maps\mp\alien\_prestige::prestige_getMoveSlowScalar();
|
||||
self.perk_data[ "medic" ].move_speed_scalar = self.moveSpeedScaler;
|
||||
self.perk_data[ "medic" ].revive_damage_scalar = DEFAULT_REVIVE_DAMAGE_SCALAR;
|
||||
|
||||
}
|
||||
|
||||
set_perk_medic_3()
|
||||
{
|
||||
|
||||
self.perk_data[ "medic" ].gas_damage_scalar = LEVEL_1_MEDIC_GAS_DAMAGE_SCALAR;
|
||||
self givePerk( "specialty_longersprint", false );
|
||||
self thread medic_health_regen( LEVEL_2_MEDIC_HEALTH_REGEN_DIST_SQR );
|
||||
self.perk_data[ "medic" ].revive_time_scalar = LEVEL_0_MEDIC_REVIVE_TIME_SCALAR;
|
||||
self.moveSpeedScaler = LEVEL_2_MOVE_SPEED_SCALAR * self maps\mp\alien\_prestige::prestige_getMoveSlowScalar();
|
||||
self.perk_data[ "medic" ].move_speed_scalar = self.moveSpeedScaler;
|
||||
self.perk_data[ "medic" ].revive_damage_scalar = LEVEL_3_REVIVE_DAMAGE_SCALAR;
|
||||
|
||||
}
|
||||
|
||||
unset_perk_medic_3()
|
||||
{
|
||||
|
||||
self.perk_data[ "medic" ].gas_damage_scalar = DEFAULT_GAS_DAMAGE_SCALAR;
|
||||
self _unsetPerk( "specialty_longersprint" );
|
||||
self notify( "end_medic_health_regen" );
|
||||
self.perk_data[ "medic" ].revive_time_scalar = DEFAULT_REVIVE_TIME_SCALAR;
|
||||
self.moveSpeedScaler = DEFAULT_MOVE_SPEED_SCALAR * self maps\mp\alien\_prestige::prestige_getMoveSlowScalar();
|
||||
self.perk_data[ "medic" ].move_speed_scalar = self.moveSpeedScaler;
|
||||
self.perk_data[ "medic" ].revive_damage_scalar = DEFAULT_REVIVE_DAMAGE_SCALAR;
|
||||
|
||||
}
|
||||
|
||||
set_perk_medic_4()
|
||||
{
|
||||
self.perk_data[ "medic" ].revive_time_scalar = LEVEL_0_MEDIC_REVIVE_TIME_SCALAR;
|
||||
self.perk_data[ "medic" ].gas_damage_scalar = LEVEL_1_MEDIC_GAS_DAMAGE_SCALAR;
|
||||
self thread medic_health_regen( LEVEL_4_MEDIC_HEALTH_REGEN_DIST_SQR );
|
||||
self.moveSpeedScaler = LEVEL_4_MOVE_SPEED_SCALAR * self maps\mp\alien\_prestige::prestige_getMoveSlowScalar();
|
||||
self.perk_data[ "medic" ].move_speed_scalar = self.moveSpeedScaler;
|
||||
self givePerk( "specialty_longersprint", false );
|
||||
self givePerk( "specialty_fastsprintrecovery", false );
|
||||
self.perk_data[ "medic" ].revive_damage_scalar = LEVEL_3_REVIVE_DAMAGE_SCALAR;
|
||||
}
|
||||
|
||||
unset_perk_medic_4()
|
||||
{
|
||||
self.perk_data[ "medic" ].revive_time_scalar = DEFAULT_REVIVE_TIME_SCALAR;
|
||||
self.perk_data[ "medic" ].gas_damage_scalar = DEFAULT_GAS_DAMAGE_SCALAR;
|
||||
self notify( "end_medic_health_regen" );
|
||||
self.moveSpeedScaler = DEFAULT_MOVE_SPEED_SCALAR * self maps\mp\alien\_prestige::prestige_getMoveSlowScalar();
|
||||
self.perk_data[ "medic" ].move_speed_scalar = self.moveSpeedScaler;
|
||||
self _unsetPerk( "specialty_longersprint" );
|
||||
self _unsetPerk( "specialty_fastsprintrecovery" );
|
||||
self.perk_data[ "medic" ].revive_damage_scalar = DEFAULT_REVIVE_DAMAGE_SCALAR;
|
||||
}
|
||||
|
||||
medic_health_regen( dist_sqr )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "end_medic_health_regen" );
|
||||
do_dist_check = dist_sqr > 0.0;
|
||||
while ( 1 )
|
||||
{
|
||||
foreach ( player in level.players ) // Includes self
|
||||
{
|
||||
if ( isReallyAlive( player )
|
||||
&& !isDefined( player.medic_regeneration ) )
|
||||
{
|
||||
if ( do_dist_check && DistanceSquared( self.origin, player.origin ) > dist_sqr )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
player thread medic_regenerate_health_once();
|
||||
}
|
||||
}
|
||||
wait 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
medic_regenerate_health_once()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
if ( !self has_fragile_relic_and_is_sprinting() )
|
||||
{
|
||||
self.medic_regeneration = true;
|
||||
wait 1.0;
|
||||
self.health = int( min( self.maxhealth, self.health + LEVEL_2_MEDIC_REGEN_RATE ) );
|
||||
self.medic_regeneration = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
/// Engineer Perks ///
|
||||
////////////////////////////////////////
|
||||
|
||||
DEFAULT_DRILL_HEALTH_SCALAR = 1.0;
|
||||
LEVEL_0_DRILL_HEALTH_SCALAR = 1.256;
|
||||
DEFAULT_DRILL_TIME_SCALAR = 1.0;
|
||||
LEVEL_1_DRILL_TIME_SCALAR = 0.5;
|
||||
DEFAULT_TRAP_COST_SCALAR = 1;
|
||||
LEVEL_2_TRAP_COST_SCALAR = 0.8;
|
||||
DEFAULT_TRAP_DURATION_SCALAR = 1;
|
||||
LEVEL_3_TRAP_DURATION_SCALAR = 1.5;
|
||||
DEFAULT_TRAP_DAMAGE_SCALAR = 1;
|
||||
LEVEL_4_TRAP_DAMAGE_SCALAR = 2;
|
||||
DEFAULT_MONEY_SCALE_PER_HIVE = 1.0;
|
||||
LEVEL_0_MONEY_SCALE_PER_HIVE = 1.2;
|
||||
DEFAULT_WALLET_SIZE = 6000;
|
||||
LEVEL_4_WALLET_SIZE = 8000;
|
||||
DEFAULT_EXPLOSIVE_DAMAGE_SCALAR = 1.0;
|
||||
LEVEL_4_EXPLOSIVE_DAMAGE_SCALAR = 1.5;
|
||||
DEFAULT_REPAIR_DAMAGE_SCALAR = 1.0;
|
||||
LEVEL_3_REPAIR_DAMAGE_SCALAR = 0.75;
|
||||
|
||||
|
||||
init_perk_rigger()
|
||||
{
|
||||
perk_data = spawnStruct();
|
||||
perk_data.drill_health_scalar = DEFAULT_DRILL_HEALTH_SCALAR;
|
||||
perk_data.drill_time_scalar = DEFAULT_DRILL_TIME_SCALAR;
|
||||
perk_data.trap_cost_scalar = DEFAULT_TRAP_COST_SCALAR;
|
||||
perk_data.trap_duration_scalar = DEFAULT_TRAP_DURATION_SCALAR;
|
||||
perk_data.trap_damage_scalar = DEFAULT_TRAP_DAMAGE_SCALAR;
|
||||
perk_data.currency_scale_per_hive = DEFAULT_MONEY_SCALE_PER_HIVE;
|
||||
perk_data.explosive_damage_scalar = DEFAULT_EXPLOSIVE_DAMAGE_SCALAR;
|
||||
perk_data.repair_damage_scalar = DEFAULT_REPAIR_DAMAGE_SCALAR;
|
||||
|
||||
return perk_data;
|
||||
}
|
||||
|
||||
set_perk_rigger_0()
|
||||
{
|
||||
self.perk_data[ "rigger" ].drill_health_scalar = LEVEL_0_DRILL_HEALTH_SCALAR;
|
||||
self.perk_data[ "rigger" ].currency_scale_per_hive = LEVEL_0_MONEY_SCALE_PER_HIVE;
|
||||
}
|
||||
|
||||
unset_perk_rigger_0()
|
||||
{
|
||||
self.perk_data[ "rigger" ].drill_health_scalar = DEFAULT_DRILL_HEALTH_SCALAR;
|
||||
self.perk_data[ "rigger" ].currency_scale_per_hive = DEFAULT_MONEY_SCALE_PER_HIVE;
|
||||
}
|
||||
|
||||
set_perk_rigger_1()
|
||||
{
|
||||
self.perk_data[ "rigger" ].drill_health_scalar = LEVEL_0_DRILL_HEALTH_SCALAR;
|
||||
self.perk_data[ "rigger" ].currency_scale_per_hive = LEVEL_0_MONEY_SCALE_PER_HIVE;
|
||||
self.perk_data[ "rigger" ].drill_time_scalar = LEVEL_1_DRILL_TIME_SCALAR;
|
||||
|
||||
}
|
||||
|
||||
unset_perk_rigger_1()
|
||||
{
|
||||
self.perk_data[ "rigger" ].drill_health_scalar = DEFAULT_DRILL_HEALTH_SCALAR;
|
||||
self.perk_data[ "rigger" ].drill_time_scalar = DEFAULT_DRILL_TIME_SCALAR;
|
||||
self.perk_data[ "rigger" ].currency_scale_per_hive = DEFAULT_MONEY_SCALE_PER_HIVE;
|
||||
}
|
||||
|
||||
set_perk_rigger_2()
|
||||
{
|
||||
self.perk_data[ "rigger" ].drill_health_scalar = LEVEL_0_DRILL_HEALTH_SCALAR;
|
||||
self.perk_data[ "rigger" ].currency_scale_per_hive = LEVEL_0_MONEY_SCALE_PER_HIVE;
|
||||
self.perk_data[ "rigger" ].drill_time_scalar = LEVEL_1_DRILL_TIME_SCALAR;
|
||||
self.perk_data[ "rigger" ].trap_cost_scalar = LEVEL_2_TRAP_COST_SCALAR;
|
||||
|
||||
}
|
||||
|
||||
unset_perk_rigger_2()
|
||||
{
|
||||
self.perk_data[ "rigger" ].drill_health_scalar = DEFAULT_DRILL_HEALTH_SCALAR;
|
||||
self.perk_data[ "rigger" ].drill_time_scalar = DEFAULT_TRAP_COST_SCALAR;
|
||||
self.perk_data[ "rigger" ].trap_cost_scalar = DEFAULT_DRILL_TIME_SCALAR;
|
||||
self.perk_data[ "rigger" ].currency_scale_per_hive = DEFAULT_MONEY_SCALE_PER_HIVE;
|
||||
}
|
||||
|
||||
set_perk_rigger_3()
|
||||
{
|
||||
self.perk_data[ "rigger" ].drill_health_scalar = LEVEL_0_DRILL_HEALTH_SCALAR;
|
||||
self.perk_data[ "rigger" ].currency_scale_per_hive = LEVEL_0_MONEY_SCALE_PER_HIVE;
|
||||
self.perk_data[ "rigger" ].drill_time_scalar = LEVEL_1_DRILL_TIME_SCALAR;
|
||||
self.perk_data[ "rigger" ].trap_cost_scalar = LEVEL_2_TRAP_COST_SCALAR;
|
||||
self.perk_data[ "rigger" ].trap_duration_scalar = LEVEL_3_TRAP_DURATION_SCALAR;
|
||||
self.perk_data[ "rigger" ].repair_damage_scalar = LEVEL_3_REPAIR_DAMAGE_SCALAR;
|
||||
}
|
||||
|
||||
unset_perk_rigger_3()
|
||||
{
|
||||
self.perk_data[ "rigger" ].drill_health_scalar = DEFAULT_DRILL_HEALTH_SCALAR;
|
||||
self.perk_data[ "rigger" ].drill_time_scalar = DEFAULT_TRAP_COST_SCALAR;
|
||||
self.perk_data[ "rigger" ].trap_cost_scalar = DEFAULT_DRILL_TIME_SCALAR;
|
||||
self.perk_data[ "rigger" ].trap_duration_scalar = DEFAULT_TRAP_DURATION_SCALAR;
|
||||
self.perk_data[ "rigger" ].currency_scale_per_hive = DEFAULT_MONEY_SCALE_PER_HIVE;
|
||||
self.perk_data[ "rigger" ].repair_damage_scalar = DEFAULT_REPAIR_DAMAGE_SCALAR;
|
||||
|
||||
}
|
||||
|
||||
set_perk_rigger_4()
|
||||
{
|
||||
self.perk_data[ "rigger" ].drill_health_scalar = LEVEL_0_DRILL_HEALTH_SCALAR;
|
||||
self.perk_data[ "rigger" ].currency_scale_per_hive = LEVEL_0_MONEY_SCALE_PER_HIVE;
|
||||
self.perk_data[ "rigger" ].drill_time_scalar = LEVEL_1_DRILL_TIME_SCALAR;
|
||||
self.perk_data[ "rigger" ].trap_cost_scalar = LEVEL_2_TRAP_COST_SCALAR;
|
||||
self.perk_data[ "rigger" ].trap_duration_scalar = LEVEL_3_TRAP_DURATION_SCALAR;
|
||||
self.perk_data[ "rigger" ].trap_damage_scalar = LEVEL_4_TRAP_DAMAGE_SCALAR;
|
||||
self maps\mp\alien\_persistence::set_player_max_currency( LEVEL_4_WALLET_SIZE * maps\mp\alien\_prestige::prestige_getWalletSizeScalar() );
|
||||
self.perk_data[ "rigger" ].repair_damage_scalar = LEVEL_3_REPAIR_DAMAGE_SCALAR;
|
||||
self.perk_data[ "rigger" ].explosive_damage_scalar = LEVEL_4_EXPLOSIVE_DAMAGE_SCALAR;
|
||||
|
||||
}
|
||||
|
||||
unset_perk_rigger_4()
|
||||
{
|
||||
self.perk_data[ "rigger" ].drill_health_scalar = DEFAULT_DRILL_HEALTH_SCALAR;
|
||||
self.perk_data[ "rigger" ].drill_time_scalar = DEFAULT_TRAP_COST_SCALAR;
|
||||
self.perk_data[ "rigger" ].trap_cost_scalar = DEFAULT_DRILL_TIME_SCALAR;
|
||||
self.perk_data[ "rigger" ].trap_duration_scalar = DEFAULT_TRAP_DURATION_SCALAR;
|
||||
self.perk_data[ "rigger" ].trap_damage_scalar = DEFAULT_TRAP_DAMAGE_SCALAR;
|
||||
self.perk_data[ "rigger" ].currency_scale_per_hive = DEFAULT_MONEY_SCALE_PER_HIVE;
|
||||
self maps\mp\alien\_persistence::set_player_max_currency( DEFAULT_WALLET_SIZE * maps\mp\alien\_prestige::prestige_getWalletSizeScalar() );
|
||||
self.perk_data[ "rigger" ].repair_damage_scalar = DEFAULT_REPAIR_DAMAGE_SCALAR;
|
||||
self.perk_data[ "rigger" ].explosive_damage_scalar = DEFAULT_EXPLOSIVE_DAMAGE_SCALAR;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
/// Pistol Perk Data Init ///
|
||||
////////////////////////////////////////
|
||||
|
||||
init_perk_pistol()
|
||||
{
|
||||
perk_data = spawnStruct();
|
||||
perk_data.pistol_overkill = false;
|
||||
perk_data.pistol_regen = false;
|
||||
|
||||
return perk_data;
|
||||
}
|
||||
|
||||
check_for_pistol_ammo( base_pistol_name, full_pistol_name )
|
||||
{
|
||||
self.lastWeapon = self GetCurrentWeapon();
|
||||
self.pistol_clip_ammo_right = self GetWeaponAmmoClip( full_pistol_name, "right" );
|
||||
self.pistol_ammo_remaining = self GetWeaponAmmoStock( full_pistol_name );
|
||||
}
|
||||
|
||||
give_new_pistol( new_pistol_name )
|
||||
{
|
||||
pistol = new_pistol_name;
|
||||
self _giveWeapon( pistol );
|
||||
self SetWeaponAmmoClip( pistol, self.pistol_clip_ammo_right, "right" );
|
||||
self SetWeaponAmmoStock( pistol, self.pistol_ammo_remaining );
|
||||
weaponlist = self GetWeaponsListPrimaries();
|
||||
if ( !self HasWeapon( self.lastWeapon ) && !self has_special_weapon() && !self is_holding_deployable() )
|
||||
self SwitchToWeapon( pistol );
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
/// Pistol P226 Perk ///
|
||||
////////////////////////////////////////
|
||||
|
||||
set_perk_pistol_p226_0()
|
||||
{
|
||||
}
|
||||
|
||||
unset_perk_pistol_p226_0()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienp226_mp" );
|
||||
}
|
||||
|
||||
set_perk_pistol_p226_1()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienp226_mp_alienmuzzlebrakepi" );
|
||||
else
|
||||
self give_new_pistol( "iw6_alienp226_mp_barrelrange02" );
|
||||
//We are setting combatspeedscalar for all pistol Rank 1.
|
||||
}
|
||||
|
||||
unset_perk_pistol_p226_1()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienp226_mp" );
|
||||
}
|
||||
|
||||
set_perk_pistol_p226_2()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienp226_mp_alienmuzzlebrakepi_xmags" );
|
||||
else
|
||||
self give_new_pistol( "iw6_alienp226_mp_barrelrange02_xmags" );
|
||||
}
|
||||
|
||||
unset_perk_pistol_p226_2()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienp226_mp" );
|
||||
}
|
||||
|
||||
set_perk_pistol_p226_3()
|
||||
{
|
||||
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienp226_mp_alienmuzzlebrakepi_xmags" );
|
||||
else
|
||||
self give_new_pistol( "iw6_alienp226_mp_barrelrange02_xmags" );
|
||||
|
||||
self.perk_data[ "pistol" ].pistol_overkill = true;
|
||||
}
|
||||
|
||||
unset_perk_pistol_p226_3()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienp226_mp" );
|
||||
self.perk_data[ "pistol" ].pistol_overkill = false;
|
||||
}
|
||||
|
||||
set_perk_pistol_p226_4()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw5_alienp226_mp_akimbo_alienmuzzlebrakepi_xmags" );
|
||||
else
|
||||
self give_new_pistol( "iw5_alienp226_mp_akimbo_barrelrange02_xmags" );
|
||||
|
||||
self.perk_data[ "pistol" ].pistol_overkill = true;
|
||||
}
|
||||
|
||||
unset_perk_pistol_p226_4()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw5_alienp226_mp" );
|
||||
self.perk_data[ "pistol" ].pistol_overkill = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
/// Pistol Magnum Perk ///
|
||||
////////////////////////////////////////
|
||||
|
||||
set_perk_pistol_magnum_0()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
unset_perk_pistol_magnum_0()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienmagnum_mp" );
|
||||
}
|
||||
|
||||
set_perk_pistol_magnum_1()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "magnum_acog_upgrade" ) && !self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienmagnum_mp_acogpistol_barrelrange02_scope5" );
|
||||
else if ( !self maps\mp\alien\_persistence::is_upgrade_enabled( "magnum_acog_upgrade" ) && self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienmagnum_mp_alienmuzzlebrakepi" );
|
||||
else if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "magnum_acog_upgrade" ) && self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienmagnum_mp_acogpistol_alienmuzzlebrakepi_scope5" );
|
||||
else
|
||||
self give_new_pistol( "iw6_alienmagnum_mp_barrelrange02" );
|
||||
}
|
||||
|
||||
unset_perk_pistol_magnum_1()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienmagnum_mp" );
|
||||
}
|
||||
|
||||
set_perk_pistol_magnum_2()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "magnum_acog_upgrade" ) && !self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienmagnum_mp_acogpistol_barrelrange02_xmags_scope5" );
|
||||
else if ( !self maps\mp\alien\_persistence::is_upgrade_enabled( "magnum_acog_upgrade" ) && self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienmagnum_mp_alienmuzzlebrakepi_xmags" );
|
||||
else if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "magnum_acog_upgrade" ) && self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienmagnum_mp_acogpistol_alienmuzzlebrakepi_xmags_scope5" );
|
||||
else
|
||||
self give_new_pistol( "iw6_alienmagnum_mp_barrelrange02_xmags" );
|
||||
}
|
||||
|
||||
unset_perk_pistol_magnum_2()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienmagnum_mp" );
|
||||
}
|
||||
|
||||
set_perk_pistol_magnum_3()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "magnum_acog_upgrade" ) && !self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienmagnum_mp_acogpistol_barrelrange02_xmags_scope5" );
|
||||
else if ( !self maps\mp\alien\_persistence::is_upgrade_enabled( "magnum_acog_upgrade" ) && self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienmagnum_mp_alienmuzzlebrakepi_xmags" );
|
||||
else if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "magnum_acog_upgrade" ) && self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienmagnum_mp_acogpistol_alienmuzzlebrakepi_xmags_scope5" );
|
||||
else
|
||||
self give_new_pistol( "iw6_alienmagnum_mp_barrelrange02_xmags" );
|
||||
|
||||
self.perk_data[ "pistol" ].pistol_overkill = true;
|
||||
}
|
||||
|
||||
unset_perk_pistol_magnum_3()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienmagnum_mp" );
|
||||
self.perk_data[ "pistol" ].pistol_overkill = false;
|
||||
}
|
||||
|
||||
set_perk_pistol_magnum_4()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "magnum_acog_upgrade" ) && !self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw5_alienmagnum_mp_acogpistol_akimbo_barrelrange02_xmags_scope5" );
|
||||
else if ( !self maps\mp\alien\_persistence::is_upgrade_enabled( "magnum_acog_upgrade" ) && self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw5_alienmagnum_mp_akimbo_alienmuzzlebrakepi_xmags" );
|
||||
else if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "magnum_acog_upgrade" ) && self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw5_alienmagnum_mp_acogpistol_akimbo_alienmuzzlebrakepi_xmags_scope5" );
|
||||
else
|
||||
self give_new_pistol( "iw5_alienmagnum_mp_akimbo_barrelrange02_xmags" );
|
||||
self.perk_data[ "pistol" ].pistol_overkill = true;
|
||||
}
|
||||
|
||||
unset_perk_pistol_magnum_4()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw5_alienmagnum_mp" );
|
||||
self.perk_data[ "pistol" ].pistol_overkill = false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
/// Pistol M9A1 Perk ///
|
||||
////////////////////////////////////////
|
||||
|
||||
|
||||
set_perk_pistol_m9a1_0()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
unset_perk_pistol_m9a1_0()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienm9a1_mp" );
|
||||
}
|
||||
|
||||
set_perk_pistol_m9a1_1()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienm9a1_mp_alienmuzzlebrakep3" );
|
||||
else
|
||||
self give_new_pistol( "iw6_alienm9a1_mp_barrelrange02" );
|
||||
}
|
||||
|
||||
unset_perk_pistol_m9a1_1()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienm9a1_mp" );
|
||||
}
|
||||
|
||||
set_perk_pistol_m9a1_2()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienm9a1_mp_alienmuzzlebrakep3_xmags" );
|
||||
else
|
||||
self give_new_pistol( "iw6_alienm9a1_mp_barrelrange02_xmags" );
|
||||
}
|
||||
|
||||
unset_perk_pistol_m9a1_2()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienm9a1_mp" );
|
||||
}
|
||||
|
||||
set_perk_pistol_m9a1_3()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienm9a1_mp_alienmuzzlebrakep3_xmags" );
|
||||
else
|
||||
self give_new_pistol( "iw6_alienm9a1_mp_barrelrange02_xmags" );
|
||||
|
||||
self.perk_data[ "pistol" ].pistol_overkill = true;
|
||||
}
|
||||
|
||||
unset_perk_pistol_m9a1_3()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienm9a1_mp" );
|
||||
self.perk_data[ "pistol" ].pistol_overkill = false;
|
||||
}
|
||||
|
||||
set_perk_pistol_m9a1_4()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw5_alienm9a1_mp_akimbo_alienmuzzlebrakep3_xmags" );
|
||||
else
|
||||
self give_new_pistol( "iw5_alienm9a1_mp_akimbo_barrelrange02_xmags" );
|
||||
|
||||
self.perk_data[ "pistol" ].pistol_overkill = true;
|
||||
}
|
||||
|
||||
unset_perk_pistol_m9a1_4()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw5_alienm9a1_mp" );
|
||||
self.perk_data[ "pistol" ].pistol_overkill = false;
|
||||
}
|
||||
/*
|
||||
get_current_pistol()
|
||||
{
|
||||
weap_list = self GetWeaponsListPrimaries();
|
||||
foreach ( weap in weap_list )
|
||||
{
|
||||
weap_class = getWeaponClass ( weap );
|
||||
if ( weap_class == "weapon_pistol" )
|
||||
{
|
||||
return weap;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
store_ammo_and_take_pistol( baseweapon )
|
||||
{
|
||||
current_pistol = self get_current_pistol();
|
||||
self check_for_pistol_ammo ( baseweapon, current_pistol );
|
||||
self TakeWeapon( current_pistol );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
/// Pistol MP443 Perk ///
|
||||
////////////////////////////////////////
|
||||
|
||||
|
||||
set_perk_pistol_mp443_0()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
unset_perk_pistol_mp443_0()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienmp443_mp" );
|
||||
}
|
||||
|
||||
set_perk_pistol_mp443_1()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienmp443_mp_alienmuzzlebrakepa" );
|
||||
else
|
||||
self give_new_pistol( "iw6_alienmp443_mp_barrelrange02" );
|
||||
}
|
||||
|
||||
unset_perk_pistol_mp443_1()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienmp443_mp" );
|
||||
}
|
||||
|
||||
set_perk_pistol_mp443_2()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienmp443_mp_alienmuzzlebrakepa_xmags" );
|
||||
else
|
||||
self give_new_pistol( "iw6_alienmp443_mp_barrelrange02_xmags" );
|
||||
}
|
||||
|
||||
unset_perk_pistol_mp443_2()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienmp443_mp" );
|
||||
}
|
||||
|
||||
set_perk_pistol_mp443_3()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw6_alienmp443_mp_alienmuzzlebrakepa_xmags" );
|
||||
else
|
||||
self give_new_pistol( "iw6_alienmp443_mp_barrelrange02_xmags" );
|
||||
self.perk_data[ "pistol" ].pistol_overkill = true;
|
||||
}
|
||||
|
||||
unset_perk_pistol_mp443_3()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw6_alienmp443_mp" );
|
||||
self.perk_data[ "pistol" ].pistol_overkill = false;
|
||||
}
|
||||
|
||||
set_perk_pistol_mp443_4()
|
||||
{
|
||||
if ( self maps\mp\alien\_persistence::is_upgrade_enabled( "ark_pistol_upgrade" ) )
|
||||
self give_new_pistol( "iw5_alienmp443_mp_akimbo_alienmuzzlebrakepa_xmags" );
|
||||
else
|
||||
self give_new_pistol( "iw5_alienmp443_mp_akimbo_barrelrange02_xmags" );
|
||||
self.perk_data[ "pistol" ].pistol_overkill = true;
|
||||
}
|
||||
|
||||
unset_perk_pistol_mp443_4()
|
||||
{
|
||||
self store_ammo_and_take_pistol( "iw5_alienmp443_mp" );
|
||||
self.perk_data[ "pistol" ].pistol_overkill = false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// //
|
||||
// Pistol Speed Perk //
|
||||
// //
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
watchCombatSpeedScaler()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
|
||||
self.pistolCombatSpeedScalar = 1.0;
|
||||
self.alienSnareSpeedScalar = 1.0;
|
||||
|
||||
self.alienSnareCount = 0;
|
||||
|
||||
self.combatSpeedScalar = getCombatSpeedScalar();
|
||||
self maps\mp\gametypes\_weapons::updateMoveSpeedScale();
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill ( "weapon_change", newWeapon );
|
||||
if ( self has_perk( "perk_pistol_p226", [1,2,3,4] ) || self has_perk( "perk_pistol_magnum", [1,2,3,4] ) || self has_perk( "perk_pistol_m9a1", [1,2,3,4] ) || self has_perk( "perk_pistol_mp443", [1,2,3,4] ) )
|
||||
{
|
||||
currentweapon = self GetCurrentWeapon();
|
||||
baseweapon = getRawBaseWeaponName( currentweapon );
|
||||
if ( IsDefined( baseweapon ) )
|
||||
{
|
||||
if ( baseweapon == "alienp226" || baseweapon == "alienmagnum" || baseweapon == "alienm9a1" || baseweapon == "alienmp443" )
|
||||
{
|
||||
self.pistolCombatSpeedScalar = 1.1;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.pistolCombatSpeedScalar = 1.0;
|
||||
}
|
||||
|
||||
wait 0.05; //Don't want to risk called this twice in the same frame since it's already called onm weapon_change
|
||||
updateCombatSpeedScalar();
|
||||
}
|
||||
}
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
updateCombatSpeedScalar()
|
||||
{
|
||||
self.combatSpeedScalar = getCombatSpeedScalar();
|
||||
self maps\mp\gametypes\_weapons::updateMoveSpeedScale();
|
||||
}
|
||||
|
||||
getCombatSpeedScalar()
|
||||
{
|
||||
return ( self.pistolCombatSpeedScalar * self.alienSnareSpeedScalar );
|
||||
}
|
||||
|
||||
watchFlamingRiotShield()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
currentweapon = self GetCurrentWeapon();
|
||||
if ( IsDefined( currentweapon ) )
|
||||
{
|
||||
if ( currentweapon == "iw5_alienriotshield4_mp_camo05" && self.fireShield == 1.0 )
|
||||
{
|
||||
PlayFXOnTag( level._effect[ "Riotshield_fire" ], self, "TAG_origin" );
|
||||
}
|
||||
else
|
||||
{
|
||||
StopFXOnTag( level._effect[ "Riotshield_fire" ], self, "TAG_origin" );
|
||||
}
|
||||
}
|
||||
}
|
||||
wait 0.05;
|
||||
}
|
||||
|
||||
|
||||
|
223
maps/mp/alien/_perks.gsc
Normal file
223
maps/mp/alien/_perks.gsc
Normal file
@ -0,0 +1,223 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\agents\_agent_utility;
|
||||
#include maps\mp\alien\_utility;
|
||||
#include maps\mp\alien\_perkfunctions;
|
||||
|
||||
init_perks()
|
||||
{
|
||||
init_perks_callback();
|
||||
|
||||
init_perks_from_table();
|
||||
}
|
||||
|
||||
PERK_TABLE = "mp/alien/perks_tree.csv";
|
||||
|
||||
init_perks_from_table()
|
||||
{
|
||||
// level.alien_perks_table can be used to override default table, should be set before _alien::main()
|
||||
if ( !isdefined( level.alien_perks_table ) )
|
||||
level.alien_perks_table = PERK_TABLE;
|
||||
|
||||
level.alien_perks = [];
|
||||
|
||||
update_perks_from_table( 0, "perk_0" );
|
||||
update_perks_from_table( 100, "perk_1" );
|
||||
}
|
||||
|
||||
init_perks_callback()
|
||||
{
|
||||
level.alien_perk_callbacks = [];
|
||||
|
||||
register_perk_callback( "perk_health", ::set_perk_health_level_0, ::unset_perk_health_level_0 );
|
||||
register_perk_callback( "perk_health_1", ::set_perk_health_level_1, ::unset_perk_health_level_1 );
|
||||
register_perk_callback( "perk_health_2", ::set_perk_health_level_2, ::unset_perk_health_level_2 );
|
||||
register_perk_callback( "perk_health_3", ::set_perk_health_level_3, ::unset_perk_health_level_3 );
|
||||
register_perk_callback( "perk_health_4", ::set_perk_health_level_4, ::unset_perk_health_level_4 );
|
||||
|
||||
register_perk_callback( "perk_pistol_p226", ::set_perk_pistol_p226_0, ::unset_perk_pistol_p226_0 );
|
||||
register_perk_callback( "perk_pistol_p226_1", ::set_perk_pistol_p226_1, ::unset_perk_pistol_p226_1 );
|
||||
register_perk_callback( "perk_pistol_p226_2", ::set_perk_pistol_p226_2, ::unset_perk_pistol_p226_2 );
|
||||
register_perk_callback( "perk_pistol_p226_3", ::set_perk_pistol_p226_3, ::unset_perk_pistol_p226_3 );
|
||||
register_perk_callback( "perk_pistol_p226_4", ::set_perk_pistol_p226_4, ::unset_perk_pistol_p226_4 );
|
||||
|
||||
register_perk_callback( "perk_pistol_magnum", ::set_perk_pistol_magnum_0, ::unset_perk_pistol_magnum_0 );
|
||||
register_perk_callback( "perk_pistol_magnum_1", ::set_perk_pistol_magnum_1, ::unset_perk_pistol_magnum_1 );
|
||||
register_perk_callback( "perk_pistol_magnum_2", ::set_perk_pistol_magnum_2, ::unset_perk_pistol_magnum_2 );
|
||||
register_perk_callback( "perk_pistol_magnum_3", ::set_perk_pistol_magnum_3, ::unset_perk_pistol_magnum_3 );
|
||||
register_perk_callback( "perk_pistol_magnum_4", ::set_perk_pistol_magnum_4, ::unset_perk_pistol_magnum_4 );
|
||||
|
||||
register_perk_callback( "perk_pistol_m9a1", ::set_perk_pistol_m9a1_0, ::unset_perk_pistol_m9a1_0 );
|
||||
register_perk_callback( "perk_pistol_m9a1_1", ::set_perk_pistol_m9a1_1, ::unset_perk_pistol_m9a1_1 );
|
||||
register_perk_callback( "perk_pistol_m9a1_2", ::set_perk_pistol_m9a1_2, ::unset_perk_pistol_m9a1_2 );
|
||||
register_perk_callback( "perk_pistol_m9a1_3", ::set_perk_pistol_m9a1_3, ::unset_perk_pistol_m9a1_3 );
|
||||
register_perk_callback( "perk_pistol_m9a1_4", ::set_perk_pistol_m9a1_4, ::unset_perk_pistol_m9a1_4 );
|
||||
|
||||
register_perk_callback( "perk_pistol_mp443", ::set_perk_pistol_mp443_0, ::unset_perk_pistol_mp443_0 );
|
||||
register_perk_callback( "perk_pistol_mp443_1", ::set_perk_pistol_mp443_1, ::unset_perk_pistol_mp443_1 );
|
||||
register_perk_callback( "perk_pistol_mp443_2", ::set_perk_pistol_mp443_2, ::unset_perk_pistol_mp443_2 );
|
||||
register_perk_callback( "perk_pistol_mp443_3", ::set_perk_pistol_mp443_3, ::unset_perk_pistol_mp443_3 );
|
||||
register_perk_callback( "perk_pistol_mp443_4", ::set_perk_pistol_mp443_4, ::unset_perk_pistol_mp443_4 );
|
||||
|
||||
register_perk_callback( "perk_bullet_damage", ::set_perk_bullet_damage_0, ::unset_perk_bullet_damage_0 );
|
||||
register_perk_callback( "perk_bullet_damage_1", ::set_perk_bullet_damage_1, ::unset_perk_bullet_damage_1 );
|
||||
register_perk_callback( "perk_bullet_damage_2", ::set_perk_bullet_damage_2, ::unset_perk_bullet_damage_2 );
|
||||
register_perk_callback( "perk_bullet_damage_3", ::set_perk_bullet_damage_3, ::unset_perk_bullet_damage_3 );
|
||||
register_perk_callback( "perk_bullet_damage_4", ::set_perk_bullet_damage_4, ::unset_perk_bullet_damage_4 );
|
||||
|
||||
register_perk_callback( "perk_medic", ::set_perk_medic_0, ::unset_perk_medic_0 );
|
||||
register_perk_callback( "perk_medic_1", ::set_perk_medic_1, ::unset_perk_medic_1 );
|
||||
register_perk_callback( "perk_medic_2", ::set_perk_medic_2, ::unset_perk_medic_2 );
|
||||
register_perk_callback( "perk_medic_3", ::set_perk_medic_3, ::unset_perk_medic_3 );
|
||||
register_perk_callback( "perk_medic_4", ::set_perk_medic_4, ::unset_perk_medic_4 );
|
||||
|
||||
register_perk_callback( "perk_rigger", ::set_perk_rigger_0, ::unset_perk_rigger_0 );
|
||||
register_perk_callback( "perk_rigger_1", ::set_perk_rigger_1, ::unset_perk_rigger_1 );
|
||||
register_perk_callback( "perk_rigger_2", ::set_perk_rigger_2, ::unset_perk_rigger_2 );
|
||||
register_perk_callback( "perk_rigger_3", ::set_perk_rigger_3, ::unset_perk_rigger_3 );
|
||||
register_perk_callback( "perk_rigger_4", ::set_perk_rigger_4, ::unset_perk_rigger_4 );
|
||||
|
||||
register_perk_callback( "perk_none", ::set_perk_none, ::unset_perk_none );
|
||||
register_perk_callback( "perk_none_1", ::set_perk_none, ::unset_perk_none );
|
||||
register_perk_callback( "perk_none_2", ::set_perk_none, ::unset_perk_none );
|
||||
register_perk_callback( "perk_none_3", ::set_perk_none, ::unset_perk_none );
|
||||
register_perk_callback( "perk_none_4", ::set_perk_none, ::unset_perk_none );
|
||||
}
|
||||
|
||||
register_perk_callback( perk_name, set_func, unSet_func )
|
||||
{
|
||||
perk_callback = spawnstruct();
|
||||
perk_callback.Set = set_func;
|
||||
perk_callback.unSet = unSet_func;
|
||||
|
||||
level.alien_perk_callbacks[ perk_name ] = perk_callback;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Perks Table
|
||||
// ================================================================
|
||||
TABLE_INDEX = 0; // [int] Indexing
|
||||
TABLE_REF = 1; // [string] Reference
|
||||
TABLE_UNLOCK = 2; // [int] Unlocked at rank number
|
||||
TABLE_POINT_COST = 3; // [int] Combat point cost to enable this perk(upgrades)
|
||||
TABLE_NAME = 4; // [string] Name localized
|
||||
TABLE_DESC = 5; // [string] Description localized
|
||||
TABLE_ICON = 6; // [string] Reference string of icon for perk
|
||||
TABLE_IS_UPGRADE = 7; // [int] 1 if this is an upgrade, 0 if not
|
||||
|
||||
TABLE_PERK_MAX_INDEX = 100;
|
||||
// Populates data table entries into level array
|
||||
update_perks_from_table( start_idx, perk_type )
|
||||
{
|
||||
level.alien_perks[ perk_type ] = [];
|
||||
|
||||
for ( i = start_idx; i <= start_idx + TABLE_PERK_MAX_INDEX; i++ )
|
||||
{
|
||||
// break on end of line
|
||||
perk_ref = get_perk_ref_by_index( i );
|
||||
if ( perk_ref == "" ) { break; }
|
||||
|
||||
if ( !isdefined( level.alien_perks[ perk_ref ] ) )
|
||||
{
|
||||
perk = spawnstruct();
|
||||
perk.upgrades = [];
|
||||
perk.unlock = get_unlock_by_ref( perk_ref );
|
||||
perk.name = get_name_by_ref( perk_ref );
|
||||
perk.icon = get_icon_by_ref( perk_ref );
|
||||
perk.ref = perk_ref;
|
||||
perk.type = perk_type;
|
||||
perk.callbacks = level.alien_perk_callbacks[ perk_ref ];
|
||||
perk.baseIdx = i;
|
||||
|
||||
level.alien_perks[ perk_type ][ perk_ref ] = perk;
|
||||
}
|
||||
|
||||
// grab all upgrades for this perk
|
||||
for ( j = i; j <= start_idx + TABLE_PERK_MAX_INDEX; j++ )
|
||||
{
|
||||
upgrade_ref = get_perk_ref_by_index( j );
|
||||
if ( upgrade_ref == "" ) { break; }
|
||||
|
||||
if ( upgrade_ref == perk_ref || is_perk_set( perk_ref, upgrade_ref ) )
|
||||
{
|
||||
upgrade = spawnstruct();
|
||||
upgrade.ref = upgrade_ref;
|
||||
upgrade.desc = get_desc_by_ref( upgrade_ref );
|
||||
upgrade.point_cost = get_point_cost_by_ref( upgrade_ref );
|
||||
|
||||
level.alien_perks[ perk_type ][ perk_ref ].upgrades[ j - i ] = upgrade;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// point index to next perk set
|
||||
i = j - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if upgrade_ref is/or an upgrade of perk_ref
|
||||
is_perk_set( perk_ref, upgrade_ref )
|
||||
{
|
||||
// ex: "perk_blah" is perk ref
|
||||
// all upgrade refs should be in form of "perk_blah_#"
|
||||
|
||||
assert( isdefined( perk_ref ) && isdefined( upgrade_ref ) );
|
||||
|
||||
if ( perk_ref == upgrade_ref )
|
||||
return false;
|
||||
|
||||
if ( !issubstr( upgrade_ref, perk_ref ) )
|
||||
return false;
|
||||
|
||||
perk_toks = StrTok( perk_ref, "_" );
|
||||
upgrade_toks = StrTok( upgrade_ref, "_" );
|
||||
|
||||
if ( upgrade_toks.size - perk_toks.size != 1 )
|
||||
return false;
|
||||
|
||||
for ( i = 0; i < upgrade_toks.size - 1; i++ )
|
||||
{
|
||||
if ( upgrade_toks[ i ] != perk_toks[ i ] )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
get_perk_ref_by_index( index )
|
||||
{
|
||||
return tablelookup( level.alien_perks_table, TABLE_INDEX, index, TABLE_REF );
|
||||
}
|
||||
|
||||
get_name_by_ref( ref )
|
||||
{
|
||||
return tablelookup( level.alien_perks_table, TABLE_REF, ref, TABLE_NAME );
|
||||
}
|
||||
|
||||
get_icon_by_ref( ref )
|
||||
{
|
||||
return tablelookup( level.alien_perks_table, TABLE_REF, ref, TABLE_ICON );
|
||||
}
|
||||
|
||||
get_desc_by_ref( ref )
|
||||
{
|
||||
return tablelookup( level.alien_perks_table, TABLE_REF, ref, TABLE_DESC );
|
||||
}
|
||||
|
||||
get_point_cost_by_ref( ref )
|
||||
{
|
||||
return int( tablelookup( level.alien_perks_table, TABLE_REF, ref, TABLE_POINT_COST ) );
|
||||
}
|
||||
|
||||
get_unlock_by_ref( ref )
|
||||
{
|
||||
return int( tablelookup( level.alien_perks_table, TABLE_REF, ref, TABLE_UNLOCK ) );
|
||||
}
|
||||
|
||||
get_is_upgrade_by_ref( ref )
|
||||
{
|
||||
return int( tablelookup( level.alien_perks_table, TABLE_REF, ref, TABLE_IS_UPGRADE ) );
|
||||
}
|
1864
maps/mp/alien/_persistence.gsc
Normal file
1864
maps/mp/alien/_persistence.gsc
Normal file
File diff suppressed because it is too large
Load Diff
2670
maps/mp/alien/_pillage.gsc
Normal file
2670
maps/mp/alien/_pillage.gsc
Normal file
File diff suppressed because it is too large
Load Diff
175
maps/mp/alien/_prestige.gsc
Normal file
175
maps/mp/alien/_prestige.gsc
Normal file
@ -0,0 +1,175 @@
|
||||
CONST_MAX_NUM_PRESTIGE_NERF = 32; // The max number of nerf options
|
||||
|
||||
CONST_NERF_TABLE = "mp/alien/prestige_nerf.csv";
|
||||
CONST_NERF_TABLE_IDX_COLUMN = 0;
|
||||
CONST_NERF_TABLE_REF_COLUMN = 1;
|
||||
|
||||
CONST_NERF_SCALAR_DAMAGE_TAKEN = 1.33; // Greater than 1 to make player takes more damage from aliens
|
||||
CONST_NERF_SCALAR_THREATBIAS = 500; // Greater than 0 to make aliens attack this particular player more often
|
||||
CONST_NERF_SCALAR_WALLET_SIZE = 0.5; // Less than 1 to make the wallet size smaller;
|
||||
CONST_NERF_SCALAR_EARN_LESS_MONEY = 0.75; // Less then 1 to make player earn less money
|
||||
CONST_NERF_SCALAR_WEAPON_DAMAGE = 0.66; // Less than 1 to make player do less damage on aliens;
|
||||
CONST_NERF_NO_CLASS_ALLOWED = 1.0; // 1 = can't select a class, 0 or undefined means you can
|
||||
CONST_NERF_PISTOLS_ONLY = 1.0; // 1 = can't but weapons, 0 or undefined means you can
|
||||
CONST_NERF_SCALAR_HEALTH_REGEN = 1.5; // slow health regen by 50%
|
||||
CONST_NERF_SCALAR_MOVE_SLOWER = 0.7; // movement scalar
|
||||
CONST_NERF_NO_ABILITIES = 1.0; // 1 = can't use Left and Right Dpad abilities, 0 = you can use them
|
||||
CONST_NERF_SCALAR_MIN_AMMO = 0.25; // scalar of max stock for give ammo calls
|
||||
CONST_NERF_NO_DEPLOYABLES = 1.0; // 1 = can't use Up and Down Dpad abilities, 0 = you can use them
|
||||
|
||||
// Those name references need to match the "reference string" column in the prestige_nerf csv table
|
||||
CONST_REF_NO_NERF = "none";
|
||||
CONST_REF_TAKE_MORE_DAMAGE = "nerf_take_more_damage";
|
||||
CONST_REF_HIGHER_THREATBIAS = "nerf_higher_threatbias";
|
||||
CONST_REF_SMALLER_WALLET = "nerf_smaller_wallet";
|
||||
CONST_REF_EARN_LESS_MONEY = "nerf_earn_less_money"; // This one is not in the prestige_nerf csv table. It is the additional nerf for smaller wallet
|
||||
CONST_REF_LOWER_WEAPON_DAMAGE = "nerf_lower_weapon_damage";
|
||||
CONST_REF_NO_CLASS_ALLOWED = "nerf_no_class";
|
||||
CONST_REF_PISTOLS_ONLY = "nerf_pistols_only";
|
||||
CONST_REF_SLOW_HEALTH_REGEN = "nerf_fragile";
|
||||
CONST_REF_MOVE_SLOWER = "nerf_move_slower";
|
||||
CONST_REF_NO_ABILITIES = "nerf_no_abilities";
|
||||
CONST_REF_MIN_AMMO = "nerf_min_ammo";
|
||||
CONST_REF_NO_DEPLOYABLES = "nerf_no_deployables";
|
||||
|
||||
init_prestige()
|
||||
{
|
||||
nerf_func = [];
|
||||
|
||||
nerf_func[CONST_REF_NO_NERF] = ::empty;
|
||||
nerf_func[CONST_REF_TAKE_MORE_DAMAGE] = ::increase_damage_scalar;
|
||||
nerf_func[CONST_REF_HIGHER_THREATBIAS] = ::increase_threatbias;
|
||||
nerf_func[CONST_REF_SMALLER_WALLET] = ::reduce_wallet_size_and_money_earned;
|
||||
nerf_func[CONST_REF_LOWER_WEAPON_DAMAGE] = ::lower_weapon_damage;
|
||||
nerf_func[CONST_REF_NO_CLASS_ALLOWED] = ::no_class;
|
||||
nerf_func[CONST_REF_PISTOLS_ONLY] = ::pistols_only;
|
||||
nerf_func[CONST_REF_SLOW_HEALTH_REGEN] = ::slow_health_regen;
|
||||
nerf_func[CONST_REF_MOVE_SLOWER] = ::move_slower;
|
||||
nerf_func[CONST_REF_NO_ABILITIES] = ::no_abilities;
|
||||
nerf_func[CONST_REF_MIN_AMMO] = ::min_ammo;
|
||||
nerf_func[CONST_REF_NO_DEPLOYABLES] = ::no_deployables;
|
||||
|
||||
level.prestige_nerf_func = nerf_func;
|
||||
|
||||
table_list = [];
|
||||
|
||||
for( i = 0; i < CONST_MAX_NUM_PRESTIGE_NERF; i++ )
|
||||
{
|
||||
nerfRef = TableLookupByRow( CONST_NERF_TABLE, i, CONST_NERF_TABLE_REF_COLUMN );
|
||||
|
||||
if( !IsDefined( nerfRef ) || nerfRef == "" )
|
||||
break;
|
||||
|
||||
table_list[table_list.size] = nerfRef;
|
||||
}
|
||||
|
||||
level.nerf_list = table_list;
|
||||
}
|
||||
|
||||
init_player_prestige()
|
||||
{
|
||||
init_nerf_scalar();
|
||||
|
||||
if ( is_relics_enabled() )
|
||||
nerf_based_on_selection();
|
||||
}
|
||||
|
||||
init_nerf_scalar()
|
||||
{
|
||||
nerf_scalars = [];
|
||||
|
||||
nerf_scalars[CONST_REF_TAKE_MORE_DAMAGE] = 1.0;
|
||||
nerf_scalars[CONST_REF_HIGHER_THREATBIAS] = 0; //<NOTE J.C> Default threatbias value is 0
|
||||
nerf_scalars[CONST_REF_SMALLER_WALLET] = 1.0;
|
||||
nerf_scalars[CONST_REF_EARN_LESS_MONEY] = 1.0;
|
||||
nerf_scalars[CONST_REF_LOWER_WEAPON_DAMAGE] = 1.0;
|
||||
nerf_scalars[CONST_REF_NO_CLASS_ALLOWED] = 0; // 0 = can use classes
|
||||
nerf_scalars[CONST_REF_PISTOLS_ONLY] = 0; // 0 = not pistols only, can buy weapons
|
||||
nerf_scalars[CONST_REF_SLOW_HEALTH_REGEN] = 1.0; // default health regen scalar is 1
|
||||
nerf_scalars[CONST_REF_MOVE_SLOWER] = 1.0; //Move speed scalar
|
||||
nerf_scalars[CONST_REF_NO_ABILITIES] = 0; // 0 = can use abilities
|
||||
nerf_scalars[CONST_REF_MIN_AMMO] = 1.0;
|
||||
nerf_scalars[CONST_REF_NO_DEPLOYABLES] = 0; // 0 = can use abilities
|
||||
|
||||
self.nerf_scalars = nerf_scalars;
|
||||
self.activated_nerfs = [];
|
||||
}
|
||||
|
||||
nerf_based_on_selection()
|
||||
{
|
||||
|
||||
foreach( nerf in level.nerf_list )
|
||||
{
|
||||
if ( self alienscheckisrelicenabled( nerf ) )
|
||||
{
|
||||
activate_nerf( nerf );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
activate_nerf( reference )
|
||||
{
|
||||
register_nerf_activated( reference );
|
||||
|
||||
[[level.prestige_nerf_func[reference]]]();
|
||||
}
|
||||
|
||||
nerf_already_activated( reference )
|
||||
{
|
||||
return common_scripts\utility::array_contains( self.activated_nerfs, reference );
|
||||
}
|
||||
|
||||
register_nerf_activated( reference )
|
||||
{
|
||||
self.activated_nerfs[self.activated_nerfs.size] = reference;
|
||||
}
|
||||
|
||||
reduce_wallet_size_and_money_earned()
|
||||
{
|
||||
reduce_wallet_size();
|
||||
|
||||
reduce_money_earned();
|
||||
}
|
||||
|
||||
is_relics_enabled()
|
||||
{
|
||||
if ( maps\mp\alien\_utility::is_chaos_mode() )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
is_no_nerf( reference ) { return reference == "none"; }
|
||||
get_num_nerf_selected() { return self.activated_nerfs.size; }
|
||||
|
||||
empty() {}
|
||||
increase_damage_scalar() { set_nerf_scalar( CONST_REF_TAKE_MORE_DAMAGE , CONST_NERF_SCALAR_DAMAGE_TAKEN ); }
|
||||
increase_threatbias() { set_nerf_scalar( CONST_REF_HIGHER_THREATBIAS , CONST_NERF_SCALAR_THREATBIAS ); }
|
||||
reduce_wallet_size() { set_nerf_scalar( CONST_REF_SMALLER_WALLET , CONST_NERF_SCALAR_WALLET_SIZE ); }
|
||||
reduce_money_earned() { set_nerf_scalar( CONST_REF_EARN_LESS_MONEY , CONST_NERF_SCALAR_EARN_LESS_MONEY ); }
|
||||
lower_weapon_damage() { set_nerf_scalar( CONST_REF_LOWER_WEAPON_DAMAGE , CONST_NERF_SCALAR_WEAPON_DAMAGE ); }
|
||||
no_class() { set_nerf_scalar( CONST_REF_NO_CLASS_ALLOWED , CONST_NERF_NO_CLASS_ALLOWED ); }
|
||||
pistols_only() { set_nerf_scalar( CONST_REF_PISTOLS_ONLY , CONST_NERF_PISTOLS_ONLY ); }
|
||||
slow_health_regen() { set_nerf_scalar( CONST_REF_SLOW_HEALTH_REGEN , CONST_NERF_SCALAR_HEALTH_REGEN ); }
|
||||
move_slower() { set_nerf_scalar( CONST_REF_MOVE_SLOWER , CONST_NERF_SCALAR_MOVE_SLOWER ); }
|
||||
no_abilities() { set_nerf_scalar( CONST_REF_NO_ABILITIES , CONST_NERF_NO_ABILITIES ); }
|
||||
min_ammo() { set_nerf_scalar( CONST_REF_MIN_AMMO , CONST_NERF_SCALAR_MIN_AMMO ); }
|
||||
no_deployables() { set_nerf_scalar( CONST_REF_NO_DEPLOYABLES , CONST_NERF_NO_DEPLOYABLES ); }
|
||||
|
||||
set_nerf_scalar( field, value ) { self.nerf_scalars[field] = value; }
|
||||
get_nerf_scalar( field ) { return self.nerf_scalars[field]; }
|
||||
get_selected_nerf( index ) { return self getcoopplayerdata( "alienPlayerLoadout", "nerfs", index ); }
|
||||
|
||||
// Interface function for external systems
|
||||
prestige_getDamageTakenScalar() { return get_nerf_scalar( CONST_REF_TAKE_MORE_DAMAGE ); }
|
||||
prestige_getThreatbiasScalar() { return get_nerf_scalar( CONST_REF_HIGHER_THREATBIAS ); }
|
||||
prestige_getWalletSizeScalar() { return get_nerf_scalar( CONST_REF_SMALLER_WALLET ); }
|
||||
prestige_getMoneyEarnedScalar() { return get_nerf_scalar( CONST_REF_EARN_LESS_MONEY ); }
|
||||
prestige_getWeaponDamageScalar() { return get_nerf_scalar( CONST_REF_LOWER_WEAPON_DAMAGE ); }
|
||||
prestige_getNoClassAllowed() { return get_nerf_scalar( CONST_REF_NO_CLASS_ALLOWED ); }
|
||||
prestige_getPistolsOnly() { return get_nerf_scalar( CONST_REF_PISTOLS_ONLY ); }
|
||||
prestige_getSlowHealthRegenScalar() { return get_nerf_scalar( CONST_REF_SLOW_HEALTH_REGEN ); }
|
||||
prestige_getMoveSlowScalar() { return get_nerf_scalar( CONST_REF_MOVE_SLOWER ); }
|
||||
prestige_getNoAbilities() { return get_nerf_scalar( CONST_REF_NO_ABILITIES ); }
|
||||
prestige_getMinAmmo() { return get_nerf_scalar( CONST_REF_MIN_AMMO ); }
|
||||
prestige_getNoDeployables() { return get_nerf_scalar( CONST_REF_NO_DEPLOYABLES ); }
|
677
maps/mp/alien/_progression.gsc
Normal file
677
maps/mp/alien/_progression.gsc
Normal file
@ -0,0 +1,677 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\alien\_utility;
|
||||
#include maps\mp\agents\_agent_utility;
|
||||
#include maps\mp\alien\_persistence;
|
||||
|
||||
MAX_CURRENCY = 6000;
|
||||
ACTION_SLOT_MAX_FREQUENCY = 0.2;
|
||||
|
||||
main()
|
||||
{
|
||||
// init perks from data table
|
||||
maps\mp\alien\_perks::init_perks();
|
||||
|
||||
// init combat resources from data table
|
||||
maps\mp\alien\_combat_resources::init_combat_resources();
|
||||
}
|
||||
|
||||
//=== Common ===
|
||||
|
||||
player_setup()
|
||||
{
|
||||
self SetActionSlot( 1, "" );
|
||||
self SetActionSlot( 2, "" );
|
||||
self SetActionSlot( 3, "" );
|
||||
self SetActionSlot( 4, "" );
|
||||
|
||||
self NotifyOnPlayerCommand( "action_slot_1", "+actionslot 1" );
|
||||
self NotifyOnPlayerCommand( "action_slot_2", "+actionslot 2" );
|
||||
self NotifyOnPlayerCommand( "action_slot_3", "+actionslot 3" );
|
||||
self NotifyOnPlayerCommand( "action_slot_4", "+actionslot 4" );
|
||||
self NotifyOnPlayerCommand( "action_slot_1", "+actionslot 5" );
|
||||
self NotifyOnPlayerCommand( "action_slot_2", "+actionslot 6" );
|
||||
self NotifyOnPlayerCommand( "action_slot_3", "+actionslot 7" );
|
||||
self NotifyOnPlayerCommand( "action_use", "+attack");
|
||||
self NotifyOnPlayerCommand( "action_use", "+attack_akimbo_accessible");
|
||||
self NotifyOnPlayerCommand( "change_weapon", "weapnext");
|
||||
|
||||
self thread player_watcher();
|
||||
}
|
||||
|
||||
player_watcher()
|
||||
{
|
||||
if ( can_use_munition() )
|
||||
{
|
||||
self thread player_action_slot( level.alien_combat_resources[ "munition" ][ self get_selected_dpad_up() ], ::get_dpad_up_level, "action_slot_1" );
|
||||
self thread player_action_slot( level.alien_combat_resources[ "support" ][ self get_selected_dpad_down() ], ::get_dpad_down_level, "action_slot_2" );
|
||||
}
|
||||
if ( can_use_ability() )
|
||||
{
|
||||
self thread player_action_slot( level.alien_combat_resources[ "defense" ][ self get_selected_dpad_left() ], ::get_dpad_left_level, "action_slot_3" );
|
||||
self thread player_action_slot( level.alien_combat_resources[ "offense" ][ self get_selected_dpad_right() ], ::get_dpad_right_level, "action_slot_4" );
|
||||
}
|
||||
self thread player_watch_upgrade();
|
||||
|
||||
if ( !is_chaos_mode() )
|
||||
self thread player_watch_currency_transfer();
|
||||
}
|
||||
|
||||
can_use_munition()
|
||||
{
|
||||
if ( is_chaos_mode() )
|
||||
return false;
|
||||
|
||||
if ( self maps\mp\alien\_prestige::prestige_getNoDeployables() == 1.0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
can_use_ability() //checks the nerf_no_abilities and allows or disallows the left and right abilities
|
||||
{
|
||||
if ( self maps\mp\alien\_prestige::prestige_getNoAbilities() == 1.0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
player_watch_upgrade()
|
||||
{
|
||||
self thread player_watch_dpad_upgrade( level.alien_combat_resources[ "munition" ][ self get_selected_dpad_up() ] );
|
||||
self thread player_watch_dpad_upgrade( level.alien_combat_resources[ "support" ][ self get_selected_dpad_down() ] );
|
||||
self thread player_watch_dpad_upgrade( level.alien_combat_resources[ "defense" ][ self get_selected_dpad_left() ] );
|
||||
self thread player_watch_dpad_upgrade( level.alien_combat_resources[ "offense" ][ self get_selected_dpad_right() ] );
|
||||
|
||||
self thread player_watch_perk_upgrade( level.alien_perks["perk_0"][ self get_selected_perk_0() ], "perk_0" );
|
||||
self thread player_watch_perk_upgrade( level.alien_perks["perk_1"][ self get_selected_perk_1() ], "perk_1" );
|
||||
}
|
||||
|
||||
player_watch_dpad_upgrade( resource )
|
||||
{
|
||||
self player_watch_upgrade_internal( resource, resource.type );
|
||||
}
|
||||
|
||||
player_watch_perk_upgrade( resource, slot )
|
||||
{
|
||||
self thread player_watch_upgrade_internal( resource, slot );
|
||||
self thread player_handle_perk_upgrades( resource, slot );
|
||||
}
|
||||
|
||||
player_watch_upgrade_internal( resource, type )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
notifyname = type + "_try_upgrade";
|
||||
while( true )
|
||||
{
|
||||
self waittillmatch( "luinotifyserver", notifyname );
|
||||
rank = self get_upgrade_level( type );
|
||||
|
||||
if ( (rank + 1 < resource.upgrades.size) && self try_take_player_points( resource.upgrades[rank + 1].point_cost ) )
|
||||
{
|
||||
rank += 1;
|
||||
self set_upgrade_level( type, rank );
|
||||
self notify( "upgrade_" + type );
|
||||
|
||||
// track upgrades
|
||||
self thread update_resource_stats( "upgrade", resource.ref, 1 );
|
||||
|
||||
maps\mp\alien\_alien_matchdata::record_perk_upgrade( resource.ref );
|
||||
|
||||
// ============ BBPRINT for combat resource upgrade =============
|
||||
cyclenum = -1;
|
||||
if ( isdefined( level.current_cycle_num ) )
|
||||
cyclenum = level.current_cycle_num;
|
||||
|
||||
playername = "unknown";
|
||||
if ( isdefined( self.name ) )
|
||||
playername = self.name;
|
||||
|
||||
hivename = "unknown";
|
||||
if ( isdefined( level.current_hive_name ) )
|
||||
hivename = level.current_hive_name;
|
||||
|
||||
/#
|
||||
if ( GetDvarInt( "alien_bbprint_debug" ) > 0 )
|
||||
{
|
||||
IPrintLnBold( "^8bbprint: aliencombatresourceupgraded \n" +
|
||||
" cyclenum=" + cyclenum +
|
||||
" hivename=" + hivename +
|
||||
" resource=" + resource.ref +
|
||||
" resourcelevel=" + rank +
|
||||
" ownername=" + playername );
|
||||
}
|
||||
#/
|
||||
|
||||
bbprint( "aliencombatresourceupgraded",
|
||||
"cyclenum %i hivename %s resource %s resourcelevel %s ownername %s ",
|
||||
cyclenum,
|
||||
hivename,
|
||||
resource.ref,
|
||||
rank,
|
||||
playername );
|
||||
// ============ BBPRINT for combat resource usage [END] =============
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=== Perks ===
|
||||
|
||||
get_perk_ref_at_upgrade_level( perk_type, perk_ref, upgrade_level )
|
||||
{
|
||||
return ( level.alien_perks[ perk_type ][ perk_ref ].upgrades[ upgrade_level ].ref );
|
||||
}
|
||||
|
||||
player_handle_perk_upgrades( resource, type )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "upgrade_" + type );
|
||||
rank = self get_upgrade_level( type );
|
||||
assert( rank > 0 );
|
||||
unset_perk( get_perk_ref_at_upgrade_level( type, resource.ref, rank - 1 ) );
|
||||
set_perk( get_perk_ref_at_upgrade_level( type, resource.ref, rank ) );
|
||||
|
||||
//kind of hacky, but this is probably the best place to piggyback for the secondary class upgrade
|
||||
secondaryPerk = get_selected_perk_0_secondary();
|
||||
if ( type == "perk_0" && secondaryPerk != "perk_none" )
|
||||
{
|
||||
secondaryResource = level.alien_perks["perk_0"][ secondaryPerk ];
|
||||
unset_perk( get_perk_ref_at_upgrade_level( type, secondaryResource.ref, rank - 1 ) );
|
||||
set_perk( get_perk_ref_at_upgrade_level( type, secondaryResource.ref, rank ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
restore_all_perks()
|
||||
{
|
||||
perK_0_ref = self get_selected_perk_0();
|
||||
perk_0_level = self get_perk_0_level();
|
||||
set_perk( get_perk_ref_at_upgrade_level( "perk_0", perK_0_ref, perk_0_level ) );
|
||||
|
||||
secondaryPerk = get_selected_perk_0_secondary();
|
||||
if ( secondaryPerk != "perk_none" )
|
||||
{
|
||||
secondaryResource = level.alien_perks["perk_0"][ secondaryPerk ];
|
||||
set_perk( get_perk_ref_at_upgrade_level( "perk_0", secondaryResource.ref, perk_0_level ) );
|
||||
}
|
||||
}
|
||||
|
||||
//=== Action ===
|
||||
player_cancel()
|
||||
{
|
||||
self player_cancel_internal();
|
||||
|
||||
//cleanup
|
||||
self EnableWeapons( );
|
||||
|
||||
// Don't think we need this as it was definately switching the riotshield back to the pistol quickly when that was not intended. Put all last.weapon switching directly into the use callback.
|
||||
// if ( IsDefined( self.last_weapon ) )
|
||||
// self SwitchToWeapon( self.last_weapon );
|
||||
|
||||
self.alien_used_resource = undefined;
|
||||
}
|
||||
|
||||
player_cancel_internal()
|
||||
{
|
||||
self endon( "player_action_slot_restart" );
|
||||
self endon( "fired_ability_gun" );
|
||||
|
||||
self waittill_any( "change_weapon", "action_slot_1", "action_slot_2", "action_slot_3", "action_slot_4" ,"last_stand", "dpad_cancel" );
|
||||
if ( self is_holding_deployable() && !self.is_holding_crate_marker )
|
||||
{
|
||||
// special case for escape chopper, cancels whatever you have in your hand
|
||||
if ( !isdefined ( self.playerLinkedToChopper ) || !self.playerLinkedToChopper )
|
||||
{
|
||||
self.deployable = false;
|
||||
self notify( "cancel_deployable_via_marker" );
|
||||
if ( !self HasWeapon( "mortar_detonator_mp" ) && !self HasWeapon( "switchblade_laptop_mp" ) ) //special case for the mortar clacker and laptop, these need to get taken away from the player
|
||||
self notify( "player_action_slot_restart" );
|
||||
}
|
||||
}
|
||||
resource = self.alien_used_resource;
|
||||
rank = self.alien_used_resource_rank;
|
||||
self [[resource.callbacks.CancelUse]]( resource, rank );
|
||||
|
||||
self notify( "player_action_slot_restart" );
|
||||
}
|
||||
|
||||
player_watch_use()
|
||||
{
|
||||
self endon( "cancel_watch" );
|
||||
self waittill( "action_use" );
|
||||
return true;
|
||||
}
|
||||
|
||||
player_watch_riotshield_use( resource, rank )
|
||||
{
|
||||
self endon( "cancel_watch" );
|
||||
self _disableUsability();
|
||||
self thread reenable_usability( 3.1 );
|
||||
self waittill_any_timeout( 3, "action_use", "riotshield_block", "riotshield_melee" );
|
||||
|
||||
if ( self player_has_enough_currency( Ceil( resource.upgrades[rank].cost ) ) )
|
||||
return true;
|
||||
else
|
||||
{
|
||||
self [[resource.callbacks.CancelUse]]( resource, rank );
|
||||
self notify( "action_finish_used" );
|
||||
self notify( "player_action_slot_restart" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
player_watch_equalizer_use( resource, rank )
|
||||
{
|
||||
self endon( "cancel_watch" );
|
||||
self waittill_any_timeout( 3, "action_use" );
|
||||
if ( self player_has_enough_currency( Ceil( resource.upgrades[rank].cost ) ) )
|
||||
return true;
|
||||
else
|
||||
{
|
||||
self [[resource.callbacks.CancelUse]]( resource, rank );
|
||||
self notify( "action_finish_used" );
|
||||
self notify( "player_action_slot_restart" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
player_watch_use_manned_turret()
|
||||
{
|
||||
self endon( "cancel_watch" );
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "action_use" );
|
||||
if ( isDefined ( self.carriedSentry ) )
|
||||
{
|
||||
if ( is_true ( self.carriedSentry.canbeplaced ) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
player_watch_use_ims()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "cancel_watch" );
|
||||
|
||||
self waittill( "IMS_placed" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
player_watch_use_sentry()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "cancel_watch" );
|
||||
assertex( isdefined( self.current_sentry ), "Sentry ent not set on owner holding it" );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
self waittill( "action_use" );
|
||||
|
||||
if ( isdefined( self.current_sentry ) )
|
||||
{
|
||||
canBePlaced = self maps\mp\alien\_autosentry_alien::can_place_sentry( self.current_sentry );
|
||||
if ( canBePlaced )
|
||||
return true;
|
||||
}
|
||||
|
||||
wait ( 0.05 );
|
||||
}
|
||||
}
|
||||
|
||||
player_use( resource, rank )
|
||||
{
|
||||
// self.last_weapon = self GetCurrentWeapon();
|
||||
|
||||
self endon( "player_action_slot_restart" );
|
||||
self endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
self thread player_cancel();
|
||||
|
||||
self [[resource.callbacks.TryUse]]( resource, rank );
|
||||
|
||||
if( self [[resource.callbacks.CanUse]]( resource ) )
|
||||
{
|
||||
if ( !show_alternate_spend_hint( resource ) ) //these already have a use hint, just need to show how to cancel
|
||||
self thread maps\mp\alien\_hud::createSpendHintHUD( resource, rank );
|
||||
else
|
||||
self thread maps\mp\alien\_hud::createSpendHintHUD( resource, rank , &"ALIENS_PATCH_CANCEL_USE" );
|
||||
|
||||
usage = wait_for_use( resource, rank );
|
||||
if ( !isDefined ( usage ) || !usage )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !self player_has_enough_currency( Ceil( resource.upgrades[rank].cost ) ) )
|
||||
{
|
||||
self notify("dpad_cancel" );
|
||||
return;
|
||||
}
|
||||
|
||||
self PlayLocalSound( "alien_killstreak_equip" );
|
||||
self thread [[resource.callbacks.Use]]( resource, rank );
|
||||
|
||||
// track resource usage
|
||||
self thread update_resource_stats( "purchase", resource.ref, 1 );
|
||||
|
||||
self take_player_currency( Ceil( resource.upgrades[rank].cost ), false, "ability" );
|
||||
|
||||
self.alien_used_resource = undefined;
|
||||
|
||||
// ============ BBPRINT for combat resource usage =============
|
||||
cyclenum = -1;
|
||||
if ( isdefined( level.current_cycle_num ) )
|
||||
cyclenum = level.current_cycle_num;
|
||||
|
||||
playername = "unknown";
|
||||
if ( isdefined( self.name ) )
|
||||
playername = self.name;
|
||||
|
||||
hivename = "unknown";
|
||||
if ( isdefined( level.current_hive_name ) )
|
||||
hivename = level.current_hive_name;
|
||||
|
||||
/#
|
||||
if ( GetDvarInt( "alien_bbprint_debug" ) > 0 )
|
||||
{
|
||||
IPrintLnBold( "^8bbprint: aliencombatresourceused \n" +
|
||||
" cyclenum=" + cyclenum +
|
||||
" hivename=" + hivename +
|
||||
" resource=" + resource.ref +
|
||||
" resourcelevel=" + rank +
|
||||
" ownername=" + playername );
|
||||
}
|
||||
#/
|
||||
|
||||
bbprint( "aliencombatresourceused",
|
||||
"cyclenum %i hivename %s resource %s resourcelevel %s ownername %s ",
|
||||
cyclenum,
|
||||
hivename,
|
||||
resource.ref,
|
||||
rank,
|
||||
playername );
|
||||
|
||||
// ============ BBPRINT for combat resource usage [END] =============
|
||||
|
||||
self notify( "action_finish_used" );
|
||||
self notify( "player_action_slot_restart" );
|
||||
}
|
||||
}
|
||||
|
||||
show_alternate_spend_hint( resource )
|
||||
{
|
||||
//check for maaws rocket on certain maps
|
||||
if(level_uses_MAAWS() && IsSubStr( resource.ref,"predator" ))
|
||||
return true;
|
||||
|
||||
return ( IsSubStr( resource.ref,"turret" ) || isSubStr( resource.ref, "_ims") );
|
||||
}
|
||||
|
||||
wait_for_use( resource, rank )
|
||||
{
|
||||
switch ( resource.ref )
|
||||
{
|
||||
case "dpad_sentry":
|
||||
return player_watch_use_sentry();
|
||||
|
||||
case "dpad_minigun_turret":
|
||||
case "dpad_gl_sentry":
|
||||
return player_watch_use_manned_turret();
|
||||
|
||||
case "dpad_ims":
|
||||
return player_watch_use_ims();
|
||||
|
||||
case "dpad_team_ammo_reg":
|
||||
case "dpad_team_armor":
|
||||
case "dpad_team_boost":
|
||||
case "dpad_team_adrenaline":
|
||||
case "dpad_team_explosives":
|
||||
case "dpad_team_randombox":
|
||||
case "dpad_team_ammo_stun":
|
||||
case "dpad_team_ammo_explo":
|
||||
case "dpad_team_ammo_ap":
|
||||
case "dpad_team_ammo_in":
|
||||
case "dpad_placeholder_ammo_2":
|
||||
return player_watch_box_thrown();
|
||||
|
||||
case "dpad_riotshield":
|
||||
return player_watch_riotshield_use( resource, rank );
|
||||
|
||||
case "dpad_war_machine":
|
||||
case "dpad_death_machine":
|
||||
return player_watch_equalizer_use( resource, rank );
|
||||
|
||||
case "dpad_predator":
|
||||
//if not maaws, just do the default
|
||||
if(level_uses_MAAWS())
|
||||
return player_watch_equalizer_use( resource, rank );
|
||||
|
||||
default:
|
||||
return player_watch_use();
|
||||
}
|
||||
}
|
||||
|
||||
player_watch_box_thrown()
|
||||
{
|
||||
self endon( "cancel_watch" );
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "grenade_fire", item_thrown, weapon_name );
|
||||
|
||||
if ( weapon_name == "aliendeployable_crate_marker_mp" )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
player_action_slot_internal( resource, get_rank_func, waittillname )
|
||||
{
|
||||
self endon( "player_action_slot_block" );
|
||||
self endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( waittillname );
|
||||
|
||||
if ( is_true ( self.player_action_disabled ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self UseButtonPressed() ) //can't hold use button at the same time as pressing a dpad button or bad things can happen
|
||||
continue;
|
||||
|
||||
if ( self IsOnLadder() )
|
||||
continue;
|
||||
|
||||
if ( self has_special_weapon() )
|
||||
{
|
||||
self setLowerMessage( "cant_buy", &"ALIEN_COLLECTIBLES_PLAYER_HAS_SPECIALWEAPON", 3 );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( is_true ( self.picking_up_item ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( self IsUsingTurret() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( is_true ( self.hasprogressbar ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( is_true ( self.isCarrying ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isDefined ( self.throwingGrenade ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( flag_exist( "escape_conditions_met" ) && flag ( "escape_conditions_met" ) )
|
||||
continue;
|
||||
|
||||
rank = self [[get_rank_func]]();
|
||||
|
||||
if ( !self player_has_enough_currency( Ceil( resource.upgrades[rank].cost ) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
self _DisableUsability();
|
||||
self thread reenable_usability();
|
||||
|
||||
if ( !IsDefined( self.alien_used_resource ) )
|
||||
{
|
||||
if ( self [[resource.callbacks.CanPurchase]]( resource, rank ) )
|
||||
{
|
||||
self.alien_used_resource = resource;
|
||||
self.alien_used_resource_rank = rank;
|
||||
self thread player_use( resource, rank );
|
||||
self notify( "player_action_slot_block" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reenable_usability( wait_time )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
if( !isDefined( wait_time ) )
|
||||
wait_time = 1;
|
||||
|
||||
wait ( wait_time );
|
||||
self _enableUsability();
|
||||
}
|
||||
|
||||
player_action_slot( resource, get_dpad_level_func, dpad_notify_name )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
while( true )
|
||||
{
|
||||
self thread player_action_slot_internal( resource, get_dpad_level_func, dpad_notify_name );
|
||||
self waittill( "player_action_slot_restart" );
|
||||
wait ACTION_SLOT_MAX_FREQUENCY;
|
||||
}
|
||||
}
|
||||
|
||||
// ========== Player currency transfer ============
|
||||
|
||||
player_watch_currency_transfer()
|
||||
{
|
||||
// self is player
|
||||
self endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
wait 0.05;
|
||||
|
||||
if ( isPlayingSolo() )
|
||||
return;
|
||||
|
||||
currency_rank = 0;
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
// allow drop of health pack
|
||||
if ( self is_drop_button_pressed() )
|
||||
{
|
||||
// wait for release
|
||||
hold_time = 2;
|
||||
while ( self is_drop_button_pressed() && hold_time >= 0 )
|
||||
{
|
||||
wait 0.05;
|
||||
hold_time -= 0.05;
|
||||
}
|
||||
|
||||
if ( hold_time > 0 )
|
||||
{
|
||||
wait 0.05;
|
||||
continue;
|
||||
}
|
||||
|
||||
// drop money!
|
||||
assertex( isdefined( level.deployable_currency_ranks[ currency_rank ] ), "Rank out of bound" );
|
||||
if ( self player_has_enough_currency( level.deployable_currency_ranks[ currency_rank ] ) )
|
||||
{
|
||||
self deploy_currency( currency_rank );
|
||||
level notify( "currency_dropped", self );
|
||||
}
|
||||
|
||||
// prevent repeated dropping of money
|
||||
while ( self is_drop_button_pressed() )
|
||||
wait 0.05;
|
||||
}
|
||||
wait 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
is_drop_button_pressed()
|
||||
{
|
||||
if ( !isdefined( self ) || !isalive( self ) )
|
||||
return false;
|
||||
|
||||
if ( isdefined( self.laststand ) && self.laststand )
|
||||
return false;
|
||||
|
||||
pressed_button_1 = self AdsButtonPressed();
|
||||
pressed_button_2 = self JumpButtonPressed();
|
||||
|
||||
return pressed_button_1 && pressed_button_2;
|
||||
}
|
||||
|
||||
deploy_currency( currency_rank )
|
||||
{
|
||||
// self is player who drops this
|
||||
self endon( "disconnect" );
|
||||
self notify( "deploying_currency" );
|
||||
|
||||
assertex( isdefined( level.deployable_currency_ranks[ currency_rank ] ), "Rank out of bound" );
|
||||
|
||||
self take_player_currency( level.deployable_currency_ranks[ currency_rank ],true );
|
||||
|
||||
boxType = "deployable_currency";
|
||||
|
||||
// only one time use
|
||||
self.team_currency_rank = currency_rank;
|
||||
maxUses = level.boxSettings[ boxType ].maxUses; // store old maxUses for restoring later
|
||||
level.boxSettings[ boxType ].maxUses = 1; // override with 1
|
||||
box = maps\mp\alien\_deployablebox::createBoxForPlayer( boxType, self.origin , self );
|
||||
level.boxSettings[ boxType ].maxUses = maxUses; // restore
|
||||
box.upgrade_rank = currency_rank;
|
||||
box playSoundToPlayer( level.boxSettings[ boxType ].deployedSfx, self );
|
||||
|
||||
self thread currency_box_think( box );
|
||||
}
|
||||
|
||||
currency_box_think( box )
|
||||
{
|
||||
// self is player
|
||||
self endon( "disconnect" );
|
||||
box endon( "death" );
|
||||
|
||||
wait 0.05;
|
||||
box thread maps\mp\alien\_deployablebox::box_setActive( true );
|
||||
|
||||
// waittill deploying new box, remove old box if exist
|
||||
self waittill( "deploying_currency" );
|
||||
if ( isdefined( box ) )
|
||||
box maps\mp\alien\_deployablebox::box_leave();
|
||||
}
|
2954
maps/mp/alien/_spawn_director.gsc
Normal file
2954
maps/mp/alien/_spawn_director.gsc
Normal file
File diff suppressed because it is too large
Load Diff
2270
maps/mp/alien/_spawnlogic.gsc
Normal file
2270
maps/mp/alien/_spawnlogic.gsc
Normal file
File diff suppressed because it is too large
Load Diff
360
maps/mp/alien/_switchblade_alien.gsc
Normal file
360
maps/mp/alien/_switchblade_alien.gsc
Normal file
@ -0,0 +1,360 @@
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include common_scripts\utility;
|
||||
|
||||
|
||||
//============================================
|
||||
// constants
|
||||
//============================================
|
||||
CONST_DRONE_HIVE_DEBUG = false;
|
||||
CONST_MISSILE_COUNT = 0;
|
||||
|
||||
|
||||
//============================================
|
||||
// init
|
||||
//============================================
|
||||
init()
|
||||
{
|
||||
level.killstreakFuncs["drone_hive"] = ::tryUseDroneHive;
|
||||
|
||||
level.droneMissileSpawnArray = GetEntArray( "remoteMissileSpawn", "targetname" );
|
||||
|
||||
foreach( missileSpawn in level.droneMissileSpawnArray )
|
||||
{
|
||||
missileSpawn.targetEnt = GetEnt( missileSpawn.target, "targetname" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// tryUseDroneHive
|
||||
//============================================
|
||||
tryUseDroneHive( rank, num_missiles, missile_name, altitude, baby_missile_name )
|
||||
{
|
||||
/#
|
||||
if( (!IsDefined(level.droneMissileSpawnArray) || !level.droneMissileSpawnArray.size) )
|
||||
{
|
||||
AssertMsg( "map needs remoteMissileSpawn entities" );
|
||||
}
|
||||
#/
|
||||
self notify( "action_use" );
|
||||
level thread maps\mp\alien\_music_and_dialog::PlayVOForPredator( self );
|
||||
return useDroneHive( self, rank, num_missiles, missile_name, altitude, baby_missile_name );
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// useDroneHive
|
||||
//============================================
|
||||
useDroneHive( player, rank, num_missiles, missile_name, altitude, baby_missile_name )
|
||||
{
|
||||
player setUsingRemote( "remotemissile" );
|
||||
|
||||
self VisionSetNakedForPlayer( "black_bw", 0.75 );
|
||||
self maps\mp\alien\_utility::restore_client_fog( 0 );
|
||||
self thread set_visionset_for_watching_players( "black_bw", 0.75, 1.0 );
|
||||
//blackOutWait = self waittill_any_timeout( 0.2, "disconnect", "death" );
|
||||
|
||||
level thread runDroneHive( player, rank, num_missiles, missile_name, altitude, baby_missile_name );
|
||||
// level thread monitorDisownKillstreaks( player );
|
||||
level thread monitorGameEnd( player, rank );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// useDroneHive
|
||||
//============================================
|
||||
runDroneHive( player, rank, num_missiles, missile_name, altitude, baby_missile_name )
|
||||
{
|
||||
player endon( "killstreak_disowned" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
if ( !IsDefined( missile_name ) )
|
||||
missile_name = "switchblade_rocket_mp";
|
||||
|
||||
if ( !IsDefined( num_missiles ) )
|
||||
num_missiles = 0;
|
||||
|
||||
player notifyOnPlayerCommand( "missileTargetSet", "+attack" );
|
||||
remoteMissileSpawn = getClosest( player.origin,level.droneMissileSpawnArray );
|
||||
|
||||
startPos = remoteMissileSpawn.origin;
|
||||
targetPos = player.origin;
|
||||
vector = VectorNormalize( startPos - targetPos );
|
||||
startPos = ( vector * altitude ) + targetPos;
|
||||
|
||||
/#
|
||||
if( CONST_DRONE_HIVE_DEBUG )
|
||||
{
|
||||
level thread drawLine( startPos, targetPos, 15, (1,0,0) );
|
||||
}
|
||||
#/
|
||||
|
||||
rocket = MagicBullet( missile_name, startpos, targetPos, player );
|
||||
rocket SetCanDamage( true );
|
||||
|
||||
if( num_missiles != 0 )
|
||||
rocket DisableMissileBoosting();
|
||||
|
||||
rocket.team = player.team;
|
||||
|
||||
rocket.type = "remote";
|
||||
rocket.owner = player;
|
||||
rocket.entityNumber = rocket GetEntityNumber();
|
||||
|
||||
level.rockets[ rocket.entityNumber ] = rocket;
|
||||
level.remoteMissileInProgress = true;
|
||||
|
||||
level thread monitorDeath( rocket );
|
||||
level thread monitorBoost( rocket );
|
||||
|
||||
missileEyes( player, rocket, rank );
|
||||
// player setDepthOfField( 0, 96, 768, 4000, 4, 0 );
|
||||
player notify( "action_use" );
|
||||
|
||||
player SetClientOmnvar( "ui_predator_missile", 1 );
|
||||
|
||||
missileCount = 0;
|
||||
|
||||
while( true )
|
||||
{
|
||||
result = rocket waittill_any_return( "death", "missileTargetSet" );
|
||||
|
||||
if( result == "death" )
|
||||
break;
|
||||
|
||||
if ( missileCount < num_missiles )
|
||||
{
|
||||
level thread spawnSwitchBlade( rocket, missileCount, baby_missile_name );
|
||||
missileCount++;
|
||||
}
|
||||
|
||||
if( missileCount == num_missiles )
|
||||
rocket EnableMissileBoosting();
|
||||
}
|
||||
|
||||
player.turn_off_class_skill_activation = undefined;
|
||||
returnPlayer( player, rank );
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// getEnemyTargets
|
||||
//============================================
|
||||
getEnemyTargets( owner )
|
||||
{
|
||||
enemyTargets = [];
|
||||
|
||||
foreach ( agent in level.agentArray )
|
||||
{
|
||||
// only active
|
||||
if ( !IsDefined( agent.isActive ) || !agent.isActive )
|
||||
continue;
|
||||
|
||||
enemyTargets[ enemyTargets.size ] = agent;
|
||||
}
|
||||
|
||||
return enemyTargets;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// spawnSwitchBlade
|
||||
//============================================
|
||||
spawnSwitchBlade( rocket, spawnOnLeft, baby_missile_name )
|
||||
{
|
||||
rocket.owner playLocalSound( "ammo_crate_use" );
|
||||
|
||||
forwardDir = AnglesToForward( rocket.angles );
|
||||
rightDir = AnglesToRight( rocket.angles );
|
||||
spawnOffset = (35,35,35);
|
||||
targetOffset = (15000,15000,15000);
|
||||
|
||||
if(spawnOnLeft)
|
||||
spawnOffset = spawnOffset * -1;
|
||||
|
||||
result = BulletTrace( rocket.origin, rocket.origin + (forwardDir * targetOffset), false, rocket );
|
||||
|
||||
targetOffset = targetOffset * result["fraction"];
|
||||
startPoistion = rocket.origin + (rightDir * spawnOffset );
|
||||
targetLocation = startPoistion + (forwardDir * targetOffset );
|
||||
|
||||
targets = rocket.owner getEnemyTargets( rocket.owner );
|
||||
|
||||
missile = MagicBullet( baby_missile_name, startPoistion, targetLocation, rocket.owner );
|
||||
|
||||
TargetArea = 262144; //512*512
|
||||
|
||||
foreach ( targ in targets )
|
||||
{
|
||||
if ( Distance2dsquared( targ.origin, targetLocation ) < TargetArea )
|
||||
{
|
||||
missile Missile_SetTargetEnt( targ );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
missile SetCanDamage( true );
|
||||
|
||||
missile.team = rocket.team;
|
||||
|
||||
missile.owner = rocket.owner;
|
||||
missile.entityNumber = missile GetEntityNumber();
|
||||
|
||||
level.rockets[ missile.entityNumber ] = missile;
|
||||
level thread monitorDeath( rocket );
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// getNextMissileSpawnIndex
|
||||
//============================================
|
||||
getNextMissileSpawnIndex( oldIndex )
|
||||
{
|
||||
index = oldIndex + 1;
|
||||
|
||||
if( index == level.droneMissileSpawnArray.size )
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// monitorBoost
|
||||
//============================================
|
||||
monitorBoost( rocket )
|
||||
{
|
||||
rocket endon( "death" );
|
||||
|
||||
while( true )
|
||||
{
|
||||
rocket.owner waittill( "missileTargetSet" );
|
||||
rocket notify( "missileTargetSet" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// missileEyes
|
||||
//============================================
|
||||
missileEyes( player, rocket, rank )
|
||||
{
|
||||
delayTime = 1.0;
|
||||
|
||||
player freezeControlsWrapper( true );
|
||||
|
||||
if ( rank >= 1 )
|
||||
player thread delayedFOFOverlay();
|
||||
|
||||
player CameraLinkTo( rocket, "tag_origin" );
|
||||
player ControlsLinkTo( rocket );
|
||||
player VisionSetMissilecamForPlayer( "default", delayTime );
|
||||
player set_visionset_for_watching_players( "default", delayTime, undefined, true );
|
||||
player VisionSetMissilecamForPlayer( game["thermal_vision_trinity"], 0.0 );
|
||||
level thread unfreezeControls( player, delayTime );
|
||||
}
|
||||
|
||||
delayedFOFOverlay()
|
||||
{
|
||||
self endon ( "death" );
|
||||
self endon ( "disconnect" );
|
||||
level endon ( "game_ended" );
|
||||
|
||||
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( 0.25 );
|
||||
|
||||
self ThermalVisionFOFOverlayOn();
|
||||
}
|
||||
|
||||
//============================================
|
||||
// unfreezeControls
|
||||
//============================================
|
||||
unfreezeControls( player, delayTime, i )
|
||||
{
|
||||
player endon( "disconnect" );
|
||||
|
||||
wait( delayTime - 0.35 );
|
||||
player freezeControlsWrapper( false );
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// monitorDisownKillstreaks
|
||||
//============================================
|
||||
monitorDisownKillstreaks( player, rank )
|
||||
{
|
||||
player endon( "end_kill_streak" );
|
||||
|
||||
player waittill( "killstreak_disowned" );
|
||||
|
||||
level thread returnPlayer( player, rank );
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// monitorGameEnd
|
||||
//============================================
|
||||
monitorGameEnd( player, rank )
|
||||
{
|
||||
player endon( "end_kill_streak" );
|
||||
|
||||
level waittill( "game_ended" );
|
||||
|
||||
level thread returnPlayer( player, rank );
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// monitorDeath
|
||||
//============================================
|
||||
monitorDeath( killStreakEnt )
|
||||
{
|
||||
killStreakEnt waittill( "death" );
|
||||
|
||||
level.rockets[ killStreakEnt.entityNumber ] = undefined;
|
||||
level.remoteMissileInProgress = undefined;
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
// returnPlayer
|
||||
//============================================
|
||||
returnPlayer( player, rank )
|
||||
{
|
||||
if( !IsDefined(player) )
|
||||
return;
|
||||
|
||||
player SetClientOmnvar( "ui_predator_missile", 2 );
|
||||
player notify( "end_kill_streak" );
|
||||
|
||||
player freezeControlsWrapper( true );
|
||||
if ( rank >= 1 )
|
||||
{
|
||||
player ThermalVisionFOFOverlayOff();
|
||||
}
|
||||
|
||||
player ControlsUnlink();
|
||||
// player setDepthOfField( 0, 96, 768, 4000, 6, 1.8 );
|
||||
player setExitPredatorVisionSet();
|
||||
|
||||
wait( 0.95 );
|
||||
|
||||
player CameraUnlink();
|
||||
player SetClientOmnvar( "ui_predator_missile", 0 );
|
||||
player clearUsingRemote();
|
||||
if ( IsDefined( player.last_weapon ) )
|
||||
player SwitchToWeapon( player.last_weapon );
|
||||
}
|
||||
|
||||
setExitPredatorVisionSet()
|
||||
{
|
||||
transition_time = 0.5;
|
||||
|
||||
self VisionSetNakedForPlayer( "", transition_time );
|
||||
self VisionSetStage( 0, transition_time );
|
||||
}
|
2096
maps/mp/alien/_trap.gsc
Normal file
2096
maps/mp/alien/_trap.gsc
Normal file
File diff suppressed because it is too large
Load Diff
140
maps/mp/alien/_unlock.gsc
Normal file
140
maps/mp/alien/_unlock.gsc
Normal file
@ -0,0 +1,140 @@
|
||||
// For the alien mode, certain unlocks are not based on the player's rank. This file keeps track of the in-game condition that
|
||||
// will trigger those unlocks.
|
||||
|
||||
ALIEN_UNLOCK_TABLE = "mp/alien/unlocktable.csv";
|
||||
|
||||
TABLE_STARTING_ROW_INDEX = 100;
|
||||
TABLE_END_ROW_INDEX = 110;
|
||||
|
||||
TABLE_INDEX = 0;
|
||||
COLUMN_UNLOCK_ITEM = 1;
|
||||
COLUMN_UNLOCK_TYPE = 3;
|
||||
|
||||
GOAL_ESCAPE = 1;
|
||||
GOAL_ESCAPE_10_TIMES = 10;
|
||||
GOAL_ESCAPE_20_TIMES = 20;
|
||||
GOAL_ESCAPE_50_TIMES = 50;
|
||||
|
||||
init_unlock()
|
||||
{
|
||||
load_unlock_from_table();
|
||||
}
|
||||
|
||||
init_player_unlock()
|
||||
{
|
||||
self.unlock_list = [];
|
||||
|
||||
if ( isDefined( level.unlock_registration_func ) )
|
||||
[[level.unlock_registration_func]]();
|
||||
|
||||
if ( maps\mp\alien\_utility::is_true( level.include_default_unlocks ) )
|
||||
register_default_unlocks();
|
||||
}
|
||||
|
||||
register_default_unlocks()
|
||||
{
|
||||
register_unlock( "UNLOCK_ESCAPE" , 1, GOAL_ESCAPE , ::default_init );
|
||||
register_unlock( "UNLOCK_ESCAPE_10_TIMES", 2, GOAL_ESCAPE_10_TIMES, ::default_init );
|
||||
register_unlock( "UNLOCK_ESCAPE_20_TIMES", 3, GOAL_ESCAPE_20_TIMES, ::default_init );
|
||||
register_unlock( "UNLOCK_ESCAPE_50_TIMES", 4, GOAL_ESCAPE_50_TIMES, ::default_init );
|
||||
}
|
||||
|
||||
register_unlock( reference, index_map, goal, init_func )
|
||||
{
|
||||
unlock = spawnStruct();
|
||||
unlock [[init_func]]( index_map, goal );
|
||||
self.unlock_list[reference] = unlock;
|
||||
}
|
||||
|
||||
default_init( index_map, goal )
|
||||
{
|
||||
self.progress = 0;
|
||||
self.index_map = index_map;
|
||||
self.goal = goal;
|
||||
}
|
||||
|
||||
update_progress( progress_amount )
|
||||
{
|
||||
self.progress += progress_amount;
|
||||
}
|
||||
|
||||
is_goal_achieved()
|
||||
{
|
||||
return ( self.progress >= self.goal );
|
||||
}
|
||||
|
||||
is_valid_unlock( unlock )
|
||||
{
|
||||
return ( isDefined ( unlock ) );
|
||||
}
|
||||
|
||||
update_unlock( reference, progress_amt )
|
||||
{
|
||||
unlock = self.unlock_list[reference];
|
||||
|
||||
if ( !is_valid_unlock( unlock ) )
|
||||
return;
|
||||
|
||||
unlock update_progress( progress_amt );
|
||||
|
||||
if ( unlock is_goal_achieved() )
|
||||
{
|
||||
unlock_item_info = level.alien_unlock_data[unlock.index_map];
|
||||
|
||||
/#
|
||||
maps\mp\alien\_debug::debug_print_item_unlocked( unlock_item_info.item, unlock_item_info.type );
|
||||
#/
|
||||
//self unlockAlienItem( unlock_item_info.item, unlock_item_info.type ); //<TODO J.C.> Waiting for real unlock code function here
|
||||
}
|
||||
}
|
||||
|
||||
update_escape_item_unlock( players_escaped )
|
||||
{
|
||||
foreach( player in players_escaped )
|
||||
{
|
||||
times_escaped = player maps\mp\alien\_persistence::get_player_escaped();
|
||||
player update_personal_escape_item_unlock( times_escaped );
|
||||
|
||||
num_nerf_selected = player maps\mp\alien\_prestige::get_num_nerf_selected();
|
||||
most_nerfs_escaped_with = player maps\mp\alien\_persistence::get_player_highest_nerf_escape_count();
|
||||
|
||||
if ( num_nerf_selected > most_nerfs_escaped_with )
|
||||
{
|
||||
player SetCoopPlayerData( "alienPlayerStats", "headShots", num_nerf_selected );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_personal_escape_item_unlock( times_escaped )
|
||||
{
|
||||
update_unlock( "UNLOCK_ESCAPE" , 1 );
|
||||
update_unlock( "UNLOCK_ESCAPE_10_TIMES", times_escaped );
|
||||
update_unlock( "UNLOCK_ESCAPE_20_TIMES", times_escaped );
|
||||
update_unlock( "UNLOCK_ESCAPE_50_TIMES", times_escaped );
|
||||
}
|
||||
|
||||
load_unlock_from_table()
|
||||
{
|
||||
level.alien_unlock_data = [];
|
||||
|
||||
if ( isDefined ( level.alien_unlock_table ) )
|
||||
unlock_table = level.alien_unlock_table;
|
||||
else
|
||||
unlock_table = ALIEN_UNLOCK_TABLE;
|
||||
|
||||
for ( rowIndex = TABLE_STARTING_ROW_INDEX; rowIndex <= TABLE_END_ROW_INDEX; rowIndex++ )
|
||||
{
|
||||
unlock_item = tableLookup( unlock_table, TABLE_INDEX, rowIndex, COLUMN_UNLOCK_ITEM );
|
||||
|
||||
if ( unlock_item == "" )
|
||||
break;
|
||||
|
||||
unlock_type = tableLookup( unlock_table, TABLE_INDEX, rowIndex, COLUMN_UNLOCK_TYPE );
|
||||
|
||||
unlock_item_info = spawnStruct();
|
||||
unlock_item_info.item = unlock_item;
|
||||
unlock_item_info.type = unlock_type;
|
||||
|
||||
level.alien_unlock_data[level.alien_unlock_data.size] = unlock_item_info;
|
||||
}
|
||||
}
|
3670
maps/mp/alien/_utility.gsc
Normal file
3670
maps/mp/alien/_utility.gsc
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user