Skip to content
Merged
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
2 changes: 2 additions & 0 deletions cfg/cs2fixes/cs2fixes.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,5 @@ entwatch_enable 0 // INCOMPATIBLE WITH CS#. Whether to enable EntWatch feat
entwatch_auto_filter 1 // Whether to automatically block non-item holders from triggering uses
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)
4 changes: 2 additions & 2 deletions src/cs2_sdk/entity/ccsweaponbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#pragma once

#include "cbaseentity.h"
#include "cbasemodelentity.h"

extern CGlobalVars* GetGlobals();

Expand Down Expand Up @@ -61,7 +61,7 @@ class CAttributeContainer
SCHEMA_FIELD(CEconItemView, m_Item)
};

class CEconEntity : public CBaseEntity
class CEconEntity : public CBaseModelEntity
{
public:
DECLARE_SCHEMA_CLASS(CEconEntity)
Expand Down
3 changes: 3 additions & 0 deletions src/cs2_sdk/entity/globaltypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,5 +224,8 @@ class CGlowProperty
SCHEMA_FIELD(int, m_nGlowRangeMin)
SCHEMA_FIELD(Color, m_glowColorOverride)
SCHEMA_FIELD(bool, m_bFlashing)
SCHEMA_FIELD(float, m_flGlowTime)
SCHEMA_FIELD(float, m_flGlowStartTime)
SCHEMA_FIELD(bool, m_bEligibleForScreenHighlight)
SCHEMA_FIELD(bool, m_bGlowing)
};
190 changes: 189 additions & 1 deletion src/entwatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,37 @@ SH_DECL_MANUALHOOK1_void(CTriggerMultiple_EndTouch, 0, 0, 0, CBaseEntity*);
CConVar<bool> g_cvarEnableEntWatch("entwatch_enable", FCVAR_NONE, "INCOMPATIBLE WITH CS#. Whether to enable EntWatch features", false);
CConVar<bool> g_cvarEnableFiltering("entwatch_auto_filter", FCVAR_NONE, "Whether to automatically block non-item holders from triggering uses", true);
CConVar<bool> g_cvarUseEntwatchClantag("entwatch_clantag", FCVAR_NONE, "Whether to set item holder's clantag and set score", true);

CConVar<int> g_cvarItemHolderScore("entwatch_score", FCVAR_NONE, "Score to give item holders (0 = dont change score at all) Requires entwatch_clantag 1", 9999, true, 0, false, 0);

void ItemGlowDistanceChanged(CConVar<int>* ref, CSplitScreenSlot nSlot, const int* pNewValue, const int* pOldValue)
{
if (!g_pEWHandler || !g_pEWHandler->IsConfigLoaded() || g_pEWHandler->vecItems.size() < 1)
return;

int newValue = *pNewValue;
for (int i = 0; i < g_pEWHandler->vecItems.size(); i++)
{
std::shared_ptr<EWItemInstance> item = g_pEWHandler->vecItems[i];
CCSWeaponBase* pItemWeapon = (CCSWeaponBase*)g_pEntitySystem->GetEntityInstance((CEntityIndex)item->iWeaponEnt);
if (!pItemWeapon)
continue;

if (pItemWeapon->m_Glow().m_bGlowing)
{
if (newValue > 0)
pItemWeapon->m_Glow().m_nGlowRange = newValue;
else
item->EndGlow();
}
else if (item->bShouldGlow && newValue > 0)
{
item->StartGlow();
}
}
}
CConVar<int> g_cvarItemDroppedGlow("entwatch_glow", FCVAR_NONE, "Distance that dropped item weapon glow will be visible (0 = glow disabled)", 1000, true, 0, false, 0, ItemGlowDistanceChanged);
CConVar<bool> g_cvarItemDroppedGlowTeam("entwatch_glow_team", FCVAR_NONE, "Whether dropped item glow is only visible to the team the item belongs to (0 = glow to all players)", false);

void EWItemHandler::SetDefaultValues()
{
type = EWHandlerType::Other;
Expand Down Expand Up @@ -462,6 +490,7 @@ void EWItem::SetDefaultValues()
szShortName = "";
/* no default hammerid */
V_strcpy(sChatColor, "\x01");
colorGlow = Color(255, 255, 255, 255);
bShowPickup = true;
bShowHud = true;
transfer = EWCfg_Auto;
Expand All @@ -473,36 +502,81 @@ void EWItem::SetDefaultValues()
void EWItem::ParseColor(std::string value)
{
if (value == "white" || value == "default")
{
V_strcpy(sChatColor, "\x01");
colorGlow = Color(255, 255, 255, 255);
}
else if (value == "darkred")
{
V_strcpy(sChatColor, "\x02");
colorGlow = Color(220, 0, 0, 255);
}
else if (value == "team")
{
V_strcpy(sChatColor, "\x03");
colorGlow = Color(184, 130, 242, 255);
}
else if (value == "green")
{
V_strcpy(sChatColor, "\x04");
colorGlow = Color(30, 255, 30, 255);
}
else if (value == "lightgreen")
{
V_strcpy(sChatColor, "\x05");
colorGlow = Color(178, 255, 145, 255);
}
else if (value == "olive")
{
V_strcpy(sChatColor, "\x06");
colorGlow = Color(184, 220, 63, 255);
}
else if (value == "red")
{
V_strcpy(sChatColor, "\x07");
colorGlow = Color(255, 65, 65, 255);
}
else if (value == "gray" || value == "grey")
{
V_strcpy(sChatColor, "\x08");
colorGlow = Color(175, 180, 180, 255);
}
else if (value == "yellow")
{
V_strcpy(sChatColor, "\x09");
colorGlow = Color(250, 250, 25, 255);
}
else if (value == "silver")
{
V_strcpy(sChatColor, "\x0A");
colorGlow = Color(165, 180, 210, 255);
}
else if (value == "blue")
{
V_strcpy(sChatColor, "\x0B");
colorGlow = Color(114, 188, 255, 255);
}
else if (value == "darkblue")
{
V_strcpy(sChatColor, "\x0C");
colorGlow = Color(45, 75, 255, 255);
}
// \x0D is the same as \x0A
else if (value == "purple" || value == "pink")
{
V_strcpy(sChatColor, "\x0E");
colorGlow = Color(210, 43, 229, 255);
}
else if (value == "red2")
{
V_strcpy(sChatColor, "\x0F");
colorGlow = Color(230, 120, 120, 255);
}
else if (value == "orange" || value == "gold")
{
V_strcpy(sChatColor, "\x10");
colorGlow = Color(235, 145, 46, 255);
}
}

EWItem::EWItem(std::shared_ptr<EWItem> pItem)
Expand All @@ -512,6 +586,7 @@ EWItem::EWItem(std::shared_ptr<EWItem> pItem)
szShortName = pItem->szShortName;
szHammerid = pItem->szHammerid;
V_strcpy(sChatColor, pItem->sChatColor);
colorGlow = pItem->colorGlow;
bShowPickup = pItem->bShowPickup;
bShowHud = pItem->bShowHud;
transfer = pItem->transfer;
Expand Down Expand Up @@ -740,6 +815,9 @@ void EWItemInstance::Pickup(int slot)
}
}

bShouldGlow = false;
EndGlow();

if (bShowPickup)
ClientPrintAll(HUD_PRINTTALK, EW_PREFIX "\x03%s \x05has picked up %s%s", pController->GetPlayerName(), sChatColor, szItemName.c_str());
}
Expand All @@ -753,6 +831,9 @@ void EWItemInstance::Drop(EWDropReason reason, CCSPlayerController* pController)
return;
}

if (bAllowDrop)
bShouldGlow = true;

if (g_cvarUseEntwatchClantag.Get() && bShowHud && bHasThisClantag)
{
bool bSetAnotherClantag = false;
Expand Down Expand Up @@ -845,10 +926,16 @@ void EWItemInstance::Drop(EWDropReason reason, CCSPlayerController* pController)
}
break;
case EWDropReason::Deleted:
bShouldGlow = false;
break;
default:
break;
}

// Start glowing
if (g_cvarItemDroppedGlow.Get() > 0 && reason != EWDropReason::Deleted && bAllowDrop)
StartGlow();

iOwnerSlot = -1;
}

Expand Down Expand Up @@ -877,6 +964,107 @@ std::string EWItemInstance::GetHandlerStateText()
return sText;
}

void EWItemInstance::StartGlow()
{
if (IsEmpty())
return;

if (!GetGlobals())
{
Message("Failed to get globals while glowing dropped item\n");
return;
}

CCSWeaponBase* pItemWeapon = (CCSWeaponBase*)g_pEntitySystem->GetEntityInstance((CEntityIndex)iWeaponEnt);
if (!pItemWeapon)
{
Message("Error getting weapon entity while creating item glow.\n");
return;
}

int r = colorGlow.r();
int g = colorGlow.g();
int b = colorGlow.b();
int a = colorGlow.a();
int iTeam = iTeamNum;
CHandle<CCSWeaponBase> hWep = pItemWeapon->GetHandle();
new CTimer(0.1f, false, false, [hWep, iTeam, r, g, b, a] {
CCSWeaponBase* pWep = hWep.Get();
if (pWep)
{
pWep->m_Glow().m_glowColorOverride = Color(r, g, b, a);

int team = g_cvarItemDroppedGlowTeam.Get() ? iTeam : -1;
pWep->m_Glow().m_iGlowTeam = team;

pWep->m_Glow().m_iGlowType = 3;
pWep->m_Glow().m_flGlowStartTime = GetGlobals()->curtime;
pWep->m_Glow().m_flGlowTime = 0;
pWep->m_Glow().m_nGlowRange = g_cvarItemDroppedGlow.Get();
pWep->m_Glow().m_bGlowing = true;
}
return -1.0f;
});
}

void EWItemInstance::EndGlow()
{
CCSWeaponBase* pItemWeapon = (CCSWeaponBase*)g_pEntitySystem->GetEntityInstance((CEntityIndex)iWeaponEnt);
if (pItemWeapon)
{
pItemWeapon->m_Glow().m_glowColorOverride = Color(0, 0, 0, 0);
pItemWeapon->m_Glow().m_iGlowType = 0;
pItemWeapon->m_Glow().m_iGlowTeam = -1;
pItemWeapon->m_Glow().m_flGlowStartTime = 0;
pItemWeapon->m_Glow().m_flGlowTime = 0;
pItemWeapon->m_Glow().m_nGlowRange = 0;
pItemWeapon->m_Glow().m_bGlowing = false;
}
}

bool EWItemInstance::IsEmpty()
{
// Empty items don't glow when dropped, so have to be careful since some items can recharge
// Only return true if ALL handlers that appear in any way (chat/ui) are empty (non-counter max-uses)
// If it has no visible handlers, its not empty
//
// TODO: maybe add an optional config setting for whether a handler is rechargable (depends if people complain)

if (vecHandlers.size() < 1)
return false;

// True until proven otherwise
bool bAllInvisible = true;
bool bAllEmpty = true;

for (int i = 0; i < vecHandlers.size(); i++)
{
// Any visible counter or non-maxuses handlers are never empty
if ((vecHandlers[i]->bShowHud || vecHandlers[i]->bShowUse) && vecHandlers[i]->szOutput != "")
{
if (vecHandlers[i]->IsCounter() || vecHandlers[i]->mode != EWHandlerMode::MaxUses)
{
return false;
}

// Maxuses handler (can be empty)
// Check if it is empty
bAllInvisible = false;
if (vecHandlers[i]->iCurrentUses < vecHandlers[i]->iMaxUses)
bAllEmpty = false;
}
else
{
// Invisible handler / no ouput
}
}

if (bAllInvisible)
return false;

return bAllEmpty;
}

void CEWHandler::UnLoadConfig()
{
if (!bConfigLoaded)
Expand Down
9 changes: 8 additions & 1 deletion src/entwatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ struct EWItemHandler
float flLastUsed; // For tracking cd on the hud
float flLastShownUse; // To prevent too much chat spam

bool IsCounter() { return (type == EWHandlerType::CounterDown || type == EWHandlerType::CounterUp); }
void SetDefaultValues();
void Print();

Expand All @@ -136,6 +137,7 @@ struct EWItem
std::string szShortName; /* Name to show on hud/scoreboard */
std::string szHammerid; /* Hammerid of the weapon */
char sChatColor[2];
Color colorGlow;
bool bShowPickup; /* Whether to show pickup/drop messages in chat */
bool bShowHud; /* Whether to show this item on hud/scoreboard */
EWAutoConfigOption transfer; /* Can this item be transferred */
Expand All @@ -161,6 +163,7 @@ struct EWItemInstance : EWItem /* Current instance of defined items */
bool bHasThisClantag;
int iTeamNum;
std::string sLastOwnerName; // For etransfer info
bool bShouldGlow;

public:
EWItemInstance(int iWeapon, std::shared_ptr<EWItem> pItem) :
Expand All @@ -171,7 +174,8 @@ struct EWItemInstance : EWItem /* Current instance of defined items */
bAllowDrop(true),
sClantag(""),
bHasThisClantag(false),
iTeamNum(CS_TEAM_NONE){};
iTeamNum(CS_TEAM_NONE),
bShouldGlow(false) {};
bool RegisterHandler(CBaseEntity* pEnt, int iHandlerTemplateNum);
bool RemoveHandler(CBaseEntity* pEnt);
int FindHandlerByEntIndex(int indexToFind);
Expand All @@ -180,6 +184,9 @@ struct EWItemInstance : EWItem /* Current instance of defined items */
void Pickup(int slot);
void Drop(EWDropReason reason, CCSPlayerController* pController);
std::string GetHandlerStateText();
void StartGlow();
void EndGlow();
bool IsEmpty();
};

struct ETransferInfo
Expand Down