Skip to content

Commit

Permalink
Add spt_qc_cmd
Browse files Browse the repository at this point in the history
  • Loading branch information
lipsanen committed Feb 4, 2025
1 parent 02d8e7d commit fe67718
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 1 deletion.
1 change: 1 addition & 0 deletions spt.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,7 @@ del "$(OutDir)spt-version.obj"</Command>
<ClCompile Include="spt\features\playerio.cpp" />
<ClCompile Include="spt\features\portalled_pause.cpp" />
<ClCompile Include="spt\features\property_getter.cpp" />
<ClCompile Include="spt\features\qccmd.cpp" />
<ClCompile Include="spt\features\restart.cpp" />
<ClCompile Include="spt\features\saveloads.cpp" />
<ClCompile Include="spt\features\shadow.cpp" />
Expand Down
3 changes: 3 additions & 0 deletions spt.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,9 @@
<ClCompile Include="spt\features\strafehud.cpp">
<Filter>spt\features</Filter>
</ClCompile>
<ClCompile Include="spt\features\qccmd.cpp">
<Filter>spt\features</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\public\tier0\basetypes.h">
Expand Down
100 changes: 100 additions & 0 deletions spt/features/qccmd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#include "stdafx.hpp"
#ifndef OE

#include "..\feature.hpp"
#include "..\sptlib-wrapper.hpp"
#include "playerio.hpp"
#include "shadow.hpp"
#include "signals.hpp"

ConVar spt_qc_cmd("spt_qc_cmd",
"",
FCVAR_CHEAT,
"Execute command when quickclip occurs. "
"This is detected by the difference between "
"the quake position and the shadow position "
"rising above some threshold "
"and then teleporting to the same position\n");

ConVar spt_qc_threshold("spt_qc_threshold",
"32",
FCVAR_CHEAT,
"Threshold for quickclip detection, the distance between the quake hitbox and havok hitbox must exceed this before the teleport.\n");

ConVar spt_qc_maxdist_to_prev("spt_qc_maxdist_to_prev",
"200",
FCVAR_CHEAT | FCVAR_HIDDEN,
"Max distance to previous shadow position. This is to prevent loading a save with a havok hitbox differential causing the qc command to trigger.\n");

ConVar spt_qc_teleport_eps("spt_qc_teleport_eps",
"1",
FCVAR_CHEAT | FCVAR_HIDDEN,
"Quake hitbox needs to be within this many units to be considered teleported.\n");

// Execute command on quickclip
class QcCmdFeature : public FeatureWrapper<QcCmdFeature>
{
public:
Vector previousShadowPosition;
float previousShadowDiff;
protected:
virtual bool ShouldLoadFeature() override;

virtual void InitHooks() override;

virtual void LoadFeature() override;

virtual void UnloadFeature() override;

};

static QcCmdFeature qc_cmd;

static void Tick()
{
if (spt_qc_cmd.GetString()[0] == '\0')
{
return;
}

Vector playerPos = spt_playerio.m_vecAbsOrigin.GetValue();
Vector havokPos;
spt_player_shadow.GetPlayerHavokPos(&havokPos, nullptr);
float diffToCurrent = playerPos.DistTo(havokPos);
float diffToPrev = playerPos.DistTo(qc_cmd.previousShadowPosition);

if(qc_cmd.previousShadowDiff > spt_qc_threshold.GetFloat() &&
diffToCurrent < spt_qc_teleport_eps.GetFloat() &&
diffToPrev < spt_qc_maxdist_to_prev.GetFloat())
{
EngineConCmd(spt_qc_cmd.GetString());
spt_qc_cmd.SetValue("");
}

qc_cmd.previousShadowDiff = diffToCurrent;
qc_cmd.previousShadowPosition = havokPos;
}

bool QcCmdFeature::ShouldLoadFeature()
{
return true;
}

void QcCmdFeature::InitHooks() {}

void QcCmdFeature::LoadFeature()
{
if (spt_player_shadow.ORIG_GetShadowPosition)
{
previousShadowDiff = 0.0f;
previousShadowPosition.Zero();
InitConcommandBase(spt_qc_cmd);
InitConcommandBase(spt_qc_threshold);
InitConcommandBase(spt_qc_maxdist_to_prev);
TickSignal.Connect(Tick);
}
}

void QcCmdFeature::UnloadFeature() {}

#endif
4 changes: 3 additions & 1 deletion spt/features/shadow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ class ShadowPosition : public FeatureWrapper<ShadowPosition>
{
protected:
static int __fastcall HOOKED_GetShadowPosition(void* thisptr, int _, Vector* worldPosition, QAngle* angles);
_GetShadowPosition ORIG_GetShadowPosition = nullptr;

_beam_object_to_new_position ORIG_beam_object_to_new_position = nullptr;

Expand Down Expand Up @@ -60,6 +59,9 @@ class ShadowPosition : public FeatureWrapper<ShadowPosition>
* 4 bytes from this pointer.
*/
IPhysicsPlayerController* GetPlayerController();

// Get shadow position is public so other features can check if it's available
_GetShadowPosition ORIG_GetShadowPosition = nullptr;
};

extern ShadowPosition spt_player_shadow;

0 comments on commit fe67718

Please sign in to comment.