From d6833b6fd60d3a714316036618cb5cb27d17735b Mon Sep 17 00:00:00 2001 From: c0d3d3v Date: Mon, 16 May 2022 23:17:19 +0200 Subject: [PATCH] fix jump display --- datasrc/network.py | 2 +- src/game/client/components/hud.cpp | 36 ++++++++++++------- .../client/prediction/entities/character.cpp | 25 ++++++++++--- src/game/gamecore.cpp | 35 +++++++++++------- src/game/gamecore.h | 1 + src/game/server/entities/character.cpp | 25 ++++++++++--- 6 files changed, 87 insertions(+), 37 deletions(-) diff --git a/datasrc/network.py b/datasrc/network.py index be8447d52..81b1fe462 100644 --- a/datasrc/network.py +++ b/datasrc/network.py @@ -244,7 +244,7 @@ Objects = [ ]), NetObjectEx("DDNetCharacterDisplayInfo", "character-display-info@netobj.ddnet.tw", [ - NetIntRange("m_JumpedTotal", -2, 255), + NetIntRange("m_JumpedTotal", 0, 255), NetTick("m_NinjaActivationTick"), NetTick("m_FreezeTick"), NetBool("m_IsInFreeze"), diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index 4bf8b9e17..5a8a58d71 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -840,37 +840,47 @@ void CHud::RenderPlayerState(const int ClientID) CCharacterCore *pCharacter = &m_pClient->m_aClients[ClientID].m_Predicted; int TotalJumpsToDisplay, AvailableJumpsToDisplay; - // If the player is predicted in the Game World, we take the predicted jump values, otherwise the values from a snap if(m_pClient->m_Snap.m_aCharacters[ClientID].m_HasExtendedDisplayInfo) { - const float PhysSize = 28.0f; bool Grounded = false; - if(Collision()->CheckPoint(pCharacter->m_Pos.x + PhysSize / 2, pCharacter->m_Pos.y + PhysSize / 2 + 5)) + if(Collision()->CheckPoint(pCharacter->m_Pos.x + CCharacter::ms_PhysSize / 2, + pCharacter->m_Pos.y + CCharacter::ms_PhysSize / 2 + 5)) + { Grounded = true; - if(Collision()->CheckPoint(pCharacter->m_Pos.x - PhysSize / 2, pCharacter->m_Pos.y + PhysSize / 2 + 5)) + } + if(Collision()->CheckPoint(pCharacter->m_Pos.x - CCharacter::ms_PhysSize / 2, + pCharacter->m_Pos.y + CCharacter::ms_PhysSize / 2 + 5)) + { Grounded = true; + } int UsedJumps = pCharacter->m_JumpedTotal; - if(UsedJumps < pCharacter->m_Jumps && pCharacter->m_Jumps > 1 && !Grounded) + if(pCharacter->m_Jumps > 1) { - UsedJumps += 1; + UsedJumps += !Grounded; } - if(pCharacter->m_Jumps == -1) + else if(pCharacter->m_Jumps == 1) { + // If the player has only one jump, each jump is the last one + UsedJumps = pCharacter->m_Jumped & 2; + } + else if(pCharacter->m_Jumps == -1) + { + // The player has only one ground jump UsedJumps = !Grounded; } - if(pCharacter->m_EndlessJump) + + if(pCharacter->m_EndlessJump && UsedJumps >= abs(pCharacter->m_Jumps)) { - UsedJumps = 0; + UsedJumps = abs(pCharacter->m_Jumps) - 1; } int UnusedJumps = abs(pCharacter->m_Jumps) - UsedJumps; - if(!(pCharacter->m_Jumped & 2) && UnusedJumps == 0) + if(!(pCharacter->m_Jumped & 2) && UnusedJumps <= 0) { - // In some edge cases when the player just got another number of jumps, the prediction of m_JumpedTotal is not correct - UnusedJumps += 1; + // In some edge cases when the player just got another number of jumps, UnusedJumps is not correct + UnusedJumps = 1; } - TotalJumpsToDisplay = maximum(minimum(abs(pCharacter->m_Jumps), 10), 0); AvailableJumpsToDisplay = maximum(minimum(UnusedJumps, TotalJumpsToDisplay), 0); } diff --git a/src/game/client/prediction/entities/character.cpp b/src/game/client/prediction/entities/character.cpp index c15e8d387..b646b7bad 100644 --- a/src/game/client/prediction/entities/character.cpp +++ b/src/game/client/prediction/entities/character.cpp @@ -861,7 +861,7 @@ void CCharacter::HandleTiles(int Index) if(m_Core.m_Vel.y > 0 && m_Core.m_Colliding && m_Core.m_LeftWall) { m_Core.m_LeftWall = false; - m_Core.m_JumpedTotal = m_Core.m_Jumps - 1; + m_Core.m_JumpedTotal = m_Core.m_Jumps >= 2 ? m_Core.m_Jumps - 2 : 0; m_Core.m_Jumped = 1; } } @@ -968,17 +968,32 @@ void CCharacter::DDRacePostCoreTick() if(m_DeepFreeze && !m_Super) Freeze(); - if(m_Core.m_Jumps == -1 && !m_Super) + if(m_Core.m_Jumps == -1) + { + // The player has only one ground jump, so his feet are always dark m_Core.m_Jumped |= 2; - else if(m_Core.m_Jumps == 0 && !m_Super) - m_Core.m_Jumped = 3; + } + else if(m_Core.m_Jumps == 0) + { + // The player has no jumps at all, so his feet are always dark + m_Core.m_Jumped |= 2; + } else if(m_Core.m_Jumps == 1 && m_Core.m_Jumped > 0) - m_Core.m_Jumped = 3; + { + // If the player has only one jump, each jump is the last one + m_Core.m_Jumped |= 2; + } else if(m_Core.m_JumpedTotal < m_Core.m_Jumps - 1 && m_Core.m_Jumped > 1) + { + // The player has not yet used up all his jumps, so his feet remain light m_Core.m_Jumped = 1; + } if((m_Super || m_SuperJump) && m_Core.m_Jumped > 1) + { + // Super players and players with infinite jumps always have light feet m_Core.m_Jumped = 1; + } int CurrentIndex = Collision()->GetMapIndex(m_Pos); HandleSkippableTiles(CurrentIndex); diff --git a/src/game/gamecore.cpp b/src/game/gamecore.cpp index 864471490..94c9ad04c 100644 --- a/src/game/gamecore.cpp +++ b/src/game/gamecore.cpp @@ -134,6 +134,15 @@ void CCharacterCore::Tick(bool UseInput) float Accel = Grounded ? m_Tuning.m_GroundControlAccel : m_Tuning.m_AirControlAccel; float Friction = Grounded ? m_Tuning.m_GroundFriction : m_Tuning.m_AirFriction; + // handle jumping + // 1 bit = to keep track if a jump has been made on this input (player is holding space bar) + // 2 bit = to track if all air-jumps have been used up (tee gets dark feet) + if(Grounded) + { + m_Jumped &= ~2; + m_JumpedTotal = 0; + } + // handle input if(UseInput) { @@ -153,16 +162,23 @@ void CCharacterCore::Tick(bool UseInput) // handle jump if(m_Input.m_Jump) { - if(!(m_Jumped & 1)) + if(!(m_Jumped & 1) && m_Jumps != 0) { if(Grounded) { m_TriggeredEvents |= COREEVENT_GROUND_JUMP; m_Vel.y = -m_Tuning.m_GroundJumpImpulse; - m_Jumped |= 1; - m_JumpedTotal = 1; + if(m_Jumps > 1) + { + m_Jumped |= 1; + } + else + { + m_Jumped |= 3; + } + m_JumpedTotal = 0; } - else if(!(m_Jumped & 2)) + else if(!(m_Jumped & 2) && m_Jumps >= 1) { m_TriggeredEvents |= COREEVENT_AIR_JUMP; m_Vel.y = -m_Tuning.m_AirJumpImpulse; @@ -172,7 +188,9 @@ void CCharacterCore::Tick(bool UseInput) } } else + { m_Jumped &= ~1; + } // handle hook if(m_Input.m_Hook) @@ -203,15 +221,6 @@ void CCharacterCore::Tick(bool UseInput) if(m_Direction == 0) m_Vel.x *= Friction; - // handle jumping - // 1 bit = to keep track if a jump has been made on this input (player is holding space bar) - // 2 bit = to keep track if a air-jump has been made (tee gets dark feet) - if(Grounded) - { - m_Jumped &= ~2; - m_JumpedTotal = 0; - } - // do hook if(m_HookState == HOOK_IDLE) { diff --git a/src/game/gamecore.h b/src/game/gamecore.h index c174e53a0..e8493b912 100644 --- a/src/game/gamecore.h +++ b/src/game/gamecore.h @@ -243,6 +243,7 @@ public: bool m_NewHook; int m_Jumped; + // m_JumpedTotal counts the jumps performed in the air int m_JumpedTotal; int m_Jumps; diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index 539733ce8..23394cd67 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -1617,7 +1617,7 @@ void CCharacter::HandleTiles(int Index) if(m_Core.m_Vel.y > 0 && m_Core.m_Colliding && m_Core.m_LeftWall) { m_Core.m_LeftWall = false; - m_Core.m_JumpedTotal = m_Core.m_Jumps - 1; + m_Core.m_JumpedTotal = m_Core.m_Jumps >= 2 ? m_Core.m_Jumps - 2 : 0; m_Core.m_Jumped = 1; } } @@ -2146,17 +2146,32 @@ void CCharacter::DDRacePostCoreTick() if(m_DeepFreeze && !m_Super) Freeze(); - if(m_Core.m_Jumps == -1 && !m_Super) + if(m_Core.m_Jumps == -1) + { + // The player has only one ground jump, so his feet are always dark m_Core.m_Jumped |= 2; - else if(m_Core.m_Jumps == 0 && !m_Super) - m_Core.m_Jumped = 3; + } + else if(m_Core.m_Jumps == 0) + { + // The player has no jumps at all, so his feet are always dark + m_Core.m_Jumped |= 2; + } else if(m_Core.m_Jumps == 1 && m_Core.m_Jumped > 0) - m_Core.m_Jumped = 3; + { + // If the player has only one jump, each jump is the last one + m_Core.m_Jumped |= 2; + } else if(m_Core.m_JumpedTotal < m_Core.m_Jumps - 1 && m_Core.m_Jumped > 1) + { + // The player has not yet used up all his jumps, so his feet remain light m_Core.m_Jumped = 1; + } if((m_Super || m_SuperJump) && m_Core.m_Jumped > 1) + { + // Super players and players with infinite jumps always have light feet m_Core.m_Jumped = 1; + } int CurrentIndex = GameServer()->Collision()->GetMapIndex(m_Pos); HandleSkippableTiles(CurrentIndex);