314 lines
17 KiB
Plaintext
314 lines
17 KiB
Plaintext
#using scripts\codescripts\struct;
|
|
|
|
#using scripts\shared\callbacks_shared;
|
|
#using scripts\shared\challenges_shared;
|
|
#using scripts\shared\clientfield_shared;
|
|
#using scripts\shared\flagsys_shared;
|
|
#using scripts\shared\killcam_shared;
|
|
#using scripts\shared\player_shared;
|
|
#using scripts\shared\scoreevents_shared;
|
|
#using scripts\shared\system_shared;
|
|
#using scripts\shared\util_shared;
|
|
#using scripts\shared\visionset_mgr_shared;
|
|
|
|
#using scripts\shared\weapons\_weaponobjects;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#precache( "fx", "weapon/fx_lightninggun_arc" );
|
|
|
|
|
|
|
|
#namespace lightninggun;
|
|
|
|
function init_shared()
|
|
{
|
|
level.weaponLightningGun = GetWeapon( "hero_lightninggun" );
|
|
level.weaponLightningGunArc = GetWeapon( "hero_lightninggun_arc" );
|
|
level.weaponLightningGunKillcamTime = GetDvarFloat( "scr_lightningGunKillcamTime", 0.35 );
|
|
level.weaponLightningGunKillcamDecelPercent = GetDvarFloat( "scr_lightningGunKillcamDecelPercent", 0.25 );
|
|
level.weaponLightningGunKillcamOffset = GetDvarFloat( "scr_lightningGunKillcamOffset", 150.0 );
|
|
|
|
level.lightninggun_arc_range = 300;
|
|
level.lightninggun_arc_range_sq = level.lightninggun_arc_range * level.lightninggun_arc_range;
|
|
level.lightninggun_arc_speed = 650;
|
|
level.lightninggun_arc_speed_sq = level.lightninggun_arc_speed * level.lightninggun_arc_speed;
|
|
level.lightninggun_arc_fx_min_range = 1;
|
|
level.lightninggun_arc_fx_min_range_sq = level.lightninggun_arc_fx_min_range * level.lightninggun_arc_fx_min_range;
|
|
|
|
level._effect["lightninggun_arc"] = "weapon/fx_lightninggun_arc";
|
|
|
|
callback::add_weapon_damage( level.weaponLightningGun, &on_damage_lightninggun );
|
|
|
|
/#
|
|
level thread update_dvars();
|
|
#/
|
|
}
|
|
|
|
/#
|
|
function update_dvars()
|
|
{
|
|
while(1)
|
|
{
|
|
wait(1);
|
|
level.weaponLightningGunKillcamTime = GetDvarFloat( "scr_lightningGunKillcamTime", 0.35 );
|
|
level.weaponLightningGunKillcamDecelPercent = GetDvarFloat( "scr_lightningGunKillcamDecelPercent", 0.25 );
|
|
level.weaponLightningGunKillcamOffset = GetDvarFloat( "scr_lightningGunKillcamOffset", 150.0 );
|
|
}
|
|
}
|
|
#/
|
|
|
|
function lightninggun_start_damage_effects( eAttacker )
|
|
{
|
|
self endon( "disconnect" );
|
|
|
|
/#
|
|
If ( IsGodMode( self ) )
|
|
{
|
|
return;
|
|
}
|
|
#/
|
|
|
|
self SetElectrifiedState( true );
|
|
self.electrifiedBy = eAttacker;
|
|
self PlayRumbleOnEntity( "lightninggun_victim" );
|
|
|
|
wait( 2 );
|
|
|
|
self.electrifiedBy = undefined;
|
|
self SetElectrifiedState( false );
|
|
}
|
|
|
|
function lightninggun_arc_killcam( arc_source_pos, arc_target, arc_target_pos, original_killcam_ent, waitTime )
|
|
{
|
|
arc_target.killcamKilledByEnt = create_killcam_entity( original_killcam_ent.origin, original_killcam_ent.angles, level.weaponLightningGunArc );
|
|
arc_target.killcamKilledByEnt killcam::store_killcam_entity_on_entity(original_killcam_ent);
|
|
|
|
arc_target.killcamKilledByEnt killcam_move( arc_source_pos, arc_target_pos, waitTime );
|
|
}
|
|
|
|
function lightninggun_arc_fx( arc_source_pos, arc_target, arc_target_pos, distanceSq, original_killcam_ent )
|
|
{
|
|
if ( !isdefined( arc_target ) || !isdefined( original_killcam_ent ) )
|
|
return;
|
|
|
|
waitTime = 0.25;
|
|
if ( level.lightninggun_arc_speed_sq > 100 && distanceSq > 1 )
|
|
{
|
|
waitTime = distanceSq / level.lightninggun_arc_speed_sq;
|
|
}
|
|
|
|
lightninggun_arc_killcam( arc_source_pos, arc_target, arc_target_pos, original_killcam_ent, waitTime );
|
|
killcamEntity = arc_target.killcamKilledByEnt;
|
|
|
|
if ( !isdefined( arc_target ) || !isdefined( original_killcam_ent ) )
|
|
return;
|
|
|
|
if ( distanceSq < level.lightninggun_arc_fx_min_range_sq )
|
|
{
|
|
wait( waitTime );
|
|
|
|
killcamEntity delete();
|
|
|
|
if ( isdefined( arc_target ) )
|
|
{
|
|
arc_target.killcamKilledByEnt = undefined;
|
|
}
|
|
//Not playing arcing FX. Enemies too close
|
|
return;
|
|
}
|
|
|
|
// this needs to be clientsided.
|
|
fxOrg = spawn( "script_model", arc_source_pos );
|
|
fxOrg SetModel( "tag_origin" );
|
|
|
|
fx = PlayFxOnTag( level._effect["lightninggun_arc"], fxOrg, "tag_origin" );
|
|
playsoundatposition( "wpn_lightning_gun_bounce", fxOrg.origin );
|
|
|
|
fxOrg MoveTo( arc_target_pos, waitTime );
|
|
fxOrg waittill( "movedone" );
|
|
util::wait_network_frame();
|
|
util::wait_network_frame();
|
|
util::wait_network_frame();
|
|
fxOrg delete();
|
|
|
|
killcamEntity delete();
|
|
|
|
if ( isdefined( arc_target ) )
|
|
{
|
|
arc_target.killcamKilledByEnt = undefined;
|
|
}
|
|
}
|
|
|
|
function lightninggun_arc( delay, eAttacker, arc_source, arc_source_origin, arc_source_pos, arc_target, arc_target_pos, distanceSq )
|
|
{
|
|
if ( delay )
|
|
{
|
|
wait( delay );
|
|
|
|
if ( !IsDefined( arc_target ) || !IsAlive( arc_target ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// make sure we're still in range after the delay
|
|
distanceSq = DistanceSquared( arc_target.origin, arc_source_origin );
|
|
if ( distanceSq > level.lightninggun_arc_range_sq )
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( !isdefined( arc_source ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( !isdefined( arc_source.killcamKilledByEnt ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
level thread lightninggun_arc_fx( arc_source_pos, arc_target, arc_target_pos, distanceSq, arc_source.killcamKilledByEnt );
|
|
arc_target thread lightninggun_start_damage_effects( eAttacker );
|
|
arc_target DoDamage( arc_target.health, arc_source_pos, eAttacker, arc_source, "none", "MOD_PISTOL_BULLET", 0, level.weaponLightningGunArc );
|
|
}
|
|
|
|
// arc_source_origin is the origin of the player initially hit, arc_source_pos is the pos of the tag the arc will be emanating from
|
|
function lightninggun_find_arc_targets( eAttacker, arc_source, arc_source_origin, arc_source_pos )
|
|
{
|
|
delay = 0.05;
|
|
|
|
if ( !isdefined( eAttacker ) )
|
|
return;
|
|
|
|
allEnemyAlivePlayers = util::get_other_teams_alive_players_s( eAttacker.team );
|
|
|
|
closestPlayers = ArraySort( allEnemyAlivePlayers.a, arc_source_origin, true );
|
|
|
|
foreach( player in closestPlayers )
|
|
{
|
|
if ( IsDefined( arc_source ) && player == arc_source )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( player player::is_spawn_protected() )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
distanceSq = DistanceSquared( player.origin, arc_source_origin );
|
|
if ( distanceSq > level.lightninggun_arc_range_sq )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if ( eAttacker != player && weaponobjects::friendlyFireCheck( eAttacker, player ) )
|
|
{
|
|
if ( isdefined( self ) && !player DamageConeTrace( arc_source_pos, self ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
level thread lightninggun_arc( delay, eAttacker, arc_source, arc_source_origin, arc_source_pos, player, player GetTagOrigin( "j_spineupper" ), distanceSq );
|
|
delay += 0.05;
|
|
}
|
|
}
|
|
}
|
|
|
|
function create_killcam_entity( origin, angles, weapon )
|
|
{
|
|
killcamKilledByEnt = spawn( "script_model", origin );
|
|
killcamKilledByEnt SetModel( "tag_origin" );
|
|
killcamKilledByEnt.angles = angles;
|
|
killcamKilledByEnt SetWeapon( weapon );
|
|
return killcamKilledByEnt;
|
|
}
|
|
|
|
function killcam_move( start_origin, end_origin, time )
|
|
{
|
|
delta = end_origin - start_origin;
|
|
dist = Length( delta );
|
|
delta = VectorNormalize( delta );
|
|
move_to_dist = dist - level.weaponLightningGunKillcamOffset;
|
|
|
|
end_angles = (0,0,0);
|
|
|
|
if ( move_to_dist > 0 )
|
|
{
|
|
move_to_pos = start_origin + (delta * move_to_dist);
|
|
self MoveTo( move_to_pos, time, 0, time * level.weaponLightningGunKillcamDecelPercent );
|
|
end_angles = VectorToAngles( delta );
|
|
}
|
|
else
|
|
{
|
|
delta = end_origin - self.origin;
|
|
end_angles = VectorToAngles( delta );
|
|
}
|
|
|
|
//self RotateTo( end_angles, time, 0, time * level.weaponLightningGunKillcamDecelPercent );
|
|
}
|
|
|
|
function lightninggun_damage_response( eAttacker, eInflictor, weapon, meansOfDeath, damage )
|
|
{
|
|
source_pos = eAttacker.origin;
|
|
bolt_source_pos = eAttacker GetTagOrigin( "tag_flash" );
|
|
|
|
arc_source = self;
|
|
arc_source_origin = self.origin;
|
|
arc_source_pos = self GetTagOrigin( "j_spineupper" );
|
|
|
|
delta = arc_source_pos - bolt_source_pos;
|
|
angles = (0,0,0); //VectorToAngles( delta );
|
|
|
|
arc_source.killcamKilledByEnt = create_killcam_entity( bolt_source_pos, angles, weapon );
|
|
arc_source.killcamKilledByEnt killcam_move( bolt_source_pos, arc_source_pos, level.weaponLightningGunKillcamTime );
|
|
killcamEntity = arc_source.killcamKilledByEnt;
|
|
|
|
self thread lightninggun_start_damage_effects( eAttacker );
|
|
// self DoDamage( self.health, source_pos, eAttacker, eAttacker, "none", "MOD_PISTOL_BULLET", 0, level.weaponLightningGunArc );
|
|
|
|
wait( 2 );
|
|
|
|
if ( !IsDefined( self ) )
|
|
{
|
|
self thread lightninggun_find_arc_targets( eAttacker, undefined, arc_source_origin, arc_source_pos );
|
|
return;
|
|
}
|
|
|
|
// get latest positioning
|
|
if ( IsDefined( self.body ) )
|
|
{
|
|
arc_source_origin = self.body.origin;
|
|
arc_source_pos = self.body GetTagOrigin( "j_spineupper" );
|
|
}
|
|
|
|
self thread lightninggun_find_arc_targets( eAttacker, arc_source, arc_source_origin, arc_source_pos );
|
|
|
|
// wait the maximum amount of time that we could still be arcing. The other players
|
|
// will use this killcamEntity
|
|
wait( 0.05 * 9 );
|
|
killcamEntity delete();
|
|
|
|
if ( IsDefined( arc_source ) )
|
|
{
|
|
arc_source.killcamKilledByEnt = undefined;
|
|
}
|
|
}
|
|
|
|
function on_damage_lightninggun( eAttacker, eInflictor, weapon, meansOfDeath, damage )
|
|
{
|
|
if ( "MOD_PISTOL_BULLET" != meansOfDeath && "MOD_HEAD_SHOT" != meansOfDeath )
|
|
return;
|
|
|
|
// no additional lightning gun damage response if the player has armor on for now.
|
|
// if ( self flagsys::get( "gadget_armor_on" ) )
|
|
// return;
|
|
|
|
self thread lightninggun_damage_response( eAttacker, eInflictor, weapon, meansOfDeath, damage );
|
|
}
|