SBSPSS/source/enemy/npcpath.cpp

407 lines
8.3 KiB
C++
Raw Normal View History

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
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2001-07-23 21:26:37 +02:00
bool CNpcPath::isPointNear( DVECTOR const &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-06-21 22:10:19 +02:00
void CNpcPath::getCurrentWaypointPos( DVECTOR *waypointPos )
{
u16 *waypoint = waypointPtr;
waypoint += 2 * currentWaypoint;
waypointPos->vx = ( *waypoint << 4 ) + 8;
waypoint++;
waypointPos->vy = ( *waypoint << 4 ) + 16;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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-08-07 21:45:40 +02:00
decLockout = false;
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-08-07 21:45:40 +02:00
decLockout = false;
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()
{
2001-08-07 21:45:40 +02:00
decLockout = false;
2001-01-16 22:56:29 +01:00
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-07-20 17:52:22 +02:00
2001-08-07 21:45:40 +02:00
bool CNpcPath::decPath()
2001-07-20 17:52:22 +02:00
{
2001-08-07 21:45:40 +02:00
if ( !decLockout )
2001-07-20 17:52:22 +02:00
{
2001-08-07 21:45:40 +02:00
if ( currentWaypoint > 0 )
{
lastWaypoint = currentWaypoint;
currentWaypoint--;
}
else
{
lastWaypoint = currentWaypoint;
currentWaypoint = waypointCount;
}
decLockout = true;
return( true );
2001-07-20 17:52:22 +02:00
}
2001-08-07 21:45:40 +02:00
return( false );
2001-07-20 17:52:22 +02:00
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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-07-23 21:26:37 +02:00
bool CNpcPath::getDistToNextWaypoint( DVECTOR const &currentPos, s32 *distX, s32 *distY )
2001-01-19 22:46:30 +01:00
{
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-07-23 21:26:37 +02:00
s32 CNpcPath::think( DVECTOR const &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-07-27 15:31:52 +02:00
s32 headingToTarget = ratan2( *distY, *distX ) & 4095;
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-07-23 21:26:37 +02:00
bool CNpcPath::thinkFlat( DVECTOR const &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-07-23 21:26:37 +02:00
bool CNpcPath::thinkVertical( DVECTOR const &currentPos, bool *pathComplete, s32 *distX, s32 *distY, s32 *heading )
2001-04-07 17:39:22 +02: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-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
}