275 lines
13 KiB
Plaintext
275 lines
13 KiB
Plaintext
// tagTMR<NOTE>: this is a stripped down last stand implementation for the purposes of hooking into
|
|
// the resurrect gadget. Removed suicide and revive triggers, all hud elements, anything cp/zm specific
|
|
|
|
#using scripts\codescripts\struct;
|
|
|
|
#using scripts\shared\callbacks_shared;
|
|
#using scripts\shared\demo_shared;
|
|
#using scripts\shared\flag_shared;
|
|
#using scripts\shared\hud_util_shared;
|
|
#using scripts\shared\killcam_shared;
|
|
#using scripts\shared\laststand_shared;
|
|
#using scripts\shared\scoreevents_shared;
|
|
#using scripts\shared\system_shared;
|
|
#using scripts\shared\util_shared;
|
|
#using scripts\shared\clientfield_shared;
|
|
|
|
#using scripts\shared\abilities\gadgets\_gadget_resurrect;
|
|
#using scripts\shared\abilities\_ability_util;
|
|
|
|
|
|
|
|
|
|
#using scripts\mp\gametypes\_globallogic_player;
|
|
#using scripts\mp\gametypes\_globallogic_spawn;
|
|
#using scripts\mp\gametypes\_killcam;
|
|
|
|
#namespace laststand;
|
|
|
|
function autoexec __init__sytem__() { system::register("laststand",&__init__,undefined,undefined); }
|
|
|
|
function __init__()
|
|
{
|
|
if (level.script=="frontend")
|
|
{
|
|
return ;
|
|
}
|
|
}
|
|
|
|
function player_last_stand_stats( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
|
|
{
|
|
//stat tracking
|
|
if ( IsDefined( attacker ) && IsPlayer( attacker ) && attacker != self )
|
|
{
|
|
attacker.kills++;
|
|
|
|
if (isdefined(weapon))
|
|
{
|
|
dmgweapon = weapon;
|
|
|
|
weaponPickedUp = false;
|
|
if( isdefined( attacker.pickedUpWeapons ) && isdefined( attacker.pickedUpWeapons[weapon] ) )
|
|
{
|
|
weaponPickedUp = true;
|
|
}
|
|
|
|
attacker AddWeaponStat(dmgweapon, "kills", 1, attacker.class_num, weaponPickedUp );
|
|
}
|
|
}
|
|
|
|
self.downs++;
|
|
}
|
|
|
|
function PlayerLastStand( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, delayOverride )
|
|
{
|
|
if( self player_is_in_laststand() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( isdefined( self.resurrect_not_allowed_by ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
self globallogic_player::Callback_PlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, 0, true );
|
|
|
|
self notify("entering_last_stand");
|
|
|
|
// check to see if we are in a game module that wants to do something with PvP damage
|
|
if( isDefined( level._game_module_player_laststand_callback ) )
|
|
{
|
|
self [[ level._game_module_player_laststand_callback ]]( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, delayOverride );
|
|
}
|
|
|
|
self.lastStandParams = spawnstruct();
|
|
self.lastStandParams.eInflictor = eInflictor;
|
|
self.lastStandParams.attacker = attacker;
|
|
self.lastStandParams.iDamage = iDamage;
|
|
self.lastStandParams.sMeansOfDeath = sMeansOfDeath;
|
|
self.lastStandParams.sWeapon = weapon;
|
|
self.lastStandParams.vDir = vDir;
|
|
self.lastStandParams.sHitLoc = sHitLoc;
|
|
self.lastStandParams.lastStandStartTime = gettime();
|
|
self.lastStandParams.killcam_entity_info_cached = killcam::get_killcam_entity_info( attacker, eInflictor, weapon );
|
|
|
|
self thread player_last_stand_stats( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, delayOverride );
|
|
|
|
self.health = 1;
|
|
self.laststand = true;
|
|
self.ignoreme = true;
|
|
self EnableInvulnerability();
|
|
self.meleeAttackers = undefined;
|
|
self.no_revive_trigger = true;
|
|
|
|
callback::callback( #"on_player_laststand" );
|
|
|
|
assert( IsDefined( self.resurrect_weapon ) ); // defined in gadget_resurrect.gsc
|
|
assert( self.resurrect_weapon != level.weaponNone );
|
|
|
|
slot = self ability_util::gadget_slot_for_type( 40 );
|
|
self GadgetStateChange( slot, self.resurrect_weapon, 2 );
|
|
self laststand_disable_player_weapons();
|
|
self thread MakeSureSwitchToWeapon();
|
|
self thread resurrect::enter_rejack_standby(); // UI and input watchers
|
|
self thread watch_player_input();
|
|
|
|
demo::bookmark( "player_downed", gettime(), self );
|
|
}
|
|
|
|
function MakeSureSwitchToWeapon()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
self endon( "bleed_out" );
|
|
self endon( "player_input_revive" );
|
|
self endon( "player_input_suicide" );
|
|
level endon("game_ended");
|
|
|
|
while( 1 )
|
|
{
|
|
if( self getcurrentweapon() != self.resurrect_weapon )
|
|
{
|
|
self SwitchToWeapon( self.resurrect_weapon );
|
|
}
|
|
{wait(.05);};
|
|
}
|
|
}
|
|
|
|
// self = a player
|
|
function laststand_disable_player_weapons()
|
|
{
|
|
weaponInventory = self GetWeaponsList( true );
|
|
self.lastActiveWeapon = self GetCurrentWeapon();
|
|
if ( self IsThrowingGrenade() )
|
|
{
|
|
primaryWeapons = self GetWeaponsListPrimaries();
|
|
if( IsDefined( primaryWeapons ) && primaryWeapons.size > 0 )
|
|
{
|
|
self.lastActiveWeapon = primaryWeapons[0];
|
|
self SwitchToWeaponImmediate( self.lastActiveWeapon );
|
|
}
|
|
}
|
|
}
|
|
|
|
function laststand_enable_player_weapons( b_allow_grenades = true ) // self == player
|
|
{
|
|
self EnableWeaponCycling();
|
|
|
|
if ( b_allow_grenades )
|
|
{
|
|
self EnableOffhandWeapons();
|
|
}
|
|
|
|
if( IsDefined(self.lastActiveWeapon) && (self.lastActiveWeapon != level.weaponNone) && self HasWeapon( self.lastActiveWeapon ) )
|
|
{
|
|
self SwitchToWeapon( self.lastActiveWeapon );
|
|
}
|
|
else
|
|
{
|
|
primaryWeapons = self GetWeaponsListPrimaries();
|
|
if( IsDefined( primaryWeapons ) && primaryWeapons.size > 0 )
|
|
{
|
|
self SwitchToWeapon( primaryWeapons[0] );
|
|
}
|
|
}
|
|
}
|
|
|
|
function laststand_clean_up_on_interrupt( playerBeingRevived, reviverGun )
|
|
{
|
|
self endon( "do_revive_ended_normally" );
|
|
|
|
reviveTrigger = playerBeingRevived.revivetrigger;
|
|
|
|
playerBeingRevived util::waittill_any( "disconnect", "game_ended", "death" );
|
|
|
|
if( isdefined( reviveTrigger ) )
|
|
{
|
|
reviveTrigger delete();
|
|
}
|
|
self cleanup_suicide_hud();
|
|
|
|
if( isdefined( self.reviveProgressBar ) )
|
|
{
|
|
self.reviveProgressBar hud::destroyElem();
|
|
}
|
|
|
|
if( isdefined( self.reviveTextHud ) )
|
|
{
|
|
self.reviveTextHud destroy();
|
|
}
|
|
}
|
|
|
|
function laststand_clean_up_reviving_any( playerBeingRevived )
|
|
{
|
|
self endon( "do_revive_ended_normally" );
|
|
|
|
playerBeingRevived util::waittill_any( "disconnect", "zombified", "stop_revive_trigger" );
|
|
|
|
self.is_reviving_any--;
|
|
if ( 0 > self.is_reviving_any )
|
|
{
|
|
self.is_reviving_any = 0;
|
|
}
|
|
}
|
|
|
|
function bleed_out()
|
|
{
|
|
demo::bookmark( "player_bledout", gettime(), self, undefined, 1 );
|
|
|
|
level notify("bleed_out", self.characterindex);
|
|
|
|
self UndoLastStand();
|
|
self.ignoreme = false;
|
|
self.laststand = undefined;
|
|
|
|
self.useLastStandParams = true;
|
|
|
|
// attacker may have become undefined if the player that killed me has disconnected
|
|
if ( !isDefined( self.lastStandParams.attacker ) )
|
|
{
|
|
self.lastStandParams.attacker = self;
|
|
}
|
|
|
|
self suicide();
|
|
}
|
|
|
|
function watch_player_input() // self == player
|
|
{
|
|
self thread watch_player_input_revive();
|
|
self thread watch_player_input_suicide();
|
|
}
|
|
|
|
function watch_player_input_revive() // self == player
|
|
{
|
|
level endon("game_ended");
|
|
|
|
self endon( "player_input_bleed_out" );
|
|
self endon( "disconnect" );
|
|
self endon( "death" );
|
|
|
|
self waittill("player_input_revive");
|
|
|
|
demo::bookmark( "player_revived", gettime(), self, self );
|
|
|
|
self Rejack(); // TODO: split this out into gadget-specific territory and keep this file last stand only
|
|
|
|
self laststand_enable_player_weapons();
|
|
|
|
self.ignoreme = false;
|
|
self DisableInvulnerability();
|
|
self.laststand = undefined;
|
|
}
|
|
|
|
function watch_player_input_suicide() // self == player
|
|
{
|
|
level endon("game_ended");
|
|
|
|
self endon( "player_input_revive" );
|
|
self endon( "disconnect" );
|
|
self endon( "death" );
|
|
|
|
self waittill("player_input_suicide");
|
|
|
|
self bleed_out();
|
|
} |