161 lines
3.3 KiB
Ucode
161 lines
3.3 KiB
Ucode
//-----------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------
|
|
class HardPatController extends BossZombieController;
|
|
|
|
var NavigationPoint MidGoals[2];
|
|
var byte ReachOffset;
|
|
var Actor OldPathsCheck[3];
|
|
|
|
function Debugf( string S )
|
|
{
|
|
Level.GetLocalPlayerController().ClientMessage(S);
|
|
Log(S);
|
|
}
|
|
final function FindPathAround()
|
|
{
|
|
local Actor Res;
|
|
local NavigationPoint N;
|
|
local NavigationPoint OldPts[12];
|
|
local byte i;
|
|
local bool bResult;
|
|
|
|
if( Enemy==None || VSizeSquared(Enemy.Location-Pawn.Location)<360000 )
|
|
return; // No can do this.
|
|
|
|
// Attempt to find an alternative path to enemy.
|
|
/* This works by:
|
|
- finding shortest path to enemy
|
|
- block middle path point
|
|
- if the path is still about same to enemy, try block the new path and repeat up to 6 times.
|
|
*/
|
|
for( i=0; i<ArrayCount(OldPts); ++i )
|
|
{
|
|
Res = FindPathToward(Enemy);
|
|
if( Res==None )
|
|
break;
|
|
if( i>0 && CompareOldPaths() )
|
|
{
|
|
bResult = true;
|
|
break;
|
|
}
|
|
N = GetMidPoint();
|
|
if( N==None )
|
|
break;
|
|
N.bBlocked = true;
|
|
OldPts[i] = N;
|
|
if( i==0 )
|
|
SetOldPaths();
|
|
}
|
|
|
|
// Unblock temp blocked paths.
|
|
for( i=0; i<ArrayCount(OldPts); ++i )
|
|
if( OldPts[i]!=None )
|
|
OldPts[i].bBlocked = false;
|
|
if( !bResult )
|
|
return;
|
|
|
|
// Fetch results and switch state.
|
|
GetMidGoals();
|
|
if( ReachOffset<2 )
|
|
GoToState('PatFindWay');
|
|
}
|
|
final function NavigationPoint GetMidPoint()
|
|
{
|
|
local byte n;
|
|
|
|
for( n=0; n<ArrayCount(RouteCache); ++n )
|
|
if( RouteCache[n]==None )
|
|
break;
|
|
if( n==0 )
|
|
return None;
|
|
return NavigationPoint(RouteCache[(n-1)*0.5]);
|
|
}
|
|
final function bool CompareOldPaths()
|
|
{
|
|
local byte n,i;
|
|
|
|
for( i=0; i<6; ++i )
|
|
{
|
|
if( RouteCache[i]==None )
|
|
break;
|
|
for( n=0; n<ArrayCount(OldPathsCheck); ++n )
|
|
if( RouteCache[i]==OldPathsCheck[n] )
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
final function SetOldPaths()
|
|
{
|
|
local byte n;
|
|
|
|
for( n=0; n<ArrayCount(OldPathsCheck); ++n )
|
|
OldPathsCheck[n] = RouteCache[n+1];
|
|
if( RouteCache[1]==None )
|
|
OldPathsCheck[0] = RouteCache[0];
|
|
}
|
|
final function GetMidGoals()
|
|
{
|
|
local byte n;
|
|
|
|
for( n=0; n<ArrayCount(RouteCache); ++n )
|
|
if( RouteCache[n]==None )
|
|
break;
|
|
if( n==0 )
|
|
{
|
|
ReachOffset = 2;
|
|
return;
|
|
}
|
|
--n;
|
|
MidGoals[0] = NavigationPoint(RouteCache[n*0.5]);
|
|
MidGoals[1] = NavigationPoint(RouteCache[n]);
|
|
if( MidGoals[0]==MidGoals[1] )
|
|
ReachOffset = 1;
|
|
else ReachOffset = 0;
|
|
}
|
|
|
|
function bool CanKillMeYet()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
state PatFindWay
|
|
{
|
|
Ignores Timer,SeePlayer,HearNoise,DamageAttitudeTo,EnemyChanged,Startle,Tick;
|
|
|
|
final function PickDestination()
|
|
{
|
|
if( ReachOffset>=2 )
|
|
{
|
|
GotoState('ZombieHunt');
|
|
return;
|
|
}
|
|
if( ActorReachable(MidGoals[ReachOffset]) )
|
|
{
|
|
MoveTarget = MidGoals[ReachOffset];
|
|
++ReachOffset;
|
|
}
|
|
else
|
|
{
|
|
MoveTarget = FindPathToward(MidGoals[ReachOffset]);
|
|
if( MoveTarget==None )
|
|
++ReachOffset;
|
|
}
|
|
}
|
|
function BreakUpDoor( KFDoorMover Other, bool bTryDistanceAttack )
|
|
{
|
|
Global.BreakUpDoor(Other,bTryDistanceAttack);
|
|
Pawn.GoToState('');
|
|
}
|
|
Begin:
|
|
PickDestination();
|
|
if( MoveTarget==None )
|
|
Sleep(0.5f);
|
|
else MoveToward(MoveTarget,MoveTarget,,False);
|
|
GoTo'Begin';
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
}
|