This commit is contained in:
parent
3f2ebeb556
commit
af42f43345
@ -192,7 +192,7 @@ bool CNpcEnemy::processGroundCollisionReverse( s32 *moveX, s32 *moveY )
|
|||||||
return( xBlocked | yBlocked );
|
return( xBlocked | yBlocked );
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNpcEnemy::processGenericFixedPathMove( int _frames, s32 *moveX, s32 *moveY, s32 *moveVel, s32 *moveDist )
|
u8 CNpcEnemy::processGenericFixedPathMove( int _frames, s32 *moveX, s32 *moveY, s32 *moveVel, s32 *moveDist )
|
||||||
{
|
{
|
||||||
bool pathComplete;
|
bool pathComplete;
|
||||||
bool waypointChange;
|
bool waypointChange;
|
||||||
@ -302,6 +302,8 @@ void CNpcEnemy::processGenericFixedPathMove( int _frames, s32 *moveX, s32 *moveY
|
|||||||
|
|
||||||
//processGroundCollisionReverse( moveX, moveY );
|
//processGroundCollisionReverse( moveX, moveY );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return( waypointChange );
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNpcEnemy::processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY )
|
void CNpcEnemy::processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY )
|
||||||
|
@ -260,7 +260,7 @@ protected:
|
|||||||
|
|
||||||
void processGenericGotoTarget( int _frames, s32 xDist, s32 yDist, s32 speed );
|
void processGenericGotoTarget( int _frames, s32 xDist, s32 yDist, s32 speed );
|
||||||
void processGenericGetUserDist( int _frames, s32 *distX, s32 *distY );
|
void processGenericGetUserDist( int _frames, s32 *distX, s32 *distY );
|
||||||
void processGenericFixedPathMove( int _frames, s32 *moveX, s32 *moveY, s32 *moveVel, s32 *moveDist );
|
u8 processGenericFixedPathMove( int _frames, s32 *moveX, s32 *moveY, s32 *moveVel, s32 *moveDist );
|
||||||
void processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY );
|
void processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY );
|
||||||
bool processGroundCollisionReverse( s32 *moveX, s32 *moveY );
|
bool processGroundCollisionReverse( s32 *moveX, s32 *moveY );
|
||||||
virtual void processEnemyCollision( CThing *thisThing );
|
virtual void processEnemyCollision( CThing *thisThing );
|
||||||
|
@ -435,7 +435,7 @@ CNpcEnemy::NPC_DATA CNpcEnemy::m_data[NPC_UNIT_TYPE_MAX] =
|
|||||||
NPC_TIMER_NONE,
|
NPC_TIMER_NONE,
|
||||||
false,
|
false,
|
||||||
3,
|
3,
|
||||||
256,
|
64,
|
||||||
DETECT_ALL_COLLISION,
|
DETECT_ALL_COLLISION,
|
||||||
DAMAGE__SHOCK_ENEMY,
|
DAMAGE__SHOCK_ENEMY,
|
||||||
1,
|
1,
|
||||||
|
@ -45,6 +45,20 @@ bool CNpcPath::isPointNear( DVECTOR testPos, s32 *xDist, s32 *yDist )
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void CNpcPath::getCurrentWaypointPos( DVECTOR *waypointPos )
|
||||||
|
{
|
||||||
|
u16 *waypoint = waypointPtr;
|
||||||
|
waypoint += 2 * currentWaypoint;
|
||||||
|
|
||||||
|
waypointPos->vx = ( *waypoint << 4 ) + 8;
|
||||||
|
|
||||||
|
waypoint++;
|
||||||
|
|
||||||
|
waypointPos->vy = ( *waypoint << 4 ) + 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void CNpcPath::initPath()
|
void CNpcPath::initPath()
|
||||||
{
|
{
|
||||||
//waypoint = NULL;
|
//waypoint = NULL;
|
||||||
|
@ -45,6 +45,7 @@ public:
|
|||||||
void setPathExtents();
|
void setPathExtents();
|
||||||
u16 *getWaypointPtr() { return( waypointPtr ); }
|
u16 *getWaypointPtr() { return( waypointPtr ); }
|
||||||
bool isPointNear( DVECTOR testPos, s32 *xDist, s32 *yDist );
|
bool isPointNear( DVECTOR testPos, s32 *xDist, s32 *yDist );
|
||||||
|
void getCurrentWaypointPos( DVECTOR *waypointPos );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NPC_PATH_TYPE pathType;
|
NPC_PATH_TYPE pathType;
|
||||||
|
@ -166,6 +166,7 @@ void CNpcSeaSnakeEnemy::postInit()
|
|||||||
m_movementTimer = 2 * GameState::getOneSecondInFrames();
|
m_movementTimer = 2 * GameState::getOneSecondInFrames();
|
||||||
m_collTimer = 0;
|
m_collTimer = 0;
|
||||||
m_meterOn=false;
|
m_meterOn=false;
|
||||||
|
m_turnDir = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -249,7 +250,161 @@ void CNpcSeaSnakeEnemy::processMovement( int _frames )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processGenericFixedPathMove( _frames, &moveX, &moveY, &moveVel, &moveDist );
|
switch( m_turnDir )
|
||||||
|
{
|
||||||
|
case NPC_SEA_SNAKE_CIRCLE_CLOCKWISE:
|
||||||
|
{
|
||||||
|
m_circleHeading += m_data[m_type].turnSpeed;
|
||||||
|
|
||||||
|
if ( m_circleHeading > 4096 )
|
||||||
|
{
|
||||||
|
m_circleHeading = 0;
|
||||||
|
m_turnDir = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_heading = ( m_origHeading + m_circleHeading ) & 4095;
|
||||||
|
|
||||||
|
s32 preShiftX = _frames * m_speed * rcos( m_heading );
|
||||||
|
s32 preShiftY = _frames * m_speed * rsin( m_heading );
|
||||||
|
|
||||||
|
s32 moveX = preShiftX >> 12;
|
||||||
|
if ( !moveX && preShiftX )
|
||||||
|
{
|
||||||
|
moveX = preShiftX / abs( preShiftX );
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 moveY = preShiftY >> 12;
|
||||||
|
if ( !moveY && preShiftY )
|
||||||
|
{
|
||||||
|
moveY = preShiftY / abs( preShiftY );
|
||||||
|
}
|
||||||
|
|
||||||
|
Pos.vx += moveX;
|
||||||
|
Pos.vy += moveY;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NPC_SEA_SNAKE_CIRCLE_ANTICLOCKWISE:
|
||||||
|
{
|
||||||
|
m_circleHeading -= m_data[m_type].turnSpeed;
|
||||||
|
|
||||||
|
if ( m_circleHeading < -4096 )
|
||||||
|
{
|
||||||
|
m_circleHeading = 0;
|
||||||
|
m_turnDir = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_heading = ( m_origHeading + m_circleHeading ) & 4095;
|
||||||
|
|
||||||
|
s32 preShiftX = _frames * m_speed * rcos( m_heading );
|
||||||
|
s32 preShiftY = _frames * m_speed * rsin( m_heading );
|
||||||
|
|
||||||
|
s32 moveX = preShiftX >> 12;
|
||||||
|
if ( !moveX && preShiftX )
|
||||||
|
{
|
||||||
|
moveX = preShiftX / abs( preShiftX );
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 moveY = preShiftY >> 12;
|
||||||
|
if ( !moveY && preShiftY )
|
||||||
|
{
|
||||||
|
moveY = preShiftY / abs( preShiftY );
|
||||||
|
}
|
||||||
|
|
||||||
|
Pos.vx += moveX;
|
||||||
|
Pos.vy += moveY;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
DVECTOR waypointPos;
|
||||||
|
m_npcPath.getCurrentWaypointPos( &waypointPos );
|
||||||
|
waypointPos.vy -= 8;
|
||||||
|
|
||||||
|
if ( CGameScene::getCollision()->getHeightFromGround( waypointPos.vx, waypointPos.vy ) < 0 )
|
||||||
|
{
|
||||||
|
// waypoint is either start or end waypoint
|
||||||
|
|
||||||
|
s32 distX, distY;
|
||||||
|
|
||||||
|
distX = waypointPos.vx - Pos.vx;
|
||||||
|
distY = waypointPos.vy - Pos.vy;
|
||||||
|
|
||||||
|
if( !distX && !distY )
|
||||||
|
{
|
||||||
|
if ( isSnakeStopped() )
|
||||||
|
{
|
||||||
|
m_npcPath.incPath();
|
||||||
|
|
||||||
|
m_npcPath.getCurrentWaypointPos( &waypointPos );
|
||||||
|
waypointPos.vy -= 8;
|
||||||
|
|
||||||
|
if ( CGameScene::getCollision()->getHeightFromGround( waypointPos.vx, waypointPos.vy ) < 0 )
|
||||||
|
{
|
||||||
|
// if next waypoint is ALSO a start/end waypoint, teleport directly to it
|
||||||
|
|
||||||
|
moveEntireSnake( waypointPos );
|
||||||
|
oldPos.vx = waypointPos.vx;
|
||||||
|
oldPos.vy = waypointPos.vy;
|
||||||
|
|
||||||
|
// increment path
|
||||||
|
m_npcPath.incPath();
|
||||||
|
|
||||||
|
// point snake in correct direction
|
||||||
|
m_npcPath.getCurrentWaypointPos( &waypointPos );
|
||||||
|
|
||||||
|
m_heading = ratan2( waypointPos.vy - Pos.vy, waypointPos.vx - Pos.vx ) & 4095;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
processGenericGotoTarget( _frames, distX, distY, m_speed );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( processGenericFixedPathMove( _frames, &moveX, &moveY, &moveVel, &moveDist ) )
|
||||||
|
{
|
||||||
|
// path has changed
|
||||||
|
|
||||||
|
DVECTOR newWaypointPos;
|
||||||
|
|
||||||
|
m_npcPath.getCurrentWaypointPos( &newWaypointPos );
|
||||||
|
newWaypointPos.vy -= 8;
|
||||||
|
|
||||||
|
if ( newWaypointPos.vy == waypointPos.vy )
|
||||||
|
{
|
||||||
|
int testDir = newWaypointPos.vx - waypointPos.vx;
|
||||||
|
|
||||||
|
if ( testDir > 0 && testDir <= 16 )
|
||||||
|
{
|
||||||
|
// clockwise
|
||||||
|
|
||||||
|
m_turnDir = NPC_SEA_SNAKE_CIRCLE_CLOCKWISE;
|
||||||
|
m_circleHeading = 0;
|
||||||
|
m_origHeading = m_heading;
|
||||||
|
m_npcPath.incPath();
|
||||||
|
}
|
||||||
|
else if ( testDir < 0 && testDir >= -16 )
|
||||||
|
{
|
||||||
|
// anticlockwise
|
||||||
|
|
||||||
|
m_turnDir = NPC_SEA_SNAKE_CIRCLE_ANTICLOCKWISE;
|
||||||
|
m_circleHeading = 0;
|
||||||
|
m_origHeading = m_heading;
|
||||||
|
m_npcPath.incPath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Pos.vx += moveX;
|
Pos.vx += moveX;
|
||||||
Pos.vy += moveY;
|
Pos.vy += moveY;
|
||||||
@ -751,3 +906,46 @@ s32 CNpcSeaSnakeEnemy::getFrameShift( int _frames )
|
|||||||
{
|
{
|
||||||
return( ( _frames << 8 ) >> 3 );
|
return( ( _frames << 8 ) >> 3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
u8 CNpcSeaSnakeEnemy::isSnakeStopped()
|
||||||
|
{
|
||||||
|
if ( !m_segmentCount )
|
||||||
|
{
|
||||||
|
return( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
DVECTOR tailPos = m_segmentArray[m_segmentCount - 1].getPos();
|
||||||
|
|
||||||
|
if ( tailPos.vx == Pos.vx && tailPos.vy == Pos.vy )
|
||||||
|
{
|
||||||
|
return( true );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return( false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void CNpcSeaSnakeEnemy::moveEntireSnake( DVECTOR newPos )
|
||||||
|
{
|
||||||
|
Pos.vx = newPos.vx;
|
||||||
|
Pos.vy = newPos.vy;
|
||||||
|
|
||||||
|
int segmentCount;
|
||||||
|
|
||||||
|
for ( segmentCount = 0 ; segmentCount < m_segmentCount ; segmentCount++ )
|
||||||
|
{
|
||||||
|
m_segmentArray[segmentCount].setPos( Pos );
|
||||||
|
}
|
||||||
|
|
||||||
|
s16 maxArraySize = NPC_SEA_SNAKE_LENGTH * NPC_SEA_SNAKE_SPACING;
|
||||||
|
|
||||||
|
for ( int histLength = 0 ; histLength < maxArraySize ; histLength++ )
|
||||||
|
{
|
||||||
|
m_positionHistoryArray[histLength].pos = Pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -64,11 +64,15 @@ protected:
|
|||||||
virtual void processShot( int _frames );
|
virtual void processShot( int _frames );
|
||||||
virtual void processEnemyCollision( CThing *thisThing );
|
virtual void processEnemyCollision( CThing *thisThing );
|
||||||
virtual void processUserCollision( CThing *thisThing );
|
virtual void processUserCollision( CThing *thisThing );
|
||||||
|
u8 isSnakeStopped();
|
||||||
|
void moveEntireSnake( DVECTOR newPos );
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
NPC_SEA_SNAKE_SPACING = 6,
|
NPC_SEA_SNAKE_SPACING = 6,
|
||||||
NPC_SEA_SNAKE_LENGTH = 10,
|
NPC_SEA_SNAKE_LENGTH = 10,
|
||||||
|
NPC_SEA_SNAKE_CIRCLE_CLOCKWISE = 1,
|
||||||
|
NPC_SEA_SNAKE_CIRCLE_ANTICLOCKWISE = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
// position history stuff
|
// position history stuff
|
||||||
@ -90,6 +94,9 @@ protected:
|
|||||||
s32 m_snapTimer;
|
s32 m_snapTimer;
|
||||||
//s32 m_openTimer;
|
//s32 m_openTimer;
|
||||||
bool m_meterOn;
|
bool m_meterOn;
|
||||||
|
u8 m_turnDir;
|
||||||
|
s16 m_circleHeading;
|
||||||
|
s16 m_origHeading;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue
Block a user