diff --git a/source/platform/pfblock.cpp b/source/platform/pfblock.cpp index a01a3d838..c50845adc 100644 --- a/source/platform/pfblock.cpp +++ b/source/platform/pfblock.cpp @@ -155,6 +155,56 @@ CRECT const &collisionArea=getCollisionArea(); m_contact = true; } + else + { + DVECTOR shove; + int leftDist = playerCollisionArea.x2 - collisionArea.x1; + int rightDist = collisionArea.x2 - playerCollisionArea.x1; + + if ( leftDist < rightDist ) + { + shove.vx = -leftDist; + } + else + { + shove.vx = rightDist; + } + shove.vy = 0; + + player->shove( shove ); + } + } + else + { + int testPosY; + + testPosY = playerPos.vy - CPlayer::HEIGHT_FOR_HEAD_COLLISION; + + if ( testPosY >= collisionArea.y1 && testPosY <= collisionArea.y2 ) + { + // player's head is colliding with platform, but feet aren't + + player->forceFall(); + + if ( collisionArea.y2 - testPosY > 8 ) + { + DVECTOR shove; + int leftDist = playerCollisionArea.x2 - collisionArea.x1; + int rightDist = collisionArea.x2 - playerCollisionArea.x1; + + if ( leftDist < rightDist ) + { + shove.vx = -leftDist; + } + else + { + shove.vx = rightDist; + } + shove.vy = 0; + + player->shove( shove ); + } + } } } } diff --git a/source/player/player.cpp b/source/player/player.cpp index db76bf7c0..3b4ed635f 100644 --- a/source/player/player.cpp +++ b/source/player/player.cpp @@ -2722,6 +2722,29 @@ void CPlayer::setLockoutPlatform(CThing *_newPlatform) +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CPlayer::forceFall() +{ + if(m_currentMode!=PLAYER_MODE_DEAD) + { + if ( m_currentPlayerModeClass->getState() != STATE_FALL ) + { + m_currentPlayerModeClass->setState(STATE_FALL); + DVECTOR moveVel; + + moveVel=*getMoveVelocity(); + moveVel.vy=0; + m_fallFrames=0; + setMoveVelocity(&moveVel); + } + } +} + /*---------------------------------------------------------------------- Function: Purpose: @@ -2853,19 +2876,40 @@ int CPlayer::moveVertical(int _moveDistance) blockAfter[i+1]=CGameScene::getCollision()->getCollisionBlock(x,y+_moveDistance); } + bool isGoingToFall = false; + // See if either side is about to go through the ground for(i=0;i<3;i++) { if(colHeightBefore[i]>=0&&colHeightAfter[i]<=0&&((blockAfter[i]&COLLISION_TYPE_MASK)!=COLLISION_TYPE_FLAG_NORMAL)) { - //moveRequired[i]=16+colHeightAfter[i]; - moveRequired[i]=colHeightAfter[i]; + moveRequired[i]=16+colHeightAfter[i]; + //moveRequired[i]=colHeightAfter[i]; // hitGround=true; // do not call hitground code, because this will set it to STATE_IDLE for a frame // instead, do the appropriate stuff for a fall - if(!hitThisSuspectBlock)hitThisSuspectBlock=blockAfter[i]; + + isGoingToFall = true; + } + else + { + moveRequired[i]=0; + } + } + + if ( isGoingToFall ) + { + // check where feet are + + if ( getHeightFromGround(pos.vx, pos.vy, 16 ) == 0 ) + { + // standing on ground, hence do not fall + hitGround = true; + } + else + { m_currentPlayerModeClass->setState(STATE_FALL); DVECTOR moveVel; @@ -2874,10 +2918,6 @@ int CPlayer::moveVertical(int _moveDistance) m_fallFrames=0; setMoveVelocity(&moveVel); } - else - { - moveRequired[i]=0; - } } // Find the smallest move required to hit ground diff --git a/source/player/player.h b/source/player/player.h index f81e4460b..64c9d42cb 100644 --- a/source/player/player.h +++ b/source/player/player.h @@ -233,6 +233,7 @@ public: void buttFall(); // " " " " " virtual int moveVertical(int _moveDistance); virtual int moveHorizontal(int _moveDistance); + void forceFall(); int isTryingToConversateWithFriend() {return m_allowConversation;}