diff --git a/source/enemy/nffolk.cpp b/source/enemy/nffolk.cpp index 9345f45cc..b9314d97e 100644 --- a/source/enemy/nffolk.cpp +++ b/source/enemy/nffolk.cpp @@ -26,10 +26,11 @@ void CNpc::processFishFolkMovementModifier( int _frames, s32 distX, s32 distY ) { + Pos.vy += distY; + if ( m_movementTimer > 0 ) { Pos.vx += distX; - Pos.vy += distY; m_movementTimer -= _frames; diff --git a/source/enemy/ngeneric.cpp b/source/enemy/ngeneric.cpp index be63a7c80..77e28a839 100644 --- a/source/enemy/ngeneric.cpp +++ b/source/enemy/ngeneric.cpp @@ -99,6 +99,75 @@ void CNpc::processGenericGetUserDist( int _frames, s32 *distX, s32 *distY ) *distY = playerPos.vy - this->Pos.vy; } +void CNpc::processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY ) +{ + s32 maxHeight = 10; + s32 distX, distY; + s32 fallSpeed = 5; + s8 yMovement = fallSpeed * _frames; + s32 groundHeight; + + *moveX = 0; + *moveY = 0; + + // ignore y component of waypoint, since we are stuck to the ground + + if ( m_npcPath.think2D( Pos, &distX, &distY ) ) + { + // path has finished, waypoint has changed, or there are no waypoints - do not move horizontally + + // check for vertical movement + + 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 + + *moveY = groundHeight; + } + else + { + // fall + + *moveY = yMovement; + } + } + else + { + // check for collision + + distX = distX / abs( distX ); + + if ( m_layerCollision->getHeightFromGround( Pos.vx + ( distX * m_data[m_type].speed * _frames ), Pos.vy ) < -maxHeight ) + { + // there is an obstacle in the way, increment the path point (hopefully this will resolve the problem) + + m_npcPath.incPath(); + } + else + { + // check for vertical movement + + 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 = distX * m_data[m_type].speed * _frames; + *moveY = groundHeight; + } + else + { + // fall + + *moveY = yMovement; + } + } + } +} + bool CNpc::isCollisionWithGround() { ASSERT(m_layerCollision); diff --git a/source/enemy/npc.cpp b/source/enemy/npc.cpp index a4251ed35..ce8110008 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_SMALL_JELLYFISH_1; + m_type = NPC_FISH_FOLK; m_heading = m_fireHeading = 0; m_movementTimer = 0; @@ -231,13 +231,13 @@ void CNpc::init() DVECTOR newPos; - newPos.vx = 100; - newPos.vy = 100; + newPos.vx = 200; + newPos.vy = 400; m_npcPath.addWaypoint( newPos ); newPos.vx = 500; - newPos.vy = 100; + newPos.vy = 400; m_npcPath.addWaypoint( newPos ); @@ -721,6 +721,13 @@ void CNpc::processMovement(int _frames) break; } + case NPC_MOVEMENT_FIXED_PATH_WALK: + { + processGenericFixedPathWalk( _frames, &moveX, &moveY ); + + break; + } + case NPC_MOVEMENT_MOTHER_JELLYFISH: { processMotherJellyfishMovement( _frames ); diff --git a/source/enemy/npc.h b/source/enemy/npc.h index 612e0ffe8..2d6cc0474 100644 --- a/source/enemy/npc.h +++ b/source/enemy/npc.h @@ -166,6 +166,7 @@ protected: { NPC_MOVEMENT_STATIC = 0, NPC_MOVEMENT_FIXED_PATH = 1, + NPC_MOVEMENT_FIXED_PATH_WALK, NPC_MOVEMENT_MOTHER_JELLYFISH, NPC_MOVEMENT_SUB_SHARK, NPC_MOVEMENT_FLYING_DUTCHMAN, @@ -270,6 +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 ); // small jellyfish functions diff --git a/source/enemy/npcdata.cpp b/source/enemy/npcdata.cpp index b29f8e67a..9af3376e7 100644 --- a/source/enemy/npcdata.cpp +++ b/source/enemy/npcdata.cpp @@ -262,7 +262,7 @@ CNpc::NPC_DATA CNpc::m_data[NPC_UNIT_TYPE_MAX] = { // NPC_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, diff --git a/source/enemy/npcpath.cpp b/source/enemy/npcpath.cpp index fbbe0a684..cf4aeb751 100644 --- a/source/enemy/npcpath.cpp +++ b/source/enemy/npcpath.cpp @@ -229,4 +229,32 @@ s32 CNpcPath::think( DVECTOR currentPos, bool *pathComplete, bool *waypointChang s32 headingToTarget = ratan2( yDist, xDist ); return( headingToTarget ); +} + +bool CNpcPath::think2D( DVECTOR currentPos, s32 *distX, s32 *distY ) +{ + bool pointChange = false; + + if ( !this->waypoint ) + { + return( true ); + } + + if ( !currentWaypoint ) + { + // if no currentWaypoint set, start it off + + currentWaypoint = this->waypoint; + } + + *distX = currentWaypoint->pos.vx - currentPos.vx; + *distY = currentWaypoint->pos.vy - currentPos.vy; + + if ( abs( *distX ) < 10 ) + { + pointChange = true; + incPath(); + } + + return( pointChange ); } \ No newline at end of file diff --git a/source/enemy/npcpath.h b/source/enemy/npcpath.h index aa2e4b5a9..7378f4e10 100644 --- a/source/enemy/npcpath.h +++ b/source/enemy/npcpath.h @@ -52,6 +52,7 @@ public: void resetPath(); void reversePathDir(); s32 think( DVECTOR currentPos, bool *pathComplete, bool *waypointChange ); + bool think2D( DVECTOR currentPos, s32 *distX, s32 *distY ); bool getDistToNextWaypoint( DVECTOR currentPos, s32 *distX, s32 *distY ); };