Skip to content

Player Transparency #368

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
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
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
5 changes: 4 additions & 1 deletion cfg/cs2fixes/cs2fixes.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,7 @@ entwatch_auto_filter 1 // Whether to automatically block non-item holders fro
entwatch_clantag 1 // Whether to set item holder's clantag and set 9999 score
entwatch_score 9999 // Score to give item holders (0 = dont change score at all) Requires entwatch_clantag 1
entwatch_glow 1000 // Distance that dropped item weapon glow will be visible (0 = glow disabled)
entwatch_glow_team 0 // Whether dropped item glow is only visible to the team the item belongs to (0 = glow to all players)
entwatch_glow_team 0 // Whether dropped item glow is only visible to the team the item belongs to (0 = glow to all players)

// Player Transparency
cs2f_transparency_enable 0 // Whether to enable player transparency particle
25 changes: 25 additions & 0 deletions src/commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,31 @@ CON_COMMAND_CHAT(hide, "<distance> - Hide nearby players")
ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "Now hiding players within %i units.", distance);
}

CConVar<bool> g_cvarEnableTransparency("cs2f_transparency_enable", FCVAR_NONE, "Whether to enable player transparency particle", false);

CON_COMMAND_CHAT(transparency, "Hide nearby players with ***particle***")
{
if (!player)
{
ClientPrint(player, HUD_PRINTCONSOLE, CHAT_PREFIX "You cannot use this command from the server console.");
return;
}
if (!g_cvarEnableTransparency.Get())
return;
ZEPlayer* pZEPlayer = player->GetZEPlayer();
int iPlayer = player->GetPlayerSlot();
bool bTransparencySet = g_playerManager->IsPlayerUsingTransparency(iPlayer);
g_playerManager->SetPlayerTransparency(iPlayer, !bTransparencySet);
pZEPlayer->SetTeamTransparency(!bTransparencySet, -1);
if (!bTransparencySet)
ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "Now hiding players.");
else
{
pZEPlayer->ResetTransparencyMask(true);
ClientPrint(player, HUD_PRINTTALK, CHAT_PREFIX "Hiding players is now disabled.");
}
}

void PrintHelp(const CCommand& args, CCSPlayerController* player)
{
std::vector<std::string> rgstrCommands;
Expand Down
1 change: 1 addition & 0 deletions src/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ extern CConVar<bool> g_cvarEnableHide;
extern CConVar<bool> g_cvarEnableStopSound;
extern CConVar<bool> g_cvarEnableNoShake;
extern CConVar<float> g_cvarMaxShakeAmp;
extern CConVar<bool> g_cvarEnableTransparency;

void ClientPrintAll(int destination, const char* msg, ...);
void ClientPrint(CCSPlayerController* player, int destination, const char* msg, ...);
Expand Down
34 changes: 34 additions & 0 deletions src/cs2_sdk/entity/ccsplayercontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,40 @@ class CCSPlayerController : public CBasePlayerController
if (!IsController())
return;

// disable hide particle on self for opposite team & enable hide particle on self for teammate
ZEPlayer* pZEPlayer = GetZEPlayer();
if (g_bTransparencyParticleReady && pZEPlayer)
{
if (iTeam == CS_TEAM_SPECTATOR)
pZEPlayer->ResetTransparencyMask(true);
else if (iTeam == CS_TEAM_CT || iTeam == CS_TEAM_T)
{
for (int i = 0; i < GetGlobals()->maxClients; i++)
{
if (i == GetPlayerSlot())
continue;

if (!g_playerManager->IsPlayerUsingTransparency(i))
continue;

CCSPlayerController* pPeerController = CCSPlayerController::FromSlot(i);

if (!pPeerController || pPeerController->m_bIsHLTV)
continue;
ZEPlayer* pZEPeerPlayer = pPeerController->GetZEPlayer();
if (pZEPeerPlayer)
pZEPeerPlayer->QueuePeerTransparency(pPeerController->m_iTeamNum() == iTeam, GetPlayerSlot());
}

// enable hide particle on others for self
if (g_playerManager->IsPlayerUsingTransparency(GetPlayerSlot()))
{
pZEPlayer->ResetTransparencyMask(true);
pZEPlayer->SetTeamTransparency(true, iTeam);
}
}
}

if (iTeam == CS_TEAM_SPECTATOR)
ChangeTeam(iTeam);
else
Expand Down
8 changes: 8 additions & 0 deletions src/events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,12 @@ GAME_EVENT_F(round_start)
if (g_cvarFixHudFlashing.Get() && g_pGameRules && g_pGameRules->m_bWarmupPeriod)
g_pEngineServer2->ServerCommand("mp_warmup_end");

if (g_cvarEnableTransparency.Get())
new CTimer(1.0f, false, false, [] {
g_playerManager->SetupTransparencyParticle();
return -1.0f;
});

if (!g_cvarEnableTopDefender.Get() || !GetGlobals())
return;

Expand All @@ -283,6 +289,8 @@ GAME_EVENT_F(round_end)
if (g_cvarFixHudFlashing.Get() && g_pGameRules)
g_pGameRules->m_bGameRestart = false;

g_bTransparencyParticleReady = false;

if (!g_cvarEnableTopDefender.Get() || !GetGlobals())
return;

Expand Down
161 changes: 160 additions & 1 deletion src/playermanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "utlstring.h"
#include "votemanager.h"
#include <../cs2fixes.h>
#include <stdio.h>

#include "tier0/memdbgon.h"

Expand All @@ -47,11 +48,13 @@ extern IGameEventSystem* g_gameEventSystem;
extern CUtlVector<CServerSideClient*>* GetClientList();
extern CSpawnGroupMgrGameSystem* g_pSpawnGroupMgr;

bool g_bTransparencyParticleReady = false;

CConVar<int> g_cvarAdminImmunityTargetting("cs2f_admin_immunity", FCVAR_NONE, "Mode for which admin immunity system targetting allows: 0 - strictly lower, 1 - equal to or lower, 2 - ignore immunity levels", 0, true, 0, true, 2);
CConVar<bool> g_cvarEnableMapSteamIds("cs2f_map_steamids_enable", FCVAR_NONE, "Whether to make Steam ID's available to maps", false);

ZEPlayerHandle::ZEPlayerHandle() :
m_Index(INVALID_ZEPLAYERHANDLE_INDEX){};
m_Index(INVALID_ZEPLAYERHANDLE_INDEX) {};

ZEPlayerHandle::ZEPlayerHandle(CPlayerSlot slot)
{
Expand Down Expand Up @@ -288,6 +291,12 @@ bool ZEPlayer::IsFlooding()
void PrecacheBeaconParticle(IEntityResourceManifest* pResourceManifest)
{
pResourceManifest->AddResource(g_cvarBeaconParticle.Get().String());
for (int i = 0; i < 64; i++)
{
char filePath[100];
sprintf(filePath, "particles/cs2fixes/hide2/player_hide_branch_%d.vpcf", i);
pResourceManifest->AddResource(filePath);
}
}

void ZEPlayer::StartBeacon(Color color, ZEPlayerHandle hGiver /* = 0*/)
Expand Down Expand Up @@ -753,6 +762,130 @@ void ZEPlayer::SetEntwatchHudSize(float flSize)
pText->m_flFontSize = m_flEntwatchHudSize;
}

void ZEPlayer::QueuePeerTransparency(bool bEnabled, CPlayerSlot slot)
{
if (bEnabled)
m_nTransparencyQueue |= ((uint64)1 << slot.Get());
else
m_nTransparencyQueue &= ~((uint64)1 << slot.Get());
}

void ZEPlayer::ApplyPeerTransparencyFromQueue()
{
for (int i = 0; i < GetGlobals()->maxClients; i++)
{
if (i == GetPlayerSlot().Get())
continue;
SetPeerTransparency(GetPeerTransparencyQueue(i), i);
}
}

// dispatch one to toggle, dispatch two to always disable
void ZEPlayer::SetPeerTransparency(bool bEnabled, CPlayerSlot slot)
{
bool isTransparent = GetPeerTransparency(slot);
if (bEnabled == isTransparent)
return;

CSingleRecipientFilter filter(GetPlayerSlot());
char filePath[100];
sprintf(filePath, "particles/cs2fixes/hide2/player_hide_branch_%d.vpcf", slot.Get());

CCSPlayerController* pController = CCSPlayerController::FromSlot(GetPlayerSlot());
CCSPlayerController* pPeerController = CCSPlayerController::FromSlot(slot);
if (!pPeerController)
{
if (!pController)
return;
pController->DispatchParticle(filePath, &filter);
pController->DispatchParticle(filePath, &filter);
return;
}
CCSPlayerPawn* pPawn = pPeerController->GetPlayerPawn();
if (!pPawn)
{
if (!pController)
return;
pController->DispatchParticle(filePath, &filter);
pController->DispatchParticle(filePath, &filter);
return;
}

pPawn->DispatchParticle(filePath, &filter);
if (!bEnabled)
pPawn->DispatchParticle(filePath, &filter);

if (bEnabled)
m_nTransparencyMask |= ((uint64)1 << slot.Get());
else
m_nTransparencyMask &= ~((uint64)1 << slot.Get());
// Message("Dispatched Particle %s on %d for %d\n", filePath, slot.Get(), GetPlayerSlot());
}

void ZEPlayer::SetTeamTransparency(bool bEnabled, int iTeam)
{
CCSPlayerController* pController = CCSPlayerController::FromSlot(GetPlayerSlot());
if (!pController)
return;
for (int i = 0; i < GetGlobals()->maxClients; i++)
{
if (i == GetPlayerSlot().Get())
continue;
CCSPlayerController* pPeerController = CCSPlayerController::FromSlot(i);

if (!pPeerController || pPeerController->m_bIsHLTV || !(pPeerController->m_iTeamNum() == CS_TEAM_T || pPeerController->m_iTeamNum() == CS_TEAM_CT))
continue;
if (pPeerController->m_iTeamNum() != iTeam && !(iTeam == -1 && pPeerController->m_iTeamNum() == pController->m_iTeamNum()))
continue;

CCSPlayerPawn* pPawn = pPeerController->GetPlayerPawn();
if (pPawn)
QueuePeerTransparency(bEnabled, i);
}
}

void ZEPlayer::ResetTransparencyMask(bool bClearParticles)
{
if (bClearParticles)
{
for (int i = 1; i <= 64; i++)
{
if (i == GetPlayerSlot().Get())
continue;
QueuePeerTransparency(false, i);
}
}
else
{
m_nTransparencyQueue = 0;
m_nTransparencyMask = 0;
}
}

void CPlayerManager::SetupTransparencyParticle()
{
for (int i = 0; i < GetGlobals()->maxClients; i++)
{
ZEPlayer* pPlayer = g_playerManager->GetPlayer(i);
if (!pPlayer)
continue;

pPlayer->ResetTransparencyMask(false);
if (g_playerManager->IsPlayerUsingTransparency(i))
pPlayer->SetTeamTransparency(true, -1);
}

g_bTransparencyParticleReady = true;
new CTimer(0.3f, false, false, []() {
for (int i = 0; i < GetGlobals()->maxClients; i++)
{
ZEPlayer* pPlayer = g_playerManager->GetPlayer(i);
if (pPlayer) pPlayer->ApplyPeerTransparencyFromQueue();
}
return 0.3f;
});
}

void CPlayerManager::OnBotConnected(CPlayerSlot slot)
{
m_vecPlayers[slot.Get()] = new ZEPlayer(slot, true);
Expand Down Expand Up @@ -807,6 +940,15 @@ void CPlayerManager::OnClientDisconnect(CPlayerSlot slot)
{
Message("%d disconnected\n", slot.Get());

for (int i = 0; i < GetGlobals()->maxClients; i++)
{
ZEPlayer* pPlayer = GetPlayer(i);
if (!pPlayer)
continue;

pPlayer->SetPeerTransparency(false, slot);
}

g_pUserPreferencesSystem->PushPreferences(slot.Get());
g_pUserPreferencesSystem->ClearPreferences(slot.Get());

Expand Down Expand Up @@ -1793,13 +1935,30 @@ void CPlayerManager::SetPlayerNoShake(int slot, bool set)
int iNoShakePreferenceStatus = (m_nUsingNoShake & iSlotMask) ? 1 : 0;
g_pUserPreferencesSystem->SetPreferenceInt(slot, NO_SHAKE_PREF_KEY_NAME, iNoShakePreferenceStatus);
}
void CPlayerManager::SetPlayerTransparency(int slot, bool set)
{
if (set)
m_nUsingTransparency |= ((uint64)1 << slot);
else
m_nUsingTransparency &= ~((uint64)1 << slot);

// Set the user prefs if the player is ingame
ZEPlayer* pPlayer = m_vecPlayers[slot];
if (!pPlayer)
return;

uint64 iSlotMask = (uint64)1 << slot;
int iTransparencyPreferenceStatus = (m_nUsingTransparency & iSlotMask) ? 1 : 0;
g_pUserPreferencesSystem->SetPreferenceInt(slot, TRANSPARENCY_PREF_KEY_NAME, iTransparencyPreferenceStatus);
}

void CPlayerManager::ResetPlayerFlags(int slot)
{
SetPlayerStopSound(slot, true);
SetPlayerSilenceSound(slot, false);
SetPlayerStopDecals(slot, true);
SetPlayerNoShake(slot, false);
SetPlayerTransparency(slot, false);
}

int CPlayerManager::GetOnlinePlayerCount(bool bCountBots)
Expand Down
Loading