#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"); } */