Add Freeze Bar

This commit is contained in:
c0d3d3v 2022-03-25 12:54:11 +01:00
parent 78a0a3d31e
commit b403f474a0
No known key found for this signature in database
GPG key ID: 068AF680530DFF31
14 changed files with 123 additions and 26 deletions

View file

@ -1914,6 +1914,8 @@ if(CLIENT)
components/emoticon.h
components/flow.cpp
components/flow.h
components/freezebars.cpp
components/freezebars.h
components/ghost.cpp
components/ghost.h
components/hud.cpp

View file

@ -0,0 +1,76 @@
#include <game/client/gameclient.h>
#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)
{
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;
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));
Position.x -= FreezeBarHalfWidth;
Position.y += 32;
float Alpha = m_pClient->IsOtherTeam(ClientID) ? g_Config.m_ClShowOthersAlpha / 100.0f : 1.0f;
m_pClient->m_Hud.RenderProgressBar(Position.x, Position.y, FreezeBarWidth, FreezeBarHight, FreezeProgress, Alpha);
}
void CFreezeBars::OnRender()
{
// get screen edges to avoid rendering offscreen
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
// expand the edges to prevent popping in/out onscreen
//
// it is assumed that the tee with the freeze bar fit into a 240x240 box centered on the tee
// this may need to be changed or calculated differently in the future
float BorderBuffer = 120;
ScreenX0 -= BorderBuffer;
ScreenX1 += BorderBuffer;
ScreenY0 -= BorderBuffer;
ScreenY1 += BorderBuffer;
int LocalClientID = m_pClient->m_Snap.m_LocalClientID;
// 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))
{
continue;
}
//don't render if the tee is offscreen
vec2 *pRenderPos = &m_pClient->m_aClients[ClientID].m_RenderPos;
if(pRenderPos->x < ScreenX0 || pRenderPos->x > ScreenX1 || pRenderPos->y < ScreenY0 || pRenderPos->y > ScreenY1)
{
continue;
}
RenderFreezeBar(ClientID);
}
if(LocalClientID != -1 && m_pClient->m_Snap.m_aCharacters[LocalClientID].m_Active && m_pClient->m_Players.IsPlayerInfoAvailable(LocalClientID))
{
RenderFreezeBar(LocalClientID);
}
}

View file

@ -0,0 +1,14 @@
#ifndef GAME_CLIENT_COMPONENTS_FREEZEBARS_H
#define GAME_CLIENT_COMPONENTS_FREEZEBARS_H
#include <game/client/component.h>
class CFreezeBars : public CComponent
{
void RenderFreezeBar(const int ClientID);
public:
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnRender() override;
};
#endif

View file

@ -824,10 +824,6 @@ void CHud::PreparePlayerStateQuads()
m_LiveFrozenOffset = RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 0.f, 0.f, 12.f, 12.f);
m_DummyHammerOffset = RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 0.f, 0.f, 12.f, 12.f);
m_DummyCopyOffset = RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 0.f, 0.f, 12.f, 12.f);
// Quads for displaying ninja bar
m_NinjaBarFullLeftOffset = RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 0.f, 0.f, 6.f, 12.f);
m_NinjaBarEmptyRightOffset = RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 0.f, 0.f, 6.f, 12.f);
}
void CHud::RenderPlayerState(const int ClientID)
@ -970,7 +966,7 @@ void CHud::RenderPlayerState(const int ClientID)
{
x = 5;
y += 12;
RenderNinjaBar(x, y, NinjaProgress);
RenderProgressBar(x, y, 90.0f, 12.0f, NinjaProgress);
}
}
@ -1107,13 +1103,13 @@ void CHud::RenderPlayerState(const int ClientID)
}
}
void CHud::RenderNinjaBar(float x, float y, float Progress)
void CHud::RenderProgressBar(float x, const float y, const float width, const float height, float Progress, const float Alpha)
{
Progress = clamp(Progress, 0.0f, 1.0f);
// half of the ends are also used for the progress display
const float EndWidth = 6.0f;
const float BarHeight = 12.0f;
const float WholeBarWidth = 90.f;
const float BarHeight = height;
const float WholeBarWidth = width;
const float MiddleBarWidth = WholeBarWidth - (EndWidth * 2.0f);
const float EndProgressWidth = EndWidth / 2.0f;
const float ProgressBarWidth = WholeBarWidth - (EndProgressWidth * 2.0f);
@ -1121,7 +1117,7 @@ void CHud::RenderNinjaBar(float x, float y, float Progress)
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)
@ -1132,6 +1128,7 @@ void CHud::RenderNinjaBar(float x, float y, float Progress)
// full
Graphics()->TextureSet(m_pClient->m_HudSkin.m_SpriteHudFreezeBarFullLeft);
Graphics()->QuadsBegin();
Graphics()->SetColor(1.f, 1.f, 1.f, Alpha);
Graphics()->QuadsSetSubset(0.1f, 0, 0.1f + 0.8f * BeginningPiecePercentVisible, 1);
IGraphics::CQuadItem QuadFullBeginning(x, y, EndWidth * BeginningPiecePercentVisible, BarHeight);
Graphics()->QuadsDrawTL(&QuadFullBeginning, 1);
@ -1141,6 +1138,7 @@ void CHud::RenderNinjaBar(float x, float y, float Progress)
// empty
Graphics()->TextureSet(m_pClient->m_HudSkin.m_SpriteHudFreezeBarEmptyRight);
Graphics()->QuadsBegin();
Graphics()->SetColor(1.f, 1.f, 1.f, Alpha);
Graphics()->QuadsSetSubset(0.1f, 1, 0.1f + 0.8f * (1.0f - BeginningPiecePercentVisible), 0);
Graphics()->QuadsSetRotation(pi);
IGraphics::CQuadItem QuadEmptyBeginning(x + (EndWidth * BeginningPiecePercentVisible), y, EndWidth * (1.0f - BeginningPiecePercentVisible), BarHeight);
@ -1172,6 +1170,7 @@ void CHud::RenderNinjaBar(float x, float y, float Progress)
// full ninja bar
Graphics()->TextureSet(m_pClient->m_HudSkin.m_SpriteHudFreezeBarFull);
Graphics()->QuadsBegin();
Graphics()->SetColor(1.f, 1.f, 1.f, Alpha);
// select the middle portion of the sprite so we don't get edge bleeding
if(MiddlePieceProgress * MiddleBarWidth <= EndWidth * 0.8f)
{
@ -1189,6 +1188,7 @@ void CHud::RenderNinjaBar(float x, float y, float Progress)
// empty ninja bar
Graphics()->TextureSet(m_pClient->m_HudSkin.m_SpriteHudFreezeBarEmpty);
Graphics()->QuadsBegin();
Graphics()->SetColor(1.f, 1.f, 1.f, Alpha);
// select the middle portion of the sprite so we don't get edge bleeding
if((1.0f - MiddlePieceProgress) * MiddleBarWidth <= EndWidth * 0.8f)
{
@ -1224,6 +1224,7 @@ void CHud::RenderNinjaBar(float x, float y, float Progress)
{
Graphics()->TextureSet(m_pClient->m_HudSkin.m_SpriteHudFreezeBarFullLeft);
Graphics()->QuadsBegin();
Graphics()->SetColor(1.f, 1.f, 1.f, Alpha);
Graphics()->QuadsSetSubset(0.5f + 0.4f * (1.0f - EndingPieceProgress), 1, 0.90f, 0);
Graphics()->QuadsSetRotation(pi);
IGraphics::CQuadItem QuadFullEnding(x, y, (EndWidth / 2) * EndingPieceProgress, BarHeight);
@ -1234,11 +1235,13 @@ void CHud::RenderNinjaBar(float x, float y, float Progress)
// empty
Graphics()->TextureSet(m_pClient->m_HudSkin.m_SpriteHudFreezeBarEmptyRight);
Graphics()->QuadsBegin();
Graphics()->SetColor(1.f, 1.f, 1.f, Alpha);
Graphics()->QuadsSetSubset(0.5f - 0.4f * (1.0f - EndingPieceProgress), 0, 0.9f, 1);
IGraphics::CQuadItem QuadEmptyEnding(x + ((EndWidth / 2) * EndingPieceProgress), y, (EndWidth / 2) * (1.0f - EndingPieceProgress) + (EndWidth / 2), BarHeight);
Graphics()->QuadsDrawTL(&QuadEmptyEnding, 1);
Graphics()->QuadsEnd();
Graphics()->QuadsSetSubset(0, 0, 1, 1);
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
}
void CHud::RenderSpectatorHud()

View file

@ -54,7 +54,6 @@ class CHud : public CComponent
void PreparePlayerStateQuads();
void RenderPlayerState(const int ClientID);
void RenderNinjaBar(float x, float y, float Progress);
void RenderGameTimer();
void RenderPauseNotification();
@ -79,6 +78,7 @@ public:
// DDRace
virtual void OnMessage(int MsgType, void *pRawMsg) override;
void RenderProgressBar(float x, const float y, const float width, const float height, float Progress, float Alpha = 1.0f);
private:
void RenderRecord();
@ -125,8 +125,6 @@ private:
int m_LiveFrozenOffset;
int m_DummyHammerOffset;
int m_DummyCopyOffset;
int m_NinjaBarFullLeftOffset;
int m_NinjaBarEmptyRightOffset;
};
#endif

View file

@ -37,10 +37,11 @@ class CPlayers : public CComponent
int m_WeaponSpriteMuzzleQuadContainerIndex[NUM_WEAPONS];
public:
vec2 m_CurPredictedPos[MAX_CLIENTS];
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnInit() override;
virtual void OnRender() override;
bool IsPlayerInfoAvailable(int ClientID) const;
};
#endif

View file

@ -45,6 +45,7 @@
#include "components/effects.h"
#include "components/emoticon.h"
#include "components/flow.h"
#include "components/freezebars.h"
#include "components/hud.h"
#include "components/items.h"
#include "components/killmessages.h"
@ -125,6 +126,7 @@ void CGameClient::OnConsoleInit()
m_All.Add(&m_Particles.m_RenderExplosions);
m_All.Add(&m_NamePlates);
m_All.Add(&m_Particles.m_RenderGeneral);
m_All.Add(&m_FreezeBars);
m_All.Add(&m_DamageInd);
m_All.Add(&m_Hud);
m_All.Add(&m_Spectator);

View file

@ -34,6 +34,7 @@
#include "components/effects.h"
#include "components/emoticon.h"
#include "components/flow.h"
#include "components/freezebars.h"
#include "components/ghost.h"
#include "components/hud.h"
#include "components/items.h"
@ -131,6 +132,7 @@ public:
CPlayers m_Players;
CNamePlates m_NamePlates;
CFreezeBars m_FreezeBars;
CItems m_Items;
CMapImages m_MapImages;

View file

@ -982,10 +982,10 @@ bool CCharacter::Freeze(int Seconds)
return false;
if((Seconds <= 0 || m_Super || m_FreezeTime == -1 || m_FreezeTime > Seconds * GameWorld()->GameTickSpeed()) && Seconds != -1)
return false;
if(m_FreezeTick < GameWorld()->GameTick() - GameWorld()->GameTickSpeed() || Seconds == -1)
if(m_Core.m_FreezeTick < GameWorld()->GameTick() - GameWorld()->GameTickSpeed() || Seconds == -1)
{
m_FreezeTime = Seconds == -1 ? Seconds : Seconds * GameWorld()->GameTickSpeed();
m_FreezeTick = GameWorld()->GameTick();
m_Core.m_FreezeTick = GameWorld()->GameTick();
return true;
}
return false;
@ -1003,7 +1003,7 @@ bool CCharacter::UnFreeze()
if(!m_Core.m_aWeapons[m_Core.m_ActiveWeapon].m_Got)
m_Core.m_ActiveWeapon = WEAPON_GUN;
m_FreezeTime = 0;
m_FreezeTick = 0;
m_Core.m_FreezeTick = 0;
m_FrozenLastTick = true;
return true;
}
@ -1100,7 +1100,7 @@ void CCharacter::ResetPrediction()
m_Core.m_Collision = true;
m_NumInputs = 0;
m_FreezeTime = 0;
m_FreezeTick = 0;
m_Core.m_FreezeTick = 0;
m_DeepFreeze = false;
m_LiveFreeze = false;
m_FrozenLastTick = false;
@ -1241,7 +1241,7 @@ void CCharacter::Read(CNetObj_Character *pChar, CNetObj_DDNetCharacter *pExtende
// detect unfreeze (in case the player was frozen in the tile prediction and not correctly unfrozen)
if(pChar->m_Emote != EMOTE_PAIN && pChar->m_Emote != EMOTE_NORMAL)
m_DeepFreeze = false;
if(pChar->m_Weapon != WEAPON_NINJA || pChar->m_AttackTick > m_FreezeTick || absolute(pChar->m_VelX) == 256 * 10 || !GameWorld()->m_WorldConfig.m_PredictFreeze)
if(pChar->m_Weapon != WEAPON_NINJA || pChar->m_AttackTick > m_Core.m_FreezeTick || absolute(pChar->m_VelX) == 256 * 10 || !GameWorld()->m_WorldConfig.m_PredictFreeze)
{
m_DeepFreeze = false;
UnFreeze();

View file

@ -79,7 +79,6 @@ public:
bool m_Jetpack;
bool m_NinjaJetpack;
int m_FreezeTime;
int m_FreezeTick;
bool m_FrozenLastTick;
bool m_DeepFreeze;
bool m_LiveFreeze;

View file

@ -290,6 +290,7 @@ public:
bool m_HasTelegunGun;
bool m_HasTelegunGrenade;
bool m_HasTelegunLaser;
int m_FreezeTick;
int m_FreezeEnd;
bool m_DeepFrozen;
bool m_LiveFrozen;

View file

@ -1145,7 +1145,7 @@ void CCharacter::SnapCharacter(int SnappingClient, int ID)
pCharacter->m_AmmoCount = AmmoCount;
if(m_FreezeTime > 0 || m_FreezeTime == -1 || m_DeepFreeze)
pCharacter->m_AmmoCount = m_FreezeTick + g_Config.m_SvFreezeDelay * Server()->TickSpeed();
pCharacter->m_AmmoCount = m_Core.m_FreezeTick + g_Config.m_SvFreezeDelay * Server()->TickSpeed();
else if(Weapon == WEAPON_NINJA)
pCharacter->m_AmmoCount = m_Core.m_Ninja.m_ActivationTick + g_pData->m_Weapons.m_Ninja.m_Duration * Server()->TickSpeed() / 1000;
@ -2181,11 +2181,11 @@ bool CCharacter::Freeze(int Seconds)
{
if((Seconds <= 0 || m_Super || m_FreezeTime == -1 || m_FreezeTime > Seconds * Server()->TickSpeed()) && Seconds != -1)
return false;
if(m_FreezeTick < Server()->Tick() - Server()->TickSpeed() || Seconds == -1)
if(m_Core.m_FreezeTick < Server()->Tick() - Server()->TickSpeed() || Seconds == -1)
{
m_Armor = 0;
m_FreezeTime = Seconds == -1 ? Seconds : Seconds * Server()->TickSpeed();
m_FreezeTick = Server()->Tick();
m_Core.m_FreezeTick = Server()->Tick();
return true;
}
return false;
@ -2204,7 +2204,7 @@ bool CCharacter::UnFreeze()
if(!m_Core.m_aWeapons[m_Core.m_ActiveWeapon].m_Got)
m_Core.m_ActiveWeapon = WEAPON_GUN;
m_FreezeTime = 0;
m_FreezeTick = 0;
m_Core.m_FreezeTick = 0;
m_FrozenLastTick = true;
return true;
}

View file

@ -183,7 +183,6 @@ public:
bool m_NinjaJetpack;
int m_TeamBeforeSuper;
int m_FreezeTime;
int m_FreezeTick;
bool m_FrozenLastTick;
bool m_DeepFreeze;
bool m_LiveFreeze;

View file

@ -39,7 +39,7 @@ void CSaveTee::Save(CCharacter *pChr)
m_Jetpack = pChr->m_Jetpack;
m_NinjaJetpack = pChr->m_NinjaJetpack;
m_FreezeTime = pChr->m_FreezeTime;
m_FreezeTick = pChr->Server()->Tick() - pChr->m_FreezeTick;
m_FreezeTick = pChr->Server()->Tick() - pChr->m_Core.m_FreezeTick;
m_DeepFreeze = pChr->m_DeepFreeze;
m_LiveFreeze = pChr->m_LiveFreeze;
@ -134,7 +134,7 @@ void CSaveTee::Load(CCharacter *pChr, int Team, bool IsSwap)
pChr->m_Jetpack = m_Jetpack;
pChr->m_NinjaJetpack = m_NinjaJetpack;
pChr->m_FreezeTime = m_FreezeTime;
pChr->m_FreezeTick = pChr->Server()->Tick() - m_FreezeTick;
pChr->m_Core.m_FreezeTick = pChr->Server()->Tick() - m_FreezeTick;
pChr->m_DeepFreeze = m_DeepFreeze;
pChr->m_LiveFreeze = m_LiveFreeze;