diff --git a/source/enemy/ngeneric.cpp b/source/enemy/ngeneric.cpp index 62a85057d..453f824df 100644 --- a/source/enemy/ngeneric.cpp +++ b/source/enemy/ngeneric.cpp @@ -222,7 +222,7 @@ void CNpcEnemy::processGenericFixedPathMove( int _frames, s32 *moveX, s32 *moveY *moveVel = ( _frames * m_data[m_type].speed ) << 8; - processGroundCollisionReverse( moveX, moveY ); + //processGroundCollisionReverse( moveX, moveY ); } } diff --git a/source/enemy/npc.cpp b/source/enemy/npc.cpp index 8dfdcfaf3..785367673 100644 --- a/source/enemy/npc.cpp +++ b/source/enemy/npc.cpp @@ -209,7 +209,7 @@ void CNpcEnemy::init() { CEnemyThing::init(); - m_type = NPC_CLAM_STATIC; + m_type = NPC_LINEAR_PLATFORM; // sActorHdr *Hdr = m_skel.Load( m_data[m_type].skelType ); // m_skel.Init( Hdr ); @@ -256,25 +256,25 @@ void CNpcEnemy::init() newPos.vx = 100; //newPos.vy = 10; - newPos.vy = 400; + newPos.vy = 100; m_npcPath.addWaypoint( newPos ); newPos.vx = 500; //newPos.vy = 10; - newPos.vy = 400; + newPos.vy = 100; m_npcPath.addWaypoint( newPos ); newPos.vx = 500; //newPos.vy = 100; - newPos.vy = 350; + newPos.vy = 300; m_npcPath.addWaypoint( newPos ); newPos.vx = 100; //newPos.vy = 100; - newPos.vy = 350; + newPos.vy = 300; m_npcPath.addWaypoint( newPos ); @@ -527,8 +527,19 @@ void CNpcEnemy::collidedWith( CThing *_thisThing ) { if ( m_data[m_type].detectCollision ) { - m_oldControlFunc = m_controlFunc; - m_controlFunc = NPC_CONTROL_COLLISION; + if ( m_data[m_type].damageToUserType == DAMAGE__NONE ) + { + // if we can detect a collision, but the collision does no damage, this must be a platform + + CPlayer *player = (CPlayer *) _thisThing; + + player->setPlatform( this ); + } + else + { + m_oldControlFunc = m_controlFunc; + m_controlFunc = NPC_CONTROL_COLLISION; + } } break; diff --git a/source/enemy/npcdata.cpp b/source/enemy/npcdata.cpp index a567e2901..3a2cd5c27 100644 --- a/source/enemy/npcdata.cpp +++ b/source/enemy/npcdata.cpp @@ -174,8 +174,9 @@ CNpcEnemy::NPC_DATA CNpcEnemy::m_data[NPC_UNIT_TYPE_MAX] = NPC_TIMER_NONE, false, 3, - 128, - false, + //512, + 2048, + true, DAMAGE__NONE, 0, }, diff --git a/source/player/player.cpp b/source/player/player.cpp index bc516d0a1..b01b5b40e 100644 --- a/source/player/player.cpp +++ b/source/player/player.cpp @@ -204,6 +204,9 @@ void CPlayer::init() CPlayerThing::init(); m_layerCollision=NULL; + + m_onPlatform = false; + m_prevOnPlatform = false; m_skel.Init(ACTORS_SPONGEBOB_A3D); TPLoadTex(ACTORS_ACTOR_SPONGEBOB_TEX); @@ -416,7 +419,9 @@ if(PadGetDown(0)&PAD_CIRCLE) void CPlayer::thinkVerticalMovement() { int colHeight; + colHeight=m_layerCollision->getHeightFromGround(Pos.vx,Pos.vy,1); + if(colHeight>=0) { // Above or on the ground @@ -425,6 +430,7 @@ void CPlayer::thinkVerticalMovement() { // Yes.. Check to see if we're about to hit/go through the ground colHeight=m_layerCollision->getHeightFromGround(Pos.vx,Pos.vy+(m_moveVel.vy>>VELOCITY_SHIFT),PLAYER_TERMINAL_VELOCITY+1); + if(colHeight<=0) { // Just hit the ground @@ -468,7 +474,11 @@ void CPlayer::thinkVerticalMovement() m_currentState!=STATE_JUMP) { // Was floating in the air.. fall! - setState(STATE_FALL); + + if ( !m_onPlatform ) + { + setState(STATE_FALL); + } } } } @@ -1307,5 +1317,134 @@ PLAYERINPUT CPlayer::readPadInput() return input; } +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CPlayer::clearPlatform() +{ + m_prevOnPlatform = m_onPlatform; + m_onPlatform = false; +} + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CPlayer::setPlatform( CThing *newPlatform ) +{ + int colHeight; + int platformHeight; + + m_platform = newPlatform; + m_onPlatform = true; + + if ( m_onPlatform ) + { + colHeight = m_layerCollision->getHeightFromGround( Pos.vx, Pos.vy, 16 ); + + platformHeight = m_platform->getPos().vy - Pos.vy; + + if ( platformHeight > colHeight ) + { + m_onPlatform = false; + } + else + { + colHeight = platformHeight; + } + } + + if ( m_onPlatform ) + { + // have collided with a platform + + m_moveVel.vy=0; + Pos.vy += colHeight; + + if ( !m_prevOnPlatform ) + { + if( m_currentMode != PLAYER_MODE_BALLOON ) + { + m_fallFrames=0; + + if(m_currentState==STATE_BUTTFALL) + { + // Landed from a butt bounce + setState(STATE_BUTTLAND); + } + else if(m_currentState==STATE_FALLFAR) + { + // Landed from a painfully long fall + setState(STATE_IDLE); + takeDamage(DAMAGE__FALL); + m_moveVel.vx=0; + CSoundMediator::playSfx(CSoundMediator::SFX_SPONGEBOB_LAND_AFTER_FALL); + } + else if(m_moveVel.vx) + { + // Landed from a jump with x movement + setState(STATE_RUN); + } + else + { + // Landed from a jump with no x movement + setState(STATE_IDLE); + setAnimNo(ANIM_SPONGEBOB_JUMPEND); + } + } + } + else + { + Pos.vx += m_platform->getPos().vx - m_prevPlatformPos.vx; + } + + // Move the camera offset + m_playerScreenGeomPos.vx=SCREEN_GEOM_PLAYER_OFS_X+((MAP2D_BLOCKSTEPSIZE*m_cameraScrollPos.vx)>>8); + m_playerScreenGeomPos.vy=SCREEN_GEOM_PLAYER_OFS_Y+((MAP2D_BLOCKSTEPSIZE*m_cameraScrollPos.vy)>>8); + m_cameraOffset.vx=MAP2D_CENTRE_X+((MAP2D_BLOCKSTEPSIZE*(-m_cameraScrollPos.vx))>>8); + m_cameraOffset.vy=MAP2D_CENTRE_Y+((MAP2D_BLOCKSTEPSIZE*(-m_cameraScrollPos.vy))>>8); + + + m_cameraPos.vx=Pos.vx+m_cameraOffset.vx; + m_cameraPos.vy=Pos.vy+m_cameraOffset.vy; + + + // Limit camera scroll to the edges of the map + if(m_cameraPos.vx<0) + { + m_playerScreenGeomPos.vx+=m_cameraPos.vx; + m_cameraPos.vx=0; + m_cameraScrollDir=0; + } + else if(m_cameraPos.vx>m_mapCameraEdges.vx) + { + m_playerScreenGeomPos.vx-=m_mapCameraEdges.vx-m_cameraPos.vx; + m_cameraPos.vx=m_mapCameraEdges.vx; + m_cameraScrollDir=0; + } + if(m_cameraPos.vy<0) + { + m_playerScreenGeomPos.vy+=m_cameraPos.vy; + m_cameraPos.vy=0; + m_cameraScrollDir=0; + } + else if(m_cameraPos.vy>m_mapCameraEdges.vy) + { + m_playerScreenGeomPos.vy-=m_mapCameraEdges.vy-m_cameraPos.vy; + m_cameraPos.vy=m_mapCameraEdges.vy; + m_cameraScrollDir=0; + } + + this->updateCollisionArea(); + + m_prevPlatformPos = m_platform->getPos(); + } +} + /*=========================================================================== end */ diff --git a/source/player/player.h b/source/player/player.h index 6e0d7d625..1a8344164 100644 --- a/source/player/player.h +++ b/source/player/player.h @@ -320,6 +320,16 @@ private: int m_glassesFlag; int m_squeakyBootsTimer; int m_invinvibilityRingTimer; + + // Platforms +public: + void setPlatform( CThing *newPlatform ); + void clearPlatform(); +private: + CThing *m_platform; + bool m_onPlatform; + bool m_prevOnPlatform; + DVECTOR m_prevPlatformPos; }; diff --git a/source/thing/thing.cpp b/source/thing/thing.cpp index 0340e9a33..bbe044069 100644 --- a/source/thing/thing.cpp +++ b/source/thing/thing.cpp @@ -17,6 +17,13 @@ #include "thing\thing.h" +#ifndef __PLAYER_PLAYER_H__ +#include "player\player.h" +#endif + +#ifndef __GAME_GAME_H__ +#include "game\game.h" +#endif /* Std Lib ------- */ @@ -109,6 +116,13 @@ void CThingManager::thinkAllThings(int _frames) } } + CPlayer *player = GameScene.getPlayer(); + + if ( player ) + { + player->clearPlatform(); + } + // Player -> Pickup collision thing1=s_thingLists[CThing::TYPE_PICKUP]; thing2=s_thingLists[CThing::TYPE_PLAYER]; @@ -307,7 +321,7 @@ void CThing::think(int _frames) Params: Returns: ---------------------------------------------------------------------- */ -#ifdef __USER_paul__ +#if defined (__USER_paul__) || defined (__USER_charles__) int showthings=true; #include "gfx\prim.h" #include "level\level.h"