diff --git a/README.md b/README.md
index f273ddbb..0a67a9a1 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
# What is BOIII ☄️
-BOIII is a game modification for Call of Duty: Black Ops 3.
+BOIII is a game modification for Call of Duty: Black Ops 3.
The Steam version of Black Ops 3 is required to be owned and installed for BOIII to work. You can get it from here, if you don't already own it.
diff --git a/src/client/component/client_patches.cpp b/src/client/component/client_patches.cpp
index 0f2227db..3a071e74 100644
--- a/src/client/component/client_patches.cpp
+++ b/src/client/component/client_patches.cpp
@@ -4,6 +4,7 @@
#include "scheduler.hpp"
#include
+#include
#include
#include
@@ -16,6 +17,9 @@ namespace client_patches
{
utils::hook::detour preload_map_hook;
+ const game::dvar_t* cl_yaw_speed;
+ const game::dvar_t* cl_pitch_speed;
+
void stop_intro_if_needed()
{
if (game::Com_SessionMode_GetMode() != game::MODE_ZOMBIES &&
@@ -110,6 +114,16 @@ namespace client_patches
}
}
+ float cl_key_state_yaw_speed_stub(void* key)
+ {
+ return game::CL_KeyState(key) * cl_yaw_speed->current.value.value;
+ }
+
+ float cl_key_state_pitch_speed_stub(void* key)
+ {
+ return game::CL_KeyState(key) * cl_pitch_speed->current.value.value;
+ }
+
game::fileHandle_t fs_f_open_file_write_to_dir_stub(const char* filename, [[maybe_unused]] const char* dir,
const char* os_base_path)
{
@@ -183,6 +197,8 @@ namespace client_patches
class component final : public client_component
{
public:
+ static_assert(offsetof(game::clientActive_t, viewangles) == 0xB8C8);
+
component()
{
migrate_if_needed(); // TODO: Remove me after some time
@@ -210,6 +226,17 @@ namespace client_patches
// Always get loadscreen gametype from s_gametype
utils::hook::set(0x14228F5DC_g, 0xEB);
+ cl_yaw_speed = game::register_dvar_float("cl_yawspeed", 140.0f, std::numeric_limits::min(), std::numeric_limits::max(),
+ game::DVAR_NONE, "Max yaw speed in degrees for game pad and keyboard");
+ cl_pitch_speed = game::register_dvar_float("cl_pitchspeed", 140.0f, std::numeric_limits::min(), std::numeric_limits::max(),
+ game::DVAR_NONE, "Max pitch speed in degrees for game pad");
+ // CL_AdjustAngles
+ utils::hook::call(0x1412F3324_g, cl_key_state_yaw_speed_stub); // cl_yawspeed
+ utils::hook::call(0x1412F3344_g, cl_key_state_yaw_speed_stub); // ^^
+
+ utils::hook::call(0x1412F3380_g, cl_key_state_pitch_speed_stub); // cl_pitchspeed
+ utils::hook::call(0x1412F33A1_g, cl_key_state_pitch_speed_stub); // ^^
+
patch_players_folder_name();
}
};
diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp
index d7779463..e9842c11 100644
--- a/src/client/component/patches.cpp
+++ b/src/client/component/patches.cpp
@@ -11,7 +11,6 @@ namespace patches
namespace
{
const game::dvar_t* lobby_min_players;
- const game::dvar_t* cl_yaw_speed;
void script_errors_stub([[maybe_unused]] const char* file, [[maybe_unused]] int line,
[[maybe_unused]] unsigned int code, const char* fmt, ...)
@@ -79,9 +78,6 @@ namespace patches
lobby_min_players = game::register_dvar_int("lobby_min_players", 0, 0, 8, game::DVAR_NONE, "");
utils::hook::jump(game::select(0x141A7BCF0, 0x1402CB900), scr_get_num_expected_players, true);
-
- cl_yaw_speed = game::register_dvar_float("cl_yawspeed", 140.0f, std::numeric_limits::min(), std::numeric_limits::max(),
- game::DVAR_NONE, "Max yaw speed in degrees for game pad and keyboard");
}
};
}
diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp
index a6b94825..23470f1a 100644
--- a/src/client/game/structs.hpp
+++ b/src/client/game/structs.hpp
@@ -634,6 +634,41 @@ namespace game
void* errorData;
};
+ enum connstate_t
+ {
+ CA_DISCONNECTED = 0x0,
+ CA_CINEMATIC = 0x1,
+ CA_UICINEMATIC = 0x2,
+ CA_LOGO = 0x3,
+ CA_CONNECTING = 0x4,
+ CA_CHALLENGING = 0x5,
+ CA_CONFIRMLOADING = 0x6,
+ CA_CONNECTED = 0x7,
+ CA_SENDINGDATA = 0x8,
+ CA_LOADING = 0x9,
+ CA_PRIMED = 0xA,
+ CA_ACTIVE = 0xB,
+ };
+
+ struct clientUIActive_t
+ {
+ int flags;
+ int keyCatchers;
+ connstate_t connectionState;
+ unsigned char __pad0[0x106C];
+ };
+
+ static_assert(sizeof(clientUIActive_t) == 0x1078);
+
+ struct clientActive_t
+ {
+ char __pad0[0xB8C8];
+ float viewangles[3];
+ char __pad1[0x18C15C];
+ };
+
+ static_assert(sizeof(clientActive_t) == 0x197A30);
+
typedef void* fileHandle_t;
typedef uint32_t dvarStrHash_t;
diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp
index 6af6899b..4d5933fd 100644
--- a/src/client/game/symbols.hpp
+++ b/src/client/game/symbols.hpp
@@ -20,6 +20,8 @@ namespace game
WEAK symbol CL_GetClientName{
0x1413E3140
};
+ WEAK symbol CL_LocalClient_IsActive{0x14283AA50};
+ WEAK symbol CL_KeyState{0x1412FF860};
// Game
WEAK symbol G_Say{0x0, 0x140299170};
@@ -282,6 +284,8 @@ namespace game
// Dvar variables
WEAK symbol com_maxclients{0x0, 0x14948EE70};
+ WEAK symbol clientUIActives{0x1453D8BC0};
+
namespace s_wcd
{
WEAK symbol codLogo{0x157E75A50, 0x14A640BC0};