Mid-Air Sprinting (#208)
This commit is contained in:
parent
d00f4831cd
commit
f3d7685324
@ -266,6 +266,52 @@ namespace gameplay
|
|||||||
vel_out[2] = new_z * length_scale;
|
vel_out[2] = new_z * length_scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* pm_can_start_sprint_stub()
|
||||||
|
{
|
||||||
|
return utils::hook::assemble([=](utils::hook::assembler& a)
|
||||||
|
{
|
||||||
|
const auto skip_jz = a.newLabel();
|
||||||
|
const auto loc_2C98EF = a.newLabel();
|
||||||
|
|
||||||
|
// save rax's original value
|
||||||
|
a.push(rax);
|
||||||
|
|
||||||
|
// move dvar pointer to rax
|
||||||
|
a.mov(rax, qword_ptr(reinterpret_cast<uint64_t>(&dvars::pm_sprintInAir)));
|
||||||
|
|
||||||
|
// move *(rax + 16) into al
|
||||||
|
a.mov(al, byte_ptr(rax, 0x10));
|
||||||
|
|
||||||
|
// compare al with 1
|
||||||
|
a.cmp(al, 1);
|
||||||
|
|
||||||
|
// restore rax to its original value
|
||||||
|
a.pop(rax);
|
||||||
|
|
||||||
|
// jz == jump zero, jumps if the two operands in cmp are equal
|
||||||
|
a.jz(skip_jz); // skip the last cmp & jz
|
||||||
|
|
||||||
|
// execute original code at 0x2C98C0 & 0x2C98C6
|
||||||
|
// necessary because our jump overwrites 12 bytes after it
|
||||||
|
a.mov(eax, 0x7FF); // rax got overwritted by our long jump (it does mov rax, <jmpaddr>; jmp rax)
|
||||||
|
a.cmp(word_ptr(rbx, 0x22), ax);
|
||||||
|
a.jz(loc_2C98EF);
|
||||||
|
|
||||||
|
a.bind(skip_jz);
|
||||||
|
|
||||||
|
// execute original code from 0x2C98C6 to 0x2C98CC
|
||||||
|
a.mov(edx, dword_ptr(rdi, 0x8));
|
||||||
|
a.mov(rcx, rbx);
|
||||||
|
|
||||||
|
// the section of code that was overwritten by our jump is finished so we can jump back to the game code
|
||||||
|
a.jmp(0x2C98CC_b);
|
||||||
|
|
||||||
|
// original code
|
||||||
|
a.bind(loc_2C98EF);
|
||||||
|
a.jmp(0x2C98EF_b);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface
|
||||||
@ -307,6 +353,10 @@ namespace gameplay
|
|||||||
utils::hook::jump(0x3FF812_b, client_end_frame_stub(), true);
|
utils::hook::jump(0x3FF812_b, client_end_frame_stub(), true);
|
||||||
utils::hook::nop(0x3FF808_b, 1);
|
utils::hook::nop(0x3FF808_b, 1);
|
||||||
|
|
||||||
|
dvars::pm_sprintInAir = dvars::register_bool("pm_sprintInAir", false,
|
||||||
|
game::DVAR_FLAG_REPLICATED, "Enable Mid-Air Sprinting");
|
||||||
|
utils::hook::jump(0x2C98C0_b, pm_can_start_sprint_stub(), true);
|
||||||
|
|
||||||
auto* timescale = dvars::register_float("timescale", 1.0f, 0.1f, 50.0f, game::DVAR_FLAG_REPLICATED, "Changes Timescale of the game");
|
auto* timescale = dvars::register_float("timescale", 1.0f, 0.1f, 50.0f, game::DVAR_FLAG_REPLICATED, "Changes Timescale of the game");
|
||||||
utils::hook::inject(0x15B204_b, ×cale->current.value); // Com_GetTimeScale
|
utils::hook::inject(0x15B204_b, ×cale->current.value); // Com_GetTimeScale
|
||||||
utils::hook::inject(0x17D243_b, ×cale->current.value); // Com_Restart
|
utils::hook::inject(0x17D243_b, ×cale->current.value); // Com_Restart
|
||||||
|
@ -32,6 +32,7 @@ namespace dvars
|
|||||||
|
|
||||||
game::dvar_t* pm_bouncing = nullptr;
|
game::dvar_t* pm_bouncing = nullptr;
|
||||||
game::dvar_t* pm_bouncingAllAngles = nullptr;
|
game::dvar_t* pm_bouncingAllAngles = nullptr;
|
||||||
|
game::dvar_t* pm_sprintInAir = nullptr;
|
||||||
|
|
||||||
game::dvar_t* jump_ladderPushVel = nullptr;
|
game::dvar_t* jump_ladderPushVel = nullptr;
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ namespace dvars
|
|||||||
|
|
||||||
extern game::dvar_t* pm_bouncing;
|
extern game::dvar_t* pm_bouncing;
|
||||||
extern game::dvar_t* pm_bouncingAllAngles;
|
extern game::dvar_t* pm_bouncingAllAngles;
|
||||||
|
extern game::dvar_t* pm_sprintInAir;
|
||||||
|
|
||||||
extern game::dvar_t* jump_ladderPushVel;
|
extern game::dvar_t* jump_ladderPushVel;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user