From 13b3eec55c11432f2034c65c2c9b21e7a5ced775 Mon Sep 17 00:00:00 2001
From: theTwister <6237734+twist84@users.noreply.github.com>
Date: Mon, 16 Sep 2024 22:45:22 +0100
Subject: [PATCH] Implemented `cheat_jetpack` (WIP)
This is in no way the correct implementation
---
game/game.vcxproj | 3 ++
game/game.vcxproj.filters | 9 +++++
game/source/game/player_control.cpp | 37 +++++++++++++++++++-
game/source/game/player_control.hpp | 4 ++-
game/source/motor/motor_system.cpp | 8 +++++
game/source/motor/motor_system.hpp | 18 ++++++++++
game/source/motor/mover.cpp | 8 +++++
game/source/motor/mover.hpp | 2 ++
game/source/objects/damage.cpp | 3 ++
game/source/objects/objects.cpp | 7 +++-
game/source/objects/objects.hpp | 1 +
game/source/units/bipeds.cpp | 52 +++++++++++++++++++++++++++++
game/source/units/bipeds.hpp | 2 ++
13 files changed, 151 insertions(+), 3 deletions(-)
create mode 100644 game/source/motor/motor_system.cpp
create mode 100644 game/source/motor/motor_system.hpp
create mode 100644 game/source/motor/mover.cpp
diff --git a/game/game.vcxproj b/game/game.vcxproj
index 3c386c9c2..98ca5d5be 100644
--- a/game/game.vcxproj
+++ b/game/game.vcxproj
@@ -247,7 +247,9 @@ copy /b $(ProjectDir)source\config\version.cpp +,, $(ProjectDir)source\config\ve
+
+
@@ -889,6 +891,7 @@ copy /b $(ProjectDir)source\config\version.cpp +,, $(ProjectDir)source\config\ve
+
diff --git a/game/game.vcxproj.filters b/game/game.vcxproj.filters
index 5976f73c2..e5ebc56b2 100644
--- a/game/game.vcxproj.filters
+++ b/game/game.vcxproj.filters
@@ -1614,6 +1614,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
@@ -3788,6 +3794,9 @@
Header Files
+
+ Header Files
+
diff --git a/game/source/game/player_control.cpp b/game/source/game/player_control.cpp
index 9c818e1b0..1babf8d2f 100644
--- a/game/source/game/player_control.cpp
+++ b/game/source/game/player_control.cpp
@@ -1,13 +1,16 @@
#include "game/player_control.hpp"
+#include "game/cheats.hpp"
#include "game/game.hpp"
#include "game/player_mapping.hpp"
#include "interface/c_controller.hpp"
#include "interface/user_interface_utilities.hpp"
#include "memory/module.hpp"
#include "memory/thread_local.hpp"
+#include "motor/mover.hpp"
#include "shell/shell.hpp"
#include "simulation/simulation.hpp"
+#include "units/bipeds.hpp"
HOOK_DECLARE_CALL(0x005D1389, evaluate_piecewise_linear_function);
HOOK_DECLARE_CALL(0x005D13B4, evaluate_piecewise_linear_function);
@@ -183,7 +186,11 @@ void __cdecl player_control_get_aiming_vector(e_output_user_index output_user_in
INVOKE(0x005D0C30, player_control_get_aiming_vector, output_user_index, aiming_vector);
}
-//.text:005D0C90 ; void __cdecl player_control_get_controller_input(e_input_user_index, e_controller_index, real, real, s_game_input_state**, s_player_control_input*)
+void __cdecl player_control_get_controller_input(e_input_user_index input_user_index, e_controller_index controller_index, real world_seconds_elapsed, real game_seconds_elapsed, s_game_input_state** input_states, s_player_control_input* input)
+{
+ INVOKE(0x005D0C90, player_control_get_controller_input, input_user_index, controller_index, world_seconds_elapsed, game_seconds_elapsed, input_states, input);
+}
+
//.text:005D29E0 ; euler_angles2d const* __cdecl player_control_get_facing_angles(long)
//.text:005D2A10 ; real __cdecl player_control_get_field_of_view(long)
//.text:005D2AA0 ; real __cdecl player_control_get_field_of_view_change_time(long)
@@ -426,3 +433,31 @@ void __cdecl player_control_update_player(long player_index, e_input_user_index
//.text:005D62B0 ;
//.text:005D62C0 ; bool __cdecl user_currently_piloting_aircraft(enum e_input_user_index)
+void __cdecl player_control_get_controller_input_for_jetpack(e_input_user_index input_user_index, e_controller_index controller_index, real world_seconds_elapsed, real game_seconds_elapsed, s_game_input_state** input_states, s_player_control_input* input)
+{
+ player_control_get_controller_input(input_user_index, controller_index, world_seconds_elapsed, game_seconds_elapsed, input_states, input);
+
+ if (cheat.jetpack)
+ {
+ TLS_DATA_GET_VALUE_REFERENCE(player_control_globals);
+
+ long unit_index = player_control_globals->input_states[controller_index].unit_index;
+ if (biped_datum* biped = (biped_datum*)object_get_and_verify_type(unit_index, _object_mask_biped))
+ {
+ bool v0 = false;
+ if (input_states[controller_index]->get_button(_button_action_jump).down_frames() && mover_get_motor_program(unit_index) == 1)
+ {
+ bool v1 = TEST_BIT(biped->unit.unit_control_flags, 1);
+ real jump_control_ticks = (real)biped->biped.jump_control_ticks;
+ real v2 = (real)game_tick_rate() / 15.0f;
+ bool v3 = v2 > jump_control_ticks;
+ if ((v1 && v3) || TEST_BIT(biped->unit.unit_control_flags, 15))
+ v0 = true;
+ }
+
+ SET_BIT(input->control_flags, 15, v0);
+ }
+ }
+}
+HOOK_DECLARE_CALL(0x005D4C66, player_control_get_controller_input_for_jetpack);
+
diff --git a/game/source/game/player_control.hpp b/game/source/game/player_control.hpp
index 1785c9e35..d28d58aab 100644
--- a/game/source/game/player_control.hpp
+++ b/game/source/game/player_control.hpp
@@ -300,6 +300,8 @@ struct s_player_control_globals
};
static_assert(sizeof(s_player_control_globals) == 0x8B0);
+struct s_game_input_state;
+
extern e_input_user_index first_input_user();
extern e_input_user_index next_input_user(e_input_user_index input_user_index);
extern e_output_user_index first_output_user();
@@ -368,7 +370,7 @@ extern void __cdecl player_control_dispose_from_old_map();
extern s_player_action_context const* __cdecl player_control_get_action_context(long user_index);
//extern long __cdecl player_control_get_aiming_unit_index(e_output_user_index);
extern void __cdecl player_control_get_aiming_vector(e_output_user_index output_user_index, vector3d* aiming_vector);
-//extern void __cdecl player_control_get_controller_input(e_input_user_index, e_controller_index, real, real, s_game_input_state**, s_player_control_input*);
+extern void __cdecl player_control_get_controller_input(e_input_user_index input_user_index, e_controller_index controller_index, real world_seconds_elapsed, real game_seconds_elapsed, s_game_input_state** input_states, s_player_control_input* input);
//extern euler_angles2d const* __cdecl player_control_get_facing_angles(long);
//extern real __cdecl player_control_get_field_of_view(long);
//extern real __cdecl player_control_get_field_of_view_change_time(long);
diff --git a/game/source/motor/motor_system.cpp b/game/source/motor/motor_system.cpp
new file mode 100644
index 000000000..3e906bc56
--- /dev/null
+++ b/game/source/motor/motor_system.cpp
@@ -0,0 +1,8 @@
+#include "motor/motor_system.hpp"
+
+//e_motor_result __cdecl motor_system_submit(long motor_index, c_motor_request const* request)
+long __cdecl motor_system_submit(long motor_index, c_motor_request const* request)
+{
+ return INVOKE(0x00B749C0, motor_system_submit, motor_index, request);
+}
+
diff --git a/game/source/motor/motor_system.hpp b/game/source/motor/motor_system.hpp
new file mode 100644
index 000000000..4638504a0
--- /dev/null
+++ b/game/source/motor/motor_system.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "cseries/cseries.hpp"
+
+struct c_motor_request
+{
+ byte __unknown0;
+ byte __unknown1;
+ byte __data2[0x2];
+ long __unknown4;
+ long __unknown8;
+ long __unknownC;
+ byte __data10[0xC];
+};
+static_assert(sizeof(c_motor_request) == 0x1C);
+
+extern long __cdecl motor_system_submit(long motor_index, c_motor_request const* request);
+
diff --git a/game/source/motor/mover.cpp b/game/source/motor/mover.cpp
new file mode 100644
index 000000000..6e53c6aa1
--- /dev/null
+++ b/game/source/motor/mover.cpp
@@ -0,0 +1,8 @@
+#include "motor/mover.hpp"
+
+//e_motor_program __cdecl mover_get_motor_program(long motor_index)
+long __cdecl mover_get_motor_program(long motor_index)
+{
+ return INVOKE(0x00BA66A0, mover_get_motor_program, motor_index);
+}
+
diff --git a/game/source/motor/mover.hpp b/game/source/motor/mover.hpp
index a87de395f..077791e66 100644
--- a/game/source/motor/mover.hpp
+++ b/game/source/motor/mover.hpp
@@ -18,3 +18,5 @@ struct motor_datum
};
static_assert(sizeof(motor_datum) == sizeof(long) + sizeof(_object_datum) + sizeof(_motor_datum));
+extern long __cdecl mover_get_motor_program(long motor_index);
+
diff --git a/game/source/objects/damage.cpp b/game/source/objects/damage.cpp
index c55e15652..dddc50a18 100644
--- a/game/source/objects/damage.cpp
+++ b/game/source/objects/damage.cpp
@@ -120,6 +120,9 @@ real __cdecl compute_total_damage(s_damage_data* damage_data, void* damage_effec
{
real result = INVOKE(0x00B4FB10, compute_total_damage, damage_data, damage_effect_definition, damage_definition, object_index, a5);
+ if (cheat.jetpack && TEST_MASK(FLAG(object_get_type(object_index)), _object_mask_biped))
+ result = 0.0f;
+
if (cheat.chevy && TEST_MASK(FLAG(object_get_type(object_index)), _object_mask_vehicle))
result = 0.0f;
diff --git a/game/source/objects/objects.cpp b/game/source/objects/objects.cpp
index 5200098ec..b7fce4b65 100644
--- a/game/source/objects/objects.cpp
+++ b/game/source/objects/objects.cpp
@@ -1509,7 +1509,12 @@ void __cdecl object_set_requires_motion(long object_index)
//.text:00B33EE0 ;
//.text:00B33F80 ; void __cdecl object_set_sync_action(long, long, long)
//.text:00B33FC0 ; void __cdecl object_set_variant_direct(long, long)
-//.text:00B34040 ; void __cdecl object_set_velocities(long, vector3d const*, vector3d const*)
+
+void __cdecl object_set_velocities(long object_index, vector3d const* linear_velocity, vector3d const* angular_velocity)
+{
+ INVOKE(0x00B34040, object_set_velocities, object_index, linear_velocity, angular_velocity);
+}
+
//.text:00B34130 ; void __cdecl object_set_velocities_direct(long, vector3d const*, vector3d const*)
//.text:00B341E0 ; void __cdecl object_set_velocities_internal(long, vector3d const*, vector3d const*, bool)
//.text:00B34280 ;
diff --git a/game/source/objects/objects.hpp b/game/source/objects/objects.hpp
index bd83dc867..795c263bd 100644
--- a/game/source/objects/objects.hpp
+++ b/game/source/objects/objects.hpp
@@ -655,6 +655,7 @@ extern void __cdecl object_set_model_state_property_per_region(long object_index
extern void __cdecl object_set_object_index_for_name_index(short name_index, long object_index);
extern bool __cdecl object_set_position_internal(long object_index, real_point3d const* desired_position, vector3d const* desired_forward, vector3d const* desired_up, s_location const* location, bool compute_node_matrices, bool set_havok_object_position, bool in_editor, bool disconnected);
extern void __cdecl object_set_requires_motion(long object_index);
+extern void __cdecl object_set_velocities(long object_index, vector3d const* linear_velocity, vector3d const* angular_velocity);
extern void __cdecl object_set_position(long object_index, real_point3d const* desired_position, vector3d const* desired_forward, vector3d const* desired_up, s_location const* location);
extern void __cdecl object_set_position_direct(long object_index, real_point3d const* desired_position, vector3d const* desired_forward, vector3d const* desired_up, s_location const* location, bool in_editor);
extern void __cdecl object_set_position_in_editor(long object_index, real_point3d const* desired_position, vector3d const* desired_forward, vector3d const* desired_up, s_location const* location, bool at_rest);
diff --git a/game/source/units/bipeds.cpp b/game/source/units/bipeds.cpp
index 054cdb483..2e2fb84d9 100644
--- a/game/source/units/bipeds.cpp
+++ b/game/source/units/bipeds.cpp
@@ -5,10 +5,13 @@
#include "game/cheats.hpp"
#include "memory/module.hpp"
#include "memory/thread_local.hpp"
+#include "motor/motor_system.hpp"
#include "physics/character_physics.hpp"
#include "render/render_debug.hpp"
#include "units/bipeds.hpp"
+#include
+
HOOK_DECLARE(0x00B6B8F0, biped_bumped_object);
HOOK_DECLARE(0x00B70DF0, biped_render_debug);
HOOK_DECLARE(0x00B716C0, biped_update);
@@ -407,4 +410,53 @@ bool __cdecl biped_update_without_parent(long biped_index)
//.text:00B72BF0 ; void __cdecl bipeds_initialize(void)
//.text:00B72C00 ; void __cdecl bipeds_initialize_for_new_map(void)
+void biped_update_jetpack(long biped_index)
+{
+ biped_datum* biped = (biped_datum*)object_get_and_verify_type(biped_index, _object_mask_biped);
+ if (cheat.jetpack && biped->unit.player_index != NONE)
+ {
+ if (TEST_BIT(biped->unit.unit_control_flags, 15) || TEST_BIT(biped->unit.unit_control_flags, 1) && biped_in_airborne_state(biped_index))
+ {
+ vector3d linear_velocity{};
+ object_get_velocities(biped_index, &linear_velocity, NULL);
+ if (TEST_BIT(biped->unit.unit_control_flags, 15))
+ {
+ real v7 = dot_product3d(&biped->unit.aiming_vector, &linear_velocity);
+ if (v7 < 0.0f)
+ v7 = 0.0f;
+
+ real v8 = fminf(1.0f, fmaxf(v7 * 0.0625f, 0.0f));
+ if (v8 >= 1.0f)
+ v8 = 1.0f;
+
+ real v9 = -v7;
+ linear_velocity.i -= (0.2f * (linear_velocity.i + (v9 * biped->unit.aiming_vector.i)));
+ linear_velocity.j -= (0.2f * (linear_velocity.j + (v9 * biped->unit.aiming_vector.j)));
+ linear_velocity.k -= (0.2f * (linear_velocity.k + (v9 * biped->unit.aiming_vector.k)));
+
+ real v10 = game_tick_length();
+ real v11 = v10 * (9.0f + ((9.0f * v8) - (18.0f * (v8 * v8))));
+ linear_velocity.i += v11 * biped->unit.aiming_vector.i;
+ linear_velocity.j += v11 * biped->unit.aiming_vector.j;
+ linear_velocity.k += v11 * biped->unit.aiming_vector.k;
+
+ c_motor_request motor_request{};
+ motor_request.__unknown4 = 7;
+ motor_request.__unknown8 = 1;
+ motor_request.__unknownC = NONE;
+ motor_system_submit(biped_index, &motor_request);
+ }
+ else
+ {
+ linear_velocity.i *= 0.9f;
+ linear_velocity.j *= 0.9f;
+ linear_velocity.k *= 0.9f;
+ printf("");
+ }
+
+ linear_velocity.k += global_gravity_get() * game_tick_length();
+ object_set_velocities(biped_index, &linear_velocity, NULL);
+ }
+ }
+}
diff --git a/game/source/units/bipeds.hpp b/game/source/units/bipeds.hpp
index fe1716f7f..5baaf6cc3 100644
--- a/game/source/units/bipeds.hpp
+++ b/game/source/units/bipeds.hpp
@@ -109,3 +109,5 @@ extern bool __cdecl biped_update_stun(long biped_index);
extern bool __cdecl biped_update_with_parent(long biped_index, long parent_index);
extern bool __cdecl biped_update_without_parent(long biped_index);
+extern void biped_update_jetpack(long biped_index);
+