487 lines
14 KiB
Plaintext
487 lines
14 KiB
Plaintext
#include maps\mp\_utility;
|
|
#include common_scripts\utility;
|
|
#include maps\mp\_snd_common_mp;
|
|
|
|
EXO_REPULSOR_RADIUS = 385;
|
|
EXO_REPULSOR_REPEL_VEL = 800;
|
|
|
|
exo_repulsor_think() //self = player
|
|
{
|
|
self notify( "exo_repulsor_taken" ); // Cleans up existing Exo Trophy System threads.
|
|
|
|
level endon( "game_ended" );
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
self endon( "joined_team" );
|
|
self endon( "faux_spawn" );
|
|
self endon( "exo_repulsor_taken" );
|
|
|
|
if ( !self HasWeapon( "exorepulsor_equipment_mp" ) )
|
|
return;
|
|
|
|
exoRepulsorInit();
|
|
|
|
self thread MonitorPlayerDeath();
|
|
self thread wait_for_game_end();
|
|
|
|
while ( 1 )
|
|
{
|
|
self waittill( "exo_ability_activate", weapname );
|
|
|
|
if ( weapname == "exorepulsor_equipment_mp" )
|
|
{
|
|
self thread tryUseRepulsor();
|
|
}
|
|
}
|
|
}
|
|
|
|
exoRepulsorInit() //self = player
|
|
{
|
|
self.repulsorActive = false;
|
|
|
|
self BatterySetDischargeScale( "exorepulsor_equipment_mp", 1.0 );
|
|
full_energy = self BatteryGetSize( "exorepulsor_equipment_mp" );
|
|
self.projectilesStopped = 0;
|
|
|
|
if ( self GetTacticalWeapon() == "exorepulsor_equipment_mp" )
|
|
{
|
|
self SetClientOmnvar( "exo_ability_nrg_req0", 0 );
|
|
self SetClientOmnvar( "exo_ability_nrg_total0", full_energy );
|
|
self SetClientOmnvar( "ui_exo_battery_level0", full_energy );
|
|
}
|
|
else if ( self GetLethalWeapon() == "exorepulsor_equipment_mp" )
|
|
{
|
|
self SetClientOmnvar( "exo_ability_nrg_req1", 0 );
|
|
self SetClientOmnvar( "exo_ability_nrg_total1", full_energy );
|
|
self SetClientOmnvar( "ui_exo_battery_level1", full_energy );
|
|
}
|
|
|
|
// VFX
|
|
if ( !IsDefined( level.exo_repulsor_impact ) )
|
|
{
|
|
level.exo_repulsor_impact = LoadFX( "vfx/explosion/exo_repulsor_impact" );
|
|
}
|
|
if ( !IsDefined( level.exo_repulsor_activate_vfx ) )
|
|
{
|
|
level.exo_repulsor_activate_vfx = LoadFX( "vfx/unique/repulsor_bubble" );
|
|
}
|
|
if ( !IsDefined( level.exo_repulsor_deactivate_vfx ) )
|
|
{
|
|
level.exo_repulsor_deactivate_vfx = LoadFX( "vfx/unique/repulsor_bubble_deactivate" );
|
|
}
|
|
if ( !IsDefined( level.exo_repulsor_player_vfx_active ) )
|
|
{
|
|
level.exo_repulsor_player_vfx_active = LoadFX( "vfx/unique/exo_repulsor_emitter" );
|
|
}
|
|
if ( !IsDefined( level.exo_repulsor_player_vfx_inactive ) )
|
|
{
|
|
level.exo_repulsor_player_vfx_inactive = LoadFX( "vfx/unique/exo_repulsor_inactive" );
|
|
}
|
|
|
|
wait( 0.05 );
|
|
|
|
if ( !inVirtualLobby() )
|
|
{
|
|
PlayFXOnTag( level.exo_repulsor_player_vfx_inactive, self, "TAG_JETPACK" );
|
|
}
|
|
}
|
|
|
|
tryUseRepulsor( duration )
|
|
{
|
|
self endon( "exo_repulsor_taken" );
|
|
|
|
if (self.repulsorActive == true)
|
|
{
|
|
self thread stop_repulsor( true );
|
|
}
|
|
else
|
|
{
|
|
self thread start_repulsor();
|
|
}
|
|
}
|
|
|
|
killRepulsorFx()
|
|
{
|
|
if ( IsDefined( self.repulsor_fx ) )
|
|
{
|
|
self.repulsor_fx delete();
|
|
self.repulsor_fx = undefined;
|
|
}
|
|
}
|
|
|
|
start_repulsor()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
self endon( "joined_team" );
|
|
self endon( "faux_spawn" );
|
|
self endon( "stop_exo_repulsor" );
|
|
self endon( "exo_repulsor_taken" );
|
|
|
|
self.repulsorActive = true;
|
|
|
|
self thread do_exo_repulsor();
|
|
|
|
self BatteryDischargeBegin( "exorepulsor_equipment_mp" );
|
|
|
|
self maps\mp\_exo_battery::set_exo_ability_hud_omnvar( "exorepulsor_equipment_mp", "ui_exo_battery_toggle", 1 );
|
|
|
|
self thread maps\mp\_exo_battery::update_exo_battery_hud( "exorepulsor_equipment_mp" );
|
|
|
|
// play sfx
|
|
self snd_message( "mp_exo_repulsor_activate" );
|
|
|
|
// play vfx
|
|
killRepulsorFx();
|
|
|
|
if ( !IsDefined( self.exo_cloak_on ) || self.exo_cloak_on == false )
|
|
{
|
|
self.repulsor_fx = SpawnLinkedFx( level.exo_repulsor_player_vfx_active, self, "TAG_JETPACK" );
|
|
TriggerFX( self.repulsor_fx );
|
|
}
|
|
|
|
wait( 0.05 );
|
|
|
|
if ( !self.repulsorActive ) //turned off during wait?
|
|
return;
|
|
|
|
if ( IsDefined( level.exo_repulsor_activate_vfx ) )
|
|
{
|
|
PlayFXOnTagForClients( level.exo_repulsor_activate_vfx, self, "j_head", self );
|
|
}
|
|
}
|
|
|
|
stop_repulsor( should_play_fx ) // self = player
|
|
{
|
|
if ( !isDefined( self.repulsorActive ) || !self.repulsorActive )
|
|
return;
|
|
|
|
if ( !IsDefined( should_play_fx ) )
|
|
{
|
|
should_play_fx = true;
|
|
}
|
|
|
|
self notify( "stop_exo_repulsor" );
|
|
|
|
self.repulsorActive = false;
|
|
|
|
self BatteryDischargeEnd( "exorepulsor_equipment_mp" );
|
|
|
|
self maps\mp\_exo_battery::set_exo_ability_hud_omnvar( "exorepulsor_equipment_mp", "ui_exo_battery_toggle", 0 );
|
|
|
|
// stop vfx
|
|
killRepulsorFx();
|
|
|
|
if ( should_play_fx == true )
|
|
{
|
|
// play deactivate sfx
|
|
self snd_message( "mp_exo_repulsor_deactivate" );
|
|
|
|
// play inactive vfx
|
|
if ( !IsDefined( self.exo_cloak_on ) || self.exo_cloak_on == false )
|
|
{
|
|
self.repulsor_fx = SpawnLinkedFx( level.exo_repulsor_player_vfx_inactive, self, "TAG_JETPACK" );
|
|
TriggerFX( self.repulsor_fx );
|
|
}
|
|
|
|
wait( 0.05 );
|
|
|
|
// play deactivate hud vfx
|
|
if ( IsDefined( level.exo_repulsor_deactivate_vfx ) )
|
|
{
|
|
PlayFXOnTagForClients( level.exo_repulsor_deactivate_vfx, self, "j_head", self );
|
|
}
|
|
}
|
|
}
|
|
|
|
MonitorPlayerDeath()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "disconnect" );
|
|
|
|
self waittill_any( "death", "joined_team", "faux_spawn", "exo_repulsor_taken" );
|
|
|
|
self.projectilesStopped = 0;
|
|
|
|
self thread stop_repulsor( false );
|
|
}
|
|
|
|
update_exo_battery_hud()
|
|
{
|
|
battery_energy = self BatteryGetCharge( "exorepulsor_equipment_mp" );
|
|
// Setting ui_exo_battery_level to the current energy level.
|
|
self maps\mp\_exo_battery::set_exo_ability_hud_omnvar( "exorepulsor_equipment_mp", "ui_exo_battery_level", battery_energy );
|
|
}
|
|
|
|
do_exo_repulsor()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
self endon( "joined_team" );
|
|
self endon( "faux_spawn" );
|
|
self endon( "stop_exo_repulsor" );
|
|
self endon( "exo_repulsor_taken" );
|
|
|
|
while( self BatteryGetCharge( "exorepulsor_equipment_mp" ) > 0 )
|
|
{
|
|
for ( i = 0; i < level.grenades.size; i++ )
|
|
{
|
|
grenade = level.grenades[i];
|
|
|
|
// do not repel grenades without a weaponName.
|
|
if ( !IsDefined( grenade.weaponName ) )
|
|
continue;
|
|
|
|
// do not repel Exo Abilities.
|
|
if ( IsDefined( grenade.weaponName ) && is_exo_ability_weapon( grenade.weaponName ) )
|
|
continue;
|
|
|
|
// don't repel grenades with no owner
|
|
if ( !IsDefined( grenade.owner ) )
|
|
continue;
|
|
|
|
// don't repel your own grenades
|
|
if ( IsDefined( grenade.owner ) && grenade.owner == self )
|
|
continue;
|
|
|
|
// don't repel teammate grenades
|
|
if ( level.teamBased && Isdefined( grenade.owner.team ) && grenade.owner.team == self.team )
|
|
continue;
|
|
|
|
player_to_grenade_dist = Distance( grenade.origin, self.origin );
|
|
|
|
if ( player_to_grenade_dist < EXO_REPULSOR_RADIUS )
|
|
{
|
|
if ( SightTracePassed( self GetEye(), grenade.origin, false, self ) )
|
|
{
|
|
// play vfx
|
|
player_to_grenade_vector = grenade.origin - self.origin;
|
|
player_to_grenade_angles = VectorToAngles( player_to_grenade_vector );
|
|
player_to_grenade_up = AnglesToUp( player_to_grenade_angles );
|
|
player_to_grenade_forward = AnglesToForward( player_to_grenade_angles );
|
|
player_to_grenade_forward_norm = VectorNormalize( player_to_grenade_forward );
|
|
fx_origin = grenade.origin - ( 0.2 * player_to_grenade_dist * player_to_grenade_forward_norm );
|
|
PlayFX( level.exo_repulsor_impact, fx_origin, player_to_grenade_forward_norm, player_to_grenade_up );
|
|
|
|
// play sfx
|
|
grenade snd_message( "mp_exo_repulsor_repel" );
|
|
|
|
// explosive drone special case to remove "head" of the grenade
|
|
if ( grenade.weaponname == "explosive_drone_mp" )
|
|
{
|
|
grenade notify( "mp_exo_repulsor_repel" );
|
|
|
|
grenade thread maps\mp\_explosive_drone::explosiveGrenadeDeath();
|
|
}
|
|
else
|
|
{
|
|
grenade delete();
|
|
}
|
|
self.projectilesStopped++;
|
|
|
|
//Trophy - destroy a projectile
|
|
self maps\mp\gametypes\_missions::processChallenge("ch_exoability_repulser");
|
|
|
|
self BatteryDischargeOnce( "exorepulsor_equipment_mp", int( self BatteryGetSize( "exorepulsor_equipment_mp" ) / 2 ) );
|
|
self update_exo_battery_hud();
|
|
}
|
|
}
|
|
}
|
|
|
|
for ( i = 0; i < level.missiles.size; i++ )
|
|
{
|
|
rocket = level.missiles[i];
|
|
|
|
// do not repel rockets with no owner
|
|
if ( !IsDefined( rocket.owner ) )
|
|
continue;
|
|
|
|
// don't repel your own rockets
|
|
if ( IsDefined( rocket.owner ) && rocket.owner == self )
|
|
continue;
|
|
|
|
// don't repel teammate rockets
|
|
if ( level.teamBased && Isdefined( rocket.owner.team ) && rocket.owner.team == self.team )
|
|
continue;
|
|
|
|
player_to_rocket_dist = Distance( rocket.origin, self.origin );
|
|
|
|
if ( player_to_rocket_dist < EXO_REPULSOR_RADIUS )
|
|
{
|
|
if ( SightTracePassed( self GetEye(), rocket.origin, false, self ) )
|
|
{
|
|
// play vfx
|
|
player_to_rocket_vector = rocket.origin - self.origin;
|
|
player_to_rocket_angles = VectorToAngles( player_to_rocket_vector );
|
|
player_to_rocket_up = AnglesToUp( player_to_rocket_angles );
|
|
player_to_rocket_forward = AnglesToForward( player_to_rocket_angles );
|
|
player_to_rocket_forward_norm = VectorNormalize( player_to_rocket_forward );
|
|
fx_origin = rocket.origin - ( 0.2 * player_to_rocket_dist * player_to_rocket_forward_norm );
|
|
PlayFX( level.exo_repulsor_impact, fx_origin, player_to_rocket_forward_norm, player_to_rocket_up );
|
|
|
|
// play sfx
|
|
rocket snd_message( "mp_exo_repulsor_repel" );
|
|
|
|
// cleanup tag vfx
|
|
if ( IsDefined( rocket.weaponname ) && rocket.weaponname == "iw5_exocrossbow_mp" )
|
|
{
|
|
StopFXOnTag( getfx( "exocrossbow_sticky_blinking" ), rocket.fx_origin, "tag_origin" );
|
|
}
|
|
|
|
rocket delete();
|
|
self.projectilesStopped++;
|
|
|
|
//Trophy - destroy a projectile
|
|
self maps\mp\gametypes\_missions::processChallenge("ch_exoability_repulser");
|
|
|
|
self BatteryDischargeOnce( "exorepulsor_equipment_mp", int( self BatteryGetSize( "exorepulsor_equipment_mp" ) / 2 ) );
|
|
self update_exo_battery_hud();
|
|
}
|
|
}
|
|
}
|
|
|
|
for ( i = 0; i < level.explosivedrones.size; i++ )
|
|
{
|
|
explosiveDrone = level.explosivedrones[i];
|
|
|
|
if( IsDefined(explosiveDrone) ) // just in case clean up timing is off
|
|
{
|
|
// do not repel explosive drones with no owner
|
|
if ( !IsDefined( explosiveDrone.owner ) )
|
|
continue;
|
|
|
|
// don't repel your own explosive drones
|
|
if ( IsDefined( explosiveDrone.owner ) && explosiveDrone.owner == self )
|
|
continue;
|
|
|
|
// don't repel teammate explosive drones
|
|
if ( level.teamBased && Isdefined( explosiveDrone.owner.team ) && explosiveDrone.owner.team == self.team )
|
|
continue;
|
|
|
|
player_to_explosiveDrone_dist = Distance( explosiveDrone.origin, self.origin );
|
|
|
|
if ( player_to_explosiveDrone_dist < EXO_REPULSOR_RADIUS )
|
|
{
|
|
if ( SightTracePassed( self GetEye(), explosiveDrone.origin, false, self ) )
|
|
{
|
|
// play vfx
|
|
player_to_explosiveDrone_vector = explosiveDrone.origin - self.origin;
|
|
player_to_explosiveDrone_angles = VectorToAngles( player_to_explosiveDrone_vector );
|
|
player_to_explosiveDrone_up = AnglesToUp( player_to_explosiveDrone_angles );
|
|
player_to_explosiveDrone_forward = AnglesToForward( player_to_explosiveDrone_angles );
|
|
player_to_explosiveDrone_forward_norm = VectorNormalize( player_to_explosiveDrone_forward );
|
|
fx_origin = explosiveDrone.origin - ( 0.2 * player_to_explosiveDrone_dist * player_to_explosiveDrone_forward_norm );
|
|
PlayFX( level.exo_repulsor_impact, fx_origin, player_to_explosiveDrone_forward_norm, player_to_explosiveDrone_up );
|
|
|
|
// play sfx
|
|
explosiveDrone snd_message( "mp_exo_repulsor_repel" );
|
|
|
|
if (IsDefined (explosiveDrone.explosiveDrone) )
|
|
{
|
|
explosiveDrone.explosiveDrone delete();
|
|
}
|
|
|
|
explosiveDrone delete();
|
|
self.projectilesStopped++;
|
|
|
|
//Trophy - destroy a projectile
|
|
self maps\mp\gametypes\_missions::processChallenge("ch_exoability_repulser");
|
|
|
|
self BatteryDischargeOnce( "exorepulsor_equipment_mp", int( self BatteryGetSize( "exorepulsor_equipment_mp" ) / 2 ) );
|
|
self update_exo_battery_hud();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach ( tdrone in level.trackingDrones )
|
|
{
|
|
// don't destroy tracking drones with no owner
|
|
if ( !IsDefined( tdrone.owner ) )
|
|
continue;
|
|
|
|
// don't destroy your own tracking drones
|
|
if ( IsDefined( tdrone.owner ) && tdrone.owner == self )
|
|
continue;
|
|
|
|
// don't destroy teammate tracking drones
|
|
if ( level.teamBased && Isdefined( tdrone.owner.team ) && tdrone.owner.team == self.team )
|
|
continue;
|
|
|
|
player_to_tdrone_dist = Distance( tdrone.origin, self.origin );
|
|
|
|
if ( player_to_tdrone_dist < EXO_REPULSOR_RADIUS )
|
|
{
|
|
if ( SightTracePassed( self GetEye(), tdrone.origin, false, self ) )
|
|
{
|
|
// play vfx
|
|
player_to_tdrone_vector = tdrone.origin - self.origin;
|
|
player_to_tdrone_angles = VectorToAngles( player_to_tdrone_vector );
|
|
player_to_tdrone_up = AnglesToUp( player_to_tdrone_angles );
|
|
player_to_tdrone_forward = AnglesToForward( player_to_tdrone_angles );
|
|
player_to_tdrone_forward_norm = VectorNormalize( player_to_tdrone_forward );
|
|
fx_origin = tdrone.origin - ( 0.2 * player_to_tdrone_dist * player_to_tdrone_forward_norm );
|
|
PlayFX( level.exo_repulsor_impact, fx_origin, player_to_tdrone_forward_norm, player_to_tdrone_up );
|
|
|
|
// play sfx
|
|
tdrone snd_message( "mp_exo_repulsor_repel" );
|
|
|
|
if ( !IsRemovedEntity( tdrone ) && IsDefined( tdrone ) )
|
|
{
|
|
tdrone notify( "death" );
|
|
decrementFauxVehicleCount();
|
|
}
|
|
|
|
self.projectilesStopped++;
|
|
|
|
//Trophy - destroy a projectile
|
|
self maps\mp\gametypes\_missions::processChallenge("ch_exoability_repulser");
|
|
|
|
self BatteryDischargeOnce( "exorepulsor_equipment_mp", int( self BatteryGetSize( "exorepulsor_equipment_mp" ) / 2 ) );
|
|
self update_exo_battery_hud();
|
|
}
|
|
}
|
|
}
|
|
|
|
// The medal used to be "Four Play" when you could block 4 enemy projectiles. Now that you can only block 2, we've changed it to "Secretary of Defense".
|
|
if ( self.projectilesStopped >= 2 )
|
|
{
|
|
if ( !isdefined ( level.isHorde ) )
|
|
self thread maps\mp\_events::fourPlayEvent();
|
|
self.projectilesStopped -= 2;
|
|
}
|
|
|
|
wait 0.05;
|
|
}
|
|
|
|
// Exo Repulsor is out of energy.
|
|
self thread stop_repulsor( true );
|
|
}
|
|
|
|
take_exo_repulsor() //self = player
|
|
{
|
|
self notify( "kill_battery" );
|
|
self notify( "exo_repulsor_taken" );
|
|
self takeWeapon( "exorepulsor_equipment_mp" );
|
|
}
|
|
|
|
give_exo_repulsor() //self = player
|
|
{
|
|
self giveWeapon( "exorepulsor_equipment_mp" );
|
|
self thread exo_repulsor_think();
|
|
}
|
|
|
|
wait_for_game_end() // self = player
|
|
{
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
self endon( "joined_team" );
|
|
self endon( "faux_spawn" );
|
|
self endon( "exo_repulsor_taken" );
|
|
|
|
level waittill( "game_ended" );
|
|
|
|
self thread stop_repulsor( false );
|
|
}
|