boiii-scripts/shared/weapons/replay_gun.gsc
2023-04-13 17:30:38 +02:00

316 lines
14 KiB
Plaintext

#using scripts\codescripts\struct;
#using scripts\shared\array_shared;
#using scripts\shared\callbacks_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\flagsys_shared;
#using scripts\shared\hud_util_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#using scripts\shared\abilities\_ability_util;
#namespace replay_gun;
function autoexec __init__sytem__() { system::register("replay_gun",&__init__,undefined,undefined); }
function __init__()
{
callback::on_spawned( &watch_for_replay_gun );
}
function watch_for_replay_gun()
{
self endon( "disconnect" );
self endon( "death" );
self endon( "spawned_player" );
self endon("killReplayGunMonitor");
while( 1 )
{
self waittill( "weapon_change_complete", weapon );
self WeaponLockFree();
if ( ( isdefined( weapon.usesPivotTargeting ) && weapon.usesPivotTargeting ) )
{
self thread watch_lockon(weapon);
}
}
}
function watch_lockon(weapon)
{
self endon( "disconnect" );
self endon( "death" );
self endon( "spawned_player" );
self endon( "weapon_change_complete" );
while(1)
{
{wait(.05);};
if ( !IsDefined(self.lockonentity) )
{
ads = ( self PlayerAds() == 1.0 );
if ( ads )
{
target = self get_a_target(weapon);
// start to lock on
if ( is_valid_target( target ) )
{
self WeaponLockFree();
self.lockonentity = target;
//self WeaponLockStart( target );
}
}
}
}
}
function get_a_target(weapon)
{
origin = self GetWeaponMuzzlePoint();
forward = self GetWeaponForwardDir();
targets = self get_potential_targets();
if ( !IsDefined( targets ) )
return undefined;
if ( !IsDefined(weapon.lockOnScreenRadius) || weapon.lockOnScreenRadius< 1 )
return undefined;
validTargets = [];
should_wait = false;
for ( i = 0; i < targets.size; i++ )
{
if ( should_wait )
{
{wait(.05);};
origin = self GetWeaponMuzzlePoint();
forward = self GetWeaponForwardDir();
should_wait = false;
}
testTarget = targets[i];
if ( !is_valid_target( testTarget ) )
{
continue;
}
testOrigin = get_target_lock_on_origin( testTarget );
//test_range_squared = DistanceSquared( origin, testOrigin );
test_range = Distance( origin, testOrigin );
//gun_range = self get_replay_range(weapon);
if ( test_range > weapon.lockOnMaxRange ||
test_range < weapon.lockOnMinRange )
{
continue;
}
normal = VectorNormalize( testOrigin - origin );
dot = VectorDot( forward, normal );
if ( 0 > dot )
{
// guy's behind us
continue;
}
if ( !self inside_screen_crosshair_radius( testOrigin, weapon ) )
{
continue;
}
canSee = self can_see_projected_crosshair( testTarget, testOrigin, origin, forward, test_range );
should_wait = true; // ^^ that's expensive
if ( canSee )
{
validTargets[ validTargets.size ] = testTarget;
}
}
return pick_a_target_from( validTargets );
}
function get_potential_targets()
{
str_opposite_team = "axis";
if ( self.team == "axis" )
{
str_opposite_team = "allies";
}
potentialTargets = [];
aiTargets = GetAITeamArray( str_opposite_team );
if ( aiTargets.size > 0 )
potentialTargets = ArrayCombine( potentialTargets, aiTargets, true, false );
playerTargets = self GetEnemies();
if ( playerTargets.size > 0 )
potentialTargets = ArrayCombine( potentialTargets, playerTargets, true, false );
if ( potentialTargets.size == 0 )
return undefined;
return potentialTargets;
}
function pick_a_target_from( targets )
{
if ( !IsDefined( targets ) )
return undefined;
bestTarget = undefined;
bestTargetDistanceSquared = undefined;
for ( i = 0; i < targets.size; i++ )
{
target = targets[i];
if ( is_valid_target( target ) )
{
targetDistanceSquared = DistanceSquared( self.origin, target.origin );
if ( !IsDefined( bestTarget ) || !IsDefined( bestTargetDistanceSquared ) )
{
bestTarget = target;
bestTargetDistanceSquared = targetDistanceSquared;
}
else
{
if ( targetDistanceSquared < bestTargetDistanceSquared )
{
bestTarget = target;
bestTargetDistanceSquared = targetDistanceSquared;
}
}
}
}
return bestTarget;
}
function trace( from, to )
{
return bullettrace(from,to, 0, self )[ "position" ];
}
function can_see_projected_crosshair( target, target_origin, player_origin, player_forward, distance )
{
crosshair = player_origin + player_forward * distance;
collided = target trace( target_origin, crosshair );
if ( Distance2DSquared(crosshair,collided) > 3 * 3 )
{
return false;
}
collided = self trace( player_origin, crosshair );
if ( Distance2DSquared(crosshair,collided) > 3 * 3 )
{
return false;
}
return true;
}
function is_valid_target( ent )
{
return IsDefined( ent ) && IsAlive( ent );
}
function inside_screen_crosshair_radius( testOrigin, weapon )
{
radius = weapon.lockOnScreenRadius;
return self inside_screen_radius( testOrigin, radius );
}
function inside_screen_lockon_radius( targetOrigin )
{
radius = self getLockOnRadius();
return self inside_screen_radius( targetOrigin, radius );
}
function inside_screen_radius( targetOrigin, radius )
{
const useFov = 65;
return Target_OriginIsInCircle( targetOrigin, self, useFov, radius );
}
/*
function get_pivot_tether_distance()
{
distance = SETTING_LOCKING_TETHER_DISTANCE;
return distance;
}
function get_replay_range(weapon)
{
range = weapon.lockOnMaxRange;
return range;
}
function get_crosshair_radius(weapon)
{
crosshairRadius = weapon.lockOnScreenRadius; //25
return crosshairRadius;
}
*/
function get_target_lock_on_origin( target )
{
return self GetReplayGunLockOnOrigin( target );
}
/*
function get_Lock_on_time()
{
lockOnTime = self getlockOnSpeed();
return lockOnTime;
}
function replay_sticky_aim()
{
self notify ("replay_sticky_aim_thread");
self endon ("replay_sticky_aim_thread");
replay_sticky_aim_think();
SetDvar("aim_slowdown_pitch_scale_ads", "0.5");
SetDvar("aim_slowdown_yaw_scale_ads", "0.5");
}
function replay_sticky_aim_think()
{
self endon ("death");
self endon ("disconnect");
self endon ("replay_sticky_aim_thread");
SetDvar("aim_slowdown_pitch_scale_ads", "0.25");
SetDvar("aim_slowdown_yaw_scale_ads", "0.25");
self waittill ("replay_target_lost");
}
*/