Cstrike: Fix defuser/nvgs not being called with CS_OnBuy and fix wrong shield CSI constants
This commit is contained in:
parent
eb0222455a
commit
d08e1357dd
@ -40,10 +40,11 @@ GetWeaponInfoFunc GetWeaponInfo;
|
||||
int CurrentItemId;
|
||||
bool TriggeredFromCommand;
|
||||
|
||||
StringHashMap<int> ItemAliasList;
|
||||
// m_iTeam and m_iMenu from CBasePlayer.
|
||||
TypeDescription TeamDesc;
|
||||
TypeDescription MenuDesc;
|
||||
|
||||
// Engine global variables.
|
||||
server_static_t *ServerStatic;
|
||||
server_t *Server;
|
||||
|
||||
@ -80,16 +81,6 @@ const char *CMD_ARGV(int i)
|
||||
return g_engfuncs.pfnCmd_Argv(i);
|
||||
}
|
||||
|
||||
void OnEmitSound(edict_t *entity, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch)
|
||||
{
|
||||
// If shield is blocked with CS_OnBuy, we need to block the pickup sound ("items/gunpickup2.wav")
|
||||
// as well played right after. Why this sound is not contained in GiveShield()?
|
||||
|
||||
g_pengfuncsTable->pfnEmitSound = nullptr;
|
||||
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientCommand(edict_t *pEntity)
|
||||
{
|
||||
const char *command = CMD_ARGV(0);
|
||||
@ -97,7 +88,7 @@ DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientComma
|
||||
CurrentItemId = CSI_NONE;
|
||||
|
||||
// Purpose is to retrieve an item id based on alias name or selected item from menu,
|
||||
// to be used in OnBuy* forwards.
|
||||
// to be used in CS_OnBuy* forwards.
|
||||
if ((ForwardOnBuyAttempt != -1 || ForwardOnBuy != -1) && command && *command)
|
||||
{
|
||||
int itemId = CSI_NONE;
|
||||
@ -179,8 +170,41 @@ DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientComma
|
||||
return;
|
||||
}
|
||||
|
||||
// CS_OnBuy()
|
||||
// -
|
||||
// This forward should be called right before game gives the item.
|
||||
// All items except shield, defuser and nvgs, games executes in the following order:
|
||||
// GiveNamedItem -> AddAccount
|
||||
// Forward is fired on GiveNamedItem.
|
||||
// Shield only:
|
||||
// GiveShield -> AddAccount -> EmitSound
|
||||
// Forward is fired on GiveShield.
|
||||
// Defusal kit only:
|
||||
// m_bHasDefuser(true) -> StatusIcon -> pev_body(1) -> AddAccount -> EmitSound -> ItemStatus
|
||||
// Forward is fired on StatusIcon.
|
||||
// Nightvision only:
|
||||
// EmitSound -> m_bHasNightVision(true) -> AddAccount -> ItemStatus
|
||||
// Forward is fired on EmitSound.
|
||||
|
||||
TriggeredFromCommand = CurrentItemId != CSI_NONE;
|
||||
|
||||
if (TriggeredFromCommand)
|
||||
{
|
||||
if (CurrentItemId == CSI_NVGS)
|
||||
{
|
||||
g_pengfuncsTable->pfnEmitSound = OnEmitSound;
|
||||
}
|
||||
else if (CurrentItemId == CSI_DEFUSER)
|
||||
{
|
||||
GET_OFFSET_NO_ERROR("CBasePlayer", m_bHasDefuser);
|
||||
|
||||
if (!get_pdata<bool>(pEdict, m_bHasDefuser))
|
||||
{
|
||||
EnableMessageHooks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DETOUR_STATIC_CALL(C_ClientCommand)(pEdict);
|
||||
|
||||
TriggeredFromCommand = false;
|
||||
@ -203,6 +227,69 @@ edict_s* OnCreateNamedEntity(int classname)
|
||||
RETURN_META_VALUE(MRES_IGNORED, 0);
|
||||
}
|
||||
|
||||
void OnEmitSound(edict_t *entity, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch)
|
||||
{
|
||||
if (TriggeredFromCommand)
|
||||
{
|
||||
switch (CurrentItemId)
|
||||
{
|
||||
case CSI_NVGS:
|
||||
{
|
||||
auto client = ENTINDEX(entity);
|
||||
|
||||
if (!MF_IsPlayerAlive(client) || MF_ExecuteForward(ForwardOnBuy, static_cast<cell>(client), CSI_NVGS) <= 0)
|
||||
{
|
||||
g_pengfuncsTable->pfnEmitSound = nullptr;
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
}
|
||||
case CSI_DEFUSER:
|
||||
case CSI_SHIELD:
|
||||
{
|
||||
g_pengfuncsTable->pfnEmitSound = nullptr;
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
bool OnMessageItemStatus(edict_t *pPlayer)
|
||||
{
|
||||
if (TriggeredFromCommand && (CurrentItemId == CSI_DEFUSER || CurrentItemId == CSI_NVGS))
|
||||
{
|
||||
if (!g_pengfuncsTable->pfnEmitSound)
|
||||
{
|
||||
return true; // Block message
|
||||
}
|
||||
|
||||
DisableMessageHooks();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OnMessageStatusIcon(edict_t *pPlayer)
|
||||
{
|
||||
if (TriggeredFromCommand && CurrentItemId == CSI_DEFUSER)
|
||||
{
|
||||
auto client = ENTINDEX(pPlayer);
|
||||
|
||||
if (MF_IsPlayerAlive(client) && MF_ExecuteForward(ForwardOnBuy, static_cast<cell>(client), CSI_DEFUSER) > 0)
|
||||
{
|
||||
GET_OFFSET_NO_ERROR_RET("CBasePlayer", m_bHasDefuser);
|
||||
set_pdata<bool>(pPlayer, m_bHasDefuser, false);
|
||||
|
||||
return true; // Block message
|
||||
}
|
||||
|
||||
DisableMessageHooks();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DETOUR_DECL_MEMBER0(GiveDefaultItems, void) // void CBasePlayer::GiveDefaultItems(void)
|
||||
{
|
||||
if (NoKifesMode)
|
||||
@ -234,11 +321,11 @@ DETOUR_DECL_MEMBER1(GiveNamedItem, void, const char*, pszName) // void CBasePlay
|
||||
|
||||
DETOUR_DECL_MEMBER1(GiveShield, void, bool, bRetire) // void CBasePlayer::GiveShield(bool bRetire)
|
||||
{
|
||||
if (TriggeredFromCommand && CurrentItemId == CSI_SHIELDGUN)
|
||||
if (TriggeredFromCommand && CurrentItemId == CSI_SHIELD)
|
||||
{
|
||||
int client = TypeConversion.cbase_to_id(this);
|
||||
|
||||
if (MF_IsPlayerAlive(client) && MF_ExecuteForward(ForwardOnBuy, static_cast<cell>(client), CSI_SHIELDGUN) > 0)
|
||||
if (MF_IsPlayerAlive(client) && MF_ExecuteForward(ForwardOnBuy, static_cast<cell>(client), CSI_SHIELD) > 0)
|
||||
{
|
||||
// If shield blocked, we need to hook EmitSound to block pickup sound played right after.
|
||||
g_pengfuncsTable->pfnEmitSound = OnEmitSound;
|
||||
@ -256,9 +343,26 @@ DETOUR_DECL_MEMBER2(AddAccount, void, int, amount, bool, bTrackChange) // void C
|
||||
{
|
||||
if (TriggeredFromCommand)
|
||||
{
|
||||
if (CurrentItemId == CSI_NONE)
|
||||
switch (CurrentItemId)
|
||||
{
|
||||
return;
|
||||
case CSI_DEFUSER:
|
||||
{
|
||||
G_HL_TypeConversion.cbase_to_entvar(this)->body = 0;
|
||||
g_pengfuncsTable->pfnEmitSound = OnEmitSound; // To block pickup sound.
|
||||
EnableMessageHooks(); // To block ItemStatus
|
||||
break;
|
||||
}
|
||||
case CSI_NVGS:
|
||||
{
|
||||
GET_OFFSET_NO_ERROR("CBasePlayer", m_bHasNightVision);
|
||||
set_pdata<bool>(G_HL_TypeConversion.cbase_to_edict(this), m_bHasNightVision, false);
|
||||
EnableMessageHooks(); // To block ItemStatus
|
||||
break;
|
||||
}
|
||||
case CSI_NONE:
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ void InitGlobalVars();
|
||||
void ShutdownHacks();
|
||||
void ToggleDetour_ClientCommands(bool enable);
|
||||
void ToggleDetour_BuyCommands(bool enable);
|
||||
void OnEmitSound(edict_t *entity, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch);
|
||||
|
||||
extern AMX_NATIVE_INFO CstrikeNatives[];
|
||||
|
||||
|
@ -93,6 +93,12 @@ void OnServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax)
|
||||
DisableMessageHooks();
|
||||
}
|
||||
|
||||
void OnPluginsUnloaded()
|
||||
{
|
||||
// Force to disable all hooks at map change.
|
||||
DisableMessageHooks(true);
|
||||
}
|
||||
|
||||
void OnAmxxDetach()
|
||||
{
|
||||
ConfigManager->RemoveUserConfigHook("CommandsAliases", &ItemsManager);
|
||||
|
@ -1358,7 +1358,13 @@ static cell AMX_NATIVE_CALL cs_set_user_zoom(AMX *amx, cell *params)
|
||||
int mode = params[3];
|
||||
int weapon = *static_cast<int *>(MF_PlayerPropAddr(index, Player_CurrentWeapon));
|
||||
|
||||
Players[index].ResetZoom();
|
||||
CPlayer& player = Players[index];
|
||||
|
||||
if (player.GetZoom())
|
||||
{
|
||||
DisableMessageHooks();
|
||||
player.ResetZoom();
|
||||
}
|
||||
|
||||
if (type == CS_RESET_ZOOM)
|
||||
{
|
||||
@ -1406,7 +1412,7 @@ static cell AMX_NATIVE_CALL cs_set_user_zoom(AMX *amx, cell *params)
|
||||
|
||||
if (!mode)
|
||||
{
|
||||
Players[index].SetZoom(value);
|
||||
player.SetZoom(value);
|
||||
EnableMessageHooks();
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,13 @@
|
||||
|
||||
bool ShouldBlock;
|
||||
bool ShouldBlockHLTV;
|
||||
bool ShouldDisableHooks;
|
||||
bool RetrieveWeaponName;
|
||||
ke::AString CurrentWeaponName;
|
||||
int ArgPosition;
|
||||
|
||||
int MessageIdArmorType;
|
||||
int MessageIdItemStatus;
|
||||
int MessageIdHLTV;
|
||||
int MessageIdMoney;
|
||||
int MessageIdResetHUD;
|
||||
@ -37,6 +39,9 @@ int MessageIdTeamInfo;
|
||||
int MessageIdTextMsg;
|
||||
int MessageIdWeaponList;
|
||||
|
||||
extern bool OnMessageStatusIcon(edict_t *pPlayer);
|
||||
extern bool OnMessageItemStatus(edict_t *pPlayer);
|
||||
|
||||
struct UserMsg
|
||||
{
|
||||
const char* name;
|
||||
@ -46,6 +51,7 @@ struct UserMsg
|
||||
UserMsg MessagesList[] =
|
||||
{
|
||||
{ "ArmorType" , &MessageIdArmorType },
|
||||
{ "ItemStatus" , &MessageIdItemStatus },
|
||||
{ "HLTV" , &MessageIdHLTV },
|
||||
{ "Money" , &MessageIdMoney },
|
||||
{ "ResetHUD" , &MessageIdResetHUD },
|
||||
@ -105,7 +111,30 @@ void OnMessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *p
|
||||
int index = ENTINDEX(pEntity);
|
||||
|
||||
if (Players[index].GetZoom())
|
||||
{
|
||||
Players[index].ResetZoom();
|
||||
DisableMessageHooks();
|
||||
}
|
||||
}
|
||||
else if (msg_type == MessageIdStatusIcon)
|
||||
{
|
||||
if (OnMessageStatusIcon(pEntity))
|
||||
{
|
||||
ShouldBlock = true;
|
||||
ShouldDisableHooks = true;
|
||||
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
}
|
||||
else if (msg_type == MessageIdItemStatus)
|
||||
{
|
||||
if (OnMessageItemStatus(pEntity))
|
||||
{
|
||||
ShouldBlock = true;
|
||||
ShouldDisableHooks = true;
|
||||
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -139,11 +168,12 @@ void OnMessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *p
|
||||
|
||||
void OnWriteByte(int value)
|
||||
{
|
||||
if (ShouldBlock)
|
||||
if (ShouldBlock)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
else if (RetrieveWeaponName && ++ArgPosition == 7 && value >= 0 && value < MAX_WEAPONS)
|
||||
|
||||
if (RetrieveWeaponName && ++ArgPosition == 7 && value >= 0 && value < MAX_WEAPONS)
|
||||
{
|
||||
strncopy(WeaponNameList[value], CurrentWeaponName.chars(), sizeof(WeaponNameList[value]));
|
||||
}
|
||||
@ -153,6 +183,11 @@ void OnWriteByte(int value)
|
||||
|
||||
void OnWriteString(const char *value)
|
||||
{
|
||||
if (ShouldBlock)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
if (RetrieveWeaponName)
|
||||
{
|
||||
CurrentWeaponName = value;
|
||||
@ -166,9 +201,17 @@ void OnMessageEnd(void)
|
||||
if (ShouldBlock)
|
||||
{
|
||||
ShouldBlock = false;
|
||||
|
||||
if (ShouldDisableHooks)
|
||||
{
|
||||
ShouldDisableHooks = false;
|
||||
DisableMessageHooks();
|
||||
}
|
||||
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
else if (RetrieveWeaponName)
|
||||
|
||||
if (RetrieveWeaponName)
|
||||
{
|
||||
RetrieveWeaponName = false;
|
||||
ArgPosition = 0;
|
||||
@ -177,8 +220,12 @@ void OnMessageEnd(void)
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
size_t RefCount;
|
||||
|
||||
void EnableMessageHooks()
|
||||
{
|
||||
++RefCount;
|
||||
|
||||
if (!g_pengfuncsTable->pfnMessageBegin)
|
||||
{
|
||||
g_pengfuncsTable->pfnMessageBegin = OnMessageBegin;
|
||||
@ -188,10 +235,18 @@ void EnableMessageHooks()
|
||||
}
|
||||
}
|
||||
|
||||
void DisableMessageHooks()
|
||||
void DisableMessageHooks(bool force)
|
||||
{
|
||||
g_pengfuncsTable->pfnMessageBegin = nullptr;
|
||||
g_pengfuncsTable->pfnWriteByte = nullptr;
|
||||
g_pengfuncsTable->pfnWriteString = nullptr;
|
||||
g_pengfuncsTable->pfnMessageEnd = nullptr;
|
||||
if (force)
|
||||
{
|
||||
RefCount = 1;
|
||||
}
|
||||
|
||||
if (--RefCount == 0)
|
||||
{
|
||||
g_pengfuncsTable->pfnMessageBegin = nullptr;
|
||||
g_pengfuncsTable->pfnWriteByte = nullptr;
|
||||
g_pengfuncsTable->pfnWriteString = nullptr;
|
||||
g_pengfuncsTable->pfnMessageEnd = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,6 @@ extern int MessageIdTeamInfo;
|
||||
extern int MessageIdTextMsg;
|
||||
|
||||
void EnableMessageHooks();
|
||||
void DisableMessageHooks();
|
||||
void DisableMessageHooks(bool force = false);
|
||||
|
||||
#endif // CSTRIKE_USER_MESSAGES_H
|
||||
|
@ -80,7 +80,7 @@
|
||||
//#define FN_AMXX_PLUGINSUNLOADING OnPluginsUnloading
|
||||
|
||||
/** All plugins are now unloaded */
|
||||
//#define FN_AMXX_PLUGINSUNLOADED OnPluginsUnloaded
|
||||
#define FN_AMXX_PLUGINSUNLOADED OnPluginsUnloaded
|
||||
|
||||
|
||||
/**** METAMOD ****/
|
||||
|
Loading…
Reference in New Issue
Block a user