Skip to content
8 changes: 4 additions & 4 deletions src/game/client/neo/ui/neo_hud_compass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ void CNEOHud_Compass::UpdateStateForNeoHudElementDraw()
auto pFPPlayer = GetFirstPersonPlayer();
Assert(pFPPlayer);

// Point the objective arrow to the ghost, if it exists
if (NEORules()->GhostExists() || NEORules()->JuggernautItemExists())
// Point the objective arrow to the relevant objective, if it exists
if (NEORules()->GhostExists() || NEORules()->GetJuggernautMarkerPos() != vec3_origin)
{
const Vector objPos = NEORules()->GetGameType() == NEO_GAME_TYPE_JGR ? NEORules()->GetJuggernautMarkerPos() : NEORules()->GetGhostPos();
const Vector objVec = objPos - pFPPlayer->EyePosition();
Expand Down Expand Up @@ -207,8 +207,8 @@ void CNEOHud_Compass::DrawCompass() const
// Print compass objective arrow
if (m_objectiveVisible && !player->IsObjective())
{
// Point the objective arrow to the ghost, if it exists
if (NEORules()->GhostExists() || NEORules()->JuggernautItemExists())
// Point the objective arrow to the relevant objective, if it exists
if (NEORules()->GhostExists() || NEORules()->GetJuggernautMarkerPos() != vec3_origin)
{
const float proportion = m_objAngle / m_fov + 0.5;

Expand Down
32 changes: 27 additions & 5 deletions src/game/client/neo/ui/neo_hud_friendly_marker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,18 @@ CNEOHud_FriendlyMarker::CNEOHud_FriendlyMarker(const char* pElemName, vgui::Pane
surface()->GetScreenSize(wide, tall);
SetBounds(0, 0, wide, tall);

m_hTex = surface()->CreateNewTextureID();
Assert(m_hTex > 0);
surface()->DrawSetTextureFile(m_hTex, "vgui/hud/star", 1, false);
surface()->DrawGetTextureSize(m_hTex, m_iMarkerTexWidth, m_iMarkerTexHeight);
m_hStarTex = surface()->CreateNewTextureID();
Assert(m_hStarTex > 0);
surface()->DrawSetTextureFile(m_hStarTex, "vgui/hud/star", 1, false);
surface()->DrawGetTextureSize(m_hStarTex, m_iMarkerTexWidth, m_iMarkerTexHeight);

m_hNonStarTex = surface()->CreateNewTextureID();
Assert(m_hNonStarTex > 0);
surface()->DrawSetTextureFile(m_hNonStarTex, "vgui/hud/non_star", 1, false);

m_hUniqueTex = surface()->CreateNewTextureID();
Assert(m_hUniqueTex > 0);
surface()->DrawSetTextureFile(m_hUniqueTex, "vgui/hud/unique_star", 1, false);

SetFgColor(Color(0, 0, 0, 0));
SetBgColor(Color(0, 0, 0, 0));
Expand Down Expand Up @@ -236,7 +244,21 @@ void CNEOHud_FriendlyMarker::DrawPlayer(Color teamColor, C_NEO_Player *player, c

if (!drawOutline)
{
surface()->DrawSetTexture(m_hTex);
if (player->GetClass() != NEO_CLASS_JUGGERNAUT && player->GetClass() != NEO_CLASS_VIP)
{
if (player->GetStar() == localPlayer->GetStar())
{
surface()->DrawSetTexture(m_hStarTex);
}
else
{
surface()->DrawSetTexture(m_hNonStarTex);
}
}
else
{
surface()->DrawSetTexture(m_hUniqueTex);
}
surface()->DrawSetColor(teamColor);
surface()->DrawTexturedRect(
x - m_iMarkerWidth,
Expand Down
4 changes: 3 additions & 1 deletion src/game/client/neo/ui/neo_hud_friendly_marker.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ class CNEOHud_FriendlyMarker : public CNEOHud_WorldPosMarker
int m_y0[MAX_PLAYERS];
int m_y1[MAX_PLAYERS];

vgui::HTexture m_hTex = 0UL;
vgui::HTexture m_hStarTex = 0UL;
vgui::HTexture m_hNonStarTex = 0UL;
vgui::HTexture m_hUniqueTex = 0UL;
vgui::HFont m_hFont = 0UL;

void DrawPlayer(Color teamColor, C_NEO_Player *player, const C_NEO_Player *localPlayer) const;
Expand Down
11 changes: 6 additions & 5 deletions src/game/server/neo/neo_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3362,12 +3362,14 @@ void CNEO_Player::BecomeJuggernaut()
#define COLOR_JGR_FADE color32{170, 170, 170, 255}
UTIL_ScreenFade(this, COLOR_JGR_FADE, 1.0f, 0.0f, FFADE_IN);

RemoveAllItems(false);
m_iNeoClass = NEO_CLASS_JUGGERNAUT;
GiveDefaultItems();
// Set model after weapon change to avoid studio asserts
SetPlayerTeamModel();

SetViewOffset(VEC_VIEW_NEOSCALE(this));
InitSprinting();
RemoveAllItems(false);
GiveDefaultItems();
SetMaxHealth(MAX_HEALTH_FOR_CLASS[NEO_CLASS_JUGGERNAUT]);
SetHealth(GetMaxHealth());
SuitPower_SetCharge(100);
Expand Down Expand Up @@ -3400,10 +3402,9 @@ void CNEO_Player::SpawnJuggernautPostDeath()
soundFilter.MakeReliable();
EmitSound(soundFilter, this->entindex(), soundParams);
}

NEORules()->m_pJuggernautPlayer = nullptr;
NEORules()->m_pJuggernautItem = pJuggernautItem;
}
NEORules()->JuggernautDeactivated(pJuggernautItem);

m_hServerRagdoll = pJuggernautItem;
DispatchSpawn(pJuggernautItem);
}
Expand Down
43 changes: 38 additions & 5 deletions src/game/shared/neo/neo_gamerules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,7 @@ void CNEORules::Think(void)
}

// Allow respawn if it's an idle, warmup round, pausing, or deathmatch-type gamemode
const bool bIsDMType = (m_nGameTypeSelected == NEO_GAME_TYPE_DM || m_nGameTypeSelected == NEO_GAME_TYPE_TDM);
const bool bIsDMType = (m_nGameTypeSelected == NEO_GAME_TYPE_DM || m_nGameTypeSelected == NEO_GAME_TYPE_TDM || m_nGameTypeSelected == NEO_GAME_TYPE_JGR);
if (bIsDMType || bIsIdleState || bIsPause)
{
CRecipientFilter filter;
Expand Down Expand Up @@ -1369,9 +1369,21 @@ void CNEORules::Think(void)
Assert(false);
}

m_iJuggernautPlayerIndex = 0;
m_bJuggernautItemExists = true;
}
else if (m_pJuggernautPlayer)
{
if (m_pJuggernautPlayer->GetAbsOrigin().IsValid())
{
m_vecJuggernautMarkerPos = m_pJuggernautPlayer->WorldSpaceCenter();
}
else
{
Assert(false);
}

m_bJuggernautItemExists = false;
}
else
{
m_bJuggernautItemExists = false;
Expand Down Expand Up @@ -1921,7 +1933,10 @@ void CNEORules::SpawnTheJuggernaut(const Vector* origin)
}
else if (auto* jgr = dynamic_cast<CNEO_Juggernaut*>(pEnt))
{
m_pJuggernautItem = jgr;
if (!jgr->IsMarkedForDeletion())
{
m_pJuggernautItem = jgr;
}
}

pEnt = gEntList.NextEnt(pEnt);
Expand Down Expand Up @@ -2064,14 +2079,32 @@ void CNEORules::SelectTheVIP()
Assert(false);
}

void CNEORules::JuggernautActivated(CNEO_Player* pPlayer)
void CNEORules::JuggernautActivated(CNEO_Player *pPlayer)
{
if (GetGameType() == NEO_GAME_TYPE_JGR)
{
m_pJuggernautPlayer = pPlayer;
m_iJuggernautPlayerIndex = pPlayer->entindex();
m_pJuggernautItem = nullptr;
m_vecJuggernautMarkerPos = vec3_origin;

for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer *pTargetPlayer = UTIL_PlayerByIndex(i);
if (pTargetPlayer && pTargetPlayer->IsDead() && pTargetPlayer->DeathCount() > 0 && pTargetPlayer->GetTeamNumber() == pPlayer->GetTeamNumber())
{
pTargetPlayer->ForceRespawn();
}
}
}
}

void CNEORules::JuggernautDeactivated(CNEO_Juggernaut *pJuggernaut)
{
if (GetGameType() == NEO_GAME_TYPE_JGR)
{
m_pJuggernautPlayer = nullptr;
m_iJuggernautPlayerIndex = 0;
m_pJuggernautItem = pJuggernaut;
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/game/shared/neo/neo_gamerules.h
Original file line number Diff line number Diff line change
Expand Up @@ -412,9 +412,11 @@ class CNEORules : public CHL2MPRules, public CGameEventListener
void SelectTheVIP();
public:
void JuggernautActivated(CNEO_Player *pPlayer);
void JuggernautDeactivated(CNEO_Juggernaut *pJuggernaut);
private:
CNEO_Juggernaut *m_pJuggernautItem = nullptr;
CNEO_Player *m_pJuggernautPlayer = nullptr;
private:

friend class CNEOBotSeekAndDestroy;
CUtlVector<int> m_pGhostCaps;
CWeaponGhost *m_pGhost = nullptr;
Expand Down
17 changes: 14 additions & 3 deletions src/game/shared/neo/neo_juggernaut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include "model_types.h"
#endif

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

#define USE_DURATION 5.0f
#define USE_DISTANCE_SQUARED 22500.0f

Expand All @@ -16,8 +19,12 @@ LINK_ENTITY_TO_CLASS(neo_juggernaut, CNEO_Juggernaut);
IMPLEMENT_SERVERCLASS_ST(CNEO_Juggernaut, DT_NEO_Juggernaut)
END_SEND_TABLE()
#else
IMPLEMENT_CLIENTCLASS_DT(CNEO_Juggernaut, DT_NEO_Juggernaut, CNEO_Juggernaut)
#ifdef CNEO_Juggernaut
#undef CNEO_Juggernaut
#endif
IMPLEMENT_CLIENTCLASS_DT(C_NEO_Juggernaut, DT_NEO_Juggernaut, CNEO_Juggernaut)
END_RECV_TABLE()
#define CNEO_Juggernaut C_NEO_Juggernaut
#endif

BEGIN_DATADESC(CNEO_Juggernaut)
Expand All @@ -29,6 +36,12 @@ BEGIN_DATADESC(CNEO_Juggernaut)
#endif
END_DATADESC()

void CNEO_Juggernaut::UpdateOnRemove()
{
StopSound("HUD.CPCharge");
BaseClass::UpdateOnRemove();
}

#ifdef GAME_DLL
void CNEO_Juggernaut::Precache(void)
{
Expand Down Expand Up @@ -109,8 +122,6 @@ void CNEO_Juggernaut::Spawn(void)
SetNextThink(TICK_NEVER_THINK);
SetContextThink(&CNEO_Juggernaut::AnimThink, gpGlobals->curtime + TICK_INTERVAL, "AnimThink");

StopSound("HUD.CPCharge"); // for round reset

BaseClass::Spawn();
}

Expand Down
7 changes: 7 additions & 0 deletions src/game/shared/neo/neo_juggernaut.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
#pragma once

#include "cbase.h"
#ifdef GAME_DLL
#include "neo_player.h"
#else
#include "c_neo_player.h"
#endif

#ifdef CLIENT_DLL
#define CNEO_Juggernaut C_NEO_Juggernaut
#endif

class CNEO_Juggernaut : public CBaseAnimating
{
public:
Expand All @@ -25,6 +31,7 @@ class CNEO_Juggernaut : public CBaseAnimating
#endif

virtual unsigned int PhysicsSolidMaskForEntity() const final override { return MASK_PLAYERSOLID; }
virtual void UpdateOnRemove() override;

private:
#ifdef GAME_DLL
Expand Down