Merge pull request #141 from diamante0018/feature/custom-stance-scale

[Movement] Add customizable speed scale for stance
This commit is contained in:
Dss0 2021-11-11 17:55:52 +01:00 committed by GitHub
commit 84a086d4cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 217 additions and 1 deletions

View File

@ -104,6 +104,7 @@ namespace Components
Loader::Register(new Gamepad());
Loader::Register(new Chat());
Loader::Register(new TextRenderer());
Loader::Register(new Movement());
Loader::Register(new Client());

View File

@ -132,6 +132,7 @@ namespace Components
#include "Modules/SoundMutexFix.hpp"
#include "Modules/Chat.hpp"
#include "Modules/TextRenderer.hpp"
#include "Modules/Movement.hpp"
#include "Modules/Gamepad.hpp"
#include "Modules/Client.hpp"

View File

@ -0,0 +1,161 @@
#include "STDInclude.hpp"
namespace Components
{
Dvar::Var Movement::PlayerDuckedSpeedScale;
Dvar::Var Movement::PlayerLastStandCrawlSpeedScale;
Dvar::Var Movement::PlayerProneSpeedScale;
int Movement::PMGetEffectiveStance(Game::playerState_s* ps)
{
auto heightTarget = ps->viewHeightTarget;
if (heightTarget == 0x16)
return Game::PM_EFF_STANCE_LASTSTANDCRAWL;
if (heightTarget == 0x28)
return Game::PM_EFF_STANCE_DUCKED;
if (heightTarget == 0xB)
return Game::PM_EFF_STANCE_PRONE;
return Game::PM_EFF_STANCE_DEFAULT;
}
float Movement::PMCmdScaleForStance(Game::pmove_s* move)
{
auto* playerState = move->ps;
float scale;
if (playerState->viewHeightLerpTime != 0 && playerState->viewHeightLerpTarget == 0xB)
{
scale = move->cmd.serverTime - playerState->viewHeightLerpTime / 400.0f;
if (0.0f <= scale)
{
auto flags = 0;
if (scale < 1.0f)
{
flags |= 1 << 8;
}
if (scale == 1.0f)
{
flags |= 1 << 14;
}
if (flags == 0)
{
scale = 1.0f;
return scale * 0.15f + (1.0f - scale) * 0.65f;
}
if (scale != 0.0f)
{
return scale * 0.15f + (1.0f - scale) * 0.65f;
}
}
}
if ((playerState->viewHeightLerpTime != 0 && playerState->viewHeightLerpTarget == 0x28) &&
playerState->viewHeightLerpDown == 0)
{
scale = 400.0f / move->cmd.serverTime - playerState->viewHeightLerpTime;
if (0.0f <= scale)
{
auto flags = 0;
if (scale < 1.0f)
{
flags |= 1 << 8;
}
if (scale == 1.0f)
{
flags |= 1 << 14;
}
if (flags == 0)
{
scale = 1.0f;
}
else if (scale != 0.0f)
{
return scale * 0.65f + (1.0f - scale) * 0.15f;
}
}
}
scale = 1.0f;
auto stance = Movement::PMGetEffectiveStance(playerState);
if (stance == Game::PM_EFF_STANCE_PRONE)
{
scale = Movement::PlayerProneSpeedScale.get<float>();
}
else if (stance == Game::PM_EFF_STANCE_DUCKED)
{
scale = Movement::PlayerDuckedSpeedScale.get<float>();
}
else if (stance == Game::PM_EFF_STANCE_LASTSTANDCRAWL)
{
scale = Movement::PlayerLastStandCrawlSpeedScale.get<float>();
}
return scale;
}
__declspec(naked) void Movement::PMCmdScaleForStanceStub()
{
__asm
{
pushad
push edx
call Movement::PMCmdScaleForStance
add esp, 4
popad
ret
}
}
Game::dvar_t* Movement::Dvar_RegisterLastStandSpeedScale(const char* name, float defaultVal, float min, float max, int, const char* desc)
{
Movement::PlayerLastStandCrawlSpeedScale = Dvar::Register<float>(name, defaultVal,
min, max, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, desc);
return Movement::PlayerLastStandCrawlSpeedScale.get<Game::dvar_t*>();
}
Movement::Movement()
{
Dvar::OnInit([]
{
Movement::PlayerDuckedSpeedScale = Dvar::Register<float>("player_duckedSpeedScale",
0.65f, 0.0f, 5.0f, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED,
"The scale applied to the player speed when ducking");
Movement::PlayerProneSpeedScale = Dvar::Register<float>("player_proneSpeedScale",
0.15f, 0.0f, 5.0f, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED,
"The scale applied to the player speed when crawling");
});
// Hook PM_CmdScaleForStance in PM_CmdScale_Walk
Utils::Hook(0x572F34, Movement::PMCmdScaleForStanceStub, HOOK_CALL).install()->quick();
//Hook PM_CmdScaleForStance in PM_GetMaxSpeed
Utils::Hook(0x57395F, Movement::PMCmdScaleForStanceStub, HOOK_CALL).install()->quick();
// Hook Dvar_RegisterFloat. Only thing that's changed is that the 0x80 flag is not used.
Utils::Hook(0x448B66, Movement::Dvar_RegisterLastStandSpeedScale, HOOK_CALL).install()->quick();
}
Movement::~Movement()
{
}
}

View File

@ -0,0 +1,22 @@
#pragma once
namespace Components
{
class Movement : public Component
{
public:
Movement();
~Movement();
private:
static Dvar::Var PlayerDuckedSpeedScale;
static Dvar::Var PlayerLastStandCrawlSpeedScale;
static Dvar::Var PlayerProneSpeedScale;
static int PMGetEffectiveStance(Game::playerState_s* ps);
static float PMCmdScaleForStance(Game::pmove_s* move);
static void PMCmdScaleForStanceStub();
static Game::dvar_t* Dvar_RegisterLastStandSpeedScale(const char* name, float defaultVal, float min, float max, int flags, const char* desc);
};
}

View File

@ -109,7 +109,7 @@ namespace Game
IMG_CATEGORY_WATER = 0x5,
IMG_CATEGORY_RENDERTARGET = 0x6,
IMG_CATEGORY_TEMP = 0x7,
} ;
};
enum buttons_t
{
@ -6876,6 +6876,37 @@ namespace Game
const char* args[9];
};
struct pmove_s
{
playerState_s* ps;
usercmd_s cmd;
usercmd_s oldcmd;
int tracemask;
int numtouch;
int touchents[32];
char __pad0[24];
float xyspeed;
int proneChange;
float maxSprintTimeMultiplier;
bool mantleStarted;
float mantleEndPos[3];
int mantleDuration;
int viewChangeTime;
float viewChange;
float fTorsoPitch;
float fWaistPitch;
unsigned char handler;
};
enum EffectiveStance
{
PM_EFF_STANCE_DEFAULT = 0,
PM_EFF_STANCE_PRONE = 1,
PM_EFF_STANCE_DUCKED = 2,
PM_EFF_STANCE_LASTSTANDCRAWL = 3,
PM_EFF_STANCE_COUNT = 4
};
#pragma endregion
#ifndef IDA