add cg_thirdperson
This commit is contained in:
parent
72e89f0014
commit
02bc694695
108
src/client/component/thirdperson.cpp
Normal file
108
src/client/component/thirdperson.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#include <std_include.hpp>
|
||||||
|
#include "loader/component_loader.hpp"
|
||||||
|
|
||||||
|
#include "game/game.hpp"
|
||||||
|
#include "game/dvars.hpp"
|
||||||
|
|
||||||
|
#include "scheduler.hpp"
|
||||||
|
|
||||||
|
#include <utils/hook.hpp>
|
||||||
|
|
||||||
|
namespace thirdperson
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void* cg_offset_third_person_view_stub()
|
||||||
|
{
|
||||||
|
return utils::hook::assemble([](utils::hook::assembler& a)
|
||||||
|
{
|
||||||
|
a.push(rax);
|
||||||
|
|
||||||
|
a.mov(rax, qword_ptr(reinterpret_cast<int64_t>(&dvars::cg_thirdPersonAngle)));
|
||||||
|
a.movss(xmm11, dword_ptr(rax, 0x10));
|
||||||
|
|
||||||
|
a.mov(rax, qword_ptr(reinterpret_cast<int64_t>(&dvars::cg_thirdPersonRange)));
|
||||||
|
a.movss(xmm10, dword_ptr(rax, 0x10));
|
||||||
|
|
||||||
|
a.pop(rax);
|
||||||
|
|
||||||
|
// original code
|
||||||
|
|
||||||
|
a.mulss(xmm7, xmm0);
|
||||||
|
a.mulss(xmm6, xmm0);
|
||||||
|
a.addss(xmm7, qword_ptr(rdi));
|
||||||
|
|
||||||
|
a.jmp(0x140274596);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void* cg_offset_chase_cam_view_stub()
|
||||||
|
{
|
||||||
|
return utils::hook::assemble([](utils::hook::assembler& a)
|
||||||
|
{
|
||||||
|
a.push(rax);
|
||||||
|
|
||||||
|
a.mov(rax, qword_ptr(reinterpret_cast<int64_t>(&dvars::cg_thirdPersonAngle)));
|
||||||
|
a.movss(xmm8, dword_ptr(rax, 0x10));
|
||||||
|
|
||||||
|
a.mov(rax, qword_ptr(reinterpret_cast<int64_t>(&dvars::cg_thirdPersonRange)));
|
||||||
|
a.movss(xmm7, dword_ptr(rax, 0x10));
|
||||||
|
|
||||||
|
a.pop(rax);
|
||||||
|
|
||||||
|
// original code
|
||||||
|
|
||||||
|
a.mulss(xmm2, xmm2);
|
||||||
|
a.mulss(xmm3, xmm3);
|
||||||
|
a.addss(xmm2, xmm3);
|
||||||
|
|
||||||
|
a.jmp(0x140272069);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::hook::detour cg_should_render_third_person_hook;
|
||||||
|
int cg_should_render_third_person_stub(int localClientNum, game::cg_s* cgameGlob)
|
||||||
|
{
|
||||||
|
auto result = cg_should_render_third_person_hook.invoke<int>(localClientNum, cgameGlob);
|
||||||
|
if (!result && cgameGlob->predictedPlayerState.pm_type != 3)
|
||||||
|
{
|
||||||
|
result = static_cast<int>(dvars::cg_thirdPerson->current.enabled);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
cgameGlob->m_deathCameraFailsafeLock = false; // disable this, acts up for some reason
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class component final : public component_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void post_unpack() override
|
||||||
|
{
|
||||||
|
if (game::environment::is_dedi())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduler::once([]()
|
||||||
|
{
|
||||||
|
dvars::cg_thirdPerson = game::Dvar_RegisterBool("cg_thirdPerson", false, game::DVAR_FLAG_CHEAT, "Use third person view");
|
||||||
|
|
||||||
|
dvars::cg_thirdPersonAngle = game::Dvar_RegisterFloat("cg_thirdPersonAngle", 356.0f, -180.0f, 360.0f, game::DVAR_FLAG_CHEAT,
|
||||||
|
"The angle of the camera from the player in third person view");
|
||||||
|
|
||||||
|
dvars::cg_thirdPersonRange = game::Dvar_RegisterFloat("cg_thirdPersonRange", 120.0f, 0.0f, 1024, game::DVAR_FLAG_CHEAT,
|
||||||
|
"The range of the camera from the player in third person view");
|
||||||
|
}, scheduler::main);
|
||||||
|
|
||||||
|
utils::hook::jump(0x14027205D, cg_offset_chase_cam_view_stub(), true);
|
||||||
|
utils::hook::jump(0x14027458A, cg_offset_third_person_view_stub(), true);
|
||||||
|
|
||||||
|
cg_should_render_third_person_hook.create(0x140275B50, cg_should_render_third_person_stub);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_COMPONENT(thirdperson::component)
|
@ -164,9 +164,9 @@ namespace weapon
|
|||||||
|
|
||||||
void PM_Weapon_CheckForInspect(game::pmove_t* pm, game::pml_t* pml)
|
void PM_Weapon_CheckForInspect(game::pmove_t* pm, game::pml_t* pml)
|
||||||
{
|
{
|
||||||
if ((pm->ps->weapFlags[1] & WEAP_FLAG2_INSPECT) != 0)
|
if ((pm->ps->weapFlags.m_flags[1] & WEAP_FLAG2_INSPECT) != 0)
|
||||||
{
|
{
|
||||||
pm->ps->weapFlags[1] = ~pm->ps->weapFlags[1] & WEAP_FLAG2_INSPECT;
|
pm->ps->weapFlags.m_flags[1] = ~pm->ps->weapFlags.m_flags[1] & WEAP_FLAG2_INSPECT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -290,7 +290,7 @@ namespace weapon
|
|||||||
return scripting::script_value{};
|
return scripting::script_value{};
|
||||||
}
|
}
|
||||||
|
|
||||||
ent->client->ps.weapFlags[1] |= WEAP_FLAG2_INSPECT; // lets hope the game doesn't use this flag already...
|
ent->client->ps.weapFlags.m_flags[1] |= WEAP_FLAG2_INSPECT; // lets hope the game doesn't use this flag already...
|
||||||
return scripting::script_value{};
|
return scripting::script_value{};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -28,6 +28,10 @@ namespace dvars
|
|||||||
game::dvar_t* cg_gun_y = nullptr;
|
game::dvar_t* cg_gun_y = nullptr;
|
||||||
game::dvar_t* cg_gun_z = nullptr;
|
game::dvar_t* cg_gun_z = nullptr;
|
||||||
|
|
||||||
|
game::dvar_t* cg_thirdPerson = nullptr;
|
||||||
|
game::dvar_t* cg_thirdPersonRange = nullptr;
|
||||||
|
game::dvar_t* cg_thirdPersonAngle = nullptr;
|
||||||
|
|
||||||
game::dvar_t* cg_unlockall_items = nullptr;
|
game::dvar_t* cg_unlockall_items = nullptr;
|
||||||
game::dvar_t* cg_unlockall_loot = nullptr;
|
game::dvar_t* cg_unlockall_loot = nullptr;
|
||||||
|
|
||||||
|
@ -25,6 +25,10 @@ namespace dvars
|
|||||||
extern game::dvar_t* cg_gun_y;
|
extern game::dvar_t* cg_gun_y;
|
||||||
extern game::dvar_t* cg_gun_z;
|
extern game::dvar_t* cg_gun_z;
|
||||||
|
|
||||||
|
extern game::dvar_t* cg_thirdPerson;
|
||||||
|
extern game::dvar_t* cg_thirdPersonRange;
|
||||||
|
extern game::dvar_t* cg_thirdPersonAngle;
|
||||||
|
|
||||||
extern game::dvar_t* cg_unlockall_items;
|
extern game::dvar_t* cg_unlockall_items;
|
||||||
extern game::dvar_t* cg_unlockall_loot;
|
extern game::dvar_t* cg_unlockall_loot;
|
||||||
|
|
||||||
|
@ -687,17 +687,67 @@ namespace game
|
|||||||
assert_offsetof(PlayerActiveWeaponState, weaponDelay, 8);
|
assert_offsetof(PlayerActiveWeaponState, weaponDelay, 8);
|
||||||
assert_offsetof(PlayerActiveWeaponState, weaponState, 16);
|
assert_offsetof(PlayerActiveWeaponState, weaponState, 16);
|
||||||
|
|
||||||
typedef int GameModeFlagValues[2];
|
enum pmtype_t : std::int32_t
|
||||||
|
{
|
||||||
|
PM_NORMAL = 0x0,
|
||||||
|
PM_NORMAL_LINKED = 0x1,
|
||||||
|
PM_NOCLIP = 0x2,
|
||||||
|
PM_UFO = 0x3,
|
||||||
|
PM_MPVIEWER = 0x4,
|
||||||
|
PM_SPECTATOR = 0x5,
|
||||||
|
PM_INTERMISSION = 0x6,
|
||||||
|
PM_DEAD = 0x7,
|
||||||
|
PM_DEAD_LINKED = 0x8,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PMoveFlagsCommon : std::uint64_t;
|
||||||
|
enum PMoveFlagsSP : std::uint64_t;
|
||||||
|
enum PMoveFlagsMP : std::uint64_t;
|
||||||
|
|
||||||
|
enum POtherFlagsCommon : std::uint64_t;
|
||||||
|
enum POtherFlagsSP : std::uint64_t;
|
||||||
|
enum POtherFlagsMP : std::uint64_t;
|
||||||
|
|
||||||
|
enum PLinkFlagsCommon : std::uint32_t;
|
||||||
|
enum PLinkFlagsSP : std::uint32_t;
|
||||||
|
enum PLinkFlagsMP : std::uint32_t;
|
||||||
|
|
||||||
|
enum EntityStateFlagsCommon : std::uint32_t;
|
||||||
|
enum EntityStateFlagsSP : std::uint32_t;
|
||||||
|
enum EntityStateFlagsMP : std::uint32_t;
|
||||||
|
|
||||||
|
enum PWeaponFlagsCommon : std::uint64_t;
|
||||||
|
enum PWeaponFlagsSP : std::uint64_t;
|
||||||
|
enum PWeaponFlagsMP : std::uint64_t;
|
||||||
|
|
||||||
|
template<typename CommonE, typename spE, typename mpE, int bitSize>
|
||||||
|
struct GameModeFlagContainer
|
||||||
|
{
|
||||||
|
static_assert(bitSize % sizeof(unsigned int) * CHAR_BIT == 0, "bitSize must be divisible by sizeof(unsigned int) * CHAR_BIT");
|
||||||
|
unsigned int m_flags[bitSize >> (sizeof(unsigned int) + 1)];
|
||||||
|
};
|
||||||
|
|
||||||
struct playerState_s
|
struct playerState_s
|
||||||
{
|
{
|
||||||
int commandTime;
|
int commandTime;
|
||||||
int pm_type;
|
int pm_type;
|
||||||
char __pad0[1612];
|
int pm_time;
|
||||||
|
GameModeFlagContainer<PMoveFlagsCommon, PMoveFlagsSP, PMoveFlagsMP, 64> pm_flags;
|
||||||
|
GameModeFlagContainer<POtherFlagsCommon, POtherFlagsSP, POtherFlagsMP, 64> otherFlags;
|
||||||
|
GameModeFlagContainer<PLinkFlagsCommon, PLinkFlagsSP, PLinkFlagsMP, 32> linkFlags;
|
||||||
|
char __pad0[312];
|
||||||
|
GameModeFlagContainer<EntityStateFlagsCommon, EntityStateFlagsSP, EntityStateFlagsMP, 32> eFlags;
|
||||||
|
char __pad1[1272];
|
||||||
PlayerActiveWeaponState weapState[2];
|
PlayerActiveWeaponState weapState[2];
|
||||||
char __pad1[464];
|
char __pad2[464];
|
||||||
GameModeFlagValues weapFlags;
|
GameModeFlagContainer<PWeaponFlagsCommon, PWeaponFlagsSP, PWeaponFlagsMP, 64> weapFlags;
|
||||||
};
|
float fWeaponPosFrac;
|
||||||
|
char __pad3[0x4000];
|
||||||
|
}; // unk size
|
||||||
|
assert_offsetof(playerState_s, pm_flags, 12);
|
||||||
|
assert_offsetof(playerState_s, otherFlags, 20);
|
||||||
|
assert_offsetof(playerState_s, linkFlags, 28);
|
||||||
|
assert_offsetof(playerState_s, eFlags, 344);
|
||||||
assert_offsetof(playerState_s, weapState, 1620);
|
assert_offsetof(playerState_s, weapState, 1620);
|
||||||
assert_offsetof(playerState_s, weapFlags, 2188);
|
assert_offsetof(playerState_s, weapFlags, 2188);
|
||||||
|
|
||||||
@ -723,7 +773,7 @@ namespace game
|
|||||||
struct gclient_s
|
struct gclient_s
|
||||||
{
|
{
|
||||||
playerState_s ps;
|
playerState_s ps;
|
||||||
char __pad0[17180];
|
char __pad0[19376 - sizeof(playerState_s)];
|
||||||
char name[32]; // 19376
|
char name[32]; // 19376
|
||||||
char __pad1[1516];
|
char __pad1[1516];
|
||||||
int flags; // 20924
|
int flags; // 20924
|
||||||
@ -787,12 +837,44 @@ namespace game
|
|||||||
}
|
}
|
||||||
using namespace entity;
|
using namespace entity;
|
||||||
|
|
||||||
|
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 cg_s
|
struct cg_s
|
||||||
{
|
{
|
||||||
char __pad0[324368];
|
playerState_s predictedPlayerState;
|
||||||
|
char __pad0[19160 - sizeof(playerState_s)];
|
||||||
|
CubemapShot cubemapShot;
|
||||||
|
int cubemapSize;
|
||||||
|
char __pad1[305200];
|
||||||
float viewModelAxis[4][3];
|
float viewModelAxis[4][3];
|
||||||
};
|
char __pad2[168476];
|
||||||
|
int renderScreen;
|
||||||
|
int latestSnapshotNum;
|
||||||
|
int latestSnapshotTime;
|
||||||
|
int mapRestart;
|
||||||
|
int spectatingThirdPerson;
|
||||||
|
int renderingThirdPerson;
|
||||||
|
char __pad3[60792];
|
||||||
|
bool m_deathCameraFailsafeLock;
|
||||||
|
char __pad4[3];
|
||||||
|
char __pad5[486328];
|
||||||
|
}; static_assert(sizeof(cg_s) == 1040040);
|
||||||
|
static_assert(offsetof(cg_s, cubemapShot) == 19160);
|
||||||
|
static_assert(offsetof(cg_s, cubemapSize) == 19164);
|
||||||
static_assert(offsetof(cg_s, viewModelAxis) == 324368);
|
static_assert(offsetof(cg_s, viewModelAxis) == 324368);
|
||||||
|
static_assert(offsetof(cg_s, renderScreen) == 492892);
|
||||||
|
static_assert(offsetof(cg_s, renderingThirdPerson) == 492912);
|
||||||
|
static_assert(offsetof(cg_s, m_deathCameraFailsafeLock) == 553708);
|
||||||
|
|
||||||
namespace scripting
|
namespace scripting
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user