diff --git a/source/enemy/ngeneric.cpp b/source/enemy/ngeneric.cpp index 77e28a839..849cf9579 100644 --- a/source/enemy/ngeneric.cpp +++ b/source/enemy/ngeneric.cpp @@ -99,11 +99,11 @@ void CNpc::processGenericGetUserDist( int _frames, s32 *distX, s32 *distY ) *distY = playerPos.vy - this->Pos.vy; } -void CNpc::processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY ) +void CNpc::processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY, s32 *heading ) { s32 maxHeight = 10; s32 distX, distY; - s32 fallSpeed = 5; + s32 fallSpeed = 2; s8 yMovement = fallSpeed * _frames; s32 groundHeight; @@ -112,7 +112,7 @@ void CNpc::processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY ) // ignore y component of waypoint, since we are stuck to the ground - if ( m_npcPath.think2D( Pos, &distX, &distY ) ) + if ( m_npcPath.think2D( Pos, &distX, &distY, heading ) ) { // path has finished, waypoint has changed, or there are no waypoints - do not move horizontally diff --git a/source/enemy/npc.cpp b/source/enemy/npc.cpp index ce8110008..4c6e57eb4 100644 --- a/source/enemy/npc.cpp +++ b/source/enemy/npc.cpp @@ -54,7 +54,7 @@ class CLayerCollision *CNpc::m_layerCollision; void CNpc::init() { - m_type = NPC_FISH_FOLK; + m_type = NPC_SHARK_MAN; m_heading = m_fireHeading = 0; m_movementTimer = 0; @@ -723,7 +723,7 @@ void CNpc::processMovement(int _frames) case NPC_MOVEMENT_FIXED_PATH_WALK: { - processGenericFixedPathWalk( _frames, &moveX, &moveY ); + processGenericFixedPathWalk( _frames, &moveX, &moveY, &m_heading ); break; } diff --git a/source/enemy/npc.h b/source/enemy/npc.h index 2d6cc0474..8e5693f8c 100644 --- a/source/enemy/npc.h +++ b/source/enemy/npc.h @@ -271,7 +271,7 @@ protected: void processGenericGotoTarget( int _frames, s32 xDist, s32 yDist, s32 speed ); void processGenericGetUserDist( int _frames, s32 *distX, s32 *distY ); - void processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY ); + void processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY, s32 *heading ); // small jellyfish functions diff --git a/source/enemy/npcdata.cpp b/source/enemy/npcdata.cpp index 9af3376e7..55186bd15 100644 --- a/source/enemy/npcdata.cpp +++ b/source/enemy/npcdata.cpp @@ -276,7 +276,7 @@ CNpc::NPC_DATA CNpc::m_data[NPC_UNIT_TYPE_MAX] = { // NPC_PRICKLY_BUG NPC_INIT_DEFAULT, NPC_SENSOR_NONE, - NPC_MOVEMENT_FIXED_PATH, + NPC_MOVEMENT_FIXED_PATH_WALK, NPC_MOVEMENT_MODIFIER_NONE, NPC_CLOSE_NONE, NPC_TIMER_NONE, @@ -346,7 +346,7 @@ CNpc::NPC_DATA CNpc::m_data[NPC_UNIT_TYPE_MAX] = { // NPC_HERMIT_CRAB NPC_INIT_DEFAULT, NPC_SENSOR_NONE, - NPC_MOVEMENT_FIXED_PATH, + NPC_MOVEMENT_FIXED_PATH_WALK, NPC_MOVEMENT_MODIFIER_NONE, NPC_CLOSE_NONE, NPC_TIMER_NONE, @@ -388,7 +388,7 @@ CNpc::NPC_DATA CNpc::m_data[NPC_UNIT_TYPE_MAX] = { // NPC_SPIDER_CRAB NPC_INIT_DEFAULT, NPC_SENSOR_SPIDER_CRAB_USER_CLOSE, - NPC_MOVEMENT_FIXED_PATH, + NPC_MOVEMENT_FIXED_PATH_WALK, NPC_MOVEMENT_MODIFIER_NONE, NPC_CLOSE_SPIDER_CRAB_ATTACK, NPC_TIMER_NONE, @@ -430,7 +430,7 @@ CNpc::NPC_DATA CNpc::m_data[NPC_UNIT_TYPE_MAX] = { // NPC_ZOMBIE_FISH_FOLK NPC_INIT_FISH_FOLK, NPC_SENSOR_NONE, - NPC_MOVEMENT_FIXED_PATH, + NPC_MOVEMENT_FIXED_PATH_WALK, NPC_MOVEMENT_MODIFIER_FISH_FOLK, NPC_CLOSE_NONE, NPC_TIMER_NONE, @@ -500,7 +500,7 @@ CNpc::NPC_DATA CNpc::m_data[NPC_UNIT_TYPE_MAX] = { // NPC_SHARK_MAN NPC_INIT_DEFAULT, NPC_SENSOR_GENERIC_USER_VISIBLE, - NPC_MOVEMENT_FIXED_PATH, + NPC_MOVEMENT_FIXED_PATH_WALK, NPC_MOVEMENT_MODIFIER_NONE, NPC_CLOSE_SHARK_MAN_ATTACK, NPC_TIMER_NONE, diff --git a/source/enemy/npcpath.cpp b/source/enemy/npcpath.cpp index cf4aeb751..777ba0847 100644 --- a/source/enemy/npcpath.cpp +++ b/source/enemy/npcpath.cpp @@ -231,7 +231,7 @@ s32 CNpcPath::think( DVECTOR currentPos, bool *pathComplete, bool *waypointChang return( headingToTarget ); } -bool CNpcPath::think2D( DVECTOR currentPos, s32 *distX, s32 *distY ) +bool CNpcPath::think2D( DVECTOR currentPos, s32 *distX, s32 *distY, s32 *heading ) { bool pointChange = false; @@ -256,5 +256,14 @@ bool CNpcPath::think2D( DVECTOR currentPos, s32 *distX, s32 *distY ) incPath(); } + if ( *distX > 0 ) + { + *heading = 0; + } + else + { + *heading = 2048; + } + return( pointChange ); } \ No newline at end of file diff --git a/source/enemy/npcpath.h b/source/enemy/npcpath.h index 7378f4e10..95b6524c2 100644 --- a/source/enemy/npcpath.h +++ b/source/enemy/npcpath.h @@ -52,7 +52,7 @@ public: void resetPath(); void reversePathDir(); s32 think( DVECTOR currentPos, bool *pathComplete, bool *waypointChange ); - bool think2D( DVECTOR currentPos, s32 *distX, s32 *distY ); + bool think2D( DVECTOR currentPos, s32 *distX, s32 *distY, s32 *heading ); bool getDistToNextWaypoint( DVECTOR currentPos, s32 *distX, s32 *distY ); }; diff --git a/source/enemy/nscrab.cpp b/source/enemy/nscrab.cpp index d6de50bd3..29ac680c1 100644 --- a/source/enemy/nscrab.cpp +++ b/source/enemy/nscrab.cpp @@ -27,34 +27,35 @@ void CNpc::processCloseSpiderCrabAttack( int _frames ) { s32 velocity; + DVECTOR newPos = Pos; velocity = m_velocity * _frames; if ( m_extendDir == EXTEND_RIGHT ) { - Pos.vx += velocity; + newPos.vx += velocity; m_heading = 0; } else { - Pos.vx -= velocity; + newPos.vx -= velocity; m_heading = 2048; } - s32 horizontalExtension = abs( Pos.vx - m_base.vx ); + s32 horizontalExtension = abs( newPos.vx - m_base.vx ); if ( horizontalExtension > 128 ) { if ( m_extendDir == EXTEND_RIGHT ) { - Pos.vx = m_base.vx + 128; + newPos.vx = m_base.vx + 128; } else { - Pos.vx = m_base.vx - 128; + newPos.vx = m_base.vx - 128; } - Pos.vy = m_base.vy; + newPos.vy = m_base.vy; m_controlFunc = NPC_CONTROL_MOVEMENT; m_timerFunc = NPC_TIMER_ATTACK_DONE; @@ -63,6 +64,22 @@ void CNpc::processCloseSpiderCrabAttack( int _frames ) } else { - Pos.vy = m_base.vy - ( ( 20 * rsin( horizontalExtension << 4 ) ) >> 12 ); + newPos.vy = m_base.vy - ( ( 20 * rsin( horizontalExtension << 4 ) ) >> 12 ); + } + + // check for collision with ground + + if ( m_layerCollision->getHeightFromGround( newPos.vx, newPos.vy ) < 0 ) + { + // abort jump + + m_controlFunc = NPC_CONTROL_MOVEMENT; + m_timerFunc = NPC_TIMER_ATTACK_DONE; + m_timerTimer = GameState::getOneSecondInFrames(); + m_sensorFunc = NPC_SENSOR_NONE; + } + else + { + Pos = newPos; } } diff --git a/source/enemy/nshrkman.cpp b/source/enemy/nshrkman.cpp index 2521acc3c..e9c19ba83 100644 --- a/source/enemy/nshrkman.cpp +++ b/source/enemy/nshrkman.cpp @@ -26,8 +26,13 @@ void CNpc::processCloseSharkManAttack( int _frames ) { - s32 moveX, moveY; + s32 moveX = 0, moveY = 0; + s32 groundHeight; s16 decDir, incDir, moveDist; + s32 direction; + s32 maxHeight = 10; + s32 fallSpeed = 2; + s8 yMovement = fallSpeed * _frames; s16 headingToPlayer = ratan2( playerYDist, playerXDist ); @@ -62,32 +67,47 @@ void CNpc::processCloseSharkManAttack( int _frames ) { // continue charge - if ( playerXDist < 0 ) + if ( playerXDist != 0 ) { - m_heading = 2048; + direction = playerXDist / abs( playerXDist ); } else { - m_heading = 0; + direction = 1; } - s32 preShiftX = _frames * m_velocity * rcos( m_heading ); - s32 preShiftY = _frames * m_velocity * rsin( m_heading ); - - moveX = preShiftX >> 12; - if ( !moveX && preShiftX ) + if ( m_layerCollision->getHeightFromGround( Pos.vx + ( _frames * m_velocity * direction ), Pos.vy ) < -maxHeight ) { - moveX = preShiftX / abs( preShiftX ); - } + // there is an obstacle in the way, abort - moveY = preShiftY >> 12; - if ( !moveY && preShiftY ) + m_controlFunc = NPC_CONTROL_MOVEMENT; + m_timerFunc = NPC_TIMER_ATTACK_DONE; + m_timerTimer = GameState::getOneSecondInFrames(); + m_sensorFunc = NPC_SENSOR_NONE; + } + else { - moveY = preShiftY / abs( preShiftY ); - } + // check for vertical movement - Pos.vx += moveX; - Pos.vy += moveY; + groundHeight = m_layerCollision->getHeightFromGround( Pos.vx, Pos.vy, yMovement + 16 ); + + if ( groundHeight <= yMovement ) + { + // groundHeight <= yMovement indicates either just above ground or on or below ground + + moveX = _frames * m_velocity * direction; + moveY = groundHeight; + } + else + { + // fall + + moveY = yMovement; + } + + Pos.vx += moveX; + Pos.vy += moveY; + } } else {