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
11 changes: 11 additions & 0 deletions src/cs2_sdk/entity/cbaseplayerpawn.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,19 @@ class CBasePlayerPawn : public CBaseModelEntity
}
}

Vector pos = GetEyePosition();
for (CBasePlayerWeapon* pWeapon : vecWeaponsToDrop)
{
m_pWeaponServices()->DropWeapon(pWeapon);

CHandle<CBasePlayerWeapon> hWep = pWeapon->GetHandle();
CTimer::Create(0.0, TIMERFLAG_MAP | TIMERFLAG_ROUND, [hWep, pos] {
CBasePlayerWeapon* pWep = hWep.Get();
if (pWep)
pWep->Teleport(&pos, nullptr, nullptr);
return -1.0f;
});
}
}

void CommitSuicide(bool bExplode, bool bForce)
Expand Down
98 changes: 77 additions & 21 deletions src/entwatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -797,8 +797,9 @@ void EWItemInstance::Pickup(int slot)

if (bShouldSetClantag)
{
// Hud tick function sets it
bHasThisClantag = true;
pController->SetClanTag(sClantag);

if (g_cvarItemHolderScore.Get() > -1)
{
int score = pController->m_iScore + g_cvarItemHolderScore.Get();
Expand Down Expand Up @@ -836,9 +837,8 @@ void EWItemInstance::Drop(EWDropReason reason, CCSPlayerController* pController)
{
if (g_pEWHandler->vecItems[otherItem]->bShowHud && !g_pEWHandler->vecItems[otherItem]->bHasThisClantag)
{
// Player IS holding another item, score doesnt need adjusting
// Player IS holding another item

pController->SetClanTag(g_pEWHandler->vecItems[otherItem]->sClantag);
g_pEWHandler->vecItems[otherItem]->bHasThisClantag = true;
bSetAnotherClantag = true;
break;
Expand All @@ -847,16 +847,14 @@ void EWItemInstance::Drop(EWDropReason reason, CCSPlayerController* pController)
}
bHasThisClantag = false;

if (!bSetAnotherClantag)
if (g_cvarItemHolderScore.Get() != 0)
{
if (g_cvarItemHolderScore.Get() != 0)
{
int score = pController->m_iScore - g_cvarItemHolderScore.Get();
pController->m_iScore = score;
}
int score = pController->m_iScore - g_cvarItemHolderScore.Get();
pController->m_iScore = score;
}

if (!bSetAnotherClantag)
pController->SetClanTag("");
}
}

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

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

void CEWHandler::ClearItems()
{
vecActiveTransfers.clear();
mapTransfers.clear();
vecItems.clear();
}
Expand Down Expand Up @@ -1519,8 +1518,6 @@ int CEWHandler::RegisterItem(CBasePlayerWeapon* pWeapon)

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

V_snprintf(instance->sClantag, sizeof(EWItemInstance::sClantag), "[+]%s:", instance->szShortName.c_str());

bool bKnife = pWeapon->GetWeaponVData()->m_GearSlot() == GEAR_SLOT_KNIFE;
instance->bAllowDrop = !bKnife;

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

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

if (g_cvarEnableEntwatchHud.Get() && !m_bHudTicking)
{
m_bHudTicking = true;
CTimer::Create(EW_HUD_TICKRATE, TIMERFLAG_MAP | TIMERFLAG_ROUND, [] {
if (m_pHudTimer.expired())
m_pHudTimer = CTimer::Create(EW_HUD_TICKRATE, TIMERFLAG_MAP | TIMERFLAG_ROUND, [] {
return EW_UpdateHud();
});
}
}

void CEWHandler::PlayerDrop(EWDropReason reason, int iItemInstance, CCSPlayerController* pController)
Expand Down Expand Up @@ -1735,6 +1729,31 @@ void CEWHandler::Transfer(CCSPlayerController* pCaller, int iItemInstance, CHand
}
}

// Add this weapon and receiver to active transfers to prevent others from picking it up
if (GetGlobals())
{
std::shared_ptr<EActiveTransfer> transfer = std::make_shared<EActiveTransfer>();
transfer->hReceiver = hReceiver;
transfer->hWeapon = pItemWeapon->GetHandle();
transfer->flTime = GetGlobals()->curtime + 0.95;
vecActiveTransfers.push_back(transfer);
CTimer::Create(1.0, TIMERFLAG_MAP | TIMERFLAG_ROUND, [] {
if (!GetGlobals())
return -1.0f;

for (int i = 0; i < g_pEWHandler->vecActiveTransfers.size(); i++)
{
std::shared_ptr<EActiveTransfer> transfer = g_pEWHandler->vecActiveTransfers[i];
if (transfer->flTime < GetGlobals()->curtime)
{
g_pEWHandler->vecActiveTransfers.erase(g_pEWHandler->vecActiveTransfers.begin() + i);
i--;
}
}
return -1.0f;
});
}

// Give the item to the receiver
Vector vecOrigin = pReceiverPawn->GetAbsOrigin();
pItemWeapon->Teleport(&vecOrigin, nullptr, nullptr);
Expand Down Expand Up @@ -1968,8 +1987,17 @@ float EW_UpdateHud()

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

// TODO: std::format not supported in clang16 by default
// sHudText.append(std::format("\n[{}]{}: {}", sItemText, pItem->szShortName, pOwner->GetPlayerName()));
if (g_cvarUseEntwatchClantag.Get())
{
V_snprintf(pItem->sClantag, sizeof(EWItemInstance::sClantag), "[%s]%s:", sItemText.c_str(), pItem->szShortName.c_str());
if (pItem->bHasThisClantag)
pOwner->SetClanTag(pItem->sClantag);
}

if (!g_cvarEnableEntwatchHud.Get())
continue;

// std::format not supported in clang16 by default (steamrt3)
if (!bFirst)
{
sHudText.append("\n");
Expand Down Expand Up @@ -2045,7 +2073,6 @@ void EW_RoundPreStart()

g_pEWHandler->ResetAllClantags();
g_pEWHandler->ClearItems();
g_pEWHandler->m_bHudTicking = false;
}

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

// Limit any active transfers to the receiver only
if (g_pEWHandler->vecActiveTransfers.size() == 0)
return true;

for (int i = 0; i < g_pEWHandler->vecActiveTransfers.size(); i++)
{
std::shared_ptr<EActiveTransfer> transfer = g_pEWHandler->vecActiveTransfers[i];
CHandle<CCSPlayerController> hReceiver = transfer->hReceiver;
CHandle<CBasePlayerWeapon> hWeapon = transfer->hWeapon;
if (!hReceiver.Get() || !hWeapon.Get())
continue;

if (hWeapon.Get() != pPlayerWeapon)
continue;

if (hReceiver.Get() == ccsPlayer)
return true;
else
return false;
}

return true;
}

Expand Down Expand Up @@ -2241,6 +2289,14 @@ void EW_PlayerDeathPre(CCSPlayerController* pController)

void EW_PlayerDisconnect(int slot)
{
ZEPlayer* pPlayer = g_playerManager->GetPlayer(CPlayerSlot(slot));
if (pPlayer)
{
CPointWorldText* pText = pPlayer->GetEntwatchHud();
if (pText)
pText->Remove();
}

auto i = g_pEWHandler->mapTransfers.find(slot);
if (i != g_pEWHandler->mapTransfers.end())
g_pEWHandler->mapTransfers.erase(slot);
Expand Down
15 changes: 11 additions & 4 deletions src/entwatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ struct EWItemInstance : EWItem /* Current instance of defined items */
sClantag(""),
bHasThisClantag(false),
iTeamNum(CS_TEAM_NONE),
bShouldGlow(false){};
bShouldGlow(false) {};
bool RegisterHandler(CBaseEntity* pEnt, int iHandlerTemplateNum);
bool RemoveHandler(CBaseEntity* pEnt);
int FindHandlerByEntIndex(int indexToFind);
Expand All @@ -205,13 +205,19 @@ struct ETransferInfo
float flTime; // The time when the command was initiated
};

struct EActiveTransfer
{
CHandle<CCSPlayerController> hReceiver;
CHandle<CBasePlayerWeapon> hWeapon;
float flTime;
};

class CEWHandler
{
public:
CEWHandler()
{
bConfigLoaded = false;
m_bHudTicking = false;

iBaseBtnUseHookId = -1;
iPhysboxUseHookId = -1;
Expand Down Expand Up @@ -278,9 +284,10 @@ class CEWHandler
int iRotBtnUseHookId;
int iMomRotBtnUseHookId;

bool m_bHudTicking;
std::weak_ptr<CTimer> m_pHudTimer;

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

extern CEWHandler* g_pEWHandler;
Expand Down