Skip to content

Instantly share code, notes, and snippets.

@AltimorTASDK
Created January 25, 2015 17:58
Show Gist options
  • Select an option

  • Save AltimorTASDK/55a7a24cdf18f9b399eb to your computer and use it in GitHub Desktop.

Select an option

Save AltimorTASDK/55a7a24cdf18f9b399eb to your computer and use it in GitHub Desktop.
/*
* This plugin alters view punch to better reflect the recoil that's actually
* applied. The problem is that viewpunch is linearly proportionate to the
* increase in recoil velocity, but a higher velocity also means the recoil will
* increase for a longer time and take longer to decay. This plugin modifies
* viewpunch to increase exponentially with recoil velocity increase.
*/
#include "util.h"
#include "plugin.h"
#include <stdexcept>
ConVar view_punch_pct("view_punch_pct", "0.0015");
ConVar view_punch_exp("view_punch_exp", "2");
/**
* custom_kickback - Update player aimpunch velocity and viewpunch after a shot
* @player: Player to update for
* @angle: Recoil angle
* @magnitude: Recoil velocity increase
*
* Use the cos and sin of angle multiplied by magnitude to determine the
* components to be subtracted from the aim punch velocity, then do the same but
* with magnitude taken to a certain power and certain factor determined by
* cvars and subtract that from viewpunch.
*/
static void custom_kickback(
const char *player,
const float angle,
const float magnitude)
{
const auto x = cosf(angle * M_PI_F / 180.f);
const auto y = sinf(angle * M_PI_F / 180.f);
auto *aim_punch_vel = (QAngle*)(player + 0x9A4);
auto *view_punch = (QAngle*)(player + 0x98C);
aim_punch_vel->x -= x * magnitude;
aim_punch_vel->y -= y * magnitude;
const auto view_punch_factor =
powf(magnitude, view_punch_exp.GetFloat()) *
view_punch_pct.GetFloat();
view_punch->x -= x * view_punch_factor;
view_punch->y -= y * view_punch_factor;
}
/**
* hook_KickBack - C_CSPlayer::KickBack hook
* @ecx: Player pointer
* @xmm1: Recoil angle
* @xmm2: Recoil velocity increase
*
* Assembly wrapper to pass the player pointer, recoil angle and recoil
* magnitude to custom KickBack function
*/
__declspec(naked) static void hook_KickBack()
{
_asm {
sub esp, 8
movss dword ptr [esp + 4], xmm2
movss dword ptr [esp], xmm1
push ecx
call custom_kickback
add esp, 12
retn
}
}
/**
* plugin::Load - Valve plugin load method override
* @interfaceFactory: engine.dll factory
* @gameServerFactory: server.dll factory
*
* Detour C_CSPlayer::KickBack for custom view punch
*/
bool plugin::Load(
CreateInterfaceFn interfaceFactory,
CreateInterfaceFn gameServerFactory)
{
ConnectTier1Libraries(&interfaceFactory, 1);
ConnectTier2Libraries(&interfaceFactory, 1);
ConVar_Register(0);
uintptr_t start, end;
get_module_bounds("server.dll", &start, &end);
uintptr_t KickBack; // C_CSPlayer::KickBack
try {
const auto *KickBack_sig = "\x83\xEC\x24\x0F\x28\xC1";
const auto *KickBack_mask = "xxxxxx";
KickBack = sigscan(
start,
end,
KickBack_sig,
KickBack_mask) - 3;
} catch(...) {
Error("Sigscans failed!\n");
return false;
}
patch_jmp_rel32(KickBack, hook_KickBack);
return true;
}
/**
* plugin::Unload - Valve plugin unload method override
*
* Unregister the ICVar and disconnect libraries
*/
void plugin::Unload()
{
ConVar_Unregister();
DisconnectTier2Libraries();
DisconnectTier1Libraries();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment