diff --git a/src/game/collision.cpp b/src/game/collision.cpp index 1664d5eab..14cb0dcf8 100644 --- a/src/game/collision.cpp +++ b/src/game/collision.cpp @@ -337,7 +337,7 @@ bool CCollision::TestBox(vec2 Pos, vec2 Size) const return false; } -void CCollision::MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, float Elasticity) const +void CCollision::MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, vec2 Elasticity, bool *pGrounded) const { // do the move vec2 Pos = *pInoutPos; @@ -348,7 +348,10 @@ void CCollision::MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, float Elas if(Distance > 0.00001f) { - float Fraction = 1.0f/(float)(Max+1); + float Fraction = 1.0f / (float)(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++) { // Early break as optimization to stop checking for collisions for @@ -374,15 +377,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++; } @@ -390,10 +395,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 57672ed98..e9489a3ad 100644 --- a/src/game/collision.h +++ b/src/game/collision.h @@ -61,7 +61,7 @@ class CCollision int GetHeight() const { return m_Height; }; int IntersectLine(vec2 Pos0, vec2 Pos1, vec2 *pOutCollision = nullptr, vec2 *pOutBeforeCollision = nullptr) const; void MovePoint(vec2 *pInoutPos, vec2 *pInoutVel, float Elasticity, int *pBounces) const; - void MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, float Elasticity) const; + void MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, vec2 Elasticity, bool *pGrounded = nullptr) const; bool TestBox(vec2 Pos, vec2 Size) const; void Dest(); diff --git a/src/game/gamecore.cpp b/src/game/gamecore.cpp index b9766a5e5..718752433 100644 --- a/src/game/gamecore.cpp +++ b/src/game/gamecore.cpp @@ -469,7 +469,18 @@ void CCharacterCore::Move(CParams* pParams) NewPos.y -= PosDiff; } - m_pCollision->MoveBox(&NewPos, &m_Vel, Size, 0); + bool Grounded = false; + m_pCollision->MoveBox(&NewPos, &m_Vel, Size, + vec2(pTuningParams->m_GroundElasticityX, + pTuningParams->m_GroundElasticityY), + &Grounded); + + if(Grounded) + { + m_Jumped &= ~2; + m_JumpedTotal = 0; + } + NewPos.y += PosDiff; 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 6db20c456..58c90f5ff 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -141,7 +141,8 @@ void CCharacter::HandleWaterJump() if(m_DartLifeSpan > 0) { m_Core.m_Vel = m_DartDir * 15.0f; - GameServer()->Collision()->MoveBox(&m_Core.m_Pos, &m_Core.m_Vel, vec2(m_ProximityRadius, m_ProximityRadius), 0.f); + const vec2 GroundElasticity{}; + GameServer()->Collision()->MoveBox(&m_Core.m_Pos, &m_Core.m_Vel, vec2(m_ProximityRadius, m_ProximityRadius), GroundElasticity); m_Core.m_Vel = vec2(0.f, 0.f); } } diff --git a/src/game/server/infclass/entities/infccharacter.cpp b/src/game/server/infclass/entities/infccharacter.cpp index 54a769e6c..d3602791e 100644 --- a/src/game/server/infclass/entities/infccharacter.cpp +++ b/src/game/server/infclass/entities/infccharacter.cpp @@ -429,7 +429,8 @@ void CInfClassCharacter::HandleNinjaMove(float NinjaVelocity) { SetVelocity(m_DartDir * NinjaVelocity); - GameServer()->Collision()->MoveBox(&m_Core.m_Pos, &m_Core.m_Vel, CCharacterCore::PhysicalSizeVec2(), 0.f); + const vec2 GroundElasticity{}; + Collision()->MoveBox(&m_Core.m_Pos, &m_Core.m_Vel, vec2(GetProximityRadius(), GetProximityRadius()), GroundElasticity); // reset velocity so the client doesn't predict stuff ResetVelocity(); diff --git a/src/game/tuning.h b/src/game/tuning.h index a59969244..32fcc4f1c 100644 --- a/src/game/tuning.h +++ b/src/game/tuning.h @@ -59,3 +59,6 @@ MACRO_TUNING_PARAM(GrenadeFireDelay, grenade_fire_delay, 500, "Delay of firing g MACRO_TUNING_PARAM(LaserFireDelay, laser_fire_delay, 800, "Delay of firing laser laser") MACRO_TUNING_PARAM(NinjaFireDelay, ninja_fire_delay, 800, "Delay of firing ninja") MACRO_TUNING_PARAM(HammerHitFireDelay, hammer_hit_fire_delay, 320, "Delay of hammering (when hitting another tee)") + +MACRO_TUNING_PARAM(GroundElasticityX, ground_elasticity_x, 0, "Wall elasticity") +MACRO_TUNING_PARAM(GroundElasticityY, ground_elasticity_y, 0, "Ground/ceiling elasticity")