// todo: extend KFInvasionBot, which will support scripting class NPC_AI extends ScriptedController; var KF_StoryNPC StoryPawn; var float ReloadTime; // hack to force magazine update var bool bPendingReload; // made NPC not following dead bodies function Pawn GetMyPlayer() { local Controller C; if ( MyPlayerController == None || MyPlayerController.Pawn == None || MyPlayerController.Pawn.Health <= 0 ) { for ( C = Level.ControllerList; C != none; C = C.nextController ) { if ( PlayerController(C) != none && C.Pawn != none && C.Pawn.Health > 0 ) { MyPlayerController = PlayerController(C); break; } } } if ( MyPlayerController == None ) return None; return MyPlayerController.Pawn; } simulated function int GetTeamNum() { if(StoryPawn == none) return 255; else return StoryPawn.TeamIndex; } function Possess(Pawn aPawn) { Super.Possess(aPawn); StoryPawn = KF_StoryNPC(Pawn); } state Scripting { // added reloading -- PooSH function bool WeaponFireAgain(float RefireRate, bool bFinishedFire) { local KFWeapon W; W = KFWeapon(Pawn.Weapon); if ( W != none ) { if ( bPendingReload ) return false; if ( W.bIsReloading ) { // make sure reload finishes StartWeaponReload(); } // todo: are there any weapons with MagCapacity=1, which require reload?.. if ( W.MagCapacity > 1 && W.MagAmmoRemaining == 0 ) { StopFiring(); W.ReloadMeNow(); StartWeaponReload(); return false; } } if ( Pawn(ScriptedFocus) != none && Pawn(ScriptedFocus).Health <= 0 ) ScriptedFocus = none; // stop shooting dead bodies return super.WeaponFireAgain(RefireRate, bFinishedFire); } function StartWeaponReload() { local KFWeapon W; W = KFWeapon(Pawn.Weapon); if ( W == none ) return; bPendingReload = true; ReloadTime = Level.TimeSeconds + W.ReloadRate + 0.1; Enable('Tick'); W.ClientReload(); W.Instigator.SetAnimAction(W.WeaponReloadAnim); } // lame hack, but it seems like KFWeapon.AllowReload() supports only KFInvasionBot and KFFriendlyAI function ForceWeaponReload() { local KFWeapon W; W = KFWeapon(Pawn.Weapon); if ( W == none ) return; W.AddReloadedAmmo(); W.ActuallyFinishReloading(); } function Tick(float DeltaTime) { if ( bPendingReload ) { if ( Level.TimeSeconds >= ReloadTime ) { bPendingReload = false; ForceWeaponReload(); } } else if ( bPendingShoot ) { bPendingShoot = false; MayShootTarget(); } if ( !bPendingShoot && !bPendingReload && ((CurrentAction == None) || !CurrentAction.StillTicking(self,DeltaTime)) ) disable('Tick'); } } defaultproperties { }