Better patrolling
This is a revised patrolling state that, among other things, omits the crashing and hanging present in the vanilla code
state Patrolling
{
function SetFall()
{
StartFalling('Patrolling', 'ContinuePatrol');
}
function HitWall(vector HitNormal, actor Wall)
{
if (Physics == PHYS_Falling)
return;
Global.HitWall(HitNormal, Wall);
CheckOpenDoor(HitNormal, Wall);
}
function AnimEnd()
{
PlayWaiting();
}
function PatrolPoint PickStartPoint()
{
local NavigationPoint nav;
local PatrolPoint curNav;
local float curDist;
local PatrolPoint closestNav;
local float closestDist;
nav = Level.NavigationPointList;
while (nav != None)
{
nav.visitedWeight = 0;
nav = nav.nextNavigationPoint;
}
closestNav = None;
closestDist = 100000;
nav = Level.NavigationPointList;
while (nav != None)
{
curNav = PatrolPoint(nav);
if ((curNav != None) && (curNav.Tag == OrderTag))
{
while (curNav != None)
{
if (curNav.visitedWeight != 0) // been here before
break;
curDist = VSize(Location - curNav.Location);
if ((closestNav == None) || (closestDist > curDist))
{
closestNav = curNav;
closestDist = curDist;
}
curNav.visitedWeight = 1;
curNav = curNav.NextPatrolPoint;
}
}
nav = nav.nextNavigationPoint;
}
return (closestNav);
}
function PickDestination()
{
if (PatrolPoint(destPoint) != None)
destPoint = PatrolPoint(destPoint).NextPatrolPoint;
else
destPoint = PickStartPoint();
if (destPoint == None) // can't go anywhere...
GotoState('Standing');
}
function BeginState()
{
StandUp();
SetEnemy(None, EnemyLastSeen, true);
Disable('AnimEnd');
SetupWeapon(false);
SetDistress(false);
bStasis = false;
SeekPawn = None;
EnableCheckDestLoc(false);
}
function EndState()
{
EnableCheckDestLoc(false);
Enable('AnimEnd');
bStasis = true;
}
Begin:
destPoint = None;
Patrol:
WaitForLanding();
PickDestination();
Moving:
// Move from pathnode to pathnode until we get where we're going
if (destPoint != None)
{
if (!IsPointInCylinder(self, destPoint.Location, 16-CollisionRadius))
{
EnableCheckDestLoc(true);
MoveTarget = FindPathToward(destPoint);
if (MoveTarget != None)
{
while (MoveTarget != None)
{
if (ShouldPlayWalk(MoveTarget.Location))
PlayWalking();
MoveToward(MoveTarget, GetWalkingSpeed());
CheckDestLoc(MoveTarget.Location, true);
if (MoveTarget == destPoint)
break;
MoveTarget = FindPathToward(destPoint);
}
if ((MoveTarget != None) && (MoveTarget != destPoint))
{
SetOrders('Standing', 'None', False);
GoToState('Standing');
}
}
//MADDERS: Shout out to Hanfling on this one.
else
{
if (ShouldPlayWalk(destPoint.Location))
PlayWalking();
MoveToward(destPoint, GetWalkingSpeed());
}
EnableCheckDestLoc(false);
}
}
else
Goto('Patrol');
Pausing:
if (!bAlwaysPatrol)
bStasis = true;
Acceleration = vect(0, 0, 0);
// Turn in the direction dictated by the WanderPoint, or a random direction
if (PatrolPoint(destPoint) != None)
{
if ((PatrolPoint(destPoint).pausetime > 0) || (PatrolPoint(destPoint).NextPatrolPoint == None))
{
if (ShouldPlayTurn(Location + PatrolPoint(destPoint).lookdir))
PlayTurning();
TurnTo(Location + PatrolPoint(destPoint).lookdir);
Enable('AnimEnd');
TweenToWaiting(0.2);
PlayScanningSound();
sleepTime = PatrolPoint(destPoint).pausetime * ((-0.9*restlessness) + 1);
Sleep(sleepTime);
Disable('AnimEnd');
FinishAnim();
}
}
Goto('Patrol');
ContinuePatrol:
ContinueFromDoor:
FinishAnim();
PlayWalking();
Goto('Moving');
}