feat: free movement
This commit is contained in:
parent
87ce6fcf61
commit
9c796cd38b
76
src/client/component/free_move.cpp
Normal file
76
src/client/component/free_move.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include <std_include.hpp>
|
||||
#include "loader/component_loader.hpp"
|
||||
#include "game/game.hpp"
|
||||
#include "game/dvars.hpp"
|
||||
|
||||
#include "command.hpp"
|
||||
|
||||
#include <utils/hook.hpp>
|
||||
|
||||
namespace free_move {
|
||||
namespace {
|
||||
void cg_noclip_f() {
|
||||
if (!game::cgArray[game::LOCAL_CLIENT_0].nextSnap) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(*dvars::sv_cheats)->current.enabled) {
|
||||
game::Com_Printf(game::CON_CHANNEL_SYSTEM, "%s is cheat protected.\n",
|
||||
"cg_noclip");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*dvars::cl_freemove)->current.integer == 1) {
|
||||
if ((*dvars::cg_paused)->current.integer == 2) {
|
||||
game::Dvar_SetInt(*dvars::cg_paused, 1);
|
||||
}
|
||||
}
|
||||
|
||||
game::Dvar_SetInt(*dvars::cl_freemove,
|
||||
(*dvars::cl_freemove)->current.integer == 1 ? 0 : 1);
|
||||
game::Com_Printf(
|
||||
game::CON_CHANNEL_DONT_FILTER, "%s\n",
|
||||
game::SEH_LocalizeTextMessage((*dvars::cl_freemove)->current.integer == 1
|
||||
? "GAME_NOCLIPON"
|
||||
: "GAME_NOCLIPOFF",
|
||||
"noclip print", game::LOCMSG_SAFE));
|
||||
}
|
||||
|
||||
void cg_ufo_f() {
|
||||
if (!game::cgArray[game::LOCAL_CLIENT_0].nextSnap) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(*dvars::sv_cheats)->current.enabled) {
|
||||
game::Com_Printf(game::CON_CHANNEL_SYSTEM, "%s is cheat protected.\n",
|
||||
"cg_ufo");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*dvars::cl_freemove)->current.integer == 2) {
|
||||
if ((*dvars::cg_paused)->current.integer == 2) {
|
||||
game::Dvar_SetInt(*dvars::cg_paused, 1);
|
||||
}
|
||||
}
|
||||
|
||||
game::Dvar_SetInt(*dvars::cl_freemove,
|
||||
(*dvars::cl_freemove)->current.integer == 2 ? 0 : 2);
|
||||
game::Com_Printf(
|
||||
game::CON_CHANNEL_DONT_FILTER, "%s\n",
|
||||
game::SEH_LocalizeTextMessage((*dvars::cl_freemove)->current.integer == 2
|
||||
? "GAME_UFOON"
|
||||
: "GAME_UFOOFF",
|
||||
"ufo print", game::LOCMSG_SAFE));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class component final : public component_interface {
|
||||
public:
|
||||
void post_load() override {
|
||||
command::add("cg_noclip", cg_noclip_f);
|
||||
command::add("cg_ufo", cg_ufo_f);
|
||||
}
|
||||
};
|
||||
} // namespace free_move
|
||||
|
||||
REGISTER_COMPONENT(free_move::component)
|
@ -72,31 +72,34 @@ void __declspec(naked) string_table_get_column_value_for_row() {
|
||||
static const char* fmt =
|
||||
"Looking up row %i, column %i of table \'%s\' results in an empty string "
|
||||
"(first column is %s, second column is %s for that row)\n";
|
||||
static const DWORD Com_PrintError = 0x4C6980;
|
||||
static const DWORD Com_PrintError_t = 0x4C6980;
|
||||
|
||||
using namespace game;
|
||||
|
||||
// EAX is safe to reuse because it's nuked by the game's code after this stub exits
|
||||
__asm {
|
||||
// game's code
|
||||
mov eax, dword ptr [ecx + eax * 0x8]
|
||||
push edx
|
||||
push eax
|
||||
mov eax, dword ptr [ecx + eax * 0x8];
|
||||
push edx;
|
||||
push eax;
|
||||
|
||||
mov eax, [esp + 0xC] // get table pointer
|
||||
mov eax, [eax] // get table->name
|
||||
push eax
|
||||
mov eax, [esp + 0xC]; // get table pointer
|
||||
mov eax, [eax]; // get table->name
|
||||
push eax;
|
||||
|
||||
// game's code
|
||||
push edi // column
|
||||
push ebx // row
|
||||
push edi; // column
|
||||
push ebx; // row
|
||||
|
||||
push fmt
|
||||
// game's format string
|
||||
push fmt;
|
||||
|
||||
push 0xD // channel
|
||||
call Com_PrintError
|
||||
add esp, 0x1C
|
||||
push CON_CHANNEL_UI; // channel
|
||||
call Com_PrintError_t;
|
||||
add esp, 0x1C;
|
||||
|
||||
push 0x4BC84E
|
||||
ret
|
||||
push 0x4BC84E;
|
||||
ret;
|
||||
}
|
||||
}
|
||||
// clang-format on
|
||||
|
@ -25,11 +25,21 @@ const game::dvar_t* bug_name = nullptr;
|
||||
const game::dvar_t* g_log = nullptr;
|
||||
|
||||
// Game dvars
|
||||
const game::dvar_t** cg_paused =
|
||||
reinterpret_cast<const game::dvar_t**>(0x86D7C0);
|
||||
|
||||
const game::dvar_t** cl_freemove =
|
||||
reinterpret_cast<const game::dvar_t**>(0x89776C);
|
||||
const game::dvar_t** cl_freemoveScale =
|
||||
reinterpret_cast<const game::dvar_t**>(0x897750);
|
||||
|
||||
const game::dvar_t** g_specialops =
|
||||
reinterpret_cast<const game::dvar_t**>(0x1B2E1E8);
|
||||
|
||||
const game::dvar_t** sv_mapname =
|
||||
reinterpret_cast<const game::dvar_t**>(0x1B2E1E4);
|
||||
const game::dvar_t** sv_cheats =
|
||||
reinterpret_cast<const game::dvar_t**>(0x1B2E1EC);
|
||||
|
||||
const game::dvar_t** version =
|
||||
reinterpret_cast<const game::dvar_t**>(0x145D690);
|
||||
|
@ -25,9 +25,15 @@ extern const game::dvar_t* bug_name;
|
||||
extern const game::dvar_t* g_log;
|
||||
|
||||
// Game dvars
|
||||
extern const game::dvar_t** cg_paused;
|
||||
|
||||
extern const game::dvar_t** cl_freemove;
|
||||
extern const game::dvar_t** cl_freemoveScale;
|
||||
|
||||
extern const game::dvar_t** g_specialops;
|
||||
|
||||
extern const game::dvar_t** sv_mapname;
|
||||
extern const game::dvar_t** sv_cheats;
|
||||
|
||||
extern const game::dvar_t** version;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace game {
|
||||
int FS_FOpenFileReadForThread(const char* filename, int* file,
|
||||
FsThread thread) {
|
||||
const static DWORD FS_FOpenFileReadForThread_t = 0x630380;
|
||||
static const DWORD FS_FOpenFileReadForThread_t = 0x630380;
|
||||
int result{};
|
||||
|
||||
__asm {
|
||||
@ -23,7 +23,7 @@ int FS_FOpenFileReadForThread(const char* filename, int* file,
|
||||
}
|
||||
|
||||
void IN_KeyDown(kbutton_t* b) {
|
||||
const static DWORD IN_KeyDown_t = 0x57A350;
|
||||
static const DWORD IN_KeyDown_t = 0x57A350;
|
||||
|
||||
__asm {
|
||||
pushad;
|
||||
@ -36,7 +36,7 @@ void IN_KeyDown(kbutton_t* b) {
|
||||
}
|
||||
|
||||
void IN_KeyUp(kbutton_t* b) {
|
||||
const static DWORD IN_KeyUp_t = 0x57A3F0;
|
||||
static const DWORD IN_KeyUp_t = 0x57A3F0;
|
||||
|
||||
__asm {
|
||||
pushad;
|
||||
@ -94,7 +94,7 @@ HANDLE Sys_OpenFileReliable(const char* filename) {
|
||||
}
|
||||
|
||||
int PC_Int_Parse(int handle, int* i) {
|
||||
const static DWORD PC_Int_Parse_t = 0x62DF10;
|
||||
static const DWORD PC_Int_Parse_t = 0x62DF10;
|
||||
int result{};
|
||||
|
||||
__asm {
|
||||
@ -112,7 +112,7 @@ int PC_Int_Parse(int handle, int* i) {
|
||||
}
|
||||
|
||||
int PC_Float_Parse(int handle, float* f) {
|
||||
const static DWORD PC_Float_Parse_t = 0x62DE40;
|
||||
static const DWORD PC_Float_Parse_t = 0x62DE40;
|
||||
int result{};
|
||||
|
||||
__asm {
|
||||
@ -130,7 +130,7 @@ int PC_Float_Parse(int handle, float* f) {
|
||||
}
|
||||
|
||||
void Menu_FreeItemMemory(itemDef_s* item) {
|
||||
const static DWORD Menu_FreeItemMemory_t = 0x62B7E0;
|
||||
static const DWORD Menu_FreeItemMemory_t = 0x62B7E0;
|
||||
|
||||
__asm {
|
||||
pushad;
|
||||
|
@ -369,6 +369,11 @@ enum {
|
||||
VAR_INTEGER = 0x6,
|
||||
};
|
||||
|
||||
enum msgLocErrType_t {
|
||||
LOCMSG_SAFE = 0x0,
|
||||
LOCMSG_NOERR = 0x1,
|
||||
};
|
||||
|
||||
enum {
|
||||
CON_CHANNEL_DONT_FILTER = 0x0,
|
||||
CON_CHANNEL_ERROR = 0x1,
|
||||
@ -1745,6 +1750,109 @@ struct localization_t {
|
||||
struct Sys_File {
|
||||
HANDLE handle;
|
||||
};
|
||||
|
||||
enum ShockViewTypes {
|
||||
SHELLSHOCK_VIEWTYPE_BLURRED = 0x0,
|
||||
SHELLSHOCK_VIEWTYPE_FLASHED = 0x1,
|
||||
SHELLSHOCK_VIEWTYPE_NONE = 0x2,
|
||||
};
|
||||
|
||||
struct shellshock_parms_t {
|
||||
struct {
|
||||
int blurredFadeTime;
|
||||
int blurredEffectTime;
|
||||
int flashWhiteFadeTime;
|
||||
int flashShotFadeTime;
|
||||
ShockViewTypes type;
|
||||
} screenBlend;
|
||||
struct {
|
||||
int fadeTime;
|
||||
float kickRate;
|
||||
float kickRadius;
|
||||
} view;
|
||||
struct {
|
||||
bool affect;
|
||||
char loop[64];
|
||||
char loopSilent[64];
|
||||
char end[64];
|
||||
char endAbort[64];
|
||||
int fadeInTime;
|
||||
int fadeOutTime;
|
||||
float drylevel;
|
||||
float wetlevel;
|
||||
char roomtype[16];
|
||||
float channelvolume[64];
|
||||
int modEndDelay;
|
||||
int loopFadeTime;
|
||||
int loopEndDelay;
|
||||
} sound;
|
||||
struct {
|
||||
bool affect;
|
||||
int fadeTime;
|
||||
float mouseSensitivity;
|
||||
float maxPitchSpeed;
|
||||
float maxYawSpeed;
|
||||
} lookControl;
|
||||
struct {
|
||||
bool affect;
|
||||
} movement;
|
||||
};
|
||||
|
||||
struct cgs_t {
|
||||
int viewX;
|
||||
int viewY;
|
||||
int viewWidth;
|
||||
int viewHeight;
|
||||
float viewAspect;
|
||||
bool started;
|
||||
shellshock_parms_t holdBreathParams;
|
||||
};
|
||||
|
||||
static_assert(sizeof(cgs_t) == 0x280);
|
||||
|
||||
struct cpose_t {
|
||||
unsigned char __pad0[0x64];
|
||||
};
|
||||
|
||||
static_assert(sizeof(cpose_t) == 0x64);
|
||||
|
||||
enum CubemapShot {
|
||||
CUBEMAPSHOT_NONE = 0x0,
|
||||
CUBEMAPSHOT_RIGHT = 0x1,
|
||||
CUBEMAPSHOT_LEFT = 0x2,
|
||||
CUBEMAPSHOT_BACK = 0x3,
|
||||
CUBEMAPSHOT_FRONT = 0x4,
|
||||
CUBEMAPSHOT_UP = 0x5,
|
||||
CUBEMAPSHOT_DOWN = 0x6,
|
||||
CUBEMAPSHOT_COUNT = 0x7,
|
||||
};
|
||||
|
||||
struct snapshot_s {
|
||||
int snapFlags;
|
||||
int serverTime;
|
||||
int numEntities;
|
||||
unsigned __int16 entityNums[2048];
|
||||
int numFxEntities;
|
||||
unsigned __int16 fxEntityNums[768];
|
||||
};
|
||||
|
||||
struct cg_s {
|
||||
int clientNum;
|
||||
int localClientNum;
|
||||
CubemapShot cubemapShot;
|
||||
int cubemapSize;
|
||||
int serverCommandSequence;
|
||||
int serverLatestCommandSequence;
|
||||
int loaded;
|
||||
snapshot_s* snap;
|
||||
snapshot_s* nextSnap;
|
||||
playerState_s* ps;
|
||||
playerState_s* nextPs;
|
||||
}; // Incomplete
|
||||
|
||||
static_assert(offsetof(cg_s, snap) == 0x1C);
|
||||
static_assert(offsetof(cg_s, nextSnap) == 0x20);
|
||||
static_assert(offsetof(cg_s, nextPs) == 0x28);
|
||||
} // namespace game
|
||||
|
||||
#pragma warning(pop)
|
||||
|
@ -24,6 +24,9 @@ WEAK symbol<const char*(const char* fmt, ...)> va{0x4869F0};
|
||||
// Con
|
||||
WEAK symbol<bool(const char* cmd)> Con_IsDvarCommand{0x4B6610};
|
||||
|
||||
// SV
|
||||
WEAK symbol<void(int clientNum, usercmd_s* cmd)> SV_ClientThink{0x4B43D0};
|
||||
|
||||
// ScrPlace
|
||||
WEAK symbol<ScreenPlacement*(int localClientNum)> ScrPlace_GetActivePlacement{
|
||||
0x4D2A60};
|
||||
@ -289,11 +292,17 @@ WEAK symbol<void(const char* text, int maxChars, Font_s* font, float x, float y,
|
||||
WEAK symbol<int(const char* text, int maxChars, Font_s* font)> R_TextWidth{
|
||||
0x508960};
|
||||
|
||||
WEAK symbol<const char*(const char* pszInputBuffer, const char* pszMessageType,
|
||||
msgLocErrType_t errType)>
|
||||
SEH_LocalizeTextMessage{0x4CD8D0};
|
||||
|
||||
// Variables
|
||||
WEAK symbol<CmdArgs> cmd_args{0x144FED0};
|
||||
WEAK symbol<CmdArgs> sv_cmd_args{0x145ABA0};
|
||||
WEAK symbol<gentity_s> g_entities{0xEAAC38};
|
||||
WEAK symbol<gclient_s> g_clients{0x10911E8};
|
||||
WEAK symbol<cgs_t> cgsArray{0x762008};
|
||||
WEAK symbol<cg_s> cgArray{0x7622A0};
|
||||
|
||||
WEAK symbol<scrVmPub_t> scrVmPub{0x190DDF0};
|
||||
WEAK symbol<scrVarPub_t> scrVarPub{0x18E7508};
|
||||
|
Loading…
x
Reference in New Issue
Block a user