mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Add DDNetCharacterDisplayInfo NetObj
- Show all components of new HUD also in Spectator (Ninja Bar, Freeze Bar and Jumps) - hide freeze bar if you sit in freeze
This commit is contained in:
parent
b403f474a0
commit
e71578e468
|
@ -245,6 +245,13 @@ Objects = [
|
|||
NetIntRange("m_StrongWeakID", 0, 'MAX_CLIENTS-1'),
|
||||
]),
|
||||
|
||||
NetObjectEx("DDNetCharacterDisplayInfo", "character-display-info@netobj.ddnet.tw", [
|
||||
NetIntRange("m_JumpedTotal", -2, 255),
|
||||
NetTick("m_NinjaActivationTick"),
|
||||
NetTick("m_FreezeTick"),
|
||||
NetBool("m_IsInFreeze"),
|
||||
]),
|
||||
|
||||
NetObjectEx("DDNetPlayer", "player@netobj.ddnet.tw", [
|
||||
NetIntAny("m_Flags"),
|
||||
NetIntRange("m_AuthLevel", "AUTHED_NO", "AUTHED_ADMIN"),
|
||||
|
|
|
@ -2,29 +2,34 @@
|
|||
|
||||
#include "freezebars.h"
|
||||
|
||||
|
||||
void CFreezeBars::RenderFreezeBar(const int ClientID)
|
||||
{
|
||||
const float FreezeBarWidth = 64.0f;
|
||||
const float FreezeBarHalfWidth = 32.0f;
|
||||
const float FreezeBarHight = 16.0f;
|
||||
|
||||
if(m_pClient->m_aClients[ClientID].m_Predicted.m_FreezeEnd <= 0.0f)
|
||||
// pCharacter contains the predicted character for local players or the last snap for players who are spectated
|
||||
CCharacterCore *pCharacter = &m_pClient->m_aClients[ClientID].m_Predicted;
|
||||
|
||||
const float PhysSize = 28.0f;
|
||||
bool Grounded = false;
|
||||
if(Collision()->CheckPoint(pCharacter->m_Pos.x + PhysSize / 2, pCharacter->m_Pos.y + PhysSize / 2 + 5))
|
||||
Grounded = true;
|
||||
if(Collision()->CheckPoint(pCharacter->m_Pos.x - PhysSize / 2, pCharacter->m_Pos.y + PhysSize / 2 + 5))
|
||||
Grounded = true;
|
||||
|
||||
if(pCharacter->m_FreezeEnd <= 0.0f || !m_pClient->m_Snap.m_aCharacters[ClientID].m_HasExtendedDisplayInfo || (pCharacter->m_IsInFreeze && Grounded))
|
||||
{
|
||||
return;
|
||||
}
|
||||
const int Max = m_pClient->m_aClients[ClientID].m_Predicted.m_FreezeEnd - m_pClient->m_aClients[ClientID].m_Predicted.m_FreezeTick;
|
||||
float FreezeProgress = clamp(Max - (m_pClient->m_GameWorld.GameTick() - m_pClient->m_aClients[ClientID].m_Predicted.m_FreezeTick), 0, Max) / (float)Max;
|
||||
const int Max = pCharacter->m_FreezeEnd - pCharacter->m_FreezeTick;
|
||||
float FreezeProgress = clamp(Max - (Client()->GameTick(g_Config.m_ClDummy) - pCharacter->m_FreezeTick), 0, Max) / (float)Max;
|
||||
if(FreezeProgress <= 0.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 Position;
|
||||
if(ClientID >= 0 && ClientID < MAX_CLIENTS)
|
||||
Position = m_pClient->m_aClients[ClientID].m_RenderPos;
|
||||
else
|
||||
Position = mix(vec2(m_pClient->m_aClients[ClientID].m_RenderPrev.m_X, m_pClient->m_aClients[ClientID].m_RenderPrev.m_Y), vec2(m_pClient->m_aClients[ClientID].m_RenderCur.m_X, m_pClient->m_aClients[ClientID].m_RenderCur.m_Y), Client()->IntraGameTick(g_Config.m_ClDummy));
|
||||
vec2 Position = m_pClient->m_aClients[ClientID].m_RenderPos;
|
||||
Position.x -= FreezeBarHalfWidth;
|
||||
Position.y += 32;
|
||||
|
||||
|
@ -33,6 +38,13 @@ void CFreezeBars::RenderFreezeBar(const int ClientID)
|
|||
m_pClient->m_Hud.RenderProgressBar(Position.x, Position.y, FreezeBarWidth, FreezeBarHight, FreezeProgress, Alpha);
|
||||
}
|
||||
|
||||
inline bool CFreezeBars::IsPlayerInfoAvailable(int ClientID) const
|
||||
{
|
||||
const void *pPrevInfo = Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_PLAYERINFO, ClientID);
|
||||
const void *pInfo = Client()->SnapFindItem(IClient::SNAP_CURRENT, NETOBJTYPE_PLAYERINFO, ClientID);
|
||||
return pPrevInfo && pInfo;
|
||||
}
|
||||
|
||||
void CFreezeBars::OnRender()
|
||||
{
|
||||
// get screen edges to avoid rendering offscreen
|
||||
|
@ -53,7 +65,7 @@ void CFreezeBars::OnRender()
|
|||
// render everyone else's freeze bar, then our own
|
||||
for(int ClientID = 0; ClientID < MAX_CLIENTS; ClientID++)
|
||||
{
|
||||
if(ClientID == LocalClientID || !m_pClient->m_Snap.m_aCharacters[ClientID].m_Active || !m_pClient->m_Players.IsPlayerInfoAvailable(ClientID))
|
||||
if(ClientID == LocalClientID || !m_pClient->m_Snap.m_aCharacters[ClientID].m_Active || !IsPlayerInfoAvailable(ClientID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -66,10 +78,8 @@ void CFreezeBars::OnRender()
|
|||
}
|
||||
|
||||
RenderFreezeBar(ClientID);
|
||||
|
||||
|
||||
}
|
||||
if(LocalClientID != -1 && m_pClient->m_Snap.m_aCharacters[LocalClientID].m_Active && m_pClient->m_Players.IsPlayerInfoAvailable(LocalClientID))
|
||||
if(LocalClientID != -1 && m_pClient->m_Snap.m_aCharacters[LocalClientID].m_Active && IsPlayerInfoAvailable(LocalClientID))
|
||||
{
|
||||
RenderFreezeBar(LocalClientID);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
class CFreezeBars : public CComponent
|
||||
{
|
||||
void RenderFreezeBar(const int ClientID);
|
||||
bool IsPlayerInfoAvailable(int ClientID) const;
|
||||
|
||||
public:
|
||||
virtual int Sizeof() const override { return sizeof(*this); }
|
||||
|
|
|
@ -830,14 +830,14 @@ void CHud::RenderPlayerState(const int ClientID)
|
|||
{
|
||||
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
// pCharacter contains the predicted character for local players and the last snap for spectated players.
|
||||
// pCharacter contains the predicted character for local players or the last snap for players who are spectated
|
||||
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_pLocalCharacter)
|
||||
if(m_pClient->m_Snap.m_aCharacters[ClientID].m_HasExtendedDisplayInfo)
|
||||
{
|
||||
float PhysSize = 28.0f;
|
||||
const float PhysSize = 28.0f;
|
||||
bool Grounded = false;
|
||||
if(Collision()->CheckPoint(pCharacter->m_Pos.x + PhysSize / 2, pCharacter->m_Pos.y + PhysSize / 2 + 5))
|
||||
Grounded = true;
|
||||
|
@ -960,9 +960,9 @@ void CHud::RenderPlayerState(const int ClientID)
|
|||
Graphics()->QuadsSetRotation(0);
|
||||
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
const int Max = g_pData->m_Weapons.m_Ninja.m_Duration * m_pClient->m_GameWorld.GameTickSpeed() / 1000;
|
||||
float NinjaProgress = clamp(pCharacter->m_Ninja.m_ActivationTick + g_pData->m_Weapons.m_Ninja.m_Duration * m_pClient->m_GameWorld.GameTickSpeed() / 1000 - m_pClient->m_GameWorld.GameTick(), 0, Max) / (float)Max;
|
||||
if(NinjaProgress > 0.0f)
|
||||
const int Max = g_pData->m_Weapons.m_Ninja.m_Duration * Client()->GameTickSpeed() / 1000;
|
||||
float NinjaProgress = clamp(pCharacter->m_Ninja.m_ActivationTick + g_pData->m_Weapons.m_Ninja.m_Duration * Client()->GameTickSpeed() / 1000 - Client()->GameTick(g_Config.m_ClDummy), 0, Max) / (float)Max;
|
||||
if(NinjaProgress > 0.0f && m_pClient->m_Snap.m_aCharacters[ClientID].m_HasExtendedDisplayInfo)
|
||||
{
|
||||
x = 5;
|
||||
y += 12;
|
||||
|
@ -1117,7 +1117,7 @@ void CHud::RenderProgressBar(float x, const float y, const float width, const fl
|
|||
const float MiddleProgressProportion = MiddleBarWidth / ProgressBarWidth;
|
||||
|
||||
// we cut 10% of both sides (right and left) of all sprites so we don't get edge bleeding
|
||||
|
||||
|
||||
// beginning piece
|
||||
float BeginningPieceProgress = 1;
|
||||
if(Progress <= EndProgressProportion)
|
||||
|
|
|
@ -40,8 +40,6 @@ public:
|
|||
virtual int Sizeof() const override { return sizeof(*this); }
|
||||
virtual void OnInit() override;
|
||||
virtual void OnRender() override;
|
||||
|
||||
bool IsPlayerInfoAvailable(int ClientID) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1346,6 +1346,19 @@ void CGameClient::OnNewSnapshot()
|
|||
pClient->m_Predicted.ReadDDNet(pCharacterData);
|
||||
}
|
||||
}
|
||||
else if(Item.m_Type == NETOBJTYPE_DDNETCHARACTERDISPLAYINFO)
|
||||
{
|
||||
const CNetObj_DDNetCharacterDisplayInfo *pCharacterDisplayInfo = (const CNetObj_DDNetCharacterDisplayInfo *)pData;
|
||||
|
||||
if(Item.m_ID < MAX_CLIENTS)
|
||||
{
|
||||
m_Snap.m_aCharacters[Item.m_ID].m_ExtendedDisplayInfo = *pCharacterDisplayInfo;
|
||||
m_Snap.m_aCharacters[Item.m_ID].m_HasExtendedDisplayInfo = true;
|
||||
|
||||
CClientData *pClient = &m_aClients[Item.m_ID];
|
||||
pClient->m_Predicted.ReadDDNetDisplayInfo(pCharacterDisplayInfo);
|
||||
}
|
||||
}
|
||||
else if(Item.m_Type == NETOBJTYPE_SPECCHAR)
|
||||
{
|
||||
const CNetObj_SpecChar *pSpecCharData = (const CNetObj_SpecChar *)pData;
|
||||
|
|
|
@ -318,6 +318,9 @@ public:
|
|||
CNetObj_DDNetCharacter m_ExtendedData;
|
||||
bool m_HasExtendedData;
|
||||
|
||||
CNetObj_DDNetCharacterDisplayInfo m_ExtendedDisplayInfo;
|
||||
bool m_HasExtendedDisplayInfo;
|
||||
|
||||
// interpolated position
|
||||
vec2 m_Position;
|
||||
};
|
||||
|
|
|
@ -697,7 +697,13 @@ void CCharacter::HandleTiles(int Index)
|
|||
if(Collision()->GetSwitchType(MapIndex) == TILE_FREEZE && Team() != TEAM_SUPER)
|
||||
{
|
||||
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
|
||||
{
|
||||
Freeze(Collision()->GetSwitchDelay(MapIndex));
|
||||
if(IsGrounded())
|
||||
{
|
||||
m_Core.m_IsInFreeze = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(Collision()->GetSwitchType(MapIndex) == TILE_DFREEZE && Team() != TEAM_SUPER)
|
||||
{
|
||||
|
@ -781,6 +787,10 @@ void CCharacter::HandleTiles(int Index)
|
|||
if(((m_TileIndex == TILE_FREEZE) || (m_TileFIndex == TILE_FREEZE)) && !m_Super && !m_DeepFreeze)
|
||||
{
|
||||
Freeze();
|
||||
if(IsGrounded())
|
||||
{
|
||||
m_Core.m_IsInFreeze = true;
|
||||
}
|
||||
}
|
||||
else if(((m_TileIndex == TILE_UNFREEZE) || (m_TileFIndex == TILE_UNFREEZE)) && !m_DeepFreeze)
|
||||
{
|
||||
|
@ -946,6 +956,7 @@ void CCharacter::DDRacePostCoreTick()
|
|||
m_Core.m_HookTick = 0;
|
||||
|
||||
m_FrozenLastTick = false;
|
||||
m_Core.m_IsInFreeze = false;
|
||||
|
||||
if(m_DeepFreeze && !m_Super)
|
||||
Freeze();
|
||||
|
@ -1101,6 +1112,7 @@ void CCharacter::ResetPrediction()
|
|||
m_NumInputs = 0;
|
||||
m_FreezeTime = 0;
|
||||
m_Core.m_FreezeTick = 0;
|
||||
m_Core.m_IsInFreeze = false;
|
||||
m_DeepFreeze = false;
|
||||
m_LiveFreeze = false;
|
||||
m_FrozenLastTick = false;
|
||||
|
|
|
@ -586,6 +586,14 @@ void CCharacterCore::ReadDDNet(const CNetObj_DDNetCharacter *pObjDDNet)
|
|||
m_Jumps = pObjDDNet->m_Jumps;
|
||||
}
|
||||
|
||||
void CCharacterCore::ReadDDNetDisplayInfo(const CNetObj_DDNetCharacterDisplayInfo *pObjDDNet)
|
||||
{
|
||||
m_JumpedTotal = pObjDDNet->m_JumpedTotal;
|
||||
m_Ninja.m_ActivationTick = pObjDDNet->m_NinjaActivationTick;
|
||||
m_FreezeTick = pObjDDNet->m_FreezeTick;
|
||||
m_IsInFreeze = pObjDDNet->m_IsInFreeze;
|
||||
}
|
||||
|
||||
void CCharacterCore::Quantize()
|
||||
{
|
||||
CNetObj_CharacterCore Core;
|
||||
|
|
|
@ -276,6 +276,7 @@ public:
|
|||
void SetTeamsCore(CTeamsCore *pTeams);
|
||||
void SetTeleOuts(std::map<int, std::vector<vec2>> *pTeleOuts);
|
||||
void ReadDDNet(const CNetObj_DDNetCharacter *pObjDDNet);
|
||||
void ReadDDNetDisplayInfo(const CNetObj_DDNetCharacterDisplayInfo *pObjDDNet);
|
||||
bool m_Solo;
|
||||
bool m_Jetpack;
|
||||
bool m_NoCollision;
|
||||
|
@ -292,6 +293,7 @@ public:
|
|||
bool m_HasTelegunLaser;
|
||||
int m_FreezeTick;
|
||||
int m_FreezeEnd;
|
||||
bool m_IsInFreeze;
|
||||
bool m_DeepFrozen;
|
||||
bool m_LiveFrozen;
|
||||
CTuningParams m_Tuning;
|
||||
|
|
|
@ -1242,6 +1242,14 @@ void CCharacter::Snap(int SnappingClient)
|
|||
pDDNetCharacter->m_Jumps = m_Core.m_Jumps;
|
||||
pDDNetCharacter->m_TeleCheckpoint = m_TeleCheckpoint;
|
||||
pDDNetCharacter->m_StrongWeakID = m_StrongWeakID;
|
||||
|
||||
CNetObj_DDNetCharacterDisplayInfo *pDDNetCharacterDisplayInfo = static_cast<CNetObj_DDNetCharacterDisplayInfo *>(Server()->SnapNewItem(NETOBJTYPE_DDNETCHARACTERDISPLAYINFO, ID, sizeof(CNetObj_DDNetCharacterDisplayInfo)));
|
||||
if(!pDDNetCharacterDisplayInfo)
|
||||
return;
|
||||
pDDNetCharacterDisplayInfo->m_JumpedTotal = m_Core.m_JumpedTotal;
|
||||
pDDNetCharacterDisplayInfo->m_NinjaActivationTick = m_Core.m_Ninja.m_ActivationTick;
|
||||
pDDNetCharacterDisplayInfo->m_FreezeTick = m_Core.m_FreezeTick;
|
||||
pDDNetCharacterDisplayInfo->m_IsInFreeze = m_Core.m_IsInFreeze;
|
||||
}
|
||||
|
||||
// DDRace
|
||||
|
@ -1476,7 +1484,13 @@ void CCharacter::HandleTiles(int Index)
|
|||
|
||||
// freeze
|
||||
if(((m_TileIndex == TILE_FREEZE) || (m_TileFIndex == TILE_FREEZE)) && !m_Super && !m_DeepFreeze)
|
||||
{
|
||||
Freeze();
|
||||
if(IsGrounded())
|
||||
{
|
||||
m_Core.m_IsInFreeze = true;
|
||||
}
|
||||
}
|
||||
else if(((m_TileIndex == TILE_UNFREEZE) || (m_TileFIndex == TILE_UNFREEZE)) && !m_DeepFreeze)
|
||||
UnFreeze();
|
||||
|
||||
|
@ -1699,7 +1713,13 @@ void CCharacter::HandleTiles(int Index)
|
|||
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_FREEZE && Team() != TEAM_SUPER)
|
||||
{
|
||||
if(GameServer()->Collision()->GetSwitchNumber(MapIndex) == 0 || GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
|
||||
{
|
||||
Freeze(GameServer()->Collision()->GetSwitchDelay(MapIndex));
|
||||
if(IsGrounded())
|
||||
{
|
||||
m_Core.m_IsInFreeze = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_DFREEZE && Team() != TEAM_SUPER)
|
||||
{
|
||||
|
@ -2095,16 +2115,16 @@ void CCharacter::DDRaceTick()
|
|||
GameServer()->Collision()->GetSwitchType(Index)};
|
||||
if(IsGrounded() && !m_DeepFreeze)
|
||||
{
|
||||
bool IsInFreeze = false;
|
||||
bool IsInAnyFreeze = false;
|
||||
for(const int Tile : aTiles)
|
||||
{
|
||||
if(Tile == TILE_FREEZE || Tile == TILE_DFREEZE || Tile == TILE_LFREEZE)
|
||||
{
|
||||
IsInFreeze = true;
|
||||
IsInAnyFreeze = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!IsInFreeze)
|
||||
if(!IsInAnyFreeze)
|
||||
{
|
||||
SetRescue();
|
||||
}
|
||||
|
@ -2122,6 +2142,7 @@ void CCharacter::DDRacePostCoreTick()
|
|||
m_Core.m_HookTick = 0;
|
||||
|
||||
m_FrozenLastTick = false;
|
||||
m_Core.m_IsInFreeze = false;
|
||||
|
||||
if(m_DeepFreeze && !m_Super)
|
||||
Freeze();
|
||||
|
|
Loading…
Reference in a new issue