boiii-scripts/shared/abilities/gadgets/_gadget_resurrect.gsc
2023-04-13 17:30:38 +02:00

715 lines
25 KiB
Plaintext

#using scripts\codescripts\struct;
#using scripts\shared\callbacks_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\flag_shared;
#using scripts\shared\flagsys_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#using scripts\shared\visionset_mgr_shared;
#using scripts\shared\weapons\_smokegrenade;
#using scripts\shared\_oob;
#using scripts\shared\abilities\_ability_player;
#using scripts\shared\abilities\_ability_power;
#using scripts\shared\abilities\_ability_util;
#namespace resurrect;
function autoexec __init__sytem__() { system::register("gadget_resurrect",&__init__,undefined,undefined); }
#precache( "fx", "player/fx_plyr_revive" );
#precache( "fx", "player/fx_plyr_revive_demat" );
#precache( "fx", "player/fx_plyr_rejack_light" );
#precache( "fx", "player/fx_plyr_rejack_smoke" );
#precache( "eventstring", "create_rejack_timer" );
function __init__()
{
clientfield::register( "allplayers", "resurrecting" , 1, 1, "int" );
clientfield::register( "toplayer", "resurrect_state" , 1, 2, "int" );
clientfield::register( "clientuimodel", "hudItems.rejack.activationWindowEntered", 1, 1, "int" );
clientfield::register( "clientuimodel", "hudItems.rejack.rejackActivated", 1, 1, "int" );
ability_player::register_gadget_activation_callbacks( 40, &gadget_resurrect_on, &gadget_resurrect_off );
ability_player::register_gadget_possession_callbacks( 40, &gadget_resurrect_on_give, &gadget_resurrect_on_take );
ability_player::register_gadget_flicker_callbacks( 40, &gadget_resurrect_on_flicker );
ability_player::register_gadget_is_inuse_callbacks( 40, &gadget_resurrect_is_inuse );
ability_player::register_gadget_is_flickering_callbacks( 40, &gadget_resurrect_is_flickering );
ability_player::register_gadget_primed_callbacks( 40, &gadget_resurrect_is_primed );
ability_player::register_gadget_ready_callbacks( 40, &gadget_resurrect_is_ready );
callback::on_connect( &gadget_resurrect_on_connect );
callback::on_spawned( &gadget_resurrect_on_spawned );
if ( !IsDefined( level.vsmgr_prio_visionset_resurrect ) )
{
level.vsmgr_prio_visionset_resurrect = 62;
}
if ( !IsDefined( level.vsmgr_prio_visionset_resurrect_up ) )
{
level.vsmgr_prio_visionset_resurrect_up = 63;
}
visionset_mgr::register_info( "visionset", "resurrect", 1, level.vsmgr_prio_visionset_resurrect, 16, true, &visionset_mgr::ramp_in_out_thread_per_player_death_shutdown, false );
visionset_mgr::register_info( "visionset", "resurrect_up", 1, level.vsmgr_prio_visionset_resurrect_up, 16, true, &visionset_mgr::ramp_in_out_thread_per_player_death_shutdown, false );
}
function gadget_resurrect_is_inuse( slot )
{
return self GadgetIsActive( slot );
}
function gadget_resurrect_is_flickering( slot )
{
return self GadgetFlickering( slot );
}
function gadget_resurrect_on_flicker( slot, weapon )
{
}
function gadget_resurrect_on_give( slot, weapon )
{
self.usedResurrect = false;
self.resurrect_weapon = weapon;
//self.overridePlayerDeadStatus = &gadget_resurrect_is_player_predead;
//self.secondaryDeathCamTime = &gadget_resurrect_secondary_deathcam_time;
}
function gadget_resurrect_on_take( slot, weapon )
{
// executed when gadget is removed from the players inventory
self.overridePlayerDeadStatus = undefined;
self.resurrect_weapon = undefined;
self.secondaryDeathCamTime = undefined;
self notify("resurrect_taken");
}
//self is the player
function gadget_resurrect_on_spawned()
{
self clientfield::set_player_uimodel( "hudItems.rejack.activationWindowEntered", 0 );
self util::show_hud( 1 );
self._disable_proximity_alarms = false;
// executed when gadget is added to the players inventory
self flagsys::clear( "gadget_resurrect_ready" );
self flagsys::clear( "gadget_resurrect_pending" );
if ( self flagsys::get( "gadget_resurrect_activated" ) )
{
self thread do_resurrected_on_spawned_player_fx();
self thread resurrect_drain_power();
self flagsys::clear( "gadget_resurrect_activated" );
}
}
function resurrect_drain_power( amount )
{
if ( isdefined( self.resurrect_weapon ) )
{
slot = self GadgetGetSlot( self.resurrect_weapon );
if ( slot >= 0 && slot < 3 )
{
if ( IsDefined( amount ))
{
self GadgetPowerChange( slot, amount );
}
else
{
self GadgetStateChange( slot, self.resurrect_weapon, 3 );
}
}
}
}
//self is the player
function gadget_resurrect_on_connect()
{
// setup up stuff on player connect
}
function gadget_resurrect_on( slot, weapon )
{
// excecutes when the gadget is turned on
}
function watch_smoke_detonate()
{
self endon( "player_input_suicide" );
self endon( "player_input_revive" );
self endon( "disconnect" );
self endon( "death" );
level endon("game_ended");
while( 1 )
{
if( ( ( self IsPlayerSwimming() ) || ( self isOnGround() ) ) && !( self iswallrunning() ) && !( self istraversing() ) )
{
smoke_weapon = GetWeapon( "gadget_resurrect_smoke_grenade" );
stat_weapon = GetWeapon( "gadget_resurrect" );
smokeEffect = smokegrenade::smokeDetonate( self, stat_weapon, smoke_weapon, self.origin, 128, 5, 4 );
smokeEffect thread watch_smoke_effect_watch_suicide( self );
smokeEffect thread watch_smoke_effect_watch_resurrect( self );
smokeEffect thread watch_smoke_death( self );
return;
}
{wait(.05);};
}
}
function watch_smoke_death( player ) // self is effect
{
self endon( "death" );
player util::waittill_any_timeout( 5, "disconnect", "death" );
self delete();
}
function watch_smoke_effect_watch_suicide( player ) // self is effect
{
self endon( "death" );
player waittill ( "player_input_suicide" );
self delete();
}
function watch_smoke_effect_watch_resurrect( player ) // self is effect
{
self endon( "death" );
player waittill ( "player_input_revive" );
wait( .5 );
self delete();
}
function gadget_resurrect_is_primed( slot, weapon ) // self == player
{
if ( isdefined( self.resurrect_not_allowed_by ) )
return;
self StartResurrectViewAngleTransition();
self.lastWaterDamageTime = GetTime();
self._disable_proximity_alarms = true;
self thread watch_smoke_detonate();
self util::show_hud( 0 );
visionset_mgr::activate( "visionset", "resurrect", self, ( 1.4 ), ( 4.0 ), ( .25 ) );
self clientfield::set_to_player( "resurrect_state", 1 );
self shellshock( "resurrect", 4.0 + 1.4, false );
}
function gadget_resurrect_is_ready( slot, weapon )
{
return;
self flagsys::set( "gadget_resurrect_ready" );
self thread resurrect_breadcrumbs( slot );
self thread resurrect_watch_for_death( slot,weapon );
}
function gadget_resurrect_start( slot, weapon )
{
wait 0.1;
self GadgetSetActivateTime( slot, GetTime() );
self thread resurrect_delay( weapon );
}
function gadget_resurrect_off( slot, weapon )
{
self notify( "gadget_resurrect_off" );
// excecutes when the gadget is turned off
}
function resurrect_delay( weapon )
{
self endon ( "disconnect" );
self endon("game_ended");
self endon ( "death" );
self notify( "resurrect_delay" );
self endon( "resurrect_delay" );
}
function overrideSpawn(isPredictedSpawn)
{
if ( !self flagsys::get( "gadget_resurrect_ready" ) )
return false;
if ( !self flagsys::get( "gadget_resurrect_activated" ) )
return false;
if (!IsDefined( self.resurrect_origin ))
{
self.resurrect_origin = self.origin;
self.resurrect_angles = self.angles;
}
return true;
}
function is_jumping()
{
// checking PMF_JUMPING in code would give more accurate results
ground_ent = self GetGroundEnt();
return (!isdefined(ground_ent));
}
function player_position_valid()
{
//if ( self IsWallRunning() || self is_jumping() )
//return false;
if ( self clientfield::get_to_player( "out_of_bounds" ) )
return false;
return true;
}
function resurrect_breadcrumbs(slot)
{
self endon("disconnect");
self endon("game_ended");
self endon("resurrect_taken");
self.resurrect_slot = slot;
while(1)
{
if (IsAlive(self) && self player_position_valid() )
{
self.resurrect_origin = self.origin;
self.resurrect_angles = self.angles;
}
wait 1;
}
}
function glow_for_time( time )
{
self endon("disconnect");
self clientfield::set( "resurrecting", 1 );
wait time;
self clientfield::set( "resurrecting", 0 );
}
function wait_for_time( time, msg )
{
self endon("disconnect");
self endon("game_ended");
self endon(msg);
wait time;
self notify(msg);
}
function wait_for_activate( msg )
{
self endon("disconnect");
self endon("game_ended");
self endon(msg);
while(1)
{
if ( self OffhandSpecialButtonPressed() )
{
self flagsys::set( "gadget_resurrect_activated" );
self notify(msg);
}
{wait(.05);};
}
}
function bot_wait_for_activate( msg, time )
{
self endon("disconnect");
self endon("game_ended");
self endon(msg);
if ( !self util::is_bot() )
{
return;
}
time = int( time + 1 );
randWait = RandomInt( time );
wait randWait;
self flagsys::set( "gadget_resurrect_activated" );
self notify(msg);
}
function do_resurrect_hint_fx()
{
offset = (0,0,40);
fxOrg = spawn( "script_model", self.resurrect_origin + offset );
fxOrg SetModel( "tag_origin" );
fx = PlayFxOnTag( "player/fx_plyr_revive", fxOrg, "tag_origin" );
self waittill("resurrect_time_or_activate");
fxOrg delete();
}
function do_resurrected_on_dead_body_fx()
{
if ( isdefined( self.body ) )
{
fx = PlayFx( "player/fx_plyr_revive_demat", self.body.origin );
self.body NotSolid();
self.body Ghost();
}
}
function do_resurrected_on_spawned_player_fx()
{
playsoundatposition( "mpl_resurrect_npc", self.origin );
fx = PlayFx( "player/fx_plyr_rejack_light", self.origin );
}
function resurrect_watch_for_death( slot, weapon )
{
self endon("disconnect");
self endon("game_ended");
self waittill("death");
resurrect_time = 3;
if ( IsDefined( weapon.gadget_resurrect_duration) )
{
resurrect_time = weapon.gadget_resurrect_duration / 1000.0;
}
self.usedResurrect = false;
self flagsys::clear( "gadget_resurrect_activated" );
self flagsys::set( "gadget_resurrect_pending" );
self.resurrect_available_time = GetTime();
self thread wait_for_time(resurrect_time,"resurrect_time_or_activate");
self thread wait_for_activate("resurrect_time_or_activate");
self thread bot_wait_for_activate("resurrect_time_or_activate", resurrect_time );
self thread do_resurrect_hint_fx();
self waittill("resurrect_time_or_activate");
self flagsys::clear( "gadget_resurrect_pending" );
if ( self flagsys::get( "gadget_resurrect_activated" ) )
{
self thread do_resurrected_on_dead_body_fx();
self notify ( "end_death_delay" );
self notify ( "end_killcam" );
self.cancelKillcam = true;
self.usedResurrect = true;
self notify ( "end_death_delay" );
self notify( "force_spawn" );
if ( !( isdefined( true ) && true ) )
{
self.pers["resetMomentumOnSpawn"] = false;
}
if ( isdefined( level.playGadgetSuccess ) )
{
self [[ level.playGadgetSuccess ]]( weapon, "resurrectSuccessDelay" );
}
//self thread glow_for_time( 7 );
}
}
function gadget_resurrect_delay_updateTeamStatus()
{
if ( self flagsys::get( "gadget_resurrect_ready" ) )
{
return true;
}
return false;
}
function gadget_resurrect_is_player_predead()
{
should_not_be_dead = false;
if ( self.sessionstate == "playing" && isAlive( self ) )
should_not_be_dead = true;
if ( self flagsys::get( "gadget_resurrect_pending" ) )
{
return true;
}
return should_not_be_dead;
}
function gadget_resurrect_secondary_deathcam_time()
{
if ( self flagsys::get( "gadget_resurrect_pending" ) && IsDefined(self.resurrect_available_time) )
{
resurrect_time = 3000;
weapon = self.resurrect_weapon;
if ( IsDefined(weapon.gadget_resurrect_duration) )
resurrect_time = weapon.gadget_resurrect_duration;
time_left = resurrect_time - ( GetTime() - self.resurrect_available_time );
if ( time_left > 0 )
{
return time_left / 1000.0;
}
}
return 0.0;
}
function enter_rejack_standby() // self == player
{
self endon( "disconnect" );
self endon( "death" );
level endon("game_ended");
self.rejack_activate_requested = false;
if( isDefined( level.resetPlayerScorestreaks ) )
{
[[level.resetPlayerScorestreaks]]( self );
}
self init_rejack_ui();
self thread watch_rejack_activate_requested();
self thread watch_rejack_suicide();
wait 1.4;
self thread watch_rejack_activate();
self thread watch_rejack_timeout();
self thread watch_bad_trigger_touch();
}
function rejack_suicide()
{
self notify( "heroAbility_off" );
visionset_mgr::deactivate( "visionset", "resurrect", self );
self thread remove_rejack_ui();
self util::show_hud( 1 );
player_suicide();
}
function watch_bad_trigger_touch()
{
self endon( "player_input_revive" );
self endon( "player_input_suicide" );
self endon( "disconnect" );
self endon( "death" );
level endon("game_ended");
a_killbrushes = GetEntArray( "trigger_hurt","classname" );
while( 1 )
{
a_killbrushes = GetEntArray( "trigger_hurt","classname" );
for ( i = 0; i < a_killbrushes.size; i++)
{
if ( self IsTouching( a_killbrushes[ i ] ) )
{
if ( !a_killbrushes[ i ] IsTriggerEnabled() )
{
continue;
}
self rejack_suicide();
}
}
if( self oob::IsTouchingAnyOOBTrigger() )
{
self rejack_suicide();
}
{wait(.05);};
}
}
function watch_rejack_timeout() // self == player
{
self endon( "player_input_revive" );
self endon( "player_input_suicide" );
self endon( "disconnect" );
self endon( "death" );
level endon("game_ended");
wait 4.0;
self playsound ("mpl_rejack_suicide_timeout");
self thread resurrect_drain_power( -30 );
self rejack_suicide();
}
function watch_rejack_suicide() // self == player
{
self endon( "player_input_revive" );
self endon( "disconnect" );
self endon( "death" );
level endon("game_ended");
while ( self UseButtonPressed())
{
wait 1;
}
if ( ( isdefined( self.laststand ) && self.laststand ))
{
startTime = GetTime();
while ( true )
{
if( !( self usebuttonpressed() ) )
{
startTime = GetTime();
}
if( startTime + 500 < GetTime() )
{
self rejack_suicide();
self playsound ("mpl_rejack_suicide");
return;
}
wait .01;
}
}
}
function reload_clip_on_stand()
{
weapons = self GetWeaponsListPrimaries();
for ( i = 0; i < weapons.size; i++ )
{
self ReloadWeaponAmmo( weapons[i] );
}
}
function watch_rejack_activate_requested()
{
self endon( "player_input_suicide" );
self endon( "player_input_revive" );
self endon( "disconnect" );
self endon( "death" );
level endon("game_ended");
while ( self OffhandSpecialButtonPressed())
{
{wait(.05);};
}
self.rejack_activate_requested = false;
while( !self.rejack_activate_requested )
{
if( self OffhandSpecialButtonPressed() )
{
self.rejack_activate_requested = true;
}
{wait(.05);};
}
}
function watch_rejack_activate() // self == player
{
self endon( "player_input_suicide" );
self endon( "disconnect" );
self endon( "death" );
level endon("game_ended");
if ( ( isdefined( self.laststand ) && self.laststand ))
{
while ( true )
{
{wait(.05);};
if( ( isdefined( self.rejack_activate_requested ) && self.rejack_activate_requested ) )
{
self notify( "player_input_revive" );
if( isDefined( level.start_player_health_regen ) )
{
self thread [[level.start_player_health_regen]](); // Manually restart the health regen as it gets ended because of the player killed
}
self._disable_proximity_alarms = false;
self thread do_resurrected_on_spawned_player_fx();
self thread resurrect_drain_power();
self thread rejack_ui_activate();
visionset_mgr::deactivate( "visionset", "resurrect", self );
visionset_mgr::activate( "visionset", "resurrect_up", self, ( .35 ), ( .1 ), ( .2 ) );
self clientfield::set_to_player( "resurrect_state", 2 );
self stopshellshock();
//self SetEverHadWeaponAll( false );
self reload_clip_on_stand();
level notify( "hero_gadget_activated", self );
self notify( "hero_gadget_activated" );
return;
}
}
}
}
function init_rejack_ui()
{
self clientfield::set_player_uimodel( "hudItems.rejack.activationWindowEntered", 1 );
self LUINotifyEvent( &"create_rejack_timer", 1, GetTime() + ( int( 4.0 * 1000 ) ) );
self clientfield::set_player_uimodel( "hudItems.rejack.rejackActivated", 0 );
}
function remove_rejack_ui()
{
self endon( "disconnect" );
wait 1.5;
self clientfield::set_player_uimodel( "hudItems.rejack.activationWindowEntered", 0 );
self util::show_hud( 1 );
}
function rejack_ui_activate()
{
self clientfield::set_player_uimodel( "hudItems.rejack.rejackActivated", 1 );
self thread remove_rejack_ui();
}
function player_suicide() // self == player
{
self._disable_proximity_alarms = false;
self notify( "player_input_suicide" );
self clientfield::set_to_player( "resurrect_state", 0 );
self thread resurrect_drain_power( -30 );
}