2001-01-16 22:40:14 +01:00
|
|
|
/*=========================================================================
|
|
|
|
|
|
|
|
npcpath.cpp
|
|
|
|
|
|
|
|
Author: CRB
|
|
|
|
Created:
|
|
|
|
Project: Spongebob
|
|
|
|
Purpose:
|
|
|
|
|
|
|
|
Copyright (c) 2000 Climax Development Ltd
|
|
|
|
|
|
|
|
===========================================================================*/
|
|
|
|
|
2001-01-18 20:18:39 +01:00
|
|
|
#ifndef __ENEMY_NPCPATH_H__
|
|
|
|
#include "enemy\npcpath.h"
|
2001-01-16 22:56:29 +01:00
|
|
|
#endif
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
bool CNpcPath::isPointNear( DVECTOR testPos, s32 *xDist, s32 *yDist )
|
2001-01-16 22:40:14 +01:00
|
|
|
{
|
|
|
|
s32 xDistSqr, yDistSqr;
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
u16 *waypoint = waypointPtr;
|
|
|
|
waypoint += 2 * currentWaypoint;
|
|
|
|
|
2001-05-31 18:24:48 +02:00
|
|
|
*xDist = ( ( *waypoint << 4 ) + 8 ) - testPos.vx;
|
2001-01-18 20:18:39 +01:00
|
|
|
xDistSqr = (*xDist) * (*xDist);
|
2001-01-16 22:40:14 +01:00
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
waypoint++;
|
|
|
|
|
2001-05-31 18:24:48 +02:00
|
|
|
*yDist = ( ( *waypoint << 4 ) + 16 ) - testPos.vy;
|
2001-01-18 20:18:39 +01:00
|
|
|
yDistSqr = (*yDist) * (*yDist);
|
2001-01-16 22:40:14 +01:00
|
|
|
|
|
|
|
if ( xDistSqr + yDistSqr < 100 )
|
|
|
|
{
|
|
|
|
return( true );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return( false );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-01-16 22:56:29 +01:00
|
|
|
void CNpcPath::initPath()
|
|
|
|
{
|
2001-05-30 00:07:28 +02:00
|
|
|
//waypoint = NULL;
|
2001-01-16 22:56:29 +01:00
|
|
|
pathType = SINGLE_USE_PATH;
|
2001-05-30 00:07:28 +02:00
|
|
|
currentWaypoint = 0;
|
|
|
|
lastWaypoint = 0;
|
2001-01-16 22:56:29 +01:00
|
|
|
waypointCount = 0;
|
|
|
|
reversePath = false;
|
2001-04-07 17:39:22 +02:00
|
|
|
minX = maxX = minY = maxY = 0;
|
2001-05-30 00:07:28 +02:00
|
|
|
waypointPtr = NULL;
|
|
|
|
|
2001-01-16 22:56:29 +01:00
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-01-26 16:16:07 +01:00
|
|
|
void CNpcPath::resetPath()
|
|
|
|
{
|
2001-05-30 00:07:28 +02:00
|
|
|
lastWaypoint = currentWaypoint = 0;
|
2001-01-26 16:16:07 +01:00
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
2001-01-16 22:40:14 +01:00
|
|
|
|
2001-04-04 20:35:07 +02:00
|
|
|
void CNpcPath::getPathXExtents( s32 *minExtent, s32 *maxExtent )
|
|
|
|
{
|
|
|
|
*minExtent = minX;
|
|
|
|
*maxExtent = maxX;
|
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-04-07 17:39:22 +02:00
|
|
|
void CNpcPath::getPathYExtents( s32 *minExtent, s32 *maxExtent )
|
|
|
|
{
|
|
|
|
*minExtent = minY;
|
|
|
|
*maxExtent = maxY;
|
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
2001-01-26 16:16:07 +01:00
|
|
|
|
2001-04-02 21:21:46 +02:00
|
|
|
void CNpcPath::setPathType( u8 newPathType )
|
2001-01-16 22:56:29 +01:00
|
|
|
{
|
2001-04-02 21:21:46 +02:00
|
|
|
pathType = (NPC_PATH_TYPE) newPathType;
|
2001-01-16 22:56:29 +01:00
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-04-19 01:12:24 +02:00
|
|
|
u8 CNpcPath::getPathType()
|
|
|
|
{
|
|
|
|
return( pathType );
|
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void CNpcPath::setWaypointPtr( u16 *newPtr )
|
|
|
|
{
|
|
|
|
waypointPtr = newPtr;
|
|
|
|
|
|
|
|
setPathExtents();
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void CNpcPath::setPathExtents()
|
|
|
|
{
|
|
|
|
u8 tempWaypoint;
|
|
|
|
u16 *tempPtr = waypointPtr;
|
|
|
|
DVECTOR mapPos;
|
|
|
|
|
|
|
|
if ( tempPtr )
|
|
|
|
{
|
2001-05-31 18:24:48 +02:00
|
|
|
mapPos.vx = ( *tempPtr << 4 ) + 8;
|
2001-05-30 00:07:28 +02:00
|
|
|
*tempPtr++;
|
2001-05-31 18:24:48 +02:00
|
|
|
mapPos.vy = ( *tempPtr << 4 ) + 16;
|
2001-05-30 00:07:28 +02:00
|
|
|
*tempPtr++;
|
|
|
|
|
|
|
|
minX = maxX = mapPos.vx;
|
|
|
|
minY = maxY = mapPos.vy;
|
|
|
|
|
|
|
|
for ( tempWaypoint = 1 ; tempWaypoint <= waypointCount ; tempWaypoint++ )
|
|
|
|
{
|
2001-05-31 18:24:48 +02:00
|
|
|
mapPos.vx = ( *tempPtr << 4 ) + 8;
|
2001-05-30 00:07:28 +02:00
|
|
|
*tempPtr++;
|
2001-05-31 18:24:48 +02:00
|
|
|
mapPos.vy = ( *tempPtr << 4 ) + 16;
|
2001-05-30 00:07:28 +02:00
|
|
|
*tempPtr++;
|
|
|
|
|
|
|
|
if ( mapPos.vx < minX )
|
|
|
|
{
|
|
|
|
minX = mapPos.vx;
|
|
|
|
}
|
|
|
|
else if ( mapPos.vx > maxX )
|
|
|
|
{
|
|
|
|
maxX = mapPos.vx;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( mapPos.vy < minY )
|
|
|
|
{
|
|
|
|
minY = mapPos.vy;
|
|
|
|
}
|
|
|
|
else if ( mapPos.vy > maxY )
|
|
|
|
{
|
|
|
|
maxY = mapPos.vy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-01-16 22:56:29 +01:00
|
|
|
bool CNpcPath::incPath()
|
|
|
|
{
|
|
|
|
if ( !reversePath )
|
|
|
|
{
|
2001-05-30 00:07:28 +02:00
|
|
|
if ( currentWaypoint < waypointCount )
|
2001-01-16 22:56:29 +01:00
|
|
|
{
|
2001-02-05 15:55:11 +01:00
|
|
|
lastWaypoint = currentWaypoint;
|
2001-05-30 00:07:28 +02:00
|
|
|
currentWaypoint++;
|
2001-01-16 22:56:29 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch( pathType )
|
|
|
|
{
|
|
|
|
case SINGLE_USE_PATH:
|
|
|
|
// path is completed
|
|
|
|
|
|
|
|
return( true );
|
|
|
|
|
|
|
|
case REPEATING_PATH:
|
|
|
|
// go back to start
|
|
|
|
|
2001-02-05 15:55:11 +01:00
|
|
|
lastWaypoint = currentWaypoint;
|
2001-05-30 00:07:28 +02:00
|
|
|
currentWaypoint = 0;
|
2001-01-16 22:56:29 +01:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PONG_PATH:
|
|
|
|
// reverse path
|
|
|
|
|
|
|
|
reversePath = !reversePath;
|
2001-01-26 16:16:07 +01:00
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
if ( currentWaypoint > 0 )
|
2001-01-26 16:16:07 +01:00
|
|
|
{
|
2001-02-05 15:55:11 +01:00
|
|
|
lastWaypoint = currentWaypoint;
|
2001-05-30 00:07:28 +02:00
|
|
|
currentWaypoint--;
|
2001-01-26 16:16:07 +01:00
|
|
|
}
|
2001-01-16 22:56:29 +01:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// must be pong path if reversed
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
if ( currentWaypoint > 0 )
|
2001-01-16 22:56:29 +01:00
|
|
|
{
|
2001-02-05 15:55:11 +01:00
|
|
|
lastWaypoint = currentWaypoint;
|
2001-05-30 00:07:28 +02:00
|
|
|
currentWaypoint--;
|
2001-01-16 22:56:29 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
reversePath = !reversePath;
|
2001-01-26 16:16:07 +01:00
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
if ( currentWaypoint < waypointCount )
|
2001-01-26 16:16:07 +01:00
|
|
|
{
|
2001-02-05 15:55:11 +01:00
|
|
|
lastWaypoint = currentWaypoint;
|
2001-05-30 00:07:28 +02:00
|
|
|
currentWaypoint++;
|
2001-01-26 16:16:07 +01:00
|
|
|
}
|
2001-01-16 22:56:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return( false );
|
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-02-05 15:55:11 +01:00
|
|
|
void CNpcPath::reversePathDir()
|
|
|
|
{
|
|
|
|
if ( lastWaypoint )
|
|
|
|
{
|
2001-05-30 00:07:28 +02:00
|
|
|
u8 tempWaypoint;
|
2001-02-05 15:55:11 +01:00
|
|
|
|
|
|
|
tempWaypoint = currentWaypoint;
|
|
|
|
currentWaypoint = lastWaypoint;
|
|
|
|
lastWaypoint = tempWaypoint;
|
|
|
|
|
|
|
|
if ( pathType == PONG_PATH )
|
|
|
|
{
|
|
|
|
reversePath = !reversePath;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-01-19 22:46:30 +01:00
|
|
|
bool CNpcPath::getDistToNextWaypoint( DVECTOR currentPos, s32 *distX, s32 *distY )
|
|
|
|
{
|
2001-05-30 00:07:28 +02:00
|
|
|
return( isPointNear( currentPos, distX, distY ) );
|
2001-01-19 22:46:30 +01:00
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-04-28 19:39:24 +02:00
|
|
|
s32 CNpcPath::think( DVECTOR currentPos, bool *pathComplete, bool *waypointChange, s32 *distX, s32 *distY )
|
2001-01-16 22:56:29 +01:00
|
|
|
{
|
2001-05-30 00:07:28 +02:00
|
|
|
if ( !waypointPtr )
|
2001-01-26 16:16:07 +01:00
|
|
|
{
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2001-01-18 20:18:39 +01:00
|
|
|
*pathComplete = false;
|
2001-01-23 18:03:27 +01:00
|
|
|
*waypointChange = false;
|
2001-01-16 22:56:29 +01:00
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
if ( isPointNear( currentPos, distX, distY ) )
|
2001-01-16 22:56:29 +01:00
|
|
|
{
|
2001-01-18 20:18:39 +01:00
|
|
|
*pathComplete = incPath();
|
2001-01-23 18:03:27 +01:00
|
|
|
*waypointChange = true;
|
2001-04-03 20:32:24 +02:00
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
u16 *waypoint = waypointPtr;
|
|
|
|
waypoint += 2 * currentWaypoint;
|
|
|
|
|
2001-05-31 18:24:48 +02:00
|
|
|
*distX = ( ( *waypoint << 4 ) + 8 ) - currentPos.vx;
|
2001-05-30 00:07:28 +02:00
|
|
|
waypoint++;
|
2001-05-31 18:24:48 +02:00
|
|
|
*distY = ( ( *waypoint << 4 ) + 16 ) - currentPos.vy;
|
2001-01-16 22:56:29 +01:00
|
|
|
}
|
2001-01-18 20:18:39 +01:00
|
|
|
|
2001-04-28 19:39:24 +02:00
|
|
|
s32 headingToTarget = ratan2( *distY, *distX );
|
2001-01-18 20:18:39 +01:00
|
|
|
|
|
|
|
return( headingToTarget );
|
2001-02-22 16:39:38 +01:00
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-05-14 17:08:47 +02:00
|
|
|
bool CNpcPath::thinkFlat( DVECTOR currentPos, bool *pathComplete, s32 *distX, s32 *distY, s32 *heading, u8 waypointDist )
|
2001-02-22 16:39:38 +01:00
|
|
|
{
|
|
|
|
bool pointChange = false;
|
|
|
|
|
2001-04-18 18:34:17 +02:00
|
|
|
*pathComplete = false;
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
if ( !waypointPtr )
|
2001-02-22 16:39:38 +01:00
|
|
|
{
|
|
|
|
return( true );
|
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
u16 *waypoint = waypointPtr;
|
|
|
|
waypoint += 2 * currentWaypoint;
|
2001-02-22 16:39:38 +01:00
|
|
|
|
2001-05-31 18:24:48 +02:00
|
|
|
*distX = ( ( *waypoint << 4 ) + 8 ) - currentPos.vx;
|
2001-05-30 00:07:28 +02:00
|
|
|
waypoint++;
|
2001-05-31 18:24:48 +02:00
|
|
|
*distY = ( ( *waypoint << 4 ) + 16 ) - currentPos.vy;
|
2001-02-22 16:39:38 +01:00
|
|
|
|
2001-05-14 17:08:47 +02:00
|
|
|
if ( abs( *distX ) < waypointDist )
|
2001-02-22 16:39:38 +01:00
|
|
|
{
|
|
|
|
pointChange = true;
|
2001-04-18 18:34:17 +02:00
|
|
|
*pathComplete = incPath();
|
2001-02-22 16:39:38 +01:00
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
waypoint = waypointPtr;
|
|
|
|
waypoint += 2 * currentWaypoint;
|
|
|
|
|
2001-05-31 18:24:48 +02:00
|
|
|
*distX = ( ( *waypoint << 4 ) + 8 ) - currentPos.vx;
|
2001-05-30 00:07:28 +02:00
|
|
|
waypoint++;
|
2001-05-31 18:24:48 +02:00
|
|
|
*distY = ( ( *waypoint << 4 ) + 16 ) - currentPos.vy;
|
2001-04-03 20:32:24 +02:00
|
|
|
|
2001-02-22 17:56:27 +01:00
|
|
|
if ( *distX > 0 )
|
|
|
|
{
|
|
|
|
*heading = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*heading = 2048;
|
|
|
|
}
|
|
|
|
|
2001-04-07 17:39:22 +02:00
|
|
|
return( pointChange );
|
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-04-07 17:39:22 +02:00
|
|
|
bool CNpcPath::thinkVertical( DVECTOR currentPos, bool *pathComplete, s32 *distX, s32 *distY, s32 *heading )
|
|
|
|
{
|
|
|
|
bool pointChange = false;
|
|
|
|
|
2001-04-18 18:34:17 +02:00
|
|
|
*pathComplete = false;
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
if ( !waypointPtr )
|
2001-04-07 17:39:22 +02:00
|
|
|
{
|
|
|
|
return( true );
|
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
u16 *waypoint = waypointPtr;
|
|
|
|
waypoint += 2 * currentWaypoint;
|
2001-04-07 17:39:22 +02:00
|
|
|
|
2001-05-31 18:24:48 +02:00
|
|
|
*distX = ( ( *waypoint << 4 ) + 8 ) - currentPos.vx;
|
2001-05-30 00:07:28 +02:00
|
|
|
waypoint++;
|
2001-05-31 18:24:48 +02:00
|
|
|
*distY = ( ( *waypoint << 4 ) + 16 ) - currentPos.vy;
|
2001-04-07 17:39:22 +02:00
|
|
|
|
|
|
|
if ( abs( *distY ) < 10 )
|
|
|
|
{
|
|
|
|
pointChange = true;
|
|
|
|
*pathComplete = incPath();
|
|
|
|
}
|
|
|
|
|
2001-05-30 00:07:28 +02:00
|
|
|
waypoint = waypointPtr;
|
|
|
|
waypoint += 2 * currentWaypoint;
|
|
|
|
|
2001-05-31 18:24:48 +02:00
|
|
|
*distX = ( ( *waypoint << 4 ) + 8 ) - currentPos.vx;
|
2001-05-30 00:07:28 +02:00
|
|
|
waypoint++;
|
2001-05-31 18:24:48 +02:00
|
|
|
*distY = ( ( *waypoint << 4 ) + 16 ) - currentPos.vy;
|
2001-04-07 17:39:22 +02:00
|
|
|
|
|
|
|
if ( *distY > 0 )
|
|
|
|
{
|
|
|
|
*heading = 1024;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*heading = 3072;
|
|
|
|
}
|
|
|
|
|
2001-02-22 16:39:38 +01:00
|
|
|
return( pointChange );
|
2001-04-19 01:12:24 +02:00
|
|
|
}
|