Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions game/neo/scripts/HudLayout.res
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,16 @@
"sprint_text_color" "255 255 255 100"
"sprint_color" "255 255 255 150"
}
neo_walking_indicator
{
"fieldName" "neo_walking_indicator"
"xpos" "208"
"ypos" "470"
"wide" "24"
"tall" "24"
"visible" "1"
"enabled" "1"
}
RoundResult
{
"fieldName" "RoundResult"
Expand Down
2 changes: 2 additions & 0 deletions src/game/client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1610,6 +1610,8 @@ target_sources_grouped(
neo/ui/neo_hud_round_state.h
neo/ui/neo_hud_startup_sequence.cpp
neo/ui/neo_hud_startup_sequence.h
neo/ui/neo_hud_walking_indicator.cpp
neo/ui/neo_hud_walking_indicator.h
neo/ui/neo_hud_worldpos_marker.cpp
neo/ui/neo_hud_worldpos_marker.h
neo/ui/neo_hud_worldpos_marker_generic.cpp
Expand Down
3 changes: 2 additions & 1 deletion src/game/client/neo/c_neo_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ class C_NEO_Player : public C_HL2MP_Player
#ifdef GLOWS_ENABLE
void UpdateGlowEffects(int iNewTeam);
#endif // GLOWS_ENABLE

bool ShouldPlayerMakeFootsteps(float speed = -1.f);
float SpeedFractionToSoundThreshold(float speed = -1.f);

private:
char m_sNameWithTakeoverContextProcessingBuffer[MAX_PLAYER_NAME_LENGTH];
Expand Down
85 changes: 85 additions & 0 deletions src/game/client/neo/ui/neo_hud_walking_indicator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include "cbase.h"
#include "neo_hud_walking_indicator.h"

#include "iclientmode.h"
#include <vgui/ISurface.h>

#include "c_neo_player.h"

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

DECLARE_NAMED_HUDELEMENT(CNEOHud_WalkingIndicator, neo_walking_indicator);

NEO_HUD_ELEMENT_DECLARE_FREQ_CVAR(WalkingIndicator, 0.1)

CNEOHud_WalkingIndicator::CNEOHud_WalkingIndicator(const char *pElementName, vgui::Panel *parent)
: CHudElement(pElementName), Panel(parent, pElementName)
{
SetAutoDelete(true);
m_iHideHudElementNumber = NEO_HUD_ELEMENT_WALKING_INDICATOR;

if (parent) {
SetParent(parent);
}
else
{
SetParent(g_pClientMode->GetViewport());
}

m_hWalkingIndicatorTexture = vgui::surface()->CreateNewTextureID();
Assert(m_hWalkingIndicatorTexture > 0);
vgui::surface()->DrawSetTextureFile(m_hWalkingIndicatorTexture, "vgui/hud/player/walkingIndicator", 1, false);

SetVisible(true);
}

void CNEOHud_WalkingIndicator::ApplySchemeSettings(vgui::IScheme* pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);

SetBounds(xpos, ypos-tall, wide, tall);
SetFgColor(COLOR_TRANSPARENT);
SetBgColor(COLOR_TRANSPARENT);
}

void CNEOHud_WalkingIndicator::UpdateStateForNeoHudElementDraw()
{
}

void CNEOHud_WalkingIndicator::DrawNeoHudElement()
{
if (!ShouldDraw())
return;

C_NEO_Player* pLocalPlayer = C_NEO_Player::GetLocalNEOPlayer();
if (!pLocalPlayer)
return;

C_NEO_Player* pTargetPlayer = pLocalPlayer->IsObserver() && (pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE || pLocalPlayer->GetObserverMode() == OBS_MODE_CHASE) ? static_cast<C_NEO_Player *>(pLocalPlayer->GetObserverTarget()) : pLocalPlayer;
if (!pTargetPlayer)
return;

if (!pTargetPlayer->IsAlive() || !pTargetPlayer->IsWalking())// && !pTargetPlayer->IsInAim()) player is also silent if aiming and not abusing the threshold, but its much harder to make noise when aiming, better for the indicator to strictly appear when walk is pressed
return;

// we don't want the subrectangle taken from the texture to vary in size when speed changes but the split between the top and bottom image remains in the same spot since texture can be larger than the area its drawn to
const int pictureSplitDistanceInPixels = tall * (1 - Max(0.f, Min(1.f, pTargetPlayer->SpeedFractionToSoundThreshold())));
const float pictureSplitDistanceFraction = (float)pictureSplitDistanceInPixels / tall;

vgui::surface()->DrawSetTexture(m_hWalkingIndicatorTexture);
vgui::surface()->DrawSetColor(COLOR_WHITE);
const float ICON_WIDTH = 1 / 2.f;
const float ICON_HEIGHT = 1 / 2.f;
vgui::surface()->DrawTexturedSubRect(0, 0, wide, pictureSplitDistanceInPixels,
0, ICON_HEIGHT, ICON_WIDTH, ICON_HEIGHT + (ICON_HEIGHT * pictureSplitDistanceFraction));
vgui::surface()->DrawSetColor(255, 255 * pictureSplitDistanceFraction, 255 * pictureSplitDistanceFraction, 255);
vgui::surface()->DrawTexturedSubRect(0, pictureSplitDistanceInPixels, wide, tall,
0, ICON_HEIGHT * pictureSplitDistanceFraction, ICON_WIDTH, ICON_HEIGHT);
}

void CNEOHud_WalkingIndicator::Paint()
{
BaseClass::Paint();
PaintNeoElement();
}
34 changes: 34 additions & 0 deletions src/game/client/neo/ui/neo_hud_walking_indicator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include "neo_hud_childelement.h"
#include "hudelement.h"
#include <vgui_controls/Panel.h>

class CNEOHud_WalkingIndicator : public CNEOHud_ChildElement, public CHudElement, public vgui::Panel
{
DECLARE_CLASS_SIMPLE(CNEOHud_WalkingIndicator, Panel);

public:
CNEOHud_WalkingIndicator(const char *pElementName, vgui::Panel *parent = NULL);
void ApplySchemeSettings(vgui::IScheme* pScheme) override;

virtual void Paint() override;

protected:
virtual void UpdateStateForNeoHudElementDraw() override;
virtual void DrawNeoHudElement() override;
virtual ConVar* GetUpdateFrequencyConVar() const override;

private:
vgui::HTexture m_hWalkingIndicatorTexture = 0;

CPanelAnimationVarAliasType(int, xpos, "xpos", "r203", "proportional_xpos");
CPanelAnimationVarAliasType(int, ypos, "ypos", "446", "proportional_ypos");
CPanelAnimationVarAliasType(int, wide, "wide", "203", "proportional_xpos");
CPanelAnimationVarAliasType(int, tall, "tall", "32", "proportional_ypos");
CPanelAnimationVarAliasType(int, visible, "visible", "1", "int");
CPanelAnimationVarAliasType(int, enabled, "enabled", "1", "int");

private:
CNEOHud_WalkingIndicator(const CNEOHud_WalkingIndicator&other);
};
32 changes: 32 additions & 0 deletions src/game/server/neo/neo_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ ConVar sv_neo_warmup_godmode("sv_neo_warmup_godmode", "0", FCVAR_REPLICATED, "If
ConVar bot_class("bot_class", "-1", 0, "Force all bots to spawn with the specified class number, or -1 to disable.", true, NEO_CLASS_RANDOM, true, NEO_CLASS_LOADOUTABLE_COUNT-1);
static void BotChangeClassFn(const CCommand& args);
ConCommand bot_changeclass("bot_changeclass", BotChangeClassFn, "Force all bots to switch to the specified class number.");
static void BotChangeSkinFn(const CCommand& args);
ConCommand bot_changeskin("bot_changeskin", BotChangeSkinFn, "Force all bots to switch to the specified skin number.");

// Bot Cloak Detection Thresholds
// Base detection chance ratio (0.0 - 1.0) for bots to notice a cloaked target based on difficulty
Expand Down Expand Up @@ -4315,3 +4317,33 @@ static void BotChangeClassFn(const CCommand& args)
player->RequestSetClass(botClass);
}
}

static void BotChangeSkinFn(const CCommand& args)
{
constexpr int minValue = NEO_SKIN_FIRST;
constexpr int maxValue = NEO_SKIN__ENUM_COUNT - 1;

const auto nag = [&args]() {
Msg("Format: %s <number between %d and %d>\n", args.Arg(0), minValue, maxValue);
};

if (args.ArgC() != 2)
{
nag();
return;
}

const int botSkin = V_atoi(args.Arg(1));
if (botSkin < minValue || botSkin > maxValue)
{
nag();
return;
}

for (int i = 1; i <= gpGlobals->maxClients; ++i)
{
auto* player = assert_cast<CNEO_Player*>(UTIL_PlayerByIndex(i));
if (player && player->IsBot() && player->GetTeamNumber() >= FIRST_GAME_TEAM)
player->RequestSetSkin(botSkin);
}
}
3 changes: 3 additions & 0 deletions src/game/server/neo/neo_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ class CNEO_Player : public CHL2MP_Player
void BecomeJuggernaut();
void SpawnJuggernautPostDeath();

bool ShouldPlayerMakeFootsteps(float speed = -1.f);
float SpeedFractionToSoundThreshold(float speed = -1.f);

private:
bool m_bAllowGibbing;

Expand Down
23 changes: 6 additions & 17 deletions src/game/shared/baseplayer_shared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -693,29 +693,18 @@ void CBasePlayer::UpdateStepSound( surfacedata_t *psurface, const Vector &vecOri
}

#ifdef NEO
// Changing movement direction, looking around, wall-running accelerate the player. Threshold should be lower than regular speed, but higher than walk/aim speed
constexpr float SILENT_THRESHOLD_GRACE = 0.7f;
#endif //NEO
if (!neoPlayer->ShouldPlayerMakeFootsteps(speed))
{
return;
}
#endif // NEO

// play the sound
// 65% volume if ducking
if ( GetFlags() & FL_DUCKING )
{
fvol *= 0.65;
#ifdef NEO
if ((neoPlayer->IsInAim() || neoPlayer->IsWalking()) && speed <= (neoPlayer->GetCrouchSpeed() * SILENT_THRESHOLD_GRACE))
{
return;
}
#endif // NEO
}
#ifdef NEO

else if ((neoPlayer->IsInAim() || neoPlayer->IsWalking()) && speed <= (neoPlayer->GetNormSpeed() * SILENT_THRESHOLD_GRACE))
{
return;
}

#endif
PlayStepSound( feet, psurface, fvol, false );
}

Expand Down
1 change: 1 addition & 0 deletions src/game/shared/neo/neo_gamerules.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ enum NeoHudElements : NEO_HUD_BITS_UNDERLYING_TYPE {
NEO_HUD_ELEMENT_SCOREBOARD = (static_cast<NEO_HUD_BITS_UNDERLYING_TYPE>(1) << 14),
NEO_HUD_ELEMENT_PLAYER_PING = (static_cast<NEO_HUD_BITS_UNDERLYING_TYPE>(1) << 15),
NEO_HUD_ELEMENT_WORLDPOS_MARKER_ENT = (static_cast<NEO_HUD_BITS_UNDERLYING_TYPE>(1) << 16),
NEO_HUD_ELEMENT_WALKING_INDICATOR = (static_cast<NEO_HUD_BITS_UNDERLYING_TYPE>(1) << 17),
};

class CNEORules : public CHL2MPRules, public CGameEventListener
Expand Down
36 changes: 36 additions & 0 deletions src/game/shared/neo/neo_player_shared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,3 +403,39 @@ void CNEO_Player::CheckAimButtons()
Weapon_SetZoom(false);
}
}

// Changing movement direction, looking around, wall-running accelerate the player. Threshold should be lower than regular speed, but higher than walk/aim speed
constexpr float SILENT_THRESHOLD_GRACE = 0.7f;
bool CNEO_Player::ShouldPlayerMakeFootsteps(float speed) // Could simply always get speed from the player, but didnt want to risk changing the behavior of UpdateStepSound in baseplayer_shared
{
if (speed < 0)
{
speed = GetAbsVelocity().Length();
}

if ( GetFlags() & FL_DUCKING && (IsInAim() || IsWalking()) && speed <= (GetCrouchSpeed() * SILENT_THRESHOLD_GRACE) )
{
return false;
}
else if ((IsInAim() || IsWalking()) && speed <= (GetNormSpeed() * SILENT_THRESHOLD_GRACE))
{
return false;
}

return true;
}

float CNEO_Player::SpeedFractionToSoundThreshold(float speed)
{
if (speed < 0)
{
speed = GetAbsVelocity().Length();
}

if (IsInAim() || IsWalking())
{
const float difference = ((GetFlags() & FL_DUCKING ? GetCrouchSpeed() : GetNormSpeed()) * SILENT_THRESHOLD_GRACE) - GetPlayerMaxSpeed();
return (speed - GetPlayerMaxSpeed()) / difference;
}
return 1.f;
}
Loading