diff --git a/makefile.gaz b/makefile.gaz index 3db3829fb..ce10a9625 100644 --- a/makefile.gaz +++ b/makefile.gaz @@ -54,6 +54,8 @@ backend_src := gameover \ enemy_src := 2denemy \ npc \ npcpath \ + nsjfish \ + nclam \ enemy fileio_src := fileio \ diff --git a/source/enemy/npc.cpp b/source/enemy/npc.cpp index 612bf0cb6..5185ccfb0 100644 --- a/source/enemy/npc.cpp +++ b/source/enemy/npc.cpp @@ -44,36 +44,66 @@ CNpc::NPC_DATA CNpc::m_data[NPC_UNIT_TYPE_MAX] = { - { + { // NPC_TEST_TYPE NPC_INIT_DEFAULT, - NPC_SENSOR_USER_CLOSE, + NPC_SENSOR_JELLYFISH_USER_CLOSE, NPC_MOVEMENT_FIXED_PATH, NPC_MOVEMENT_MODIFIER_JELLYFISH, - NPC_CLOSE_EVADE, + NPC_CLOSE_JELLYFISH_EVADE, NPC_TIMER_NONE, false, }, - { + { // NPC_SANDY_CHEEKS NPC_INIT_DEFAULT, NPC_SENSOR_NONE, NPC_MOVEMENT_STATIC, NPC_MOVEMENT_MODIFIER_NONE, - NPC_CLOSE_EVADE, + NPC_CLOSE_NONE, NPC_TIMER_NONE, true, }, + + { // NPC_SMALL_JELLYFISH_1 + NPC_INIT_DEFAULT, + NPC_SENSOR_JELLYFISH_USER_CLOSE, + NPC_MOVEMENT_FIXED_PATH, + NPC_MOVEMENT_MODIFIER_JELLYFISH, + NPC_CLOSE_JELLYFISH_EVADE, + NPC_TIMER_NONE, + false, + }, + + { // NPC_ANEMONE_1 + NPC_INIT_DEFAULT, + NPC_SENSOR_NONE, + NPC_MOVEMENT_STATIC, + NPC_MOVEMENT_MODIFIER_NONE, + NPC_CLOSE_NONE, + NPC_TIMER_NONE, + false, + }, + + { // NPC_CLAM + NPC_INIT_DEFAULT, + NPC_SENSOR_CLAM_USER_CLOSE, + NPC_MOVEMENT_STATIC, + NPC_MOVEMENT_MODIFIER_NONE, + NPC_CLOSE_CLAM_ATTACK, + NPC_TIMER_NONE, + }, }; void CNpc::init() { - m_type = NPC_TEST_TYPE; + m_type = NPC_CLAM; - m_heading = 0; + m_heading = 3072; m_movementTimer = 0; m_timerTimer = 0; m_velocity = 0; + m_extension = 0; Pos.vx = 100; Pos.vy = 100; @@ -170,36 +200,61 @@ bool CNpc::processSensor() case NPC_SENSOR_NONE: return( false ); - case NPC_SENSOR_USER_CLOSE: - { - CPlayer *player = GameScene.getPlayer(); - - DVECTOR playerPos = player->getPos(); - - s32 xDistSqr, yDistSqr; - - xDistSqr = playerPos.vx - this->Pos.vx; - xDistSqr *= xDistSqr; - - yDistSqr = playerPos.vy - this->Pos.vy; - yDistSqr *= yDistSqr; - - if ( xDistSqr + yDistSqr < 10000 ) - { - this->m_controlFunc = NPC_CONTROL_CLOSE; - - this->m_evadeClockwise = ( getRnd() % 2 ) - 1; - - return( true ); - } - else - { - return( false ); - } - } - default: - return( false ); + { + CPlayer *player = GameScene.getPlayer(); + + DVECTOR playerPos = player->getPos(); + + s32 xDistSqr, yDistSqr; + + xDistSqr = playerPos.vx - this->Pos.vx; + xDistSqr *= xDistSqr; + + yDistSqr = playerPos.vy - this->Pos.vy; + yDistSqr *= yDistSqr; + + switch( m_sensorFunc ) + { + case NPC_SENSOR_JELLYFISH_USER_CLOSE: + { + if ( xDistSqr + yDistSqr < 10000 ) + { + this->m_controlFunc = NPC_CONTROL_CLOSE; + this->m_evadeClockwise = ( getRnd() % 2 ) - 1; + + return( true ); + } + else + { + return( false ); + } + } + + case NPC_SENSOR_CLAM_USER_CLOSE: + { + if ( xDistSqr + yDistSqr < 10000 ) + { + this->m_controlFunc = NPC_CONTROL_CLOSE; + this->m_extendOut = true; + this->m_extension = 0; + this->m_movementTimer = GameState::getOneSecondInFrames() >> 3; + this->m_velocity = ( getRnd() % 6 ) + 1; + + return( true ); + } + else + { + return( false ); + } + } + + default: + return( false ); + } + } + + break; } } @@ -301,7 +356,7 @@ void CNpc::processMovement(int _frames) processMovementModifier(_frames, moveX, moveY, moveVel, moveDist); } -void CNpc::processMovementModifier(int _frames, s32 distX, s32 distY, s32 dist, s32 headingChange) +void CNpc::processMovementModifier(int _frames, s32 distX, s32 distY, s32 dist, s16 headingChange) { switch( m_data[m_type].movementModifierFunc ) { @@ -320,80 +375,7 @@ void CNpc::processMovementModifier(int _frames, s32 distX, s32 distY, s32 dist, case NPC_MOVEMENT_MODIFIER_JELLYFISH: { -#define NPC_JELLYFISH_RESISTANCE 64 - - s32 newX, newY; - s32 preShiftX, preShiftY; - - u16 jellyfishData[5] = { 96, 192, 256, 192, 128, }; - - u32 dataPoint; - - m_movementTimer += _frames; - - if ( m_movementTimer > GameState::getOneSecondInFrames() ) - { - m_movementTimer = 0; - } - - dataPoint = 4 * m_movementTimer; - - if ( dataPoint != 0 ) - { - dataPoint /= GameState::getOneSecondInFrames(); - } - - s32 resistance; - s32 absVelocity = abs( m_velocity ); - s32 reqVelocity = dist; - - resistance = _frames * NPC_JELLYFISH_RESISTANCE; - - if ( absVelocity < resistance ) - { - resistance = absVelocity; - } - - if ( absVelocity != 0 ) - { - resistance = -( resistance * m_velocity ) / absVelocity; - } - else - { - resistance = 0; - } - - m_velocity += resistance; - - reqVelocity = dist * jellyfishData[dataPoint]; - reqVelocity >>= 8; - reqVelocity *= 128 + ( 128 - headingChange ); - reqVelocity >>= 8; - - s32 absReqVelocity = abs( reqVelocity ); - - if ( absReqVelocity > absVelocity ) - { - m_velocity += reqVelocity >> 1; - } - - preShiftX = ( m_velocity >> 8 ) * rcos( m_heading ); - preShiftY = ( m_velocity >> 8 ) * rsin( m_heading ); - - newX = preShiftX >> 12; - if ( !newX && preShiftX ) - { - newX = preShiftX / abs( preShiftX ); - } - - newY = preShiftY >> 12; - if ( !newY && preShiftY ) - { - newY = preShiftY / abs( preShiftY ); - } - - Pos.vx += newX; - Pos.vy += newY; + processSmallJellyfishMovementModifier( _frames, distX, distY, dist, headingChange ); break; } @@ -408,137 +390,13 @@ void CNpc::processClose(int _frames) { switch( m_data[this->m_type].closeFunc ) { - case NPC_CLOSE_EVADE: - { - s32 moveX = 0, moveY = 0; + case NPC_CLOSE_JELLYFISH_EVADE: + processCloseSmallJellyfishEvade( _frames ); - s16 moveDist = 0; + break; - s32 moveVel = 0; - - CPlayer *player = GameScene.getPlayer(); - - DVECTOR playerPos = player->getPos(); - - s32 xDist, yDist; - s32 xDistSqr, yDistSqr; - - xDist = playerPos.vx - this->Pos.vx; - xDistSqr = xDist * xDist; - - yDist = playerPos.vy - this->Pos.vy; - yDistSqr = yDist * yDist; - - if ( xDistSqr + yDistSqr > 22500 ) - { - this->m_controlFunc = NPC_CONTROL_MOVEMENT; - } - else - { - bool pathComplete; - - s16 headingToTarget = m_npcPath.think( Pos, &pathComplete ); - - if ( pathComplete ) - { - this->m_controlFunc = NPC_CONTROL_MOVEMENT; - } - else - { - s16 headingToPlayer = ratan2( yDist, xDist ); - - if ( m_evadeClockwise ) - { - headingToPlayer += 1024; - } - else - { - headingToPlayer -= 1024; - } - - headingToPlayer %= ONE; - - s16 decDir, incDir; - - decDir = headingToPlayer - headingToTarget; - - if ( decDir < 0 ) - { - decDir += ONE; - } - - incDir = headingToTarget - headingToPlayer; - - if ( incDir < 0 ) - { - incDir += ONE; - } - - if ( decDir < incDir ) - { - moveDist = decDir; - } - else - { - moveDist = incDir; - } - - if ( moveDist < 128 ) - { - // evasion angle is close to angle required to go to waypoint, hence resume waypoint movement - - this->m_controlFunc = NPC_CONTROL_MOVEMENT; - this->m_timerFunc = NPC_TIMER_EVADE_DONE; - this->m_timerTimer = GameState::getOneSecondInFrames(); - this->m_sensorFunc = NPC_SENSOR_NONE; - } - else - { - decDir = m_heading - headingToPlayer; - - if ( decDir < 0 ) - { - decDir += ONE; - } - - incDir = headingToPlayer - m_heading; - - if ( incDir < 0 ) - { - incDir += ONE; - } - - if ( decDir < incDir ) - { - moveDist = -decDir; - } - else - { - moveDist = incDir; - } - - if ( moveDist < -128 ) - { - moveDist = -128; - } - else if ( moveDist > 128 ) - { - moveDist = 128; - } - - m_heading += moveDist; - - m_heading = m_heading % ONE; - - moveX = ( _frames * 3 * rcos( m_heading ) ) >> 12; - moveY = ( _frames * 3 * rsin( m_heading ) ) >> 12; - moveVel = ( _frames * 3 ) << 8; - - processMovementModifier(_frames, moveX, moveY, moveVel, moveDist); - } - } - } - } + case NPC_CLOSE_CLAM_ATTACK: + processCloseClamAttack( _frames ); break; @@ -561,13 +419,14 @@ void CNpc::processTimer(int _frames) } case NPC_TIMER_EVADE_DONE: + case NPC_TIMER_ATTACK_DONE: { this->m_timerTimer -= _frames; if ( m_timerTimer <= 0 ) { this->m_timerFunc = NPC_TIMER_NONE; - this->m_sensorFunc = NPC_SENSOR_USER_CLOSE; + this->m_sensorFunc = m_data[this->m_type].sensorFunc; } break; diff --git a/source/enemy/npc.h b/source/enemy/npc.h index b6a4181e7..31cc7f963 100644 --- a/source/enemy/npc.h +++ b/source/enemy/npc.h @@ -41,6 +41,9 @@ protected: { NPC_TEST_TYPE = 0, NPC_SANDY_CHEEKS = 1, + NPC_SMALL_JELLYFISH_1, + NPC_ANEMONE_1, + NPC_CLAM, NPC_UNIT_TYPE_MAX, }; @@ -62,12 +65,15 @@ protected: enum NPC_SENSOR_FUNC { NPC_SENSOR_NONE = 0, - NPC_SENSOR_USER_CLOSE = 1, + NPC_SENSOR_JELLYFISH_USER_CLOSE = 1, + NPC_SENSOR_CLAM_USER_CLOSE, }; enum NPC_CLOSE_FUNC { - NPC_CLOSE_EVADE = 0, + NPC_CLOSE_NONE = 0, + NPC_CLOSE_JELLYFISH_EVADE = 1, + NPC_CLOSE_CLAM_ATTACK, }; enum NPC_MOVEMENT_FUNC @@ -89,6 +95,12 @@ protected: { NPC_TIMER_NONE = 0, NPC_TIMER_EVADE_DONE = 1, + NPC_TIMER_ATTACK_DONE, + }; + + enum + { + NPC_JELLYFISH_RESISTANCE = 64, }; @@ -104,13 +116,27 @@ protected: } NPC_DATA; + // functions + bool processSensor(); - void processMovement(int _frames); - void processMovementModifier(int _frames, s32 distX, s32 distY, s32 dist, s32 headingChange); + void processMovement( int _frames ); + void processMovementModifier( int _frames, s32 distX, s32 distY, s32 dist, s16 headingChange ); void processShot(); - void processClose(int _frames); + void processClose( int _frames ); void processCollision(); - void processTimer(int _frames); + void processTimer( int _frames ); + + // small jellyfish functions + + void processSmallJellyfishSensor(); + void processSmallJellyfishMovementModifier( int _frames, s32 distX, s32 distY, s32 dist, s16 headingChange ); + void processCloseSmallJellyfishEvade( int _frames ); + + // clam functions + + void processCloseClamAttack( int _frames ); + + // data static NPC_DATA m_data[NPC_UNIT_TYPE_MAX]; @@ -126,6 +152,8 @@ protected: s32 m_velocity; bool m_evadeClockwise; s32 m_timerTimer; + s32 m_extension; + bool m_extendOut; }; diff --git a/users/paul/spongebob project/spongebob project.dsp b/users/paul/spongebob project/spongebob project.dsp index ee2d0b3a2..4952d9ca8 100644 --- a/users/paul/spongebob project/spongebob project.dsp +++ b/users/paul/spongebob project/spongebob project.dsp @@ -125,6 +125,10 @@ SOURCE=..\..\..\source\enemy\enemy.h # End Source File # Begin Source File +SOURCE=..\..\..\source\enemy\nclam.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\source\enemy\npc.cpp # End Source File # Begin Source File @@ -139,6 +143,10 @@ SOURCE=..\..\..\source\enemy\npcpath.cpp SOURCE=..\..\..\source\enemy\npcpath.h # End Source File +# Begin Source File + +SOURCE=..\..\..\source\enemy\nsjfish.cpp +# End Source File # End Group # Begin Group "fileio"