diff --git a/src/game/collision.cpp b/src/game/collision.cpp index 5a0a361fcd..2689dfb824 100644 --- a/src/game/collision.cpp +++ b/src/game/collision.cpp @@ -144,7 +144,7 @@ bool CCollision::TestBox(vec2 Pos, vec2 Size, int Flag) const return false; } -void CCollision::MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, float Elasticity, bool *pDeath) const +void CCollision::MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, vec2 Elasticity, bool *pDeath, bool* pGrounded) const { // do the move vec2 Pos = *pInoutPos; @@ -159,6 +159,9 @@ void CCollision::MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, float Elas if(Distance > 0.00001f) { const float Fraction = 1.0f/(Max+1); + float ElasticityX = clamp(Elasticity.x, -1.0f, 1.0f); + float ElasticityY = clamp(Elasticity.y, -1.0f, 1.0f); + for(int i = 0; i <= Max; i++) { vec2 NewPos = Pos + Vel*Fraction; // TODO: this row is not nice @@ -176,15 +179,17 @@ void CCollision::MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, float Elas if(TestBox(vec2(Pos.x, NewPos.y), Size)) { + if(pGrounded && ElasticityY > 0 && Vel.y > 0) + *pGrounded = true; NewPos.y = Pos.y; - Vel.y *= -Elasticity; + Vel.y *= -ElasticityY; Hits++; } if(TestBox(vec2(NewPos.x, Pos.y), Size)) { NewPos.x = Pos.x; - Vel.x *= -Elasticity; + Vel.x *= -ElasticityX; Hits++; } @@ -192,10 +197,12 @@ void CCollision::MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, float Elas // this is a real _corner case_! if(Hits == 0) { + if(pGrounded && ElasticityY > 0 && Vel.y > 0) + *pGrounded = true; NewPos.y = Pos.y; - Vel.y *= -Elasticity; + Vel.y *= -ElasticityY; NewPos.x = Pos.x; - Vel.x *= -Elasticity; + Vel.x *= -ElasticityX; } } diff --git a/src/game/collision.h b/src/game/collision.h index d04833de7e..5d7b52e1c1 100644 --- a/src/game/collision.h +++ b/src/game/collision.h @@ -32,7 +32,7 @@ class CCollision int GetHeight() const { return m_Height; } int IntersectLine(vec2 Pos0, vec2 Pos1, vec2 *pOutCollision, vec2 *pOutBeforeCollision) const; void MovePoint(vec2 *pInoutPos, vec2 *pInoutVel, float Elasticity, int *pBounces) const; - void MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, float Elasticity, bool *pDeath=0) const; + void MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, vec2 Elasticity, bool *pDeath=0, bool* pGrounded=0) const; bool TestBox(vec2 Pos, vec2 Size, int Flag=COLFLAG_SOLID) const; }; diff --git a/src/game/gamecore.cpp b/src/game/gamecore.cpp index af7d3af464..2e454ce16f 100644 --- a/src/game/gamecore.cpp +++ b/src/game/gamecore.cpp @@ -375,7 +375,10 @@ void CCharacterCore::Move() m_Vel.x = m_Vel.x*RampValue; vec2 NewPos = m_Pos; - m_pCollision->MoveBox(&NewPos, &m_Vel, vec2(PHYS_SIZE, PHYS_SIZE), 0, &m_Death); + bool Grounded = false; + m_pCollision->MoveBox(&NewPos, &m_Vel, vec2(PHYS_SIZE, PHYS_SIZE), vec2(m_pWorld->m_Tuning.m_PlayerElasticityX, m_pWorld->m_Tuning.m_PlayerElasticityY), &m_Death, &Grounded); + if(Grounded) + m_Jumped &= ~2; m_Vel.x = m_Vel.x*(1.0f/RampValue); diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index 25dac5a3e8..d572086931 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -149,7 +149,7 @@ void CCharacter::HandleNinja() // Set velocity m_Core.m_Vel = m_Ninja.m_ActivationDir * g_pData->m_Weapons.m_Ninja.m_Velocity; vec2 OldPos = m_Pos; - GameServer()->Collision()->MoveBox(&m_Core.m_Pos, &m_Core.m_Vel, vec2(GetProximityRadius(), GetProximityRadius()), 0.f); + GameServer()->Collision()->MoveBox(&m_Core.m_Pos, &m_Core.m_Vel, vec2(GetProximityRadius(), GetProximityRadius()), vec2(GameServer()->Tuning()->m_PlayerElasticityX, GameServer()->Tuning()->m_PlayerElasticityY)); // reset velocity so the client doesn't predict stuff m_Core.m_Vel = vec2(0.f, 0.f); diff --git a/src/game/server/entities/flag.cpp b/src/game/server/entities/flag.cpp index 99bf05da01..6261c7e355 100644 --- a/src/game/server/entities/flag.cpp +++ b/src/game/server/entities/flag.cpp @@ -68,7 +68,7 @@ void CFlag::TickDefered() else { m_Vel.y += GameWorld()->m_Core.m_Tuning.m_Gravity; - GameServer()->Collision()->MoveBox(&m_Pos, &m_Vel, vec2(ms_PhysSize, ms_PhysSize), 0.5f); + GameServer()->Collision()->MoveBox(&m_Pos, &m_Vel, vec2(ms_PhysSize, ms_PhysSize), vec2(GameWorld()->m_Core.m_Tuning.m_FlagElasticity, GameWorld()->m_Core.m_Tuning.m_FlagElasticity)); } } } diff --git a/src/game/tuning.h b/src/game/tuning.h index ecd7ef08df..12c143efce 100644 --- a/src/game/tuning.h +++ b/src/game/tuning.h @@ -44,4 +44,8 @@ MACRO_TUNING_PARAM(LaserBounceCost, laser_bounce_cost, 0) MACRO_TUNING_PARAM(PlayerCollision, player_collision, 1) MACRO_TUNING_PARAM(PlayerHooking, player_hooking, 1) + +MACRO_TUNING_PARAM(PlayerElasticityX, player_elasticity_x, 0.0f) +MACRO_TUNING_PARAM(PlayerElasticityY, player_elasticity_y, 0.0f) +MACRO_TUNING_PARAM(FlagElasticity, flag_elasticity, 0.5f) #endif