Skip to content

Commit 2524b65

Browse files
tilgepVauff
authored andcommitted
Entwatch update (#422)
- Clantags show item cd/uses - Transferred items can only be picked up by the target for 1s - Dropped map weapons get teleported to player eye position to stop them falling through floors
1 parent afa30f0 commit 2524b65

3 files changed

Lines changed: 99 additions & 25 deletions

File tree

src/cs2_sdk/entity/cbaseplayerpawn.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,19 @@ class CBasePlayerPawn : public CBaseModelEntity
6262
}
6363
}
6464

65+
Vector pos = GetEyePosition();
6566
for (CBasePlayerWeapon* pWeapon : vecWeaponsToDrop)
67+
{
6668
m_pWeaponServices()->DropWeapon(pWeapon);
69+
70+
CHandle<CBasePlayerWeapon> hWep = pWeapon->GetHandle();
71+
CTimer::Create(0.0, TIMERFLAG_MAP | TIMERFLAG_ROUND, [hWep, pos] {
72+
CBasePlayerWeapon* pWep = hWep.Get();
73+
if (pWep)
74+
pWep->Teleport(&pos, nullptr, nullptr);
75+
return -1.0f;
76+
});
77+
}
6778
}
6879

6980
void CommitSuicide(bool bExplode, bool bForce)

src/entwatch.cpp

Lines changed: 77 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -797,8 +797,9 @@ void EWItemInstance::Pickup(int slot)
797797

798798
if (bShouldSetClantag)
799799
{
800+
// Hud tick function sets it
800801
bHasThisClantag = true;
801-
pController->SetClanTag(sClantag);
802+
802803
if (g_cvarItemHolderScore.Get() > -1)
803804
{
804805
int score = pController->m_iScore + g_cvarItemHolderScore.Get();
@@ -836,9 +837,8 @@ void EWItemInstance::Drop(EWDropReason reason, CCSPlayerController* pController)
836837
{
837838
if (g_pEWHandler->vecItems[otherItem]->bShowHud && !g_pEWHandler->vecItems[otherItem]->bHasThisClantag)
838839
{
839-
// Player IS holding another item, score doesnt need adjusting
840+
// Player IS holding another item
840841

841-
pController->SetClanTag(g_pEWHandler->vecItems[otherItem]->sClantag);
842842
g_pEWHandler->vecItems[otherItem]->bHasThisClantag = true;
843843
bSetAnotherClantag = true;
844844
break;
@@ -847,16 +847,14 @@ void EWItemInstance::Drop(EWDropReason reason, CCSPlayerController* pController)
847847
}
848848
bHasThisClantag = false;
849849

850-
if (!bSetAnotherClantag)
850+
if (g_cvarItemHolderScore.Get() != 0)
851851
{
852-
if (g_cvarItemHolderScore.Get() != 0)
853-
{
854-
int score = pController->m_iScore - g_cvarItemHolderScore.Get();
855-
pController->m_iScore = score;
856-
}
852+
int score = pController->m_iScore - g_cvarItemHolderScore.Get();
853+
pController->m_iScore = score;
854+
}
857855

856+
if (!bSetAnotherClantag)
858857
pController->SetClanTag("");
859-
}
860858
}
861859

862860
char sPlayerInfo[64];
@@ -871,7 +869,7 @@ void EWItemInstance::Drop(EWDropReason reason, CCSPlayerController* pController)
871869

872870
Message(EW_PREFIX "%s has dropped %s (weaponid:%d)\n", sPlayerInfo, szItemName.c_str(), iWeaponEnt);
873871
if (bShowPickup)
874-
ClientPrintAll(HUD_PRINTTALK, EW_PREFIX "\x03%s \x05has dropped %s%s", pController->GetPlayerName(), sChatColor, szItemName.c_str());
872+
ClientPrintAll(HUD_PRINTTALK, EW_PREFIX "\x03%s\x05 has dropped %s%s", pController->GetPlayerName(), sChatColor, szItemName.c_str());
875873
break;
876874
case EWDropReason::Infected:
877875
if (bAllowDrop)
@@ -1209,6 +1207,7 @@ void CEWHandler::PrintLoadedConfig(CPlayerSlot slot)
12091207

12101208
void CEWHandler::ClearItems()
12111209
{
1210+
vecActiveTransfers.clear();
12121211
mapTransfers.clear();
12131212
vecItems.clear();
12141213
}
@@ -1519,8 +1518,6 @@ int CEWHandler::RegisterItem(CBasePlayerWeapon* pWeapon)
15191518

15201519
std::shared_ptr<EWItemInstance> instance = std::make_shared<EWItemInstance>(pWeapon->entindex(), item);
15211520

1522-
V_snprintf(instance->sClantag, sizeof(EWItemInstance::sClantag), "[+]%s:", instance->szShortName.c_str());
1523-
15241521
bool bKnife = pWeapon->GetWeaponVData()->m_GearSlot() == GEAR_SLOT_KNIFE;
15251522
instance->bAllowDrop = !bKnife;
15261523

@@ -1612,13 +1609,10 @@ void CEWHandler::PlayerPickup(CCSPlayerPawn* pPawn, int iItemInstance)
16121609

16131610
item->Pickup(pPawn->m_hOriginalController->GetPlayerSlot());
16141611

1615-
if (g_cvarEnableEntwatchHud.Get() && !m_bHudTicking)
1616-
{
1617-
m_bHudTicking = true;
1618-
CTimer::Create(EW_HUD_TICKRATE, TIMERFLAG_MAP | TIMERFLAG_ROUND, [] {
1612+
if (m_pHudTimer.expired())
1613+
m_pHudTimer = CTimer::Create(EW_HUD_TICKRATE, TIMERFLAG_MAP | TIMERFLAG_ROUND, [] {
16191614
return EW_UpdateHud();
16201615
});
1621-
}
16221616
}
16231617

16241618
void CEWHandler::PlayerDrop(EWDropReason reason, int iItemInstance, CCSPlayerController* pController)
@@ -1735,6 +1729,31 @@ void CEWHandler::Transfer(CCSPlayerController* pCaller, int iItemInstance, CHand
17351729
}
17361730
}
17371731

1732+
// Add this weapon and receiver to active transfers to prevent others from picking it up
1733+
if (GetGlobals())
1734+
{
1735+
std::shared_ptr<EActiveTransfer> transfer = std::make_shared<EActiveTransfer>();
1736+
transfer->hReceiver = hReceiver;
1737+
transfer->hWeapon = pItemWeapon->GetHandle();
1738+
transfer->flTime = GetGlobals()->curtime + 0.95;
1739+
vecActiveTransfers.push_back(transfer);
1740+
CTimer::Create(1.0, TIMERFLAG_MAP | TIMERFLAG_ROUND, [] {
1741+
if (!GetGlobals())
1742+
return -1.0f;
1743+
1744+
for (int i = 0; i < g_pEWHandler->vecActiveTransfers.size(); i++)
1745+
{
1746+
std::shared_ptr<EActiveTransfer> transfer = g_pEWHandler->vecActiveTransfers[i];
1747+
if (transfer->flTime < GetGlobals()->curtime)
1748+
{
1749+
g_pEWHandler->vecActiveTransfers.erase(g_pEWHandler->vecActiveTransfers.begin() + i);
1750+
i--;
1751+
}
1752+
}
1753+
return -1.0f;
1754+
});
1755+
}
1756+
17381757
// Give the item to the receiver
17391758
Vector vecOrigin = pReceiverPawn->GetAbsOrigin();
17401759
pItemWeapon->Teleport(&vecOrigin, nullptr, nullptr);
@@ -1968,8 +1987,17 @@ float EW_UpdateHud()
19681987

19691988
std::string sItemText = pItem->GetHandlerStateText();
19701989

1971-
// TODO: std::format not supported in clang16 by default
1972-
// sHudText.append(std::format("\n[{}]{}: {}", sItemText, pItem->szShortName, pOwner->GetPlayerName()));
1990+
if (g_cvarUseEntwatchClantag.Get())
1991+
{
1992+
V_snprintf(pItem->sClantag, sizeof(EWItemInstance::sClantag), "[%s]%s:", sItemText.c_str(), pItem->szShortName.c_str());
1993+
if (pItem->bHasThisClantag)
1994+
pOwner->SetClanTag(pItem->sClantag);
1995+
}
1996+
1997+
if (!g_cvarEnableEntwatchHud.Get())
1998+
continue;
1999+
2000+
// std::format not supported in clang16 by default (steamrt3)
19732001
if (!bFirst)
19742002
{
19752003
sHudText.append("\n");
@@ -2045,7 +2073,6 @@ void EW_RoundPreStart()
20452073

20462074
g_pEWHandler->ResetAllClantags();
20472075
g_pEWHandler->ClearItems();
2048-
g_pEWHandler->m_bHudTicking = false;
20492076
}
20502077

20512078
void EW_OnEntitySpawned(CEntityInstance* pEntity)
@@ -2149,6 +2176,27 @@ bool EW_Detour_CCSPlayer_WeaponServices_CanUse(CCSPlayer_WeaponServices* pWeapon
21492176
if (!zpPlayer || zpPlayer->IsEbanned())
21502177
return false;
21512178

2179+
// Limit any active transfers to the receiver only
2180+
if (g_pEWHandler->vecActiveTransfers.size() == 0)
2181+
return true;
2182+
2183+
for (int i = 0; i < g_pEWHandler->vecActiveTransfers.size(); i++)
2184+
{
2185+
std::shared_ptr<EActiveTransfer> transfer = g_pEWHandler->vecActiveTransfers[i];
2186+
CHandle<CCSPlayerController> hReceiver = transfer->hReceiver;
2187+
CHandle<CBasePlayerWeapon> hWeapon = transfer->hWeapon;
2188+
if (!hReceiver.Get() || !hWeapon.Get())
2189+
continue;
2190+
2191+
if (hWeapon.Get() != pPlayerWeapon)
2192+
continue;
2193+
2194+
if (hReceiver.Get() == ccsPlayer)
2195+
return true;
2196+
else
2197+
return false;
2198+
}
2199+
21522200
return true;
21532201
}
21542202

@@ -2241,6 +2289,14 @@ void EW_PlayerDeathPre(CCSPlayerController* pController)
22412289

22422290
void EW_PlayerDisconnect(int slot)
22432291
{
2292+
ZEPlayer* pPlayer = g_playerManager->GetPlayer(CPlayerSlot(slot));
2293+
if (pPlayer)
2294+
{
2295+
CPointWorldText* pText = pPlayer->GetEntwatchHud();
2296+
if (pText)
2297+
pText->Remove();
2298+
}
2299+
22442300
auto i = g_pEWHandler->mapTransfers.find(slot);
22452301
if (i != g_pEWHandler->mapTransfers.end())
22462302
g_pEWHandler->mapTransfers.erase(slot);

src/entwatch.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ struct EWItemInstance : EWItem /* Current instance of defined items */
178178
sClantag(""),
179179
bHasThisClantag(false),
180180
iTeamNum(CS_TEAM_NONE),
181-
bShouldGlow(false){};
181+
bShouldGlow(false) {};
182182
bool RegisterHandler(CBaseEntity* pEnt, int iHandlerTemplateNum);
183183
bool RemoveHandler(CBaseEntity* pEnt);
184184
int FindHandlerByEntIndex(int indexToFind);
@@ -205,13 +205,19 @@ struct ETransferInfo
205205
float flTime; // The time when the command was initiated
206206
};
207207

208+
struct EActiveTransfer
209+
{
210+
CHandle<CCSPlayerController> hReceiver;
211+
CHandle<CBasePlayerWeapon> hWeapon;
212+
float flTime;
213+
};
214+
208215
class CEWHandler
209216
{
210217
public:
211218
CEWHandler()
212219
{
213220
bConfigLoaded = false;
214-
m_bHudTicking = false;
215221

216222
iBaseBtnUseHookId = -1;
217223
iPhysboxUseHookId = -1;
@@ -278,9 +284,10 @@ class CEWHandler
278284
int iRotBtnUseHookId;
279285
int iMomRotBtnUseHookId;
280286

281-
bool m_bHudTicking;
287+
std::weak_ptr<CTimer> m_pHudTimer;
282288

283-
std::map<int, std::shared_ptr<ETransferInfo>> mapTransfers; // Any etransfers that target multiple items
289+
std::map<int, std::shared_ptr<ETransferInfo>> mapTransfers; // Any etransfers that target multiple items
290+
std::vector<std::shared_ptr<EActiveTransfer>> vecActiveTransfers; // Active transfers where only the receiver can pickup the weapon
284291
};
285292

286293
extern CEWHandler* g_pEWHandler;

0 commit comments

Comments
 (0)