From facc2be5343cbd4818b8ef0dccf033f7f192c8a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Francisco=20Mu=C3=B1oz?= <fjmunozpena@gmail.com>
Date: Tue, 5 Sep 2023 00:52:44 -0300
Subject: [PATCH] Various defuser fixes and code refactory (#848)

* Defuser code refactory and fix
---
 regamedll/dlls/API/CSPlayer.cpp |  10 +---
 regamedll/dlls/client.cpp       |   3 +
 regamedll/dlls/player.cpp       | 100 +++++++++++++++-----------------
 regamedll/dlls/player.h         |   1 +
 4 files changed, 53 insertions(+), 61 deletions(-)

diff --git a/regamedll/dlls/API/CSPlayer.cpp b/regamedll/dlls/API/CSPlayer.cpp
index c59c314b..36c1d258 100644
--- a/regamedll/dlls/API/CSPlayer.cpp
+++ b/regamedll/dlls/API/CSPlayer.cpp
@@ -153,15 +153,7 @@ EXT_FUNC bool CCSPlayer::RemovePlayerItemEx(const char* pszItemName, bool bRemov
 			if (!pPlayer->m_bHasDefuser)
 				return false;
 
-			pPlayer->m_bHasDefuser = false;
-			pPlayer->pev->body = 0;
-
-			MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pPlayer->pev);
-				WRITE_BYTE(STATUSICON_HIDE);
-				WRITE_STRING("defuser");
-			MESSAGE_END();
-
-			pPlayer->SendItemStatus();
+			pPlayer->RemoveDefuser();
 		}
 		// item_longjump
 		else if (FStrEq(pszItemName, "longjump"))
diff --git a/regamedll/dlls/client.cpp b/regamedll/dlls/client.cpp
index 58062fe2..4f3245af 100644
--- a/regamedll/dlls/client.cpp
+++ b/regamedll/dlls/client.cpp
@@ -621,6 +621,9 @@ void EXT_FUNC ClientPutInServer(edict_t *pEntity)
 		return;
 	}
 
+#ifdef REGAMEDLL_FIXES
+	pPlayer->m_bHasDefuser = false;
+#endif
 	pPlayer->m_bNotKilled = true;
 	pPlayer->m_iIgnoreGlobalChat = IGNOREMSG_NONE;
 	pPlayer->m_iTeamKills = 0;
diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp
index d649fae0..398e987c 100644
--- a/regamedll/dlls/player.cpp
+++ b/regamedll/dlls/player.cpp
@@ -1690,14 +1690,6 @@ void CBasePlayer::RemoveAllItems(BOOL removeSuit)
 	if (m_bHasDefuser)
 	{
 		RemoveDefuser();
-
-		MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pev);
-			WRITE_BYTE(STATUSICON_HIDE);
-			WRITE_STRING("defuser");
-		MESSAGE_END();
-
-		SendItemStatus();
-		bKillProgBar = true;
 	}
 
 	if (m_bHasC4)
@@ -2396,8 +2388,8 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
 	}
 
 	SetSuitUpdate(nullptr, SUIT_SENTENCE, SUIT_REPEAT_OK);
-	m_iClientHealth = 0;
 
+	m_iClientHealth = 0;
 	MESSAGE_BEGIN(MSG_ONE, gmsgHealth, nullptr, pev);
 		WRITE_BYTE(m_iClientHealth);
 	MESSAGE_END();
@@ -2425,31 +2417,18 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
 	else if (m_bHasDefuser)
 	{
 		RemoveDefuser();
-
 #ifdef REGAMEDLL_FIXES
-		CItemThighPack *pDefuser = (CItemThighPack *)CBaseEntity::Create("item_thighpack", pev->origin, g_vecZero, ENT(pev));
-
-		pDefuser->SetThink(&CBaseEntity::SUB_Remove);
-		pDefuser->pev->nextthink = gpGlobals->time + CGameRules::GetItemKillDelay();
-		pDefuser->pev->spawnflags |= SF_NORESPAWN;
+		SpawnDefuser(pev->origin, ENT(pev));
 #else
 		GiveNamedItem("item_thighpack");
 #endif
-
-		MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pev);
-			WRITE_BYTE(STATUSICON_HIDE);
-			WRITE_STRING("defuser");
-		MESSAGE_END();
-
-		SendItemStatus();
 	}
 
-	if (m_bIsDefusing)
-	{
-		SetProgressBarTime(0);
-	}
+#ifndef REGAMEDLL_FIXES
+	// NOTE: moved to RemoveDefuser
+	m_bIsDefusing = false; 
+#endif
 
-	m_bIsDefusing = false;
 	BuyZoneIcon_Clear(this);
 
 #ifdef REGAMEDLL_ADD
@@ -3640,16 +3619,20 @@ void EXT_FUNC CBasePlayer::__API_HOOK(JoiningThink)()
 			ResetMenu();
 			m_iJoiningState = SHOWTEAMSELECT;
 
-			MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pev);
+#ifndef REGAMEDLL_FIXES
+			// NOTE: client already clears StatusIcon on join
+			MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pev); 
 				WRITE_BYTE(STATUSICON_HIDE);
 				WRITE_STRING("defuser");
 			MESSAGE_END();
 
-			m_bHasDefuser = false;
+			m_bHasDefuser = false; // set in ClientPutInServer
+#endif
 			m_fLastMovement = gpGlobals->time;
 			m_bMissionBriefing = false;
 
-			SendItemStatus();
+			SendItemStatus();  // NOTE: must be on UpdateClientData
+
 			break;
 		}
 		case READINGLTEXT:
@@ -3768,18 +3751,11 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Disappear)()
 	else if (m_bHasDefuser)
 	{
 		RemoveDefuser();
-
-#ifndef REGAMEDLL_FIXES
+#ifdef REGAMEDLL_FIXES
+		SpawnDefuser(pev->origin, ENT(pev));
+#else
 		GiveNamedItem("item_thighpack");
 #endif
-
-		MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pev);
-			WRITE_BYTE(STATUSICON_HIDE);
-			WRITE_STRING("defuser");
-		MESSAGE_END();
-
-		SendItemStatus();
-		SetProgressBarTime(0);
 	}
 
 	BuyZoneIcon_Clear(this);
@@ -5695,10 +5671,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Spawn)()
 	ReloadWeapons();
 #endif
 
-	if (m_bHasDefuser)
-		pev->body = 1;
-	else
-		pev->body = 0;
+	pev->body = m_bHasDefuser ? 1 : 0;
 
 	if (m_bMissionBriefing)
 	{
@@ -8293,14 +8266,6 @@ void CBasePlayer::__API_HOOK(SwitchTeam)()
 	{
 		RemoveDefuser();
 
-		MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pev);
-			WRITE_BYTE(STATUSICON_HIDE);
-			WRITE_STRING("defuser");
-		MESSAGE_END();
-
-		SendItemStatus();
-		SetProgressBarTime(0);
-
 #ifndef REGAMEDLL_FIXES
 		// NOTE: unreachable code - Vaqtincha
 		for (int i = 0; i < MAX_ITEM_TYPES; i++)
@@ -10145,6 +10110,37 @@ void CBasePlayer::RemoveDefuser()
 {
 	m_bHasDefuser = false;
 	pev->body = 0;
+
+	MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pev);
+		WRITE_BYTE(STATUSICON_HIDE);
+		WRITE_STRING("defuser");
+	MESSAGE_END();
+
+	SendItemStatus();
+
+#ifdef REGAMEDLL_FIXES
+	if (m_bIsDefusing)
+	{
+		SetProgressBarTime(0);
+		m_bIsDefusing = false;
+	}
+#else 
+	SetProgressBarTime(0);
+#endif
+}
+
+CItemThighPack *SpawnDefuser(const Vector &vecOrigin, edict_t *pentOwner)
+{
+	CItemThighPack *pDefuser = (CItemThighPack *)CBaseEntity::Create("item_thighpack", vecOrigin, g_vecZero, pentOwner);
+
+	if (pDefuser)
+	{
+		pDefuser->SetThink(&CBaseEntity::SUB_Remove);
+		pDefuser->pev->nextthink = gpGlobals->time + CGameRules::GetItemKillDelay();
+		pDefuser->pev->spawnflags |= SF_NORESPAWN;
+	}
+
+	return pDefuser;
 }
 
 void CBasePlayer::Disconnect()
diff --git a/regamedll/dlls/player.h b/regamedll/dlls/player.h
index 77b9ac2c..9d9aa67c 100644
--- a/regamedll/dlls/player.h
+++ b/regamedll/dlls/player.h
@@ -910,6 +910,7 @@ public:
 
 CWeaponBox *CreateWeaponBox(CBasePlayerItem *pItem, CBasePlayer *pPlayerOwner, const char *modelName, Vector &origin, Vector &angles, Vector &velocity, float lifeTime, bool packAmmo);
 CWeaponBox *CreateWeaponBox_OrigFunc(CBasePlayerItem *pItem, CBasePlayer *pPlayerOwner, const char *modelName, Vector &origin, Vector &angles, Vector &velocity, float lifeTime, bool packAmmo);
+CItemThighPack *SpawnDefuser(const Vector &vecOrigin, edict_t *pentOwner);
 
 class CWShield: public CBaseEntity
 {