diff --git a/source/enemy/npc.cpp b/source/enemy/npc.cpp index fa9b050ad..bfc7a8489 100644 --- a/source/enemy/npc.cpp +++ b/source/enemy/npc.cpp @@ -1147,10 +1147,12 @@ void CNpcEnemy::processMovementModifier(int _frames, s32 distX, s32 distY, s32 d //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void CNpcEnemy::hasBeenAttacked() +u8 CNpcEnemy::hasBeenAttacked() { m_controlFunc = NPC_CONTROL_SHOT; m_state = NPC_GENERIC_HIT_CHECK_HEALTH; + + return( true ); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/source/enemy/npc.h b/source/enemy/npc.h index 81b09aa7f..5df45027b 100644 --- a/source/enemy/npc.h +++ b/source/enemy/npc.h @@ -104,7 +104,7 @@ public: void addWaypoint( s32 xPos, s32 yPos ); void setPathType( u8 newType ) {m_npcPath.setPathType( newType );} void setStartPos( s32 xPos, s32 yPos ); - void hasBeenAttacked(); + virtual u8 hasBeenAttacked(); bool canBeCaughtByNet(); void caughtWithNet(); virtual int getFrameCount(); diff --git a/source/enemy/npcdata.cpp b/source/enemy/npcdata.cpp index 0b08885d5..eaf5b9aac 100644 --- a/source/enemy/npcdata.cpp +++ b/source/enemy/npcdata.cpp @@ -323,7 +323,7 @@ CNpcEnemy::NPC_DATA CNpcEnemy::m_data[NPC_UNIT_TYPE_MAX] = { // NPC_SQUID_DART 0,//ACTORS_SQUIDDART_SBK, FRM_SQUIDDART_SWIM0001, - NPC_SENSOR_NONE, + NPC_SENSOR_USER_CLOSE, NPC_MOVEMENT_FIXED_PATH, NPC_CLOSE_NONE, NPC_TIMER_NONE, diff --git a/source/enemy/nsdart.cpp b/source/enemy/nsdart.cpp index 341e81f41..621a8a164 100644 --- a/source/enemy/nsdart.cpp +++ b/source/enemy/nsdart.cpp @@ -31,6 +31,10 @@ #include "projectl\prnpcspr.h" #endif +#ifndef __UTILS_HEADER__ +#include "utils\utils.h" +#endif + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -45,10 +49,24 @@ void CNpcSquidDartEnemy::render() if (canRender()) { DVECTOR &renderPos=getRenderPos(); + + // bodge + if ( m_reversed ) + { + renderPos.vx += 32; + } + else + { + renderPos.vx -= 32; + } + + renderPos.vy -= 6; + // bodge int frame = FRM_SQUIDDART_SWIM0001 + ( m_frame >> 8 ); SprFrame = m_spriteBank->printFT4(frame,renderPos.vx,renderPos.vy,m_reversed,0,10); + //setRGB0( SprFrame, 255, 128, 255 ); /*s32 XMax = SprFrame->x1 - origRenderPos.vx; @@ -64,7 +82,8 @@ void CNpcSquidDartEnemy::render() s32 YMin = SprFrame->y0 - renderPos.vy; setCollisionSize( ( XMax - XMin ), ( YMax - YMin ) ); - setCollisionCentreOffset( ( XMax + XMin ) >> 1, ( YMax + YMin ) >> 1 ); + // bodge + setCollisionCentreOffset( 0, 0 ); //( XMax + XMin ) >> 1, ( YMax + YMin ) >> 1 ); } } } @@ -99,3 +118,65 @@ s32 CNpcSquidDartEnemy::getFrameShift( int _frames ) { return( ( _frames << 8 ) >> 2 ); } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +bool CNpcSquidDartEnemy::processSensor() +{ + switch( m_sensorFunc ) + { + case NPC_SENSOR_NONE: + return( false ); + + default: + { + if ( playerXDistSqr + playerYDistSqr < 20000 ) + { + m_controlFunc = NPC_CONTROL_CLOSE; + + m_circleCentre.vx = Pos.vx + ( playerXDist >> 1 ); + m_circleCentre.vy = Pos.vy + ( playerYDist >> 1 ); + + m_startAngle = ratan2( Pos.vy - m_circleCentre.vy, Pos.vx - m_circleCentre.vx ); + m_startAngle &= 4095; + + m_circleRadius = isqrt2( playerXDistSqr + playerYDistSqr ) >> 1; + + m_circleCentre.vx = Pos.vx - ( ( m_circleRadius * rcos( m_startAngle ) ) >> 12 ); + m_circleCentre.vy = Pos.vy - ( ( m_circleRadius * rsin( m_startAngle ) ) >> 12 ); + + m_angularDistance = 0; + + return( true ); + } + else + { + return( false ); + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void CNpcSquidDartEnemy::processClose( int _frames ) +{ + s16 m_currentAngle; + + m_currentAngle = ( m_startAngle + m_angularDistance ) & 4095; + + m_heading = ( m_currentAngle + 1024 ) & 4095; + + Pos.vx = m_circleCentre.vx + ( ( m_circleRadius * rcos( m_currentAngle ) ) >> 12 ); + Pos.vy = m_circleCentre.vy + ( ( m_circleRadius * rsin( m_currentAngle ) ) >> 12 ); + + m_angularDistance += 64 * _frames; + + if ( m_angularDistance > 4095 ) + { + m_controlFunc = NPC_CONTROL_MOVEMENT; + m_timerFunc = NPC_TIMER_ATTACK_DONE; + m_timerTimer = GameState::getOneSecondInFrames(); + m_sensorFunc = NPC_SENSOR_NONE; + } +} \ No newline at end of file diff --git a/source/enemy/nsdart.h b/source/enemy/nsdart.h index 19c8ef057..a1f3508a8 100644 --- a/source/enemy/nsdart.h +++ b/source/enemy/nsdart.h @@ -27,6 +27,13 @@ public: virtual void fireAsProjectile( s16 heading ); protected: virtual s32 getFrameShift( int _frames ); + virtual bool processSensor(); + virtual void processClose( int _frames ); + + DVECTOR m_circleCentre; + s16 m_angularDistance; + s16 m_startAngle; + s32 m_circleRadius; }; #endif diff --git a/source/enemy/nsjback.cpp b/source/enemy/nsjback.cpp index 5b160f369..c4b4e606c 100644 --- a/source/enemy/nsjback.cpp +++ b/source/enemy/nsjback.cpp @@ -267,3 +267,97 @@ void CNpcSmallJellyfishBackgroundEnemy::render() } } } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +u8 CNpcSmallJellyfishBackgroundEnemy::hasBeenAttacked() +{ + // do nothing + + return( false ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void CNpcSmallJellyfishBackgroundEnemy::collidedWith( CThing *_thisThing ) +{ + // do nothing + /*if ( m_isActive && !m_isCaught && !m_isDying ) + { + switch(_thisThing->getThingType()) + { + case TYPE_PLAYER: + { + CPlayer *player = (CPlayer *) _thisThing; + + ATTACK_STATE playerState = player->getAttackState(); + + if(playerState==ATTACK_STATE__NONE) + { + if ( !player->isRecoveringFromHit() ) + { + switch( m_data[m_type].detectCollision ) + { + case DETECT_NO_COLLISION: + { + // ignore + + break; + } + + case DETECT_ALL_COLLISION: + { + m_oldControlFunc = m_controlFunc; + m_controlFunc = NPC_CONTROL_COLLISION; + + processUserCollision( _thisThing ); + + break; + } + + case DETECT_ATTACK_COLLISION_GENERIC: + { + processAttackCollision(); + processUserCollision( _thisThing ); + + break; + } + } + } + } + else + { + // player is attacking, respond appropriately + + if ( m_controlFunc != NPC_CONTROL_SHOT ) + { + if(playerState==ATTACK_STATE__BUTT_BOUNCE) + { + player->justButtBouncedABadGuy(); + } + m_controlFunc = NPC_CONTROL_SHOT; + m_state = NPC_GENERIC_HIT_CHECK_HEALTH; + } + } + + break; + } + + case TYPE_ENEMY: + { + CNpcEnemy *enemy = (CNpcEnemy *) _thisThing; + + if ( canCollideWithEnemy() && enemy->canCollideWithEnemy() ) + { + processEnemyCollision( _thisThing ); + } + + break; + } + + default: + ASSERT(0); + break; + } + }*/ +} diff --git a/source/enemy/nsjback.h b/source/enemy/nsjback.h index ce9f9a8d0..8ae22a421 100644 --- a/source/enemy/nsjback.h +++ b/source/enemy/nsjback.h @@ -24,11 +24,13 @@ public: virtual void render(); virtual void postInit(); virtual void setTargetHeading( s16 newTargetHeading ) {m_targetHeading = newTargetHeading;} + virtual u8 hasBeenAttacked(); protected: virtual bool processSensor(); virtual void processMovement( int _frames ); virtual void shutdown(); virtual void processUserCollision( CThing *thisThing ); + virtual void collidedWith(CThing *_thisThing); s16 m_targetHeading; }; diff --git a/source/platform/pclam.cpp b/source/platform/pclam.cpp index ad33dba44..8a197b365 100644 --- a/source/platform/pclam.cpp +++ b/source/platform/pclam.cpp @@ -28,13 +28,13 @@ void CNpcClamPlatform::render() { + CNpcPlatform::render(); + if (canRender()) { - //CNpcPlatform::render(); - + #if defined (__USER_paul__) || defined (__USER_charles__) DVECTOR &renderPos=getRenderPos(); - #if defined (__USER_paul__) || defined (__USER_charles__) DVECTOR offset = CLevel::getCameraPos(); DVECTOR size; DVECTOR centre; diff --git a/source/projectl/projectl.cpp b/source/projectl/projectl.cpp index 5eea17be9..b4e747197 100644 --- a/source/projectl/projectl.cpp +++ b/source/projectl/projectl.cpp @@ -570,9 +570,10 @@ void CPlayerProjectile::collidedWith(CThing *_thisThing) { CNpcEnemy *enemy = (CNpcEnemy *) _thisThing; - enemy->hasBeenAttacked(); - - setToShutdown(); + if ( enemy->hasBeenAttacked() ) + { + setToShutdown(); + } break; }