#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; #precache( "string", "MP_CANNOT_LOCKON_TO_TARGET" ); #namespace singlelockap_guidance; //this number corresponds to a code define function autoexec __init__sytem__() { system::register("singlelockap_guidance",&__init__,undefined,undefined); } function __init__() { callback::on_spawned( &on_player_spawned ); } function on_player_spawned() { self endon( "disconnect" ); self ClearAPTarget(); thread APToggleLoop(); self thread APFiredNotify(); } function ClearAPTarget( weapon, whom ) { if (!IsDefined(self.multiLockList)) { self.multiLockList=[]; } if (IsDefined(whom)) { for(i=0;i=1) { continue; } bestTarget = self GetBestTarget(weapon); if ( !IsDefined(bestTarget) && self.multiLockList.size==0 ) { self DestroyLockOnCanceledMessage(); continue; } //append to the lock list if we have the space if (IsDefined(bestTarget) && self.multiLockList.size<1) { self WeaponLockStart(bestTarget.apTarget,self.multiLockList.size); self.multiLockList[self.multiLockList.size] = bestTarget; } } } function DestroyLockOnCanceledMessage() { if( isdefined( self.LockOnCanceledMessage ) ) self.LockOnCanceledMessage destroy(); } function DisplayLockOnCanceledMessage() { if( isdefined( self.LockOnCanceledMessage ) ) return; self.LockOnCanceledMessage = newclienthudelem( self ); self.LockOnCanceledMessage.fontScale = 1.25; self.LockOnCanceledMessage.x = 0; self.LockOnCanceledMessage.y = 50; self.LockOnCanceledMessage.alignX = "center"; self.LockOnCanceledMessage.alignY = "top"; self.LockOnCanceledMessage.horzAlign = "center"; self.LockOnCanceledMessage.vertAlign = "top"; self.LockOnCanceledMessage.foreground = true; self.LockOnCanceledMessage.hidewhendead = false; self.LockOnCanceledMessage.hidewheninmenu = true; self.LockOnCanceledMessage.archived = false; self.LockOnCanceledMessage.alpha = 1.0; self.LockOnCanceledMessage SetText( &"MP_CANNOT_LOCKON_TO_TARGET" ); } function GetBestTarget(weapon) { playerTargets = GetPlayers(); vehicleTargets = target_getArray(); targetsAll = GetAITeamArray(); targetsAll = ArrayCombine(targetsAll, playerTargets, false, false); targetsAll = ArrayCombine(targetsAll, vehicleTargets, false, false); targetsValid = []; for ( idx = 0; idx < targetsAll.size; idx++ ) { if ( level.teamBased ) //team based game modes { if ( isdefined(targetsAll[idx].team) && targetsAll[idx].team != self.team) { if ( self InsideAPReticleNoLock( targetsAll[idx] ) ) { if (self LockSightTest(targetsAll[idx])) { targetsValid[targetsValid.size] = targetsAll[idx]; } } } } else { if( self InsideAPReticleNoLock( targetsAll[idx] ) ) //Free for all { if( isdefined( targetsAll[idx].owner ) && self != targetsAll[idx].owner ) { if (self LockSightTest(targetsAll[idx])) { targetsValid[targetsValid.size] = targetsAll[idx]; } } } } } if ( targetsValid.size == 0 ) return undefined; //find the best target that isn't already in the list playerForward = AnglesToForward( self GetPlayerAngles()); dots=[]; for (i=0;ib.dot) return 1; return 0; } function InsideAPReticleNoLock( target ) { radius = self getLockOnRadius(); return target_isincircle( target, self, 65, radius ); } function InsideAPReticleLocked( target ) { radius = (self getLockOnLossRadius()); //maintaining lock is slightly larger to avoid edge case of oscillation between lock and nolock return target_isincircle( target, self, 65, radius ); } function IsStillValidTarget( weapon, ent ) { if ( ! isdefined( ent ) ) return false; if ( ! InsideAPReticleLocked( ent ) ) return false; if ( !IsAlive( ent ) ) return false; if (!LockSightTest(ent)) return false; return true; } function SeekerSound( alias, looping, id ) { self notify( "stop_sound"+id); self endon ( "stop_sound"+id ); self endon( "disconnect" ); self endon ( "death" ); if (IsDefined(alias)) { self PlayRumbleOnEntity( "stinger_lock_rumble" ); time = SoundGetPlaybackTime(alias)*0.001; do { self playLocalSound( alias ); wait(time); } while (looping); self StopRumble( "stinger_lock_rumble" ); } } function LockSightTest( target ) { eyePos = self GetEye(); if ( !isdefined( target ) ) //targets can disapear during targeting. return false; if ( !IsAlive( target ) ) return false; pos = target GetShootAtPos(); if (IsDefined(pos)) { passed = BulletTracePassed( eyePos, pos, false, target, undefined, true, true ); if ( passed ) return true; } pos = target GetCentroid(); if (IsDefined(pos)) { passed = BulletTracePassed( eyePos, pos, false, target, undefined, true, true ); if ( passed ) return true; } pos=target.origin; passed = BulletTracePassed( eyePos, pos, false, target, undefined, true, true ); if ( passed ) return true; return false; }