diff --git a/Graphics/characters/GiantWorm/AnimList.Txt b/Graphics/characters/GiantWorm/AnimList.Txt index e69de29bb..8a29b5cbd 100644 --- a/Graphics/characters/GiantWorm/AnimList.Txt +++ b/Graphics/characters/GiantWorm/AnimList.Txt @@ -0,0 +1,2 @@ +bodystatic +headstatic \ No newline at end of file diff --git a/data/DataCache.scr b/data/DataCache.scr index 2cc63fd9a..ac4494d89 100644 --- a/data/DataCache.scr +++ b/data/DataCache.scr @@ -188,6 +188,7 @@ actors/SKELETALFISH.SBK actors/SPIDERCRAB.SBK actors/SPIKEYANENOME.SBK actors/STOMPER.SBK +actors/GIANTWORM.SBK actors/SHARKSUB.SBK actors/MOTHERJELLYFISH.SBK diff --git a/makefile.gaz b/makefile.gaz index aa8c3de6e..5c1142d80 100644 --- a/makefile.gaz +++ b/makefile.gaz @@ -85,7 +85,8 @@ enemy_src := npc \ nsjback \ nsj2back \ nbuttfly \ - nshell + nshell \ + nssnake friend_src := friend \ fdata \ diff --git a/makefile.gfx b/makefile.gfx index 6fb8e0c20..2b54e3f6d 100644 --- a/makefile.gfx +++ b/makefile.gfx @@ -113,9 +113,9 @@ ACTOR_NPC := BarnacleBoy Krusty Squidward Gary Sandy Patrick MermaidMan ACTOR_ENEMY := Anenome BabyOctopus Ballblob Caterpillar clam Dustdevil \ Flamingskull FlyingDutchman Ghost HermitCrab IronDogFish \ PuffaFish Sharkman Skeletalfish SpiderCrab SpikeyAnenome Stomper \ - SharkSub Motherjellyfish SeaSnake + SharkSub Motherjellyfish SeaSnake GiantWorm -# Boogermonster GiantWorm Jellyfish2 Motherjellyfish Nautilus Neptune SeaSnake SharkSub +# Boogermonster Nautilus Neptune ACTOR_SPRITES := Jellyfish1 Squiddart Plankton Butterfly Shell Eyeball diff --git a/source/enemy/npcdata.cpp b/source/enemy/npcdata.cpp index 323f03ecb..61a824534 100644 --- a/source/enemy/npcdata.cpp +++ b/source/enemy/npcdata.cpp @@ -107,6 +107,10 @@ #include #endif +#ifndef __ANIM_GIANTWORM_HEADER__ +#include +#endif + CNpcEnemy::NPC_DATA CNpcEnemy::m_data[NPC_UNIT_TYPE_MAX] = { { // NPC_DUST_DEVIL @@ -410,8 +414,8 @@ CNpcEnemy::NPC_DATA CNpcEnemy::m_data[NPC_UNIT_TYPE_MAX] = }, { // NPC_SEA_SNAKE - ACTORS_CLAM_SBK, - ANIM_CLAM_SIDESNAP, + ACTORS_SEASNAKE_SBK, + ANIM_SEASNAKE_HEADSTATIC, NPC_SENSOR_NONE, NPC_MOVEMENT_FIXED_PATH, NPC_CLOSE_NONE, @@ -910,8 +914,8 @@ CNpcEnemy::NPC_DATA CNpcEnemy::m_data[NPC_UNIT_TYPE_MAX] = }, { // NPC_PARASITIC_WORM - ACTORS_SEASNAKE_SBK, - ANIM_SEASNAKE_HEADSTATIC, + ACTORS_GIANTWORM_SBK, + ANIM_GIANTWORM_HEADSTATIC, NPC_SENSOR_USER_CLOSE, NPC_MOVEMENT_STATIC, NPC_CLOSE_NONE, @@ -985,8 +989,8 @@ CNpcEnemy::NPC_DATA CNpcEnemy::m_data[NPC_UNIT_TYPE_MAX] = }, { // NPC_PARASITIC_WORM_SEGMENT - ACTORS_SEASNAKE_SBK, - ANIM_SEASNAKE_BODYSTATIC, + ACTORS_GIANTWORM_SBK, + ANIM_GIANTWORM_BODYSTATIC, NPC_SENSOR_NONE, NPC_MOVEMENT_STATIC, NPC_CLOSE_NONE, diff --git a/source/enemy/nssnake.h b/source/enemy/nssnake.h index e05bdf29f..98a581d75 100644 --- a/source/enemy/nssnake.h +++ b/source/enemy/nssnake.h @@ -11,11 +11,74 @@ ===========================================================================*/ -#ifndef __ENEMY_NSSNAKE_H__ -#define __ENEMY_NSSNAKE_H__ +#ifndef __ENEMY_NSSNAKE_H__ +#define __ENEMY_NSSNAKE_H__ + +class CNpcSeaSnakeSegment +{ +public: + virtual void init(); + virtual void shutdown(); + virtual void render(); + virtual void processEnemyCollision( CThing *thisThing ); + virtual void setScale( u16 scale ) {m_scale = scale;} + CNpcSeaSnakeSegment *m_nextSegment; + virtual void setPos( DVECTOR newPos ) {Pos = newPos;} + virtual DVECTOR getPos() {return( Pos );} + virtual void setHeading( s16 newHeading ) {m_heading = newHeading;} + void updateCollisionArea(); + virtual int checkCollisionAgainst(CThing *_thisThing, int _frames); + virtual void setCollisionSize(int _w,int _h); + virtual void setCollisionCentreOffset(int _x,int _y) {m_collisionCentreOffset.vx=_x;m_collisionCentreOffset.vy=_y;} + virtual CRECT const &getCollisionArea() {return m_collisionArea;} + DVECTOR const &getCollisionCentre() {return m_collisionCentre;} + int getCollisionRadius() {return m_collisionRadius;} + +protected: + u16 m_scale; + CActorGfx *m_actorGfx; + DVECTOR Pos; + s16 m_heading; + CRECT m_collisionArea; + DVECTOR m_collisionCentre; + DVECTOR m_collisionCentreOffset; + DVECTOR m_collisionSize; + int m_collisionRadius; +}; class CNpcSeaSnakeEnemy : public CNpcEnemy { +public: + virtual void postInit(); + virtual void shutdown(); + virtual void render(); + virtual int checkCollisionAgainst(CThing *_thisThing, int _frames); +protected: + virtual bool processSensor(); + virtual void processClose( int _frames ); + virtual void processMovement( int _frames ); + virtual void processShot( int _frames ); + virtual void processEnemyCollision( CThing *thisThing ); + + enum + { + NPC_SEA_SNAKE_SPACING = 4, + NPC_SEA_SNAKE_LENGTH = 10, + }; + + // position history stuff + + class CNpcPositionHistory + { + public: + DVECTOR pos; + CNpcPositionHistory *next; + CNpcPositionHistory *prev; + }; + + CNpcSeaSnakeSegment *m_segment; + CNpcPositionHistory *m_positionHistory; + s32 m_collTimer; }; -#endif +#endif \ No newline at end of file diff --git a/source/enemy/nworm.cpp b/source/enemy/nworm.cpp index 30859cf00..6f43be0ea 100644 --- a/source/enemy/nworm.cpp +++ b/source/enemy/nworm.cpp @@ -35,15 +35,15 @@ #include "gfx\prim.h" #endif -#ifndef __ANIM_SEASNAKE_HEADER__ -#include +#ifndef __ANIM_GIANTWORM_HEADER__ +#include #endif //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CNpcParasiticWormSegment::init() { - m_actorGfx=CActorPool::GetActor( (FileEquate) ACTORS_SEASNAKE_SBK ); + m_actorGfx=CActorPool::GetActor( (FileEquate) ACTORS_GIANTWORM_SBK ); m_heading = 0; m_nextSegment = NULL; @@ -587,7 +587,7 @@ void CNpcParasiticWormSegment::render() if ( renderFlag ) { - SprFrame = m_actorGfx->Render(renderPos,ANIM_SEASNAKE_BODYSTATIC,0,0); + SprFrame = m_actorGfx->Render(renderPos,ANIM_GIANTWORM_BODYSTATIC,0,0); m_actorGfx->RotateScale( SprFrame, renderPos, m_heading, 4096, m_scale ); sBBox boundingBox = m_actorGfx->GetBBox(); @@ -658,55 +658,128 @@ int CNpcParasiticWormSegment::checkCollisionAgainst( CThing *_thisThing, int _fr void CNpcParasiticWormEnemy::processShot( int _frames ) { - if ( !m_segment ) + switch( m_data[m_type].shotFunc ) { - m_drawRotation += 64 * _frames; - m_drawRotation &= 4095; - - Pos.vy += m_speed * _frames; - - if ( m_speed < 5 ) + case NPC_SHOT_NONE: { - m_speed++; + // do nothing + + break; } - DVECTOR offset = CLevel::getCameraPos(); - - if ( Pos.vy - offset.vy > VidGetScrH() ) + case NPC_SHOT_GENERIC: { - setToShutdown(); + switch ( m_state ) + { + case NPC_GENERIC_HIT_CHECK_HEALTH: + { + if ( CLevel::getCurrentChapter() == 1 && CLevel::getCurrentChapterLevel() == 1 ) + { + m_state = NPC_GENERIC_HIT_DEATH_START; + } + else + { + m_health -= 5; + + if ( m_health < 0 ) + { + m_state = NPC_GENERIC_HIT_DEATH_START; + } + else + { + m_state = NPC_GENERIC_HIT_RECOIL; + + m_animPlaying = true; + m_animNo = m_data[m_type].recoilAnim; + m_frame = 0; + } + } + + break; + } + + case NPC_GENERIC_HIT_RECOIL: + { + if ( !m_animPlaying ) + { + m_state = 0; + m_controlFunc = NPC_CONTROL_MOVEMENT; + } + + break; + } + + case NPC_GENERIC_HIT_DEATH_START: + { + m_animPlaying = true; + m_animNo = m_data[m_type].dieAnim; + m_frame = 0; + m_state = NPC_GENERIC_HIT_DEATH_END; + + if ( m_data[m_type].deathSfx < CSoundMediator::NUM_SFXIDS ) + { + CSoundMediator::playSfx( m_data[m_type].deathSfx ); + } + + m_isDying = true; + m_speed = -5; + + if (m_data[m_type].skelType) + { + m_actorGfx->SetOtPos( 0 ); + } + + break; + } + + case NPC_GENERIC_HIT_DEATH_END: + { + m_drawRotation += 64 * _frames; + m_drawRotation &= 4095; + + Pos.vy += m_speed * _frames; + + // go through segments + + CNpcParasiticWormSegment *segment = m_segment; + + while( segment ) + { + DVECTOR segPos = segment->getPos(); + segPos.vy += m_speed * _frames; + segment->setPos( segPos ); + segment->updateCollisionArea(); + + segment = segment->m_nextSegment; + } + + if ( m_speed < 5 ) + { + m_speed++; + } + + DVECTOR offset = CLevel::getCameraPos(); + + if ( Pos.vy - offset.vy > VidGetScrH() ) + { + if ( m_data[m_type].respawning ) + { + m_isActive = false; + + m_timerFunc = NPC_TIMER_RESPAWN; + m_timerTimer = 4 * GameState::getOneSecondInFrames(); + } + else + { + setToShutdown(); + } + } + + break; + } + } + + break; } } - else - { - if ( m_collTimer <= 0 ) - { - // knock segment off end of list - - CNpcParasiticWormSegment *segment = m_segment; - CNpcParasiticWormSegment *oldSegment = segment; - - while( segment->m_nextSegment ) - { - oldSegment = segment; - - segment = segment->m_nextSegment; - } - - delete segment; - - if ( segment == m_segment ) - { - m_segment = NULL; - } - else - { - oldSegment->m_nextSegment = NULL; - } - - m_collTimer = GameState::getOneSecondInFrames(); - } - - m_controlFunc = NPC_CONTROL_MOVEMENT; - } } diff --git a/tools/MapEdit/actor.ini b/tools/MapEdit/actor.ini index 1e6e04d58..91e2a5f19 100644 --- a/tools/MapEdit/actor.ini +++ b/tools/MapEdit/actor.ini @@ -244,7 +244,7 @@ Health=0 AttackStrength=20 [GiantWorm] -Gfx=..\..\graphics\characters\seasnake\render\psx\seasnake_headstatic0000.bmp +Gfx=..\..\graphics\characters\giantworm\render\psx\GiantWorm_headstatic0000.bmp WayPoints=16 Speed=3 TurnRate=128 diff --git a/users/paul/spongebob project/spongebob project.dsp b/users/paul/spongebob project/spongebob project.dsp index e3d5a2156..d2919b00e 100644 --- a/users/paul/spongebob project/spongebob project.dsp +++ b/users/paul/spongebob project/spongebob project.dsp @@ -381,6 +381,10 @@ SOURCE=..\..\..\source\enemy\nsshark.h # End Source File # Begin Source File +SOURCE=..\..\..\source\enemy\nssnake.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\source\enemy\nssnake.h # End Source File # Begin Source File