diff --git a/extensions/sdktools/hooks.cpp b/extensions/sdktools/hooks.cpp index ddfa2919..f253406c 100644 --- a/extensions/sdktools/hooks.cpp +++ b/extensions/sdktools/hooks.cpp @@ -69,6 +69,7 @@ CHookManager::CHookManager() : replay_enabled("replay_enabled", false) #endif { + m_usercmdsPreFwd = NULL; m_usercmdsFwd = NULL; m_usercmdsPostFwd = NULL; m_netFileSendFwd = NULL; @@ -97,6 +98,19 @@ void CHookManager::Initialize() plsys->AddPluginsListener(this); sharesys->AddCapabilityProvider(myself, this, FEATURECAP_PLAYERRUNCMD_11PARAMS); + + m_usercmdsPreFwd = forwards->CreateForward("OnPlayerRunCmdPre", ET_Ignore, 11, NULL, + Param_Cell, // int client + Param_Cell, // int buttons + Param_Cell, // int impulse + Param_Array, // float vel[3] + Param_Array, // float angles[3] + Param_Cell, // int weapon + Param_Cell, // int subtype + Param_Cell, // int cmdnum + Param_Cell, // int tickcount + Param_Cell, // int seed + Param_Array); // int mouse[2] m_usercmdsFwd = forwards->CreateForward("OnPlayerRunCmd", ET_Event, 11, NULL, Param_Cell, // client @@ -179,6 +193,7 @@ void CHookManager::Shutdown() } #endif + forwards->ReleaseForward(m_usercmdsPreFwd); forwards->ReleaseForward(m_usercmdsFwd); forwards->ReleaseForward(m_usercmdsPostFwd); forwards->ReleaseForward(m_netFileSendFwd); @@ -283,7 +298,10 @@ void CHookManager::PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper) RETURN_META(MRES_IGNORED); } - if (m_usercmdsFwd->GetFunctionCount() == 0) + bool hasUsercmdsPreFwds = (m_usercmdsPreFwd->GetFunctionCount() > 0); + bool hasUsercmdsFwds = (m_usercmdsFwd->GetFunctionCount() > 0); + + if (!hasUsercmdsPreFwds && !hasUsercmdsFwds) { RETURN_META(MRES_IGNORED); } @@ -311,34 +329,53 @@ void CHookManager::PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper) cell_t vel[3] = {sp_ftoc(ucmd->forwardmove), sp_ftoc(ucmd->sidemove), sp_ftoc(ucmd->upmove)}; cell_t angles[3] = {sp_ftoc(ucmd->viewangles.x), sp_ftoc(ucmd->viewangles.y), sp_ftoc(ucmd->viewangles.z)}; cell_t mouse[2] = {ucmd->mousedx, ucmd->mousedy}; - - m_usercmdsFwd->PushCell(client); - m_usercmdsFwd->PushCellByRef(&ucmd->buttons); - m_usercmdsFwd->PushCellByRef(&impulse); - m_usercmdsFwd->PushArray(vel, 3, SM_PARAM_COPYBACK); - m_usercmdsFwd->PushArray(angles, 3, SM_PARAM_COPYBACK); - m_usercmdsFwd->PushCellByRef(&ucmd->weaponselect); - m_usercmdsFwd->PushCellByRef(&ucmd->weaponsubtype); - m_usercmdsFwd->PushCellByRef(&ucmd->command_number); - m_usercmdsFwd->PushCellByRef(&ucmd->tick_count); - m_usercmdsFwd->PushCellByRef(&ucmd->random_seed); - m_usercmdsFwd->PushArray(mouse, 2, SM_PARAM_COPYBACK); - m_usercmdsFwd->Execute(&result); - - ucmd->impulse = impulse; - ucmd->forwardmove = sp_ctof(vel[0]); - ucmd->sidemove = sp_ctof(vel[1]); - ucmd->upmove = sp_ctof(vel[2]); - ucmd->viewangles.x = sp_ctof(angles[0]); - ucmd->viewangles.y = sp_ctof(angles[1]); - ucmd->viewangles.z = sp_ctof(angles[2]); - ucmd->mousedx = mouse[0]; - ucmd->mousedy = mouse[1]; - - - if (result == Pl_Handled) + + if (hasUsercmdsPreFwds) { - RETURN_META(MRES_SUPERCEDE); + m_usercmdsPreFwd->PushCell(client); + m_usercmdsPreFwd->PushCell(ucmd->buttons); + m_usercmdsPreFwd->PushCell(ucmd->impulse); + m_usercmdsPreFwd->PushArray(vel, 3); + m_usercmdsPreFwd->PushArray(angles, 3); + m_usercmdsPreFwd->PushCell(ucmd->weaponselect); + m_usercmdsPreFwd->PushCell(ucmd->weaponsubtype); + m_usercmdsPreFwd->PushCell(ucmd->command_number); + m_usercmdsPreFwd->PushCell(ucmd->tick_count); + m_usercmdsPreFwd->PushCell(ucmd->random_seed); + m_usercmdsPreFwd->PushArray(mouse, 2); + m_usercmdsPreFwd->Execute(); + } + + if (hasUsercmdsFwds) + { + m_usercmdsFwd->PushCell(client); + m_usercmdsFwd->PushCellByRef(&ucmd->buttons); + m_usercmdsFwd->PushCellByRef(&impulse); + m_usercmdsFwd->PushArray(vel, 3, SM_PARAM_COPYBACK); + m_usercmdsFwd->PushArray(angles, 3, SM_PARAM_COPYBACK); + m_usercmdsFwd->PushCellByRef(&ucmd->weaponselect); + m_usercmdsFwd->PushCellByRef(&ucmd->weaponsubtype); + m_usercmdsFwd->PushCellByRef(&ucmd->command_number); + m_usercmdsFwd->PushCellByRef(&ucmd->tick_count); + m_usercmdsFwd->PushCellByRef(&ucmd->random_seed); + m_usercmdsFwd->PushArray(mouse, 2, SM_PARAM_COPYBACK); + m_usercmdsFwd->Execute(&result); + + ucmd->impulse = impulse; + ucmd->forwardmove = sp_ctof(vel[0]); + ucmd->sidemove = sp_ctof(vel[1]); + ucmd->upmove = sp_ctof(vel[2]); + ucmd->viewangles.x = sp_ctof(angles[0]); + ucmd->viewangles.y = sp_ctof(angles[1]); + ucmd->viewangles.z = sp_ctof(angles[2]); + ucmd->mousedx = mouse[0]; + ucmd->mousedy = mouse[1]; + + + if (result == Pl_Handled) + { + RETURN_META(MRES_SUPERCEDE); + } } RETURN_META(MRES_IGNORED); @@ -576,7 +613,7 @@ void CHookManager::OnPluginLoaded(IPlugin *plugin) if (PRCH_enabled) { bool changed = false; - if (!PRCH_used && (m_usercmdsFwd->GetFunctionCount() > 0)) + if (!PRCH_used && ((m_usercmdsFwd->GetFunctionCount() > 0) || (m_usercmdsPreFwd->GetFunctionCount() > 0))) { PRCH_used = true; changed = true; @@ -634,7 +671,7 @@ void CHookManager::OnPluginLoaded(IPlugin *plugin) void CHookManager::OnPluginUnloaded(IPlugin *plugin) { - if (PRCH_used && !m_usercmdsFwd->GetFunctionCount()) + if (PRCH_used && (!m_usercmdsFwd->GetFunctionCount() && !m_usercmdsPreFwd->GetFunctionCount())) { for (size_t i = 0; i < m_runUserCmdHooks.size(); ++i) { diff --git a/extensions/sdktools/hooks.h b/extensions/sdktools/hooks.h index b46e3666..80334c8c 100644 --- a/extensions/sdktools/hooks.h +++ b/extensions/sdktools/hooks.h @@ -77,6 +77,7 @@ private: void NetChannelHook(int client); private: + IForward *m_usercmdsPreFwd; IForward *m_usercmdsFwd; IForward *m_usercmdsPostFwd; IForward *m_netFileSendFwd; diff --git a/plugins/include/sdktools_hooks.inc b/plugins/include/sdktools_hooks.inc index cd656eeb..1c20016d 100644 --- a/plugins/include/sdktools_hooks.inc +++ b/plugins/include/sdktools_hooks.inc @@ -37,6 +37,23 @@ #define FEATURECAP_PLAYERRUNCMD_11PARAMS "SDKTools PlayerRunCmd 11Params" +/** + * Called when a clients movement buttons are being processed (Read Only) + * + * @param client Index of the client. + * @param buttons Current commands (as bitflags - see entity_prop_stocks.inc). + * @param impulse Current impulse command. + * @param vel Players desired velocity. + * @param angles Players desired view angles. + * @param weapon Entity index of the new weapon if player switches weapon, 0 otherwise. + * @param subtype Weapon subtype when selected from a menu. + * @param cmdnum Command number. Increments from the first command sent. + * @param tickcount Tick count. A client's prediction based on the server's GetGameTickCount value. + * @param seed Random seed. Used to determine weapon recoil, spread, and other predicted elements. + * @param mouse Mouse direction (x, y). + */ +forward void OnPlayerRunCmdPre(int client, int buttons, int impulse, const float vel[3], const float angles[3], int weapon, int subtype, int cmdnum, int tickcount, int seed, const int mouse[2]); + /** * Called when a clients movement buttons are being processed *