[PlayerMovement]: Re-write stubs (#586)
This commit is contained in:
parent
d87e52737e
commit
dc7f6a9f6a
@ -96,7 +96,7 @@ namespace Components
|
|||||||
Loader::Register(new Gamepad());
|
Loader::Register(new Gamepad());
|
||||||
Loader::Register(new Chat());
|
Loader::Register(new Chat());
|
||||||
Loader::Register(new TextRenderer());
|
Loader::Register(new TextRenderer());
|
||||||
Loader::Register(new Movement());
|
Loader::Register(new PlayerMovement());
|
||||||
Loader::Register(new Elevators());
|
Loader::Register(new Elevators());
|
||||||
Loader::Register(new ClientCommand());
|
Loader::Register(new ClientCommand());
|
||||||
Loader::Register(new VisionFile());
|
Loader::Register(new VisionFile());
|
||||||
|
@ -126,7 +126,7 @@ namespace Components
|
|||||||
#include "Modules/SoundMutexFix.hpp"
|
#include "Modules/SoundMutexFix.hpp"
|
||||||
#include "Modules/Chat.hpp"
|
#include "Modules/Chat.hpp"
|
||||||
#include "Modules/TextRenderer.hpp"
|
#include "Modules/TextRenderer.hpp"
|
||||||
#include "Modules/Movement.hpp"
|
#include "Modules/PlayerMovement.hpp"
|
||||||
#include "Modules/Elevators.hpp"
|
#include "Modules/Elevators.hpp"
|
||||||
#include "Modules/ClientCommand.hpp"
|
#include "Modules/ClientCommand.hpp"
|
||||||
#include "Modules/VisionFile.hpp"
|
#include "Modules/VisionFile.hpp"
|
||||||
|
@ -1,302 +0,0 @@
|
|||||||
#include <STDInclude.hpp>
|
|
||||||
|
|
||||||
namespace Components
|
|
||||||
{
|
|
||||||
Dvar::Var Movement::PlayerSpectateSpeedScale;
|
|
||||||
Dvar::Var Movement::CGUfoScaler;
|
|
||||||
Dvar::Var Movement::CGNoclipScaler;
|
|
||||||
Dvar::Var Movement::BGBouncesAllAngles;
|
|
||||||
Dvar::Var Movement::BGRocketJump;
|
|
||||||
Dvar::Var Movement::BGRocketJumpScale;
|
|
||||||
Dvar::Var Movement::BGPlayerEjection;
|
|
||||||
Dvar::Var Movement::BGPlayerCollision;
|
|
||||||
Game::dvar_t* Movement::BGBounces;
|
|
||||||
Game::dvar_t* Movement::PlayerDuckedSpeedScale;
|
|
||||||
Game::dvar_t* Movement::PlayerProneSpeedScale;
|
|
||||||
|
|
||||||
__declspec(naked) void Movement::PM_PlayerDuckedSpeedScaleStub()
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
push eax
|
|
||||||
mov eax, Movement::PlayerDuckedSpeedScale
|
|
||||||
fld dword ptr [eax + 0x10] // dvar_t.current.value
|
|
||||||
pop eax
|
|
||||||
|
|
||||||
// Game's code
|
|
||||||
pop ecx
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__declspec(naked) void Movement::PM_PlayerProneSpeedScaleStub()
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
push eax
|
|
||||||
mov eax, Movement::PlayerProneSpeedScale
|
|
||||||
fld dword ptr [eax + 0x10] // dvar_t.current.value
|
|
||||||
pop eax
|
|
||||||
|
|
||||||
// Game's code
|
|
||||||
pop ecx
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float Movement::PM_MoveScale(Game::playerState_s* ps, float fmove,
|
|
||||||
float rmove, float umove)
|
|
||||||
{
|
|
||||||
assert(ps != nullptr);
|
|
||||||
|
|
||||||
auto max = std::fabsf(fmove) < std::fabsf(rmove)
|
|
||||||
? std::fabsf(rmove) : std::fabsf(fmove);
|
|
||||||
|
|
||||||
if (std::fabsf(umove) > max)
|
|
||||||
{
|
|
||||||
max = std::fabsf(umove);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max == 0.0f)
|
|
||||||
{
|
|
||||||
return 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto total = std::sqrtf(fmove * fmove
|
|
||||||
+ rmove * rmove + umove * umove);
|
|
||||||
auto scale = (static_cast<float>(ps->speed) * max) / (127.0f * total);
|
|
||||||
|
|
||||||
if (ps->pm_flags & Game::PMF_WALKING || ps->leanf != 0.0f)
|
|
||||||
{
|
|
||||||
scale *= 0.4f;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (ps->pm_type)
|
|
||||||
{
|
|
||||||
case Game::pmtype_t::PM_NOCLIP:
|
|
||||||
scale *= Movement::CGNoclipScaler.get<float>();
|
|
||||||
break;
|
|
||||||
case Game::pmtype_t::PM_UFO:
|
|
||||||
scale *= Movement::CGUfoScaler.get<float>();
|
|
||||||
break;
|
|
||||||
case Game::pmtype_t::PM_SPECTATOR:
|
|
||||||
scale *= Movement::PlayerSpectateSpeedScale.get<float>();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
__declspec(naked) void Movement::PM_MoveScaleStub()
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
pushad
|
|
||||||
|
|
||||||
push [esp + 0xC + 0x20] // umove
|
|
||||||
push [esp + 0xC + 0x20] // rmove
|
|
||||||
push [esp + 0xC + 0x20] // fmove
|
|
||||||
push esi // ps
|
|
||||||
call Movement::PM_MoveScale
|
|
||||||
add esp, 0x10
|
|
||||||
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__declspec(naked) void Movement::PM_StepSlideMoveStub()
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
// Check the value of BGBounces
|
|
||||||
push ecx
|
|
||||||
push eax
|
|
||||||
|
|
||||||
mov eax, Movement::BGBounces
|
|
||||||
mov ecx, dword ptr [eax + 0x10]
|
|
||||||
test ecx, ecx
|
|
||||||
|
|
||||||
pop eax
|
|
||||||
pop ecx
|
|
||||||
|
|
||||||
// Do not bounce if BGBounces is 0
|
|
||||||
jle noBounce
|
|
||||||
|
|
||||||
// Bounce
|
|
||||||
push 0x4B1B34
|
|
||||||
retn
|
|
||||||
|
|
||||||
noBounce:
|
|
||||||
// Original game code
|
|
||||||
cmp dword ptr [esp + 0x24], 0
|
|
||||||
push 0x4B1B48
|
|
||||||
retn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Movement::PM_ProjectVelocityStub(const float* velIn, const float* normal, float* velOut)
|
|
||||||
{
|
|
||||||
const auto lengthSquared2D = velIn[0] * velIn[0] + velIn[1] * velIn[1];
|
|
||||||
|
|
||||||
if (std::fabsf(normal[2]) < 0.001f || lengthSquared2D == 0.0)
|
|
||||||
{
|
|
||||||
velOut[0] = velIn[0];
|
|
||||||
velOut[1] = velIn[1];
|
|
||||||
velOut[2] = velIn[2];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto newZ = velIn[0] * normal[0] + velIn[1] * normal[1];
|
|
||||||
newZ = -newZ / normal[2];
|
|
||||||
const auto lengthScale = std::sqrtf((velIn[2] * velIn[2] + lengthSquared2D)
|
|
||||||
/ (newZ * newZ + lengthSquared2D));
|
|
||||||
|
|
||||||
if (Movement::BGBouncesAllAngles.get<bool>()
|
|
||||||
|| (lengthScale < 1.f || newZ < 0.f || velIn[2] > 0.f))
|
|
||||||
{
|
|
||||||
velOut[0] = velIn[0] * lengthScale;
|
|
||||||
velOut[1] = velIn[1] * lengthScale;
|
|
||||||
velOut[2] = newZ * lengthScale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Double bounces
|
|
||||||
void Movement::Jump_ClearState_Hk(Game::playerState_s* ps)
|
|
||||||
{
|
|
||||||
if (Movement::BGBounces->current.integer != Movement::DOUBLE)
|
|
||||||
{
|
|
||||||
Game::Jump_ClearState(ps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Game::gentity_s* Movement::Weapon_RocketLauncher_Fire_Hk(Game::gentity_s* ent, unsigned int weaponIndex,
|
|
||||||
float spread, Game::weaponParms* wp, const float* gunVel, Game::lockonFireParms* lockParms, bool magicBullet)
|
|
||||||
{
|
|
||||||
auto* result = Game::Weapon_RocketLauncher_Fire(ent, weaponIndex, spread, wp, gunVel, lockParms, magicBullet);
|
|
||||||
|
|
||||||
if (ent->client != nullptr && BGRocketJump.get<bool>() &&
|
|
||||||
wp->weapDef->inventoryType != Game::WEAPINVENTORY_EXCLUSIVE)
|
|
||||||
{
|
|
||||||
const auto scale = Movement::BGRocketJumpScale.get<float>();
|
|
||||||
ent->client->ps.velocity[0] += (0.0f - wp->forward[0]) * scale;
|
|
||||||
ent->client->ps.velocity[1] += (0.0f - wp->forward[1]) * scale;
|
|
||||||
ent->client->ps.velocity[2] += (0.0f - wp->forward[2]) * scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Movement::StuckInClient_Hk(Game::gentity_s* self)
|
|
||||||
{
|
|
||||||
if (Movement::BGPlayerEjection.get<bool>())
|
|
||||||
{
|
|
||||||
return Utils::Hook::Call<int(Game::gentity_s*)>(0x402D30)(self); // StuckInClient
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Movement::CM_TransformedCapsuleTrace_Hk(Game::trace_t* results, const float* start, const float* end,
|
|
||||||
const Game::Bounds* bounds, const Game::Bounds* capsule, int contents, const float* origin, const float* angles)
|
|
||||||
{
|
|
||||||
if (Movement::BGPlayerCollision.get<bool>())
|
|
||||||
{
|
|
||||||
Utils::Hook::Call<void(Game::trace_t*, const float*, const float*,
|
|
||||||
const Game::Bounds*, const Game::Bounds*, int, const float*, const float*)>
|
|
||||||
(0x478300)
|
|
||||||
(results, start, end, bounds, capsule, contents, origin, angles); // CM_TransformedCapsuleTrace
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Game::dvar_t* Movement::Dvar_RegisterSpectateSpeedScale(const char* dvarName, float value,
|
|
||||||
float min, float max, unsigned __int16 /*flags*/, const char* description)
|
|
||||||
{
|
|
||||||
Movement::PlayerSpectateSpeedScale = Dvar::Register<float>(dvarName, value,
|
|
||||||
min, max, Game::DVAR_CHEAT | Game::DVAR_CODINFO, description);
|
|
||||||
|
|
||||||
return Movement::PlayerSpectateSpeedScale.get<Game::dvar_t*>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Movement::RegisterMovementDvars()
|
|
||||||
{
|
|
||||||
Movement::PlayerDuckedSpeedScale = Game::Dvar_RegisterFloat("player_duckedSpeedScale",
|
|
||||||
0.65f, 0.0f, 5.0f, Game::DVAR_CHEAT | Game::DVAR_CODINFO,
|
|
||||||
"The scale applied to the player speed when ducking");
|
|
||||||
|
|
||||||
Movement::PlayerProneSpeedScale = Game::Dvar_RegisterFloat("player_proneSpeedScale",
|
|
||||||
0.15f, 0.0f, 5.0f, Game::DVAR_CHEAT | Game::DVAR_CODINFO,
|
|
||||||
"The scale applied to the player speed when crawling");
|
|
||||||
|
|
||||||
// 3arc naming convention
|
|
||||||
Movement::CGUfoScaler = Dvar::Register<float>("cg_ufo_scaler",
|
|
||||||
6.0f, 0.001f, 1000.0f, Game::DVAR_CHEAT | Game::DVAR_CODINFO,
|
|
||||||
"The speed at which ufo camera moves");
|
|
||||||
|
|
||||||
Movement::CGNoclipScaler = Dvar::Register<float>("cg_noclip_scaler",
|
|
||||||
3.0f, 0.001f, 1000.0f, Game::DVAR_CHEAT | Game::DVAR_CODINFO,
|
|
||||||
"The speed at which noclip camera moves");
|
|
||||||
|
|
||||||
Movement::BGBouncesAllAngles = Dvar::Register<bool>("bg_bouncesAllAngles",
|
|
||||||
false, Game::DVAR_CODINFO, "Force bounce from all angles");
|
|
||||||
|
|
||||||
Movement::BGRocketJump = Dvar::Register<bool>("bg_rocketJump",
|
|
||||||
false, Game::DVAR_CODINFO, "Enable CoD4 rocket jumps");
|
|
||||||
|
|
||||||
Movement::BGRocketJumpScale = Dvar::Register<float>("bg_rocketJumpScale",
|
|
||||||
64.0f, 1.0f, std::numeric_limits<float>::max(), Game::DVAR_CODINFO,
|
|
||||||
"The scale applied to the pushback force of a rocket");
|
|
||||||
|
|
||||||
Movement::BGPlayerEjection = Dvar::Register<bool>("bg_playerEjection",
|
|
||||||
true, Game::DVAR_CODINFO, "Push intersecting players away from each other");
|
|
||||||
|
|
||||||
Movement::BGPlayerCollision = Dvar::Register<bool>("bg_playerCollision",
|
|
||||||
true, Game::DVAR_CODINFO, "Push intersecting players away from each other");
|
|
||||||
}
|
|
||||||
|
|
||||||
Movement::Movement()
|
|
||||||
{
|
|
||||||
Scheduler::Once([]
|
|
||||||
{
|
|
||||||
static const char* bg_bouncesValues[] =
|
|
||||||
{
|
|
||||||
"disabled",
|
|
||||||
"enabled",
|
|
||||||
"double",
|
|
||||||
nullptr
|
|
||||||
};
|
|
||||||
|
|
||||||
Movement::BGBounces = Game::Dvar_RegisterEnum("bg_bounces",
|
|
||||||
bg_bouncesValues, Movement::DISABLED, Game::DVAR_CODINFO, "Bounce glitch settings");
|
|
||||||
}, Scheduler::Pipeline::MAIN);
|
|
||||||
|
|
||||||
// Hook Dvar_RegisterFloat. Only thing that's changed is that the 0x80 flag is not used.
|
|
||||||
Utils::Hook(0x448990, Movement::Dvar_RegisterSpectateSpeedScale, HOOK_CALL).install()->quick();
|
|
||||||
|
|
||||||
// PM_CmdScaleForStance
|
|
||||||
Utils::Hook(0x572D9B, Movement::PM_PlayerDuckedSpeedScaleStub, HOOK_JUMP).install()->quick();
|
|
||||||
Utils::Hook(0x572DA5, Movement::PM_PlayerProneSpeedScaleStub, HOOK_JUMP).install()->quick();
|
|
||||||
|
|
||||||
// Hook PM_MoveScale so we can add custom speed scale for Ufo and Noclip
|
|
||||||
Utils::Hook(0x56F845, Movement::PM_MoveScaleStub, HOOK_CALL).install()->quick();
|
|
||||||
Utils::Hook(0x56FABD, Movement::PM_MoveScaleStub, HOOK_CALL).install()->quick();
|
|
||||||
|
|
||||||
// Bounce logic
|
|
||||||
Utils::Hook(0x4B1B2D, Movement::PM_StepSlideMoveStub, HOOK_JUMP).install()->quick();
|
|
||||||
Utils::Hook(0x57383E, Movement::Jump_ClearState_Hk, HOOK_CALL).install()->quick();
|
|
||||||
Utils::Hook(0x4B1B97, Movement::PM_ProjectVelocityStub, HOOK_CALL).install()->quick();
|
|
||||||
|
|
||||||
// Rocket jump
|
|
||||||
Utils::Hook(0x4A4F9B, Movement::Weapon_RocketLauncher_Fire_Hk, HOOK_CALL).install()->quick(); // FireWeapon
|
|
||||||
|
|
||||||
// Hook StuckInClient & CM_TransformedCapsuleTrace
|
|
||||||
// so we can prevent intersecting players from being pushed away from each other
|
|
||||||
Utils::Hook(0x5D8153, Movement::StuckInClient_Hk, HOOK_CALL).install()->quick();
|
|
||||||
Utils::Hook(0x45A5BF, Movement::CM_TransformedCapsuleTrace_Hk, HOOK_CALL).install()->quick(); // SV_ClipMoveToEntity
|
|
||||||
Utils::Hook(0x5A0CAD, Movement::CM_TransformedCapsuleTrace_Hk, HOOK_CALL).install()->quick(); // CG_ClipMoveToEntity
|
|
||||||
|
|
||||||
Movement::RegisterMovementDvars();
|
|
||||||
}
|
|
||||||
}
|
|
278
src/Components/Modules/PlayerMovement.cpp
Normal file
278
src/Components/Modules/PlayerMovement.cpp
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
#include <STDInclude.hpp>
|
||||||
|
|
||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
Dvar::Var PlayerMovement::BGRocketJump;
|
||||||
|
Dvar::Var PlayerMovement::BGRocketJumpScale;
|
||||||
|
Dvar::Var PlayerMovement::BGPlayerEjection;
|
||||||
|
Dvar::Var PlayerMovement::BGPlayerCollision;
|
||||||
|
const Game::dvar_t* PlayerMovement::CGNoclipScaler;
|
||||||
|
const Game::dvar_t* PlayerMovement::CGUfoScaler;
|
||||||
|
const Game::dvar_t* PlayerMovement::PlayerSpectateSpeedScale;
|
||||||
|
const Game::dvar_t* PlayerMovement::BGBounces;
|
||||||
|
const Game::dvar_t* PlayerMovement::BGBouncesAllAngles;
|
||||||
|
const Game::dvar_t* PlayerMovement::PlayerDuckedSpeedScale;
|
||||||
|
const Game::dvar_t* PlayerMovement::PlayerProneSpeedScale;
|
||||||
|
|
||||||
|
__declspec(naked) void PlayerMovement::PM_PlayerDuckedSpeedScaleStub()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push eax
|
||||||
|
mov eax, PlayerDuckedSpeedScale
|
||||||
|
fld dword ptr [eax + 0x10] // dvar_t.current.value
|
||||||
|
pop eax
|
||||||
|
|
||||||
|
// Game's code
|
||||||
|
pop ecx
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(naked) void PlayerMovement::PM_PlayerProneSpeedScaleStub()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push eax
|
||||||
|
mov eax, PlayerProneSpeedScale
|
||||||
|
fld dword ptr [eax + 0x10] // dvar_t.current.value
|
||||||
|
pop eax
|
||||||
|
|
||||||
|
// Game's code
|
||||||
|
pop ecx
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(naked) void PlayerMovement::PM_MoveScale_Noclip()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
mov eax, CGNoclipScaler
|
||||||
|
fld dword ptr [eax + 0x10] // dvar_t.current.value
|
||||||
|
fmul dword ptr [esp + 0xC]
|
||||||
|
fstp dword ptr [esp + 0xC]
|
||||||
|
|
||||||
|
push 0x56F43A
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(naked) void PlayerMovement::PM_MoveScale_Ufo()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
mov eax, CGUfoScaler
|
||||||
|
fld dword ptr [eax + 0x10] // dvar_t.current.value
|
||||||
|
fmul dword ptr [esp + 0xC]
|
||||||
|
fstp dword ptr [esp + 0xC]
|
||||||
|
|
||||||
|
push 0x56F44D
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(naked) void PlayerMovement::PM_MoveScale_Spectate()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
mov eax, PlayerSpectateSpeedScale
|
||||||
|
fld dword ptr [eax + 0x10] // dvar_t.current.value
|
||||||
|
fmul dword ptr [esp + 0xC]
|
||||||
|
fstp dword ptr [esp + 0xC]
|
||||||
|
|
||||||
|
push 0x56F462
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(naked) void PlayerMovement::PM_StepSlideMoveStub()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
// Check the value of BGBounces
|
||||||
|
push ecx
|
||||||
|
push eax
|
||||||
|
|
||||||
|
mov eax, BGBounces
|
||||||
|
mov ecx, dword ptr [eax + 0x10]
|
||||||
|
test ecx, ecx
|
||||||
|
|
||||||
|
pop eax
|
||||||
|
pop ecx
|
||||||
|
|
||||||
|
// Do not bounce if BGBounces is 0
|
||||||
|
jle noBounce
|
||||||
|
|
||||||
|
// Bounce
|
||||||
|
push 0x4B1B34
|
||||||
|
retn
|
||||||
|
|
||||||
|
noBounce:
|
||||||
|
// Original game code
|
||||||
|
cmp dword ptr [esp + 0x24], 0
|
||||||
|
push 0x4B1B48
|
||||||
|
retn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Double bounces
|
||||||
|
void PlayerMovement::Jump_ClearState_Hk(Game::playerState_s* ps)
|
||||||
|
{
|
||||||
|
if (BGBounces->current.integer != DOUBLE)
|
||||||
|
{
|
||||||
|
Game::Jump_ClearState(ps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(naked) void PlayerMovement::PM_ProjectVelocityStub()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push eax
|
||||||
|
mov eax, BGBouncesAllAngles
|
||||||
|
cmp byte ptr [eax + 0x10], 1
|
||||||
|
pop eax
|
||||||
|
|
||||||
|
je bounce
|
||||||
|
|
||||||
|
fstp ST(0)
|
||||||
|
pop esi
|
||||||
|
add esp, 0x10
|
||||||
|
ret
|
||||||
|
|
||||||
|
bounce:
|
||||||
|
push 0x417B6F
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::gentity_s* PlayerMovement::Weapon_RocketLauncher_Fire_Hk(Game::gentity_s* ent, unsigned int weaponIndex,
|
||||||
|
float spread, Game::weaponParms* wp, const float* gunVel, Game::lockonFireParms* lockParms, bool magicBullet)
|
||||||
|
{
|
||||||
|
auto* result = Game::Weapon_RocketLauncher_Fire(ent, weaponIndex, spread, wp, gunVel, lockParms, magicBullet);
|
||||||
|
|
||||||
|
if (ent->client != nullptr && BGRocketJump.get<bool>() &&
|
||||||
|
wp->weapDef->inventoryType != Game::WEAPINVENTORY_EXCLUSIVE)
|
||||||
|
{
|
||||||
|
const auto scale = BGRocketJumpScale.get<float>();
|
||||||
|
ent->client->ps.velocity[0] += (0.0f - wp->forward[0]) * scale;
|
||||||
|
ent->client->ps.velocity[1] += (0.0f - wp->forward[1]) * scale;
|
||||||
|
ent->client->ps.velocity[2] += (0.0f - wp->forward[2]) * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PlayerMovement::StuckInClient_Hk(Game::gentity_s* self)
|
||||||
|
{
|
||||||
|
if (BGPlayerEjection.get<bool>())
|
||||||
|
{
|
||||||
|
return Utils::Hook::Call<int(Game::gentity_s*)>(0x402D30)(self); // StuckInClient
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerMovement::CM_TransformedCapsuleTrace_Hk(Game::trace_t* results, const float* start, const float* end,
|
||||||
|
const Game::Bounds* bounds, const Game::Bounds* capsule, int contents, const float* origin, const float* angles)
|
||||||
|
{
|
||||||
|
if (BGPlayerCollision.get<bool>())
|
||||||
|
{
|
||||||
|
Utils::Hook::Call<void(Game::trace_t*, const float*, const float*,
|
||||||
|
const Game::Bounds*, const Game::Bounds*, int, const float*, const float*)>
|
||||||
|
(0x478300)
|
||||||
|
(results, start, end, bounds, capsule, contents, origin, angles); // CM_TransformedCapsuleTrace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Game::dvar_t* PlayerMovement::Dvar_RegisterSpectateSpeedScale(const char* dvarName, float value,
|
||||||
|
float min, float max, unsigned __int16 /*flags*/, const char* description)
|
||||||
|
{
|
||||||
|
PlayerSpectateSpeedScale = Game::Dvar_RegisterFloat(dvarName, value,
|
||||||
|
min, max, Game::DVAR_CHEAT | Game::DVAR_CODINFO, description);
|
||||||
|
|
||||||
|
return PlayerSpectateSpeedScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerMovement::RegisterMovementDvars()
|
||||||
|
{
|
||||||
|
PlayerDuckedSpeedScale = Game::Dvar_RegisterFloat("player_duckedSpeedScale",
|
||||||
|
0.65f, 0.0f, 5.0f, Game::DVAR_CHEAT | Game::DVAR_CODINFO,
|
||||||
|
"The scale applied to the player speed when ducking");
|
||||||
|
|
||||||
|
PlayerProneSpeedScale = Game::Dvar_RegisterFloat("player_proneSpeedScale",
|
||||||
|
0.15f, 0.0f, 5.0f, Game::DVAR_CHEAT | Game::DVAR_CODINFO,
|
||||||
|
"The scale applied to the player speed when crawling");
|
||||||
|
|
||||||
|
// 3arc naming convention
|
||||||
|
CGUfoScaler = Game::Dvar_RegisterFloat("cg_ufo_scaler",
|
||||||
|
6.0f, 0.001f, 1000.0f, Game::DVAR_CHEAT | Game::DVAR_CODINFO,
|
||||||
|
"The speed at which ufo camera moves");
|
||||||
|
|
||||||
|
CGNoclipScaler = Game::Dvar_RegisterFloat("cg_noclip_scaler",
|
||||||
|
3.0f, 0.001f, 1000.0f, Game::DVAR_CHEAT | Game::DVAR_CODINFO,
|
||||||
|
"The speed at which noclip camera moves");
|
||||||
|
|
||||||
|
BGBouncesAllAngles = Game::Dvar_RegisterBool("bg_bouncesAllAngles",
|
||||||
|
false, Game::DVAR_CODINFO, "Force bounce from all angles");
|
||||||
|
|
||||||
|
BGRocketJump = Dvar::Register<bool>("bg_rocketJump",
|
||||||
|
false, Game::DVAR_CODINFO, "Enable CoD4 rocket jumps");
|
||||||
|
|
||||||
|
BGRocketJumpScale = Dvar::Register<float>("bg_rocketJumpScale",
|
||||||
|
64.0f, 1.0f, std::numeric_limits<float>::max(), Game::DVAR_CODINFO,
|
||||||
|
"The scale applied to the pushback force of a rocket");
|
||||||
|
|
||||||
|
BGPlayerEjection = Dvar::Register<bool>("bg_playerEjection",
|
||||||
|
true, Game::DVAR_CODINFO, "Push intersecting players away from each other");
|
||||||
|
|
||||||
|
BGPlayerCollision = Dvar::Register<bool>("bg_playerCollision",
|
||||||
|
true, Game::DVAR_CODINFO, "Push intersecting players away from each other");
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerMovement::PlayerMovement()
|
||||||
|
{
|
||||||
|
Scheduler::Once([]
|
||||||
|
{
|
||||||
|
static const char* bg_bouncesValues[] =
|
||||||
|
{
|
||||||
|
"disabled",
|
||||||
|
"enabled",
|
||||||
|
"double",
|
||||||
|
nullptr
|
||||||
|
};
|
||||||
|
|
||||||
|
BGBounces = Game::Dvar_RegisterEnum("bg_bounces",
|
||||||
|
bg_bouncesValues, DISABLED, Game::DVAR_CODINFO, "Bounce glitch settings");
|
||||||
|
}, Scheduler::Pipeline::MAIN);
|
||||||
|
|
||||||
|
// Hook Dvar_RegisterFloat. Only thing that's changed is that the 0x80 flag is not used.
|
||||||
|
Utils::Hook(0x448990, Dvar_RegisterSpectateSpeedScale, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
// PM_CmdScaleForStance
|
||||||
|
Utils::Hook(0x572D9B, PM_PlayerDuckedSpeedScaleStub, HOOK_JUMP).install()->quick();
|
||||||
|
Utils::Hook(0x572DA5, PM_PlayerProneSpeedScaleStub, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
|
// Hook PM_MoveScale so we can add custom speed scale for Ufo and Noclip
|
||||||
|
Utils::Hook(0x56F42C, PM_MoveScale_Noclip, HOOK_JUMP).install()->quick();
|
||||||
|
Utils::Hook(0x56F43F, PM_MoveScale_Ufo, HOOK_JUMP).install()->quick();
|
||||||
|
Utils::Hook(0x56F452, PM_MoveScale_Spectate, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
|
// Bounce logic
|
||||||
|
Utils::Hook(0x4B1B2D, PM_StepSlideMoveStub, HOOK_JUMP).install()->quick();
|
||||||
|
Utils::Hook(0x57383E, Jump_ClearState_Hk, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x417B66, PM_ProjectVelocityStub, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
|
// Rocket jump
|
||||||
|
Utils::Hook(0x4A4F9B, Weapon_RocketLauncher_Fire_Hk, HOOK_CALL).install()->quick(); // FireWeapon
|
||||||
|
|
||||||
|
// Hook StuckInClient & CM_TransformedCapsuleTrace
|
||||||
|
// so we can prevent intersecting players from being pushed away from each other
|
||||||
|
Utils::Hook(0x5D8153, StuckInClient_Hk, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x45A5BF, CM_TransformedCapsuleTrace_Hk, HOOK_CALL).install()->quick(); // SV_ClipMoveToEntity
|
||||||
|
Utils::Hook(0x5A0CAD, CM_TransformedCapsuleTrace_Hk, HOOK_CALL).install()->quick(); // CG_ClipMoveToEntity
|
||||||
|
|
||||||
|
RegisterMovementDvars();
|
||||||
|
}
|
||||||
|
}
|
@ -2,36 +2,37 @@
|
|||||||
|
|
||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
class Movement : public Component
|
class PlayerMovement : public Component
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Movement();
|
PlayerMovement();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum BouncesSettings { DISABLED, ENABLED, DOUBLE };
|
enum BouncesSettings { DISABLED, ENABLED, DOUBLE };
|
||||||
|
|
||||||
static Dvar::Var PlayerSpectateSpeedScale;
|
|
||||||
static Dvar::Var CGUfoScaler;
|
|
||||||
static Dvar::Var CGNoclipScaler;
|
|
||||||
static Dvar::Var BGBouncesAllAngles;
|
|
||||||
static Dvar::Var BGRocketJump;
|
static Dvar::Var BGRocketJump;
|
||||||
static Dvar::Var BGRocketJumpScale;
|
static Dvar::Var BGRocketJumpScale;
|
||||||
static Dvar::Var BGPlayerEjection;
|
static Dvar::Var BGPlayerEjection;
|
||||||
static Dvar::Var BGPlayerCollision;
|
static Dvar::Var BGPlayerCollision;
|
||||||
// Can't use Var class inside assembly stubs
|
// Can't use Var class inside assembly stubs
|
||||||
static Game::dvar_t* BGBounces;
|
static const Game::dvar_t* CGNoclipScaler;
|
||||||
static Game::dvar_t* PlayerDuckedSpeedScale;
|
static const Game::dvar_t* CGUfoScaler;
|
||||||
static Game::dvar_t* PlayerProneSpeedScale;
|
static const Game::dvar_t* PlayerSpectateSpeedScale;
|
||||||
|
static const Game::dvar_t* BGBounces;
|
||||||
|
static const Game::dvar_t* BGBouncesAllAngles;
|
||||||
|
static const Game::dvar_t* PlayerDuckedSpeedScale;
|
||||||
|
static const Game::dvar_t* PlayerProneSpeedScale;
|
||||||
|
|
||||||
static void PM_PlayerDuckedSpeedScaleStub();
|
static void PM_PlayerDuckedSpeedScaleStub();
|
||||||
static void PM_PlayerProneSpeedScaleStub();
|
static void PM_PlayerProneSpeedScaleStub();
|
||||||
|
|
||||||
static float PM_MoveScale(Game::playerState_s* ps, float fmove, float rmove, float umove);
|
static void PM_MoveScale_Noclip();
|
||||||
static void PM_MoveScaleStub();
|
static void PM_MoveScale_Ufo();
|
||||||
|
static void PM_MoveScale_Spectate();
|
||||||
|
|
||||||
// Bounce logic
|
// Bounce logic
|
||||||
static void PM_StepSlideMoveStub();
|
static void PM_StepSlideMoveStub();
|
||||||
static void PM_ProjectVelocityStub(const float* velIn, const float* normal, float* velOut);
|
static void PM_ProjectVelocityStub();
|
||||||
static void Jump_ClearState_Hk(Game::playerState_s* ps);
|
static void Jump_ClearState_Hk(Game::playerState_s* ps);
|
||||||
|
|
||||||
static Game::gentity_s* Weapon_RocketLauncher_Fire_Hk(Game::gentity_s* ent, unsigned int weaponIndex, float spread, Game::weaponParms* wp, const float* gunVel, Game::lockonFireParms* lockParms, bool a7);
|
static Game::gentity_s* Weapon_RocketLauncher_Fire_Hk(Game::gentity_s* ent, unsigned int weaponIndex, float spread, Game::weaponParms* wp, const float* gunVel, Game::lockonFireParms* lockParms, bool a7);
|
||||||
@ -40,7 +41,7 @@ namespace Components
|
|||||||
static int StuckInClient_Hk(Game::gentity_s* self);
|
static int StuckInClient_Hk(Game::gentity_s* self);
|
||||||
static void CM_TransformedCapsuleTrace_Hk(Game::trace_t* results, const float* start, const float* end, const Game::Bounds* bounds, const Game::Bounds* capsule, int contents, const float* origin, const float* angles);
|
static void CM_TransformedCapsuleTrace_Hk(Game::trace_t* results, const float* start, const float* end, const Game::Bounds* bounds, const Game::Bounds* capsule, int contents, const float* origin, const float* angles);
|
||||||
|
|
||||||
static Game::dvar_t* Dvar_RegisterSpectateSpeedScale(const char* dvarName, float value, float min, float max, unsigned __int16 flags, const char* description);
|
static const Game::dvar_t* Dvar_RegisterSpectateSpeedScale(const char* dvarName, float value, float min, float max, unsigned __int16 flags, const char* description);
|
||||||
|
|
||||||
static void RegisterMovementDvars();
|
static void RegisterMovementDvars();
|
||||||
};
|
};
|
@ -6681,9 +6681,9 @@ namespace Game
|
|||||||
|
|
||||||
typedef struct punctuation_s
|
typedef struct punctuation_s
|
||||||
{
|
{
|
||||||
char *p; //punctuation character(s)
|
char* p; //punctuation character(s)
|
||||||
int n; //punctuation indication
|
int n; //punctuation indication
|
||||||
struct punctuation_s *next; //next punctuation
|
punctuation_s* next; //next punctuation
|
||||||
} punctuation_t;
|
} punctuation_t;
|
||||||
|
|
||||||
#define MAX_TOKEN 1024
|
#define MAX_TOKEN 1024
|
||||||
@ -6691,16 +6691,16 @@ namespace Game
|
|||||||
|
|
||||||
typedef struct token_s
|
typedef struct token_s
|
||||||
{
|
{
|
||||||
char string[MAX_TOKEN]; //available token
|
char string[MAX_TOKEN]; //available token
|
||||||
int type; //last read token type
|
int type; //last read token type
|
||||||
int subtype; //last read token sub type
|
int subtype; //last read token sub type
|
||||||
unsigned long int intvalue; //integer value
|
unsigned long int intvalue; //integer value
|
||||||
long double floatvalue; //floating point value
|
long double floatvalue; //floating point value
|
||||||
char *whitespace_p; //start of white space before token
|
char* whitespace_p; //start of white space before token
|
||||||
char *endwhitespace_p; //start of white space before token
|
char* endwhitespace_p; //start of white space before token
|
||||||
int line; //line the token was on
|
int line; //line the token was on
|
||||||
int linescrossed; //lines crossed in white space
|
int linescrossed; //lines crossed in white space
|
||||||
struct token_s *next; //next token in chain
|
token_s* next; //next token in chain
|
||||||
} token_t;
|
} token_t;
|
||||||
|
|
||||||
typedef struct script_s
|
typedef struct script_s
|
||||||
|
Loading…
Reference in New Issue
Block a user