diff --git a/source/level/layercollision.cpp b/source/level/layercollision.cpp index 2b61cc48c..0acd4791a 100644 --- a/source/level/layercollision.cpp +++ b/source/level/layercollision.cpp @@ -288,7 +288,8 @@ int CLayerCollision::getHeightFromGroundCart(int _x,int _y,int _maxHeight) distanceFromGround=0; colHeight=s_collisionTable[((Map[mapX+mapY]&COLLISION_TILE_MASK)*16)+xFraction]; - if ( (Map[mapX+mapY] & COLLISION_TYPE_MASK) == COLLISION_TYPE_FLAG_DAMAGE ) + if ( (Map[mapX+mapY] & COLLISION_TYPE_MASK) == COLLISION_TYPE_FLAG_DAMAGE || + (Map[mapX+mapY] & COLLISION_TYPE_MASK) == COLLISION_TYPE_FLAG_DEATH_FALL ) { colHeight = 0; } @@ -305,7 +306,8 @@ int CLayerCollision::getHeightFromGroundCart(int _x,int _y,int _maxHeight) return -_maxHeight; } colHeight=s_collisionTable[((Map[mapX+mapY]&COLLISION_TILE_MASK)*16)+xFraction]; - if ( (Map[mapX+mapY] & COLLISION_TYPE_MASK) == COLLISION_TYPE_FLAG_DAMAGE ) + if ( (Map[mapX+mapY] & COLLISION_TYPE_MASK) == COLLISION_TYPE_FLAG_DAMAGE || + (Map[mapX+mapY] & COLLISION_TYPE_MASK) == COLLISION_TYPE_FLAG_DEATH_FALL ) { colHeight = 0; } @@ -327,7 +329,8 @@ int CLayerCollision::getHeightFromGroundCart(int _x,int _y,int _maxHeight) return _maxHeight; } colHeight=s_collisionTable[((Map[mapX+mapY]&COLLISION_TILE_MASK)*16)+xFraction]; - if ( (Map[mapX+mapY] & COLLISION_TYPE_MASK) == COLLISION_TYPE_FLAG_DAMAGE ) + if ( (Map[mapX+mapY] & COLLISION_TYPE_MASK) == COLLISION_TYPE_FLAG_DAMAGE || + (Map[mapX+mapY] & COLLISION_TYPE_MASK) == COLLISION_TYPE_FLAG_DEATH_FALL ) { colHeight = 0; } diff --git a/source/platform/pcart.cpp b/source/platform/pcart.cpp index c9ec3ece6..6ca1a1815 100644 --- a/source/platform/pcart.cpp +++ b/source/platform/pcart.cpp @@ -45,8 +45,10 @@ void CNpcCartPlatform::postInit() calculateNonRotatedCollisionData(); m_playerAttached = false; + m_falling = false; m_rebound = false; m_reboundTimer = 0; + m_inJump = false; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -67,7 +69,7 @@ void CNpcCartPlatform::processMovement( int _frames ) m_reboundTimer -= _frames; } - if ( !m_playerAttached ) + if ( !m_playerAttached && !m_falling ) { m_playerAttached = true; CPlayer *player = GameScene.getPlayer(); @@ -83,15 +85,37 @@ void CNpcCartPlatform::processMovement( int _frames ) if ( m_isActivated ) { - if ( m_rebound ) + if ( m_falling ) + { + m_vertSpeed += 192; + + if ( m_vertSpeed > ( 8 << 8 ) ) + { + m_vertSpeed = 8 << 8; + } + + moveY = ( m_vertSpeed >> 8 ) * _frames; + + Pos.vy += moveY; + + DVECTOR offset = CLevel::getCameraPos(); + + s32 yPos = Pos.vy - offset.vy; + + if ( yPos < 0 || yPos > VidGetScrH() ) + { + setToShutdown(); + } + } + else if ( m_rebound ) { moveX = -4 * _frames; m_vertSpeed += 192; - if ( m_vertSpeed > ( 5 << 8 ) ) + if ( m_vertSpeed > ( 8 << 8 ) ) { - m_vertSpeed = 5 << 8; + m_vertSpeed = 8 << 8; } else if ( m_vertSpeed < -( 6 << 8 ) ) { @@ -142,9 +166,9 @@ void CNpcCartPlatform::processMovement( int _frames ) moveY = ( m_vertSpeed >> 8 ) * _frames; - groundHeight = CGameScene::getCollision()->getHeightFromGroundCart( Pos.vx + moveX, Pos.vy + moveY, 16 ); + groundHeight = CGameScene::getCollision()->getHeightFromGroundCart( Pos.vx + moveX, Pos.vy, moveY + 16 ); - if ( groundHeight < 0 ) + if ( groundHeight < moveY ) { // have touched down @@ -186,9 +210,9 @@ void CNpcCartPlatform::processMovement( int _frames ) { m_carSpeed += 20; - if ( m_carSpeed > ( 6 << 8 ) ) + if ( m_carSpeed > ( 5 << 8 ) ) { - m_carSpeed = ( 6 << 8 ); + m_carSpeed = ( 5 << 8 ); } } } @@ -234,23 +258,31 @@ void CNpcCartPlatform::processMovement( int _frames ) setCollisionAngle( heading ); - if ( m_reboundTimer <= 0 ) + switch ( CGameScene::getCollision()->getCollisionBlock( testPos2.vx, testPos2.vy - 8 ) & COLLISION_TYPE_MASK ) { - switch ( CGameScene::getCollision()->getCollisionBlock( testPos2.vx, testPos2.vy - 8 ) & COLLISION_TYPE_MASK ) + case COLLISION_TYPE_FLAG_DAMAGE: { - case COLLISION_TYPE_FLAG_DAMAGE: + if ( m_reboundTimer <= 0 ) { m_vertSpeed = -8 << 8; m_reboundTimer = 2 * GameState::getOneSecondInFrames(); m_rebound = true; Pos.vy -= 8; - - break; } - default: - break; + break; } + + case COLLISION_TYPE_FLAG_DEATH_FALL: + { + m_playerAttached = false; + m_falling = true; + + break; + } + + default: + break; } } else @@ -319,62 +351,65 @@ void CNpcCartPlatform::jump() void CNpcCartPlatform::collidedWith( CThing *_thisThing ) { - switch(_thisThing->getThingType()) + if ( !m_falling ) { - case TYPE_PLAYER: + switch(_thisThing->getThingType()) { - CPlayer *player; - DVECTOR playerPos; - CRECT collisionArea; - - // Only interested in SBs feet colliding with the box (pkg) - player=(CPlayer*)_thisThing; - playerPos=player->getPos(); - collisionArea=getCollisionArea(); - - s32 threshold = abs( collisionArea.y2 - collisionArea.y1 ); - - if ( threshold > 16 ) + case TYPE_PLAYER: { - threshold = 16; - } + CPlayer *player; + DVECTOR playerPos; + CRECT collisionArea; - if( playerPos.vx >= collisionArea.x1 && playerPos.vx <= collisionArea.x2 ) - { - if ( checkCollisionDelta( _thisThing, threshold, collisionArea ) ) + // Only interested in SBs feet colliding with the box (pkg) + player=(CPlayer*)_thisThing; + playerPos=player->getPos(); + collisionArea=getCollisionArea(); + + s32 threshold = abs( collisionArea.y2 - collisionArea.y1 ); + + if ( threshold > 16 ) { - player->setPlatform( this ); - - m_contact = true; + threshold = 16; } - else + + if( playerPos.vx >= collisionArea.x1 && playerPos.vx <= collisionArea.x2 ) { - if( playerPos.vy >= collisionArea.y1 && playerPos.vy <= collisionArea.y2 ) + if ( checkCollisionDelta( _thisThing, threshold, collisionArea ) ) { - if ( m_isActivated || player->getPosDelta().vy >= 0 ) + player->setPlatform( this ); + + m_contact = true; + } + else + { + if( playerPos.vy >= collisionArea.y1 && playerPos.vy <= collisionArea.y2 ) { - int height = getHeightFromPlatformAtPosition( playerPos.vx, playerPos.vy ); - - if ( height >= -threshold && height < 1 ) + if ( m_isActivated || player->getPosDelta().vy >= 0 ) { - player->setPlatform( this ); + int height = getHeightFromPlatformAtPosition( playerPos.vx, playerPos.vy ); - m_contact = true; + if ( height >= -threshold && height < 1 ) + { + player->setPlatform( this ); + + m_contact = true; + } } } } } + + break; } - break; + case TYPE_NPC: + case TYPE_HAZARD: + break; + + default: + ASSERT(0); + break; } - - case TYPE_NPC: - case TYPE_HAZARD: - break; - - default: - ASSERT(0); - break; } } diff --git a/source/platform/pcart.h b/source/platform/pcart.h index a7f1ac230..c3d883a00 100644 --- a/source/platform/pcart.h +++ b/source/platform/pcart.h @@ -25,6 +25,7 @@ public: void render(); u8 isCart() {return( true );} void jump(); + bool alwaysThink() {return(true);} protected: void processMovement( int _frames ); void collidedWith(CThing *_thisThing); @@ -35,6 +36,7 @@ protected: s32 m_vertSpeed; u8 m_playerAttached; u8 m_rebound; + u8 m_falling; s32 m_reboundTimer; };