This commit is contained in:
Charles 2001-01-26 15:16:07 +00:00
parent c309d5b9bd
commit dcb2f87af0
4 changed files with 140 additions and 83 deletions

View file

@ -435,7 +435,7 @@ CNpc::NPC_DATA CNpc::m_data[NPC_UNIT_TYPE_MAX] =
void CNpc::init()
{
m_type = NPC_IRON_DOGFISH;
m_type = NPC_SKULL_STOMPER;
m_heading = m_fireHeading = 0;
m_movementTimer = 0;
@ -471,7 +471,7 @@ void CNpc::init()
m_npcPath.addWaypoint( newPos );
/*newPos.vx = 500;
newPos.vx = 500;
newPos.vy = 100;
m_npcPath.addWaypoint( newPos );
@ -479,9 +479,9 @@ void CNpc::init()
newPos.vx = 100;
newPos.vy = 100;
m_npcPath.addWaypoint( newPos );*/
m_npcPath.addWaypoint( newPos );
m_npcPath.setPathType( REPEATING_PATH );
m_npcPath.setPathType( PONG_PATH );
break;
}
@ -554,6 +554,7 @@ void CNpc::init()
void CNpc::shutdown()
{
m_npcPath.removeAllWaypoints();
}
@ -832,7 +833,7 @@ bool CNpc::processSensor()
if ( xDistSqr + yDistSqr < 40000 )
{
m_controlFunc = NPC_CONTROL_CLOSE;
m_npcPath.currentWaypoint = 0;
m_extendDir = EXTEND_DOWN;
return( true );
}

View file

@ -37,27 +37,72 @@ bool CNpcWaypoint::isPointNear( DVECTOR testPos, s32 *xDist, s32 *yDist )
void CNpcPath::initPath()
{
int loop;
for ( loop = 0 ; loop < NPC_MAX_WAYPOINTS ; loop++ )
{
waypoint[loop].pos.vx = 0;
waypoint[loop].pos.vy = 0;
}
waypoint = NULL;
pathType = SINGLE_USE_PATH;
currentWaypoint = lastWaypoint = 0;
currentWaypoint = NULL;
waypointCount = 0;
reversePath = false;
}
void CNpcPath::resetPath()
{
currentWaypoint = NULL;
}
void CNpcPath::addWaypoint( DVECTOR newPos )
{
if ( waypointCount < NPC_MAX_WAYPOINTS )
CNpcWaypoint *testWaypoint;
CNpcWaypoint *newWaypoint;
testWaypoint = this->waypoint;
if ( testWaypoint )
{
waypoint[waypointCount].pos = newPos;
// find end of path
while ( testWaypoint->nextWaypoint )
{
testWaypoint = testWaypoint->nextWaypoint;
}
newWaypoint = new( "waypoint" ) CNpcWaypoint;
newWaypoint->pos = newPos;
newWaypoint->nextWaypoint = NULL;
newWaypoint->prevWaypoint = testWaypoint;
testWaypoint->nextWaypoint = newWaypoint;
waypointCount++;
}
else
{
// no waypoints exist in this path, create
newWaypoint = new( "waypoint" ) CNpcWaypoint;
newWaypoint->pos = newPos;
newWaypoint->nextWaypoint = NULL;
newWaypoint->prevWaypoint = NULL;
this->waypoint = newWaypoint;
waypointCount++;
}
}
void CNpcPath::removeAllWaypoints()
{
CNpcWaypoint *testWaypoint;
CNpcWaypoint *lastWaypoint;
testWaypoint = this->waypoint;
while ( testWaypoint )
{
lastWaypoint = testWaypoint;
testWaypoint = testWaypoint->nextWaypoint;
delete lastWaypoint;
}
this->waypoint = NULL;
}
void CNpcPath::setPathType( NPC_PATH_TYPE newPathType )
@ -69,9 +114,9 @@ bool CNpcPath::incPath()
{
if ( !reversePath )
{
if ( currentWaypoint < waypointCount - 1 )
if ( currentWaypoint->nextWaypoint )
{
currentWaypoint++;
currentWaypoint = currentWaypoint->nextWaypoint;
}
else
{
@ -85,7 +130,7 @@ bool CNpcPath::incPath()
case REPEATING_PATH:
// go back to start
currentWaypoint = 0;
currentWaypoint = this->waypoint;
break;
@ -93,7 +138,11 @@ bool CNpcPath::incPath()
// reverse path
reversePath = !reversePath;
currentWaypoint--;
if ( currentWaypoint->prevWaypoint )
{
currentWaypoint = currentWaypoint->prevWaypoint;
}
break;
}
@ -103,14 +152,18 @@ bool CNpcPath::incPath()
{
// must be pong path if reversed
if ( currentWaypoint > 0 )
if ( currentWaypoint->prevWaypoint )
{
currentWaypoint--;
currentWaypoint = currentWaypoint->prevWaypoint;
}
else
{
reversePath = !reversePath;
currentWaypoint++;
if ( currentWaypoint->nextWaypoint )
{
currentWaypoint = currentWaypoint->nextWaypoint;
}
}
}
@ -119,17 +172,29 @@ bool CNpcPath::incPath()
bool CNpcPath::getDistToNextWaypoint( DVECTOR currentPos, s32 *distX, s32 *distY )
{
return( waypoint[currentWaypoint].isPointNear( currentPos, distX, distY ) );
return( currentWaypoint->isPointNear( currentPos, distX, distY ) );
}
s32 CNpcPath::think( DVECTOR currentPos, bool *pathComplete, bool *waypointChange )
{
if ( !this->waypoint )
{
return( 0 );
}
if ( !currentWaypoint )
{
// if no currentWaypoint set, start it off
currentWaypoint = this->waypoint;
}
s32 xDist, yDist;
*pathComplete = false;
*waypointChange = false;
if ( waypoint[currentWaypoint].isPointNear( currentPos, &xDist, &yDist ) )
if ( currentWaypoint->isPointNear( currentPos, &xDist, &yDist ) )
{
*pathComplete = incPath();
*waypointChange = true;

View file

@ -20,6 +20,8 @@ class CNpcWaypoint
{
public:
DVECTOR pos;
CNpcWaypoint *nextWaypoint;
CNpcWaypoint *prevWaypoint;
bool isPointNear( DVECTOR testPos, s32 *xDist, s32 *yDist );
};
@ -33,25 +35,21 @@ enum NPC_PATH_TYPE
class CNpcPath
{
enum
{
NPC_MAX_WAYPOINTS = 4,
};
private:
CNpcWaypoint waypoint[NPC_MAX_WAYPOINTS];
CNpcWaypoint *waypoint;
NPC_PATH_TYPE pathType;
u8 waypointCount;
u8 lastWaypoint;
bool reversePath;
public:
u8 currentWaypoint;
CNpcWaypoint *currentWaypoint;
void initPath();
void addWaypoint( DVECTOR newPos );
void removeAllWaypoints();
void setPathType( NPC_PATH_TYPE newPathType );
bool incPath();
void resetPath();
s32 think( DVECTOR currentPos, bool *pathComplete, bool *waypointChange );
bool getDistToNextWaypoint( DVECTOR currentPos, s32 *distX, s32 *distY );
};

View file

@ -38,49 +38,44 @@ void CNpc::processCloseSkullStomperAttack( int _frames )
s16 headingToTarget = m_npcPath.think( Pos, &pathComplete, &waypointChange );
s32 moveX, moveY;
if ( waypointChange && !pathComplete )
if ( waypointChange )
{
if ( !pathComplete )
{
// pause and change direction
m_timerTimer = GameState::getOneSecondInFrames();
m_extendDir = EXTEND_UP;
return;
}
else
{
}
if ( pathComplete )
{
m_controlFunc = NPC_CONTROL_MOVEMENT;
m_timerFunc = NPC_TIMER_ATTACK_DONE;
m_timerTimer = GameState::getOneSecondInFrames();
m_sensorFunc = NPC_SENSOR_NONE;
m_npcPath.resetPath();
}
else
{
if ( m_npcPath.currentWaypoint == 0 )
{
s32 preShiftX;
s32 preShiftY;
m_heading = headingToTarget;
s32 preShiftX = _frames * 8 * rcos( m_heading );
s32 preShiftY = _frames * 8 * rsin( m_heading );
moveX = preShiftX >> 12;
if ( !moveX && preShiftX )
if ( m_extendDir == EXTEND_DOWN )
{
moveX = preShiftX / abs( preShiftX );
}
moveY = preShiftY >> 12;
if ( !moveY && preShiftY )
{
moveY = preShiftY / abs( preShiftY );
}
Pos.vx += moveX;
Pos.vy += moveY;
preShiftX = _frames * 8 * rcos( m_heading );
preShiftY = _frames * 8 * rsin( m_heading );
}
else
{
m_heading = headingToTarget;
s32 preShiftX = _frames * 2 * rcos( m_heading );
s32 preShiftY = _frames * 2 * rsin( m_heading );
preShiftX = _frames * 2 * rcos( m_heading );
preShiftY = _frames * 2 * rsin( m_heading );
}
moveX = preShiftX >> 12;
if ( !moveX && preShiftX )
@ -99,5 +94,3 @@ void CNpc::processCloseSkullStomperAttack( int _frames )
}
}
}
}
}