diff --git a/source/enemy/nhcrab.cpp b/source/enemy/nhcrab.cpp index 4f8474239..b95eaa2ea 100644 --- a/source/enemy/nhcrab.cpp +++ b/source/enemy/nhcrab.cpp @@ -58,7 +58,7 @@ void CNpcEnemy::processCloseHermitCrabAttack( int _frames ) case HERMIT_CRAB_ROLL_ATTACK: { - if ( !m_animPlaying ) + if ( !m_animPlaying || m_animNo == m_data[m_type].moveAnim ) { switch( m_animNo ) { @@ -68,6 +68,15 @@ void CNpcEnemy::processCloseHermitCrabAttack( int _frames ) m_animNo = ANIM_HERMITCRAB_ROLLATTACK; m_frame = 0; + if ( playerXDist > 0 ) + { + m_extendDir = EXTEND_RIGHT; + } + else + { + m_extendDir = EXTEND_LEFT; + } + break; } @@ -97,15 +106,6 @@ void CNpcEnemy::processCloseHermitCrabAttack( int _frames ) m_animNo = ANIM_HERMITCRAB_ROLLATTACKSTART; m_frame = 0; - if ( playerXDist > 0 ) - { - m_extendDir = EXTEND_RIGHT; - } - else - { - m_extendDir = EXTEND_LEFT; - } - break; } } @@ -130,17 +130,34 @@ void CNpcEnemy::processCloseHermitCrabAttack( int _frames ) m_heading = 2048; } - groundHeight = m_layerCollision->getHeightFromGround( Pos.vx, Pos.vy, yMovement + 16 ); + s32 minX, maxX, newX; - if ( groundHeight <= yMovement ) + m_npcPath.getPathXExtents( &minX, &maxX ); + + newX = Pos.vx + moveX; + + if ( newX < minX || newX > maxX ) { - // groundHeight <= yMovement indicates either just above ground or on or below ground + // moving outside path constraints, abort - moveY = groundHeight; + m_animPlaying = true; + m_animNo = ANIM_HERMITCRAB_ROLLATTACKEND; + m_frame = 0; } + else + { + groundHeight = m_layerCollision->getHeightFromGround( newX, Pos.vy, yMovement + 16 ); - Pos.vx += moveX; - Pos.vy += moveY; + if ( groundHeight <= yMovement ) + { + // groundHeight <= yMovement indicates either just above ground or on or below ground + + moveY = groundHeight; + } + + Pos.vx = newX; + Pos.vy += moveY; + } } } diff --git a/source/enemy/npcpath.cpp b/source/enemy/npcpath.cpp index 560694369..2d7c9c3e4 100644 --- a/source/enemy/npcpath.cpp +++ b/source/enemy/npcpath.cpp @@ -43,6 +43,7 @@ void CNpcPath::initPath() lastWaypoint = NULL; waypointCount = 0; reversePath = false; + minX = maxX = 0; } void CNpcPath::resetPath() @@ -74,6 +75,15 @@ void CNpcPath::addWaypoint( DVECTOR newPos ) testWaypoint->nextWaypoint = newWaypoint; waypointCount++; + + if ( newPos.vx < minX ) + { + minX = newPos.vx; + } + else if ( newPos.vx > maxX ) + { + maxX = newPos.vx; + } } else { @@ -88,9 +98,17 @@ void CNpcPath::addWaypoint( DVECTOR newPos ) waypointCount++; currentWaypoint = this->waypoint; + + minX = maxX = newPos.vx; } } +void CNpcPath::getPathXExtents( s32 *minExtent, s32 *maxExtent ) +{ + *minExtent = minX; + *maxExtent = maxX; +} + void CNpcPath::removeAllWaypoints() { CNpcWaypoint *testWaypoint; diff --git a/source/enemy/npcpath.h b/source/enemy/npcpath.h index 972e8f483..0df295f82 100644 --- a/source/enemy/npcpath.h +++ b/source/enemy/npcpath.h @@ -46,6 +46,7 @@ public: s32 think( DVECTOR currentPos, bool *pathComplete, bool *waypointChange ); bool thinkFlat( DVECTOR currentPos, s32 *distX, s32 *distY, s32 *heading ); bool getDistToNextWaypoint( DVECTOR currentPos, s32 *distX, s32 *distY ); + void getPathXExtents( s32 *minExtent, s32 *maxExtent ); private: CNpcWaypoint *waypoint; @@ -54,6 +55,7 @@ private: bool reversePath; CNpcWaypoint *currentWaypoint; CNpcWaypoint *lastWaypoint; + s32 minX, maxX; }; #endif \ No newline at end of file