Created
January 25, 2015 17:58
-
-
Save AltimorTASDK/55a7a24cdf18f9b399eb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * 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