diff --git a/source/enemy/ngeneric.cpp b/source/enemy/ngeneric.cpp index 032da8626..f4c9f38b6 100644 --- a/source/enemy/ngeneric.cpp +++ b/source/enemy/ngeneric.cpp @@ -99,7 +99,134 @@ 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 *heading ) +bool CNpc::processGroundCollisionReverse( s32 *moveX, s32 *moveY ) +{ + bool xBlocked = false; + bool yBlocked = false; + + // check for collision with ground + + if ( m_layerCollision->Get( ( Pos.vx + *moveX ) >> 4, ( Pos.vy + *moveY ) >> 4 ) ) + { + // destination point is below ground, check in individual directions + + if ( m_layerCollision->Get( ( Pos.vx + *moveX ) >> 4, Pos.vy >> 4 ) ) + { + // X direction is blocked + + xBlocked = true; + } + + if ( m_layerCollision->Get( Pos.vx >> 4, ( Pos.vy + *moveY ) >> 4 ) ) + { + yBlocked = true; + } + + if ( xBlocked && !yBlocked ) + { + // invert X + + *moveX = -(*moveX); + + m_heading = ratan2( *moveY, *moveX ); + } + else if ( !xBlocked && yBlocked ) + { + // invert Y + + *moveY = -(*moveY); + + m_heading = ratan2( *moveY, *moveX ); + } + else + { + // invert both + + *moveX = -(*moveX); + *moveY = -(*moveY); + + m_heading += 2048; + m_heading &= 4096; + } + } + + return( xBlocked | yBlocked ); +} + +void CNpc::processGenericFixedPathMove( int _frames, s32 *moveX, s32 *moveY, s32 *moveVel, s32 *moveDist ) +{ + bool pathComplete; + bool waypointChange; + + s16 headingToTarget = m_npcPath.think( Pos, &pathComplete, &waypointChange ); + + if ( waypointChange ) + { + m_movementTimer = 0; + } + + if ( !pathComplete ) + { + s16 decDir, incDir; + s16 maxTurnRate = m_data[m_type].turnSpeed; + + decDir = m_heading - headingToTarget; + + if ( decDir < 0 ) + { + decDir += ONE; + } + + incDir = headingToTarget - m_heading; + + if ( incDir < 0 ) + { + incDir += ONE; + } + + if ( decDir < incDir ) + { + *moveDist = -decDir; + } + else + { + *moveDist = incDir; + } + + if ( *moveDist < -maxTurnRate ) + { + *moveDist = -maxTurnRate; + } + else if ( *moveDist > maxTurnRate ) + { + *moveDist = maxTurnRate; + } + + m_heading += *moveDist; + m_heading = m_heading % ONE; + + s32 preShiftX = _frames * m_data[m_type].speed * rcos( m_heading ); + s32 preShiftY = _frames * m_data[m_type].speed * rsin( m_heading ); + + *moveX = preShiftX >> 12; + if ( !(*moveX) && preShiftX ) + { + *moveX = preShiftX / abs( preShiftX ); + } + + *moveY = preShiftY >> 12; + if ( !(*moveY) && preShiftY ) + { + *moveY = preShiftY / abs( preShiftY ); + } + + *moveVel = ( _frames * m_data[m_type].speed ) << 8; + + processGroundCollisionReverse( moveX, moveY ); + } +} + +void CNpc::processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY ) { s32 maxHeight = 10; s32 distX, distY; @@ -112,7 +239,7 @@ void CNpc::processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY, s32 // ignore y component of waypoint, since we are stuck to the ground - if ( m_npcPath.thinkFlat( Pos, &distX, &distY, heading ) ) + if ( m_npcPath.thinkFlat( Pos, &distX, &distY, &m_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 4c6e57eb4..cc2ab78de 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_SHARK_MAN; + m_type = NPC_SMALL_JELLYFISH_1; m_heading = m_fireHeading = 0; m_movementTimer = 0; @@ -336,7 +336,7 @@ bool CNpc::processSensor() { case NPC_SENSOR_JELLYFISH_USER_CLOSE: { - if ( playerXDistSqr + playerYDistSqr < 10000 ) + if ( playerXDistSqr + playerYDistSqr < 5625 ) { m_controlFunc = NPC_CONTROL_CLOSE; m_evadeClockwise = getRnd() % 2; @@ -635,10 +635,8 @@ void CNpc::processMovement(int _frames) } s32 moveX = 0, moveY = 0; - - s16 moveDist = 0; - s32 moveVel = 0; + s32 moveDist = 0; switch( m_data[this->m_type].movementFunc ) { @@ -649,81 +647,14 @@ void CNpc::processMovement(int _frames) case NPC_MOVEMENT_FIXED_PATH: { - bool pathComplete; - bool waypointChange; - - s16 headingToTarget = m_npcPath.think( Pos, &pathComplete, &waypointChange ); - - if ( waypointChange ) - { - m_movementTimer = 0; - } - - if ( !pathComplete ) - { - s16 decDir, incDir; - s16 maxTurnRate = m_data[m_type].turnSpeed; - - decDir = m_heading - headingToTarget; - - if ( decDir < 0 ) - { - decDir += ONE; - } - - incDir = headingToTarget - m_heading; - - if ( incDir < 0 ) - { - incDir += ONE; - } - - if ( decDir < incDir ) - { - moveDist = -decDir; - } - else - { - moveDist = incDir; - } - - if ( moveDist < -maxTurnRate ) - { - moveDist = -maxTurnRate; - } - else if ( moveDist > maxTurnRate ) - { - moveDist = maxTurnRate; - } - - m_heading += moveDist; - - m_heading = m_heading % ONE; - - s32 preShiftX = _frames * m_data[m_type].speed * rcos( m_heading ); - s32 preShiftY = _frames * m_data[m_type].speed * rsin( m_heading ); - - moveX = preShiftX >> 12; - if ( !moveX && preShiftX ) - { - moveX = preShiftX / abs( preShiftX ); - } - - moveY = preShiftY >> 12; - if ( !moveY && preShiftY ) - { - moveY = preShiftY / abs( preShiftY ); - } - - moveVel = ( _frames * m_data[m_type].speed ) << 8; - } + processGenericFixedPathMove( _frames, &moveX, &moveY, &moveVel, &moveDist ); break; } case NPC_MOVEMENT_FIXED_PATH_WALK: { - processGenericFixedPathWalk( _frames, &moveX, &moveY, &m_heading ); + processGenericFixedPathWalk( _frames, &moveX, &moveY ); break; } @@ -789,7 +720,7 @@ void CNpc::processMovement(int _frames) break; } - processMovementModifier(_frames, moveX, moveY, moveVel, moveDist); + processMovementModifier( _frames, moveX, moveY, moveVel, moveDist ); } void CNpc::processMovementModifier(int _frames, s32 distX, s32 distY, s32 dist, s16 headingChange) diff --git a/source/enemy/npc.h b/source/enemy/npc.h index 8e5693f8c..37c1b7efb 100644 --- a/source/enemy/npc.h +++ b/source/enemy/npc.h @@ -271,7 +271,9 @@ 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, s32 *heading ); + void processGenericFixedPathMove( int _frames, s32 *moveX, s32 *moveY, s32 *moveVel, s32 *moveDist ); + void processGenericFixedPathWalk( int _frames, s32 *moveX, s32 *moveY ); + bool processGroundCollisionReverse( s32 *moveX, s32 *moveY ); // small jellyfish functions diff --git a/source/enemy/nsjfish.cpp b/source/enemy/nsjfish.cpp index f1d9d59c5..cdeb15c39 100644 --- a/source/enemy/nsjfish.cpp +++ b/source/enemy/nsjfish.cpp @@ -108,7 +108,7 @@ void CNpc::processCloseSmallJellyfishEvade( int _frames ) s32 moveVel = 0; - if ( playerXDistSqr + playerYDistSqr > 22500 ) + if ( playerXDistSqr + playerYDistSqr > 10000 ) { this->m_controlFunc = NPC_CONTROL_MOVEMENT; } @@ -214,51 +214,9 @@ void CNpc::processCloseSmallJellyfishEvade( int _frames ) moveY = ( _frames * 3 * rsin( m_heading ) ) >> 12; moveVel = ( _frames * 3 ) << 8; - // check for collision with ground - - if ( m_layerCollision->Get( ( Pos.vx + moveX ) >> 4, ( Pos.vy + moveY ) >> 4 ) ) + if ( processGroundCollisionReverse( &moveX, &moveY ) ) { - bool xBlocked = false; - bool yBlocked = false; - - // destination point is below ground, check in individual directions - - if ( m_layerCollision->Get( ( Pos.vx + moveX ) >> 4, Pos.vy >> 4 ) ) - { - // X direction is blocked - - xBlocked = true; - } - - if ( m_layerCollision->Get( Pos.vx >> 4, ( Pos.vy + moveY ) >> 4 ) ) - { - yBlocked = true; - } - - if ( xBlocked && !yBlocked ) - { - // invert X - - moveX = -moveX; - - m_heading = ratan2( moveY, moveX ); - } - else if ( !xBlocked && yBlocked ) - { - // invert Y - - moveY = -moveY; - - m_heading = ratan2( moveY, moveX ); - } - else - { - moveX = -moveX; - moveY = -moveY; - - m_heading += 2048; - m_heading &= 4096; - } + m_evadeClockwise = !m_evadeClockwise; } processMovementModifier(_frames, moveX, moveY, moveVel, moveDist);