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

500 lines
20 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\weapons\_weaponobjects;
#using scripts\shared\visionset_mgr_shared;
#using scripts\shared\abilities\_ability_gadgets;
#using scripts\shared\abilities\_ability_player;
#using scripts\shared\abilities\_ability_power;
#using scripts\shared\abilities\_ability_util;
#using scripts\shared\_burnplayer;
#namespace heat_wave;
function autoexec __init__sytem__() { system::register("gadget_heat_wave",&__init__,undefined,undefined); }
function __init__()
{
ability_player::register_gadget_activation_callbacks( 41, &gadget_heat_wave_on_activate, &gadget_heat_wave_on_deactivate );
ability_player::register_gadget_possession_callbacks( 41, &gadget_heat_wave_on_give, &gadget_heat_wave_on_take );
ability_player::register_gadget_flicker_callbacks( 41, &gadget_heat_wave_on_flicker );
ability_player::register_gadget_is_inuse_callbacks( 41, &gadget_heat_wave_is_inuse );
ability_player::register_gadget_is_flickering_callbacks( 41, &gadget_heat_wave_is_flickering );
callback::on_connect( &gadget_heat_wave_on_connect );
callback::on_spawned( &gadget_heat_wave_on_player_spawn );
clientfield::register( "scriptmover", "heatwave_fx", 1, 1, "int" );
clientfield::register( "allplayers", "heatwave_victim", 1, 1, "int" );
clientfield::register( "toplayer", "heatwave_activate", 1, 1, "int" );
if ( !IsDefined( level.vsmgr_prio_visionset_heatwave_activate ) )
{
level.vsmgr_prio_visionset_heatwave_activate = 52;
}
if ( !IsDefined( level.vsmgr_prio_visionset_heatwave_charred ) )
{
level.vsmgr_prio_visionset_heatwave_charred = 53;
}
visionset_mgr::register_info( "visionset", "heatwave", 1, level.vsmgr_prio_visionset_heatwave_activate, 16, true, &visionset_mgr::ramp_in_out_thread_per_player_death_shutdown, false );
visionset_mgr::register_info( "visionset", "charred", 1, level.vsmgr_prio_visionset_heatwave_charred, 16, true, &visionset_mgr::ramp_in_out_thread_per_player_death_shutdown, false );
/#
//level thread updateDvars();
#/
}
function updateDvars()
{
while(1)
{
wait(1.0);
}
}
function gadget_heat_wave_is_inuse( slot )
{
// returns true when local script gadget state is on
return self GadgetIsActive( slot );
}
function gadget_heat_wave_is_flickering( slot )
{
// returns true when local script gadget state is flickering
return self GadgetFlickering( slot );
}
function gadget_heat_wave_on_flicker( slot, weapon )
{
// excuted when the gadget flickers
self thread gadget_heat_wave_flicker( slot, weapon );
}
function gadget_heat_wave_on_give( slot, weapon )
{
// executed when gadget is added to the players inventory
}
function gadget_heat_wave_on_take( slot, weapon )
{
// executed when gadget is removed from the players inventory
self clientfield::set_to_player( "heatwave_activate", 0 );
}
//self is the player
function gadget_heat_wave_on_connect()
{
// setup up stuff on player connec
}
function gadget_heat_wave_on_player_spawn()
{
// setup up stuff on player spawned
self clientfield::set( "heatwave_victim", 0 );
self._heat_wave_stuned_end = 0;
self._heat_wave_stunned_by = undefined;
self thread watch_entity_shutdown();
}
function watch_entity_shutdown()
{
self endon ( "disconnect" );
self waittill( "death" );
if ( self IsRemoteControlling() == false )
{
visionset_mgr::deactivate( "visionset", "charred", self );
visionset_mgr::deactivate( "visionset", "heatwave", self );
}
}
function gadget_heat_wave_on_activate( slot, weapon )
{
self PlayRumbleOnEntity( "heat_wave_activate" );
self thread toggle_activate_clientfields();
visionset_mgr::activate( "visionset", "heatwave", self, ( .01 ), ( 0.1 ), ( 1.1 ) );
self thread heat_wave_think( slot, weapon );
}
function toggle_activate_clientfields()
{
self endon ( "death" );
self endon ( "disconnect" );
self clientfield::set_to_player( "heatwave_activate", 1 );
util::wait_network_frame();
self clientfield::set_to_player( "heatwave_activate", 0 );
}
function gadget_heat_wave_on_deactivate( slot, weapon )
{
}
function gadget_heat_wave_flicker( slot, weapon )
{
}
function set_gadget_status( status, time )
{
timeStr = "";
if ( IsDefined( time ) )
{
timeStr = "^3" + ", time: " + time;
}
if ( GetDvarInt( "scr_cpower_debug_prints" ) > 0 )
self IPrintlnBold( "Gadget Heat Wave: " + status + timeStr );
}
function is_entity_valid( entity, heatwave )
{
if( !IsPlayer( entity ) )
{
return false;
}
if( self GetEntityNumber() == entity GetEntityNumber() )
{
return false;
}
if ( !IsAlive( entity ) )
{
return false;
}
if ( !( entity util::mayApplyScreenEffect() ) )
{
return false;
}
if( !heat_wave_trace_entity( entity, heatwave ) )
{
return false;
}
return true;
}
function heat_wave_trace_entity( entity, heatwave )
{
entityPoint = entity.origin + ( 0, 0, 50 );
if ( !BulletTracePassed( heatwave.origin, entityPoint, true, self, undefined, false, true ) )
{
return false;
}
/#
thread util::draw_debug_line( heatwave.origin, entityPoint, 1 );
#/
return true;
}
function heat_wave_fx_cleanup( fxOrg, direction )
{
self util::waittill_any( "heat_wave_think", "heat_wave_think_finished" );
if( isDefined( fxOrg ) )
{
fxOrg StopLoopSound();
fxOrg PlaySound( "gdt_heatwave_dissipate" );
fxOrg clientfield::set( "heatwave_fx", 0 );
fxOrg delete();
}
}
function heat_wave_fx( origin, direction )
{
if ( direction == (0,0,0) )
{
direction = (0,0,1);
}
dirVec = VectorNormalize( direction );
angles = VectorToAngles( dirVec );
fxOrg = spawn( "script_model", origin+(0,0,-30), 0, angles );
fxOrg.angles = angles;
fxOrg setowner( self );
fxOrg SetModel( "tag_origin" );
fxOrg clientfield::set( "heatwave_fx", 1 );
fxOrg PlayLoopSound( "gdt_heatwave_3p_loop" );
fxOrg.soundMod = "heatwave";
fxOrg.hitsomething = false;
self thread heat_wave_fx_cleanup( fxOrg, direction );
return fxOrg;
}
function heat_wave_setup( weapon )
{
heatwave = spawnStruct();
heatwave.radius = weapon.gadget_shockfield_radius;
heatwave.origin = self geteye();
heatwave.direction = AnglesToForward( self GetPlayerAngles() );
heatwave.up = AnglesToUp( self GetPlayerAngles() );
heatwave.fxOrg = heat_wave_fx( heatwave.origin, heatwave.direction );
return heatwave;
}
function heat_wave_think( slot, weapon )
{
self endon( "disconnect" );
self notify ( "heat_wave_think" );
self endon( "heat_wave_think" );
self.heroAbilityActive = true;
heatwave = heat_wave_setup( weapon );
GlassRadiusDamage( heatwave.origin, heatwave.radius, 400, 400, "MOD_BURNED" );
self thread heat_wave_damage_entities( weapon, heatwave );
self thread heat_wave_damage_projectiles( weapon, heatwave );
wait( 250 / 1000 );
self.heroAbilityActive = false;
self notify( "heat_wave_think_finished" );
}
function heat_wave_damage_entities( weapon, heatwave )
{
self endon( "disconnect" );
self endon( "heat_wave_think" );
startTime = getTime();
burnedEnemy = false;
while( 250 + startTime > getTime() )
{
entities = GetDamageableEntArray( heatwave.origin, heatwave.radius, true );
foreach( entity in entities )
{
if( isDefined( entity._heat_wave_damaged_time ) && ( entity._heat_wave_damaged_time + 250 + 1 > getTime() ) )
{
continue;
}
if( is_entity_valid( entity, heatwave ) )
{
burnedEnemy |= heat_wave_burn_entities( weapon, entity, heatwave );
}
else if( !isPlayer( entity ) )
{
entity DoDamage( 1, heatwave.origin, self, self, "none", "MOD_BURNED", 0, weapon );
entity thread update_last_burned_by( heatwave );
}
}
{wait(.05);};
}
if ( IsAlive( self ) && ( isdefined( burnedEnemy ) && burnedEnemy ) && isdefined( level.playGadgetSuccess ) )
{
self [[ level.playGadgetSuccess ]]( weapon, "heatwaveSuccessDelay" );
}
}
function heat_wave_burn_entities( weapon, entity, heatwave )
{
burn_self = false;
burn_entity = true;
burned_enemy = true;
if( ( self.team == entity.team ) )
{
burned_enemy = false;
switch ( level.friendlyfire )
{
case 0: // no FF
burn_entity = false;
break;
case 1: // FF
// burns ally
break;
case 2: // reflect
burn_entity = false;
burn_self = true;
break;
case 3: // share (both)
burn_self = true;
break;
}
}
if( burn_entity )
{
apply_burn( weapon, entity, heatwave );
entity thread update_last_burned_by( heatwave );
}
if( burn_self )
{
apply_burn( weapon, self, heatwave );
self thread update_last_burned_by( heatwave );
}
return burned_enemy;
}
function heat_wave_damage_projectiles( weapon, heatwave )
{
self endon( "disconnect" );
self endon( "heat_wave_think" );
owner = self;
startTime = getTime();
while( 250 + startTime > getTime() )
{
if ( level.missileEntities.size < 1 )
{
{wait(.05);};
continue;
}
for ( index=0; index < level.missileEntities.size; index++ )
{
{wait(.05);};
grenade = level.missileEntities[index];
if ( !isdefined (grenade ) )
continue;
if ( grenade.weapon.isTacticalInsertion )
{
// tagTMR<NOTE>: trophy systems will attack the scriptmover not the invisible ET_MISSILE for tac inserts
continue;
}
switch( grenade.model )
{
case "t6_wpn_grenade_supply_projectile":
continue;
}
if ( !isdefined( grenade.owner ) )
{
grenade.owner = GetMissileOwner( grenade );
}
if ( isdefined( grenade.owner ))
{
if ( level.teamBased )
{
if ( grenade.owner.team == owner.team )
{
continue;
}
}
else
{
if ( grenade.owner == owner )
{
continue;
}
}
grenadeDistanceSquared = DistanceSquared( grenade.origin, heatwave.origin );
if ( grenadeDistanceSquared < ( heatwave.radius * heatwave.radius ))
{
if ( BulletTracePassed( grenade.origin, heatwave.origin + ( 0, 0, 29 ), false, owner, grenade, false, true ) )
{
owner projectileExplode( grenade, heatwave, weapon );
index--;
}
}
}
}
}
}
function projectileExplode( projectile, heatwave, weapon ) // self == trophy owning player
{
projPosition = projectile.origin;
playFX( level.trophyDetonationFX, projPosition );
projectile notify ( "trophy_destroyed" );
self RadiusDamage( projPosition, 128, 105, 10, self, "MOD_BURNED", weapon );
projectile delete();
}
function apply_burn( weapon, entity, heatwave )
{
damage = floor( entity.health * .2 );
entity DoDamage( damage, self.origin + ( 0, 0, 30 ), self, heatwave.fxOrg, 0, "MOD_BURNED", 0, weapon );
entity setdoublejumpenergy( 0 );
entity clientfield::set( "heatwave_victim", 1 );
visionset_mgr::activate( "visionset", "charred", entity, ( .01 ), ( 2 ), ( 1.5 ) );
entity thread watch_burn_clear();
entity resetdoublejumprechargetime();
shellshock_duration = 2.5;
entity._heat_wave_stuned_end = getTime() + ( shellshock_duration * 1000 );
if(!isdefined(entity._heat_wave_stunned_by))entity._heat_wave_stunned_by=[];
entity._heat_wave_stunned_by[self.clientid] = entity._heat_wave_stuned_end;
entity shellshock( "heat_wave", shellshock_duration, true );
entity thread heat_wave_burn_sound(shellshock_duration);
burned = true;
}
function watch_burn_clear()
{
self endon ("disconnect");
self endon ("death");
util::wait_network_frame();
self clientfield::set( "heatwave_victim", 0 );
}
function update_last_burned_by( heatwave )
{
self endon ( "disconnect" );
self endon ( "death" );
self._heat_wave_damaged_time = getTime();
wait( 250 );
}
function heat_wave_burn_sound(shellshock_duration)
{
fire_sound_ent = spawn( "script_origin", self.origin );
fire_sound_ent linkto( self, "tag_origin", (0,0,0), (0,0,0) );
fire_sound_ent playloopsound ("mpl_heatwave_burn_loop");
wait( shellshock_duration );
if ( isdefined( fire_sound_ent ) )
{
fire_sound_ent StopLoopSound( .5 );
util::wait_network_frame();
fire_sound_ent delete();
}
}