diff --git a/makefile.gaz b/makefile.gaz index a38228892..e9cf12316 100644 --- a/makefile.gaz +++ b/makefile.gaz @@ -238,6 +238,7 @@ player_src := demoplay \ psfall \ pshitgnd \ psidle \ + psjmpbck \ psjump \ psrun \ psspring diff --git a/source/enemy/npc.cpp b/source/enemy/npc.cpp index 420f54049..a7b1ed852 100644 --- a/source/enemy/npc.cpp +++ b/source/enemy/npc.cpp @@ -1287,7 +1287,7 @@ void CNpcEnemy::processCollision() { CPlayer *player = GameScene.getPlayer(); - player->takeDamage( m_data[m_type].damageToUserType ); + player->takeDamage( m_data[m_type].damageToUserType,REACT__GET_DIRECTION_FROM_THING,(CThing*)this ); processUserCollision( (CThing *) player ); m_controlFunc = m_oldControlFunc; diff --git a/source/player/player.cpp b/source/player/player.cpp index 23542d062..60966b30a 100644 --- a/source/player/player.cpp +++ b/source/player/player.cpp @@ -333,6 +333,7 @@ static s8 s_animMapNet[NUM_PLAYER_ADDONS][NUM_ANIM_SPONGEBOB]= -1, // ANIM_SPONGEBOB_IDLEWEAPON, -1, // ANIM_SPONGEBOB_WALK, -1, // ANIM_SPONGEBOB_KARATE, + ANIM_SPONGEBOB_NET_GETHIT, // ANIM_SPONGEBOB_GETHIT }, // PLAYER_ADDON_CORALBLOWER, @@ -361,6 +362,7 @@ static s8 s_animMapNet[NUM_PLAYER_ADDONS][NUM_ANIM_SPONGEBOB]= ANIM_SPONGEBOB_CORALBLOWER_IDLEWEAPON, // ANIM_SPONGEBOB_IDLEWEAPON, ANIM_SPONGEBOB_CORALBLOWER_WALK, // ANIM_SPONGEBOB_WALK, -1, // ANIM_SPONGEBOB_KARATE, + ANIM_SPONGEBOB_CORALBLOWER_GETHIT, // ANIM_SPONGEBOB_GETHIT }, // PLAYER_ADDON_JELLYLAUNCHER, @@ -389,6 +391,7 @@ static s8 s_animMapNet[NUM_PLAYER_ADDONS][NUM_ANIM_SPONGEBOB]= -1, // ANIM_SPONGEBOB_IDLEWEAPON, -1, // ANIM_SPONGEBOB_WALK, -1, // ANIM_SPONGEBOB_KARATE, + ANIM_SPONGEBOB_JELLYLAUNCHER_GETHIT, // ANIM_SPONGEBOB_GETHIT }, // PLAYER_ADDON_GLASSES, @@ -417,6 +420,7 @@ static s8 s_animMapNet[NUM_PLAYER_ADDONS][NUM_ANIM_SPONGEBOB]= ANIM_SPONGEBOB_GLASSES_IDLEWEAPON, // ANIM_SPONGEBOB_IDLEWEAPON, ANIM_SPONGEBOB_GLASSES_WALK, // ANIM_SPONGEBOB_WALK, ANIM_SPONGEBOB_GLASSES_KARATE, // ANIM_SPONGEBOB_KARATE, + ANIM_SPONGEBOB_GLASSES_GETHIT, // ANIM_SPONGEBOB_GETHIT }, // PLAYER_ADDON_BUBBLEWAND, @@ -445,6 +449,7 @@ static s8 s_animMapNet[NUM_PLAYER_ADDONS][NUM_ANIM_SPONGEBOB]= -1, // ANIM_SPONGEBOB_IDLEWEAPON, -1, // ANIM_SPONGEBOB_WALK, -1, // ANIM_SPONGEBOB_KARATE, + -1, // ANIM_SPONGEBOB_GETHIT }, // PLAYER_ADDON_JELLYFISHINNET @@ -473,6 +478,7 @@ static s8 s_animMapNet[NUM_PLAYER_ADDONS][NUM_ANIM_SPONGEBOB]= -1, // ANIM_SPONGEBOB_IDLEWEAPON, -1, // ANIM_SPONGEBOB_WALK, -1, // ANIM_SPONGEBOB_KARATE, + ANIM_SPONGEBOB_JELLYFISH_GETHIT, // ANIM_SPONGEBOB_GETHIT }, // PLAYER_ADDON_GLOVE @@ -501,6 +507,7 @@ static s8 s_animMapNet[NUM_PLAYER_ADDONS][NUM_ANIM_SPONGEBOB]= -1, // ANIM_SPONGEBOB_IDLEWEAPON, -1, // ANIM_SPONGEBOB_WALK, ANIM_SPONGEBOB_GLOVE_KARATE, // ANIM_SPONGEBOB_KARATE, + -1, // ANIM_SPONGEBOB_GETHIT }, }; @@ -1561,7 +1568,8 @@ void CPlayer::inSoakUpState() /*---------------------------------------------------------------------- Function: Purpose: - Params: + Params: When _reactDirection is REACT__GET_DIRECTION_FROM_THING then + _thing must point to the thing that caused the damage Returns: ---------------------------------------------------------------------- */ #if defined(__USER_daveo__) @@ -1569,7 +1577,7 @@ int invincibleSponge=true; // NB: This is for debugging purposes only so don't #else int invincibleSponge=false; // NB: This is for debugging purposes only so don't try and use it for a permenant cheat mode.. #endif -void CPlayer::takeDamage(DAMAGE_TYPE _damage) +void CPlayer::takeDamage(DAMAGE_TYPE _damage,REACT_DIRECTION _reactDirection,CThing *_thing) { if(m_invincibleFrameCount==0&& // Don't take damage if still recovering from the last hit m_invincibilityRingTimer==0&& // Or if we have the invincibility ring on @@ -1613,35 +1621,41 @@ void CPlayer::takeDamage(DAMAGE_TYPE _damage) if(ouchThatHurt) { int died=false; - if(invincibleSponge){m_invincibleFrameCount=INVINCIBLE_FRAMES__HIT;return;} - if(!isWearingDivingHelmet()) + if(invincibleSponge) { - if(!ouchThatHurtSoMuchThatImJustGoingToDieNow) - { - m_health--; - } - else - { - m_health=-1; - } - if(m_health<0) - { - died=true; - } + m_invincibleFrameCount=INVINCIBLE_FRAMES__HIT; } else { - if(!ouchThatHurtSoMuchThatImJustGoingToDieNow) + if(!isWearingDivingHelmet()) { - m_healthWaterLevel-=WATERHEALTHPART; + if(!ouchThatHurtSoMuchThatImJustGoingToDieNow) + { + m_health--; + } + else + { + m_health=-1; + } + if(m_health<0) + { + died=true; + } } else { - m_health=-1; - } - if(m_healthWaterLevel<0) - { - died=true; + if(!ouchThatHurtSoMuchThatImJustGoingToDieNow) + { + m_healthWaterLevel-=WATERHEALTHPART; + } + else + { + m_health=-1; + } + if(m_healthWaterLevel<0) + { + died=true; + } } } @@ -1651,6 +1665,37 @@ void CPlayer::takeDamage(DAMAGE_TYPE _damage) } else { + if(_reactDirection!=REACT__NO_REACTION) + { + if(_reactDirection==REACT__GET_DIRECTION_FROM_THING) + { + ASSERT(_thing); + if(Pos.vx<_thing->getPos().vx) + { + _reactDirection=REACT__LEFT; + } + else + { + _reactDirection=REACT__RIGHT; + } + } + + m_moveVelocity.vx=((int)_reactDirection); + switch(_reactDirection) + { + case REACT__LEFT: + setFacing(FACING_RIGHT); + break; + case REACT__RIGHT: + setFacing(FACING_LEFT); + break; + case REACT__UP: + case REACT__GET_DIRECTION_FROM_THING: + case REACT__NO_REACTION: + break; + } + m_currentPlayerModeClass->setState(STATE_JUMPBACK); + } m_invincibleFrameCount=INVINCIBLE_FRAMES__HIT; m_healthReactFrames=25; } diff --git a/source/player/player.h b/source/player/player.h index 0ec79af12..a097590b7 100644 --- a/source/player/player.h +++ b/source/player/player.h @@ -78,6 +78,7 @@ typedef enum STATE_DUCK, STATE_SOAKUP, STATE_GETUP, + STATE_JUMPBACK, NUM_STATES, }PLAYER_STATE; @@ -120,6 +121,15 @@ typedef enum DAMAGE__KILL_OUTRIGHT, }DAMAGE_TYPE; +typedef enum +{ + REACT__LEFT=-1, + REACT__UP=0, + REACT__RIGHT=+1, + REACT__GET_DIRECTION_FROM_THING=123, + REACT__NO_REACTION=234, +}REACT_DIRECTION; + // The input from the control pad is remapped to this rather than keeping it in the // normal pad format. This allows us to store all input in one byte ( as opposed to @@ -234,9 +244,9 @@ public: PLAYERINPUT getPadInputHeld() {return m_padInput;} PLAYERINPUT getPadInputDown() {return m_padInputDown;} class CLayerCollision *getLayerCollision() {return m_layerCollision;} - + void inSoakUpState(); - void takeDamage(DAMAGE_TYPE _damage); + void takeDamage(DAMAGE_TYPE _damage,REACT_DIRECTION _reactDirection=REACT__UP,CThing *_thing=NULL); void respawn(); @@ -282,7 +292,7 @@ private: enum { INVINCIBLE_FRAMES__START=200, // Invincible for this many frames at start of life - INVINCIBLE_FRAMES__HIT=100, // Invincible for this many frames after taking damage + INVINCIBLE_FRAMES__HIT=30, // Invincible for this many frames after taking damage }; int m_invincibleFrameCount; // Initial invincibility and also invincibility after taking damage diff --git a/source/player/pmbloon.cpp b/source/player/pmbloon.cpp index 16a24d52d..6efad0b13 100644 --- a/source/player/pmbloon.cpp +++ b/source/player/pmbloon.cpp @@ -69,6 +69,9 @@ static PlayerMetrics s_playerMetrics= DEFAULT_PLAYER_PLAYER_GRAVITY/3, // PM__GRAVITY DEFAULT_PLAYER_TERMINAL_VELOCITY/3, // PM__TERMINAL_VELOCITY DEFAULT_BUTT_FALL_VELOCITY, // PM__BUTT_FALL_VELOCITY + DEFAULT_HITREACT_XVELOCITY, // PM__HITREACT_XVELOCITY + DEFAULT_HITREACT_YVELOCITY, // PM__HITREACT_YVELOCITY + DEFAULT_HITREACT_FRAMES, // PM__HITREACT_FRAMES } }; diff --git a/source/player/pmbubble.cpp b/source/player/pmbubble.cpp index 8f10c5cc1..f13d0f6f1 100644 --- a/source/player/pmbubble.cpp +++ b/source/player/pmbubble.cpp @@ -207,6 +207,7 @@ int CPlayerModeBubbleMixture::canBlowBubbleFromThisState() case STATE_DUCK: case STATE_SOAKUP: case STATE_GETUP: + case STATE_JUMPBACK: break; } diff --git a/source/player/pmchop.cpp b/source/player/pmchop.cpp index c72055cad..8d9007593 100644 --- a/source/player/pmchop.cpp +++ b/source/player/pmchop.cpp @@ -189,6 +189,7 @@ int CPlayerModeChop::canAttackFromThisState() case STATE_DUCK: case STATE_SOAKUP: case STATE_GETUP: + case STATE_JUMPBACK: break; } diff --git a/source/player/pmcoral.cpp b/source/player/pmcoral.cpp index 048aa8c06..a034b6ea0 100644 --- a/source/player/pmcoral.cpp +++ b/source/player/pmcoral.cpp @@ -26,6 +26,10 @@ #include "player\psjump.h" #endif +#ifndef __PLAYER__PSJMPBCK_H__ +#include "player\psjmpbck.h" +#endif + #ifndef __PLAYER__PSRUN_H__ #include "player\psrun.h" #endif @@ -114,6 +118,7 @@ static CPlayerState *s_stateTable[]= NULL, // STATE_DUCK NULL, // STATE_SOAKUP &s_stateGetUp, // STATE_GETUP + &s_stateJumpBack, // STATE_JUMPBACK }; @@ -130,6 +135,9 @@ static PlayerMetrics s_playerMetrics= DEFAULT_PLAYER_PLAYER_GRAVITY, // PM__GRAVITY DEFAULT_PLAYER_TERMINAL_VELOCITY, // PM__TERMINAL_VELOCITY DEFAULT_BUTT_FALL_VELOCITY, // PM__BUTT_FALL_VELOCITY + DEFAULT_HITREACT_XVELOCITY, // PM__HITREACT_XVELOCITY + DEFAULT_HITREACT_YVELOCITY, // PM__HITREACT_YVELOCITY + DEFAULT_HITREACT_FRAMES, // PM__HITREACT_FRAMES } }; diff --git a/source/player/pmjelly.cpp b/source/player/pmjelly.cpp index 674e3655d..e33db632d 100644 --- a/source/player/pmjelly.cpp +++ b/source/player/pmjelly.cpp @@ -195,6 +195,7 @@ int CPlayerModeJellyLauncher::setState(int _state) switch(_state) { case STATE_FALL: + case STATE_JUMPBACK: // Break out of firing state! m_firingState=FIRING_STATE__NONE; break; @@ -254,6 +255,7 @@ int CPlayerModeJellyLauncher::canFireFromThisState() case STATE_DUCK: case STATE_SOAKUP: case STATE_GETUP: + case STATE_JUMPBACK: break; } diff --git a/source/player/pmnet.cpp b/source/player/pmnet.cpp index 1a0395f26..f3b1a6275 100644 --- a/source/player/pmnet.cpp +++ b/source/player/pmnet.cpp @@ -324,6 +324,7 @@ int CPlayerModeNet::canSwingNetFromThisState() case STATE_DUCK: case STATE_SOAKUP: case STATE_GETUP: + case STATE_JUMPBACK: break; } diff --git a/source/player/pmodes.cpp b/source/player/pmodes.cpp index c3f96da84..cb5aa7f50 100644 --- a/source/player/pmodes.cpp +++ b/source/player/pmodes.cpp @@ -34,6 +34,10 @@ #include "player\psjump.h" #endif +#ifndef __PLAYER__PSJMPBCK_H__ +#include "player\psjmpbck.h" +#endif + #ifndef __PLAYER__PSRUN_H__ #include "player\psrun.h" #endif @@ -106,6 +110,7 @@ static CPlayerState *s_stateTable[]= &s_stateDuck, // STATE_DUCK &s_stateSoakUp, // STATE_SOAKUP &s_stateGetUp, // STATE_GETUP + &s_stateJumpBack, // STATE_JUMPBACK }; static PlayerMetrics s_playerMetrics= @@ -120,6 +125,9 @@ static PlayerMetrics s_playerMetrics= DEFAULT_PLAYER_PLAYER_GRAVITY, // PM__GRAVITY DEFAULT_PLAYER_TERMINAL_VELOCITY, // PM__TERMINAL_VELOCITY DEFAULT_BUTT_FALL_VELOCITY, // PM__BUTT_FALL_VELOCITY + DEFAULT_HITREACT_XVELOCITY, // PM__HITREACT_XVELOCITY + DEFAULT_HITREACT_YVELOCITY, // PM__HITREACT_YVELOCITY + DEFAULT_HITREACT_FRAMES, // PM__HITREACT_FRAMES } }; @@ -221,6 +229,7 @@ int CPlayerModeBase::canDoLookAround() case STATE_BUTTLAND: case STATE_DUCK: case STATE_GETUP: + case STATE_JUMPBACK: break; } @@ -255,6 +264,7 @@ ATTACK_STATE CPlayerModeBase::getAttackState() case STATE_DUCK: case STATE_SOAKUP: case STATE_GETUP: + case STATE_JUMPBACK: break; } @@ -275,7 +285,8 @@ void CPlayerModeBase::thinkVerticalMovement() } else if(m_currentState!=STATE_FALL&&m_currentState!=STATE_FALLFAR&& m_currentState!=STATE_BUTTFALL&&m_currentState!=STATE_BUTTBOUNCE&& - m_currentState!=STATE_JUMP&&m_currentState!=STATE_SPRINGUP) + m_currentState!=STATE_JUMP&&m_currentState!=STATE_SPRINGUP&& + m_currentState!=STATE_JUMPBACK) { DVECTOR pos; pos=m_player->getPlayerPos(); @@ -332,7 +343,7 @@ void CPlayerModeBase::playerHasHitGround() { // Landed from a painfully long fall setState(STATE_HITGROUND); - m_player->takeDamage(DAMAGE__FALL); + m_player->takeDamage(DAMAGE__FALL,REACT__NO_REACTION); moveVel.vx=0; } else if(moveVel.vx) @@ -590,6 +601,24 @@ void CPlayerModeBase::jump() moveVel.vy=-getPlayerMetrics()->m_metric[PM__JUMP_VELOCITY]<getMoveVelocity(); + moveVel.vy=-getPlayerMetrics()->m_metric[PM__HITREACT_YVELOCITY]<m_metric[PM__HITREACT_XVELOCITY]<0) + { + moveVel.vx=xvel; + } + setMoveVelocity(&moveVel); +} void CPlayerModeBase::fall() { const PlayerMetrics *metrics; diff --git a/source/player/pmodes.h b/source/player/pmodes.h index 96ec9cd1e..aaee4fc8f 100644 --- a/source/player/pmodes.h +++ b/source/player/pmodes.h @@ -50,6 +50,9 @@ typedef enum PM__GRAVITY, PM__TERMINAL_VELOCITY, PM__BUTT_FALL_VELOCITY, + PM__HITREACT_XVELOCITY, + PM__HITREACT_YVELOCITY, + PM__HITREACT_FRAMES, NUM_PLAYER_METRICS }PLAYER_METRIC; @@ -71,6 +74,9 @@ enum DEFAULT_PLAYER_PLAYER_GRAVITY=2<<2, DEFAULT_PLAYER_TERMINAL_VELOCITY=8, DEFAULT_BUTT_FALL_VELOCITY=14, + DEFAULT_HITREACT_XVELOCITY=5, + DEFAULT_HITREACT_YVELOCITY=3, + DEFAULT_HITREACT_FRAMES=15, }; @@ -89,6 +95,7 @@ public: void inSoakUpState(); virtual int isJellyfishNetFull() {ASSERT(0);return false;} // Fugly.. + virtual int setState(int _state) {return 0;} int getPadInputHeld(); int getPadInputDown(); @@ -155,6 +162,7 @@ public: void moveRight(); int slowdown(); void jump(); + void jumpback(); void fall(); void buttFall(); diff --git a/source/player/psjmpbck.cpp b/source/player/psjmpbck.cpp index 97e07bdf2..df756cff0 100644 --- a/source/player/psjmpbck.cpp +++ b/source/player/psjmpbck.cpp @@ -61,6 +61,7 @@ CPlayerStateJumpBack s_stateJumpBack; + /*---------------------------------------------------------------------- Function: Purpose: @@ -69,10 +70,10 @@ CPlayerStateJumpBack s_stateJumpBack; ---------------------------------------------------------------------- */ void CPlayerStateJumpBack::enter(CPlayerModeBase *_playerMode) { - _playerMode->setAnimNo(ANIM_SPONGEBOB_JUMP); + _playerMode->setAnimNo(ANIM_SPONGEBOB_GETHIT); m_reactFrames=0; - _playerMode->jump(); + _playerMode->jumpback(); CSoundMediator::playSfx(CSoundMediator::SFX_SPONGEBOB_JUMP); } @@ -87,15 +88,13 @@ void CPlayerStateJumpBack::enter(CPlayerModeBase *_playerMode) void CPlayerStateJumpBack::think(CPlayerModeBase *_playerMode) { const PlayerMetrics *metrics; - int controlHeld,controlDown; + int xvel; metrics=_playerMode->getPlayerMetrics(); - controlHeld=_playerMode->getPadInputHeld(); - controlDown=_playerMode->getPadInputDown(); _playerMode->advanceAnimFrameAndCheckForEndOfAnim(); - if(m_reactFrames<=metrics->m_metric[PM__MAX_JUMP_FRAMES]&&controlHeld&PI_JUMP) + if(m_reactFrames<=metrics->m_metric[PM__HITREACT_FRAMES]) { m_reactFrames++; } @@ -103,24 +102,6 @@ void CPlayerStateJumpBack::think(CPlayerModeBase *_playerMode) { _playerMode->setState(STATE_FALL); } - - if(controlHeld&PI_LEFT) - { - _playerMode->moveLeft(); - } - else if(controlHeld&PI_RIGHT) - { - _playerMode->moveRight(); - } - else - { - _playerMode->slowdown(); - } - - if(controlDown&PI_DOWN) - { - _playerMode->setState(STATE_BUTTBOUNCE); - } } diff --git a/source/player/psjmpbck.h b/source/player/psjmpbck.h index 729eb5da7..72b7f657c 100644 --- a/source/player/psjmpbck.h +++ b/source/player/psjmpbck.h @@ -48,7 +48,7 @@ private: Globals ------- */ -extern CPlayerStateJumpBack s_stateJump; +extern CPlayerStateJumpBack s_stateJumpBack; /*---------------------------------------------------------------------- diff --git a/users/paul/spongebob project/spongebob project.dsp b/users/paul/spongebob project/spongebob project.dsp index 719b26c42..bd5217671 100644 --- a/users/paul/spongebob project/spongebob project.dsp +++ b/users/paul/spongebob project/spongebob project.dsp @@ -1435,6 +1435,14 @@ SOURCE=..\..\..\source\player\psidle.h # End Source File # Begin Source File +SOURCE=..\..\..\source\player\psjmpbck.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\source\player\psjmpbck.h +# End Source File +# Begin Source File + SOURCE=..\..\..\source\player\psjump.cpp # End Source File # Begin Source File