@@ -166,11 +166,11 @@ namespace gameplay
166
166
a.jnz (allsolid);
167
167
168
168
a.bind (stand);
169
- a.and_ (dword_ptr (r15, 0x54 ), 0xFFFFFFFD );
170
- a.jmp (0x2C9F9D_b);
169
+ a.and_ (dword_ptr (SELECT_VALUE (r14, r15) , 0x54 ), 0xFFFFFFFD );
170
+ a.jmp (SELECT_VALUE (0x499628_b, 0x2C9F9D_b) );
171
171
172
172
a.bind (allsolid);
173
- a.jmp (0x2C9F9F_b);
173
+ a.jmp (SELECT_VALUE (0x6878D4_b, 0x2C9F9F_b) );
174
174
};
175
175
176
176
void client_end_frame_stub2 (game::mp::gentity_s* entity)
@@ -266,21 +266,74 @@ namespace gameplay
266
266
vel_out[2 ] = new_z * length_scale;
267
267
}
268
268
}
269
+
270
+ void * pm_can_start_sprint_stub ()
271
+ {
272
+ return utils::hook::assemble ([=](utils::hook::assembler& a)
273
+ {
274
+ const auto skip_jz = a.newLabel ();
275
+ const auto loc_2C98EF = a.newLabel ();
276
+
277
+ // save rax's original value
278
+ a.push (rax);
279
+
280
+ // move dvar pointer to rax
281
+ a.mov (rax, qword_ptr (reinterpret_cast <uint64_t >(&dvars::pm_sprintInAir)));
282
+
283
+ // move *(rax + 16) into al
284
+ a.mov (al, byte_ptr (rax, 0x10 ));
285
+
286
+ // compare al with 1
287
+ a.cmp (al, 1 );
288
+
289
+ // restore rax to its original value
290
+ a.pop (rax);
291
+
292
+ // jz == jump zero, jumps if the two operands in cmp are equal
293
+ a.jz (skip_jz); // skip the last cmp & jz
294
+
295
+ // execute original code at 0x2C98C0 & 0x2C98C6
296
+ // necessary because our jump overwrites 12 bytes after it
297
+ a.mov (eax, 0x7FF ); // rax got overwritted by our long jump (it does mov rax, <jmpaddr>; jmp rax)
298
+ a.cmp (word_ptr (rbx, 0x22 ), ax);
299
+ a.jz (loc_2C98EF);
300
+
301
+ a.bind (skip_jz);
302
+
303
+ // execute original code from 0x2C98C6 to 0x2C98CC
304
+ a.mov (edx, dword_ptr (rdi, 0x8 ));
305
+ a.mov (rcx, rbx);
306
+
307
+ // the section of code that was overwritten by our jump is finished so we can jump back to the game code
308
+ a.jmp (0x2C98CC_b);
309
+
310
+ // original code
311
+ a.bind (loc_2C98EF);
312
+ a.jmp (0x2C98EF_b);
313
+ });
314
+ }
269
315
}
270
316
271
317
class component final : public component_interface
272
318
{
273
319
public:
274
320
void post_unpack () override
275
321
{
322
+ dvars::player_sustainAmmo = dvars::register_bool (" player_sustainAmmo" , false ,
323
+ game::DVAR_FLAG_REPLICATED, " Firing weapon will not decrease clip ammo" );
324
+ pm_weapon_use_ammo_hook.create (SELECT_VALUE (0x4AF600_b, 0x2DF830_b), &pm_weapon_use_ammo_stub);
325
+
326
+ // Influence PM_JitterPoint code flow so the trace->startsolid checks are 'ignored'
327
+ pm_player_trace_hook.create (SELECT_VALUE (0x4A0A90_b, 0x2D14C0_b), &pm_player_trace_stub);
328
+
329
+ // If g_enableElevators is 1 the 'ducked' flag will always be removed from the player state
330
+ utils::hook::jump (SELECT_VALUE (0x499617_b, 0x2C9F90_b), utils::hook::assemble (pm_trace_stub), true );
331
+ dvars::g_enableElevators = dvars::register_bool (" g_enableElevators" , false , game::DVAR_FLAG_REPLICATED, " Enables Elevators" );
332
+
276
333
if (game::environment::is_sp ())
277
334
{
278
335
return ;
279
336
}
280
-
281
- dvars::player_sustainAmmo = dvars::register_bool (" player_sustainAmmo" , false ,
282
- game::DVAR_FLAG_REPLICATED, " Firing weapon will not decrease clip ammo" );
283
- pm_weapon_use_ammo_hook.create (0x2DF830_b, &pm_weapon_use_ammo_stub);
284
337
285
338
utils::hook::nop (0x4006AD_b, 15 );
286
339
utils::hook::jump (0x4006AD_b, g_speed_stub (), true );
@@ -300,11 +353,9 @@ namespace gameplay
300
353
utils::hook::jump (0x3FF812_b, client_end_frame_stub (), true );
301
354
utils::hook::nop (0x3FF808_b, 1 );
302
355
303
- // Influence PM_JitterPoint code flow so the trace->startsolid checks are 'ignored'
304
- pm_player_trace_hook.create (0x2D14C0_b, &pm_player_trace_stub);
305
- // If g_enableElevators is 1 the 'ducked' flag will always be removed from the player state
306
- utils::hook::jump (0x2C9F90_b, utils::hook::assemble (pm_trace_stub), true );
307
- dvars::g_enableElevators = dvars::register_bool (" g_enableElevators" , false , game::DVAR_FLAG_REPLICATED, " Enables Elevators" );
356
+ dvars::pm_sprintInAir = dvars::register_bool (" pm_sprintInAir" , false ,
357
+ game::DVAR_FLAG_REPLICATED, " Enable Mid-Air Sprinting" );
358
+ utils::hook::jump (0x2C98C0_b, pm_can_start_sprint_stub (), true );
308
359
309
360
auto * timescale = dvars::register_float (" timescale" , 1 .0f , 0 .1f , 50 .0f , game::DVAR_FLAG_REPLICATED, " Changes Timescale of the game" );
310
361
utils::hook::inject (0x15B204_b, ×cale->current .value ); // Com_GetTimeScale
0 commit comments