Skip to content

Instantly share code, notes, and snippets.

@daftmugi
Last active February 5, 2023 16:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daftmugi/8febb3fce1dc0c123210db70ee34b323 to your computer and use it in GitHub Desktop.
Save daftmugi/8febb3fce1dc0c123210db70ee34b323 to your computer and use it in GitHub Desktop.
#5892: Mantle while carrying a body
diff --git game/Player.cpp game/Player.cpp
index c6f71dd..7f881ba 100644
--- game/Player.cpp
+++ game/Player.cpp
@@ -67,7 +67,7 @@ const int HEALTHPULSE_TIME = 333;
const float MIN_BOB_SPEED = 5.0f;
// shouldered body immobilizations
-const int SHOULDER_IMMOBILIZATIONS = EIM_CLIMB | EIM_ITEM_SELECT | EIM_WEAPON_SELECT | EIM_ATTACK | EIM_ITEM_USE | EIM_MANTLE | EIM_FROB_COMPLEX;
+const int SHOULDER_IMMOBILIZATIONS = EIM_CLIMB | EIM_ITEM_SELECT | EIM_WEAPON_SELECT | EIM_ATTACK | EIM_ITEM_USE | EIM_FROB_COMPLEX;
const float SHOULDER_JUMP_HINDERANCE = 0.25f;
// grayman #3485 - additional volume reduction when falling when crouched
@@ -4513,13 +4513,8 @@ void idPlayer::OnStartShoulderingBody(idEntity* body)
// TODO: Also make sure you can't grab anything else (hands are full)
// requires a new EIM flag?
- SetImmobilization( "ShoulderedBody",
- cv_pm_mantle_while_shouldering.GetBool() ?
- // #5892: Mantle while carring a body
- (SHOULDER_IMMOBILIZATIONS & ~EIM_MANTLE) :
- SHOULDER_IMMOBILIZATIONS
- );
-
+ SetImmobilization( "ShoulderedBody", SHOULDER_IMMOBILIZATIONS );
+
// set hinderance
float maxSpeed = body->spawnArgs.GetFloat("shouldered_maxspeed","1.0f");
SetHinderance( "ShoulderedBody", 1.0f, maxSpeed );
diff --git game/Player.h game/Player.h
index a51a589..b4f2fd5 100644
--- game/Player.h
+++ game/Player.h
@@ -825,6 +825,8 @@ public:
void UpdateSkinSetup( bool restart );
+ bool IsShoulderingBody( void ) { return m_bShoulderingBody; };
+
bool OnLadder( void ) const;
// Virtal override of idActor::OnElevator()
virtual CMultiStateMover* OnElevator(bool mustBeMoving) const;
diff --git game/gamesys/SysCvar.cpp game/gamesys/SysCvar.cpp
index 0bc7994..6b5ae04 100644
--- game/gamesys/SysCvar.cpp
+++ game/gamesys/SysCvar.cpp
@@ -208,9 +208,6 @@ idCVar cv_pm_softhinderance_run( "pm_softhinderance_run", "1.0", CVAR_GAME | CVA
idCVar cv_pm_weightmod( "pm_weightmod", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Gets multiplied to the force applied to objects below the player model. Defaults to 1." );
-// #5892: Mantle while carring a body
-idCVar cv_pm_mantle_while_shouldering( "pm_mantle_while_shouldering", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "If set to 1, allow mantling while shouldering a body." );
-
idCVar cv_pm_mantle_reach( "pm_mantle_reach", "0.5", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Horizontal reach of mantle ability, as fraction of player height. Default is 0.5" );
idCVar cv_pm_mantle_height( "pm_mantle_height", "0.2", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Vertical reach of mantle ability, as fraction of player height. Default is 0.2" );
idCVar cv_pm_mantle_minflatness( "pm_mantle_minflatness", "0.707", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Cannot mantle on top of surfaces whose angle's cosine is smaller than this value. e.g. >1.0 means nothing can be mantled; 1.0 means only perfectly flat floors (0 degrees) can be mantled on top of; ~0.707 means no surfaces steeper than 45 degrees can be mantled on top of; 0.5 means no surfaces steeper than 60 degrees can be mantled on top of; a large negative value (like -10) means all surfaces can be mantled regardless of steepness. Default is 0.707." );
@@ -226,6 +223,21 @@ idCVar cv_pm_mantle_pushNonCrouched_msecs("pm_mantle_pushNonCrouched_msecs","550
idCVar cv_pm_mantle_pushNonCrouched_playgrunt_speedthreshold("pm_mantle_pushNonCrouched_playgrunt_speedthreshold", "120.0", CVAR_GAME | CVAR_FLOAT, "If the player speed exceeds this threshold, a grund sound is played when performing the mantle.", 0.0f, 100000.0f);
idCVar cv_pm_mantle_fastLowObstaces("pm_mantle_fastLowObstacles", "1", CVAR_GAME | CVAR_BOOL, "If true, a faster mantle will be performed for low obstacles.", 0, 1);
idCVar cv_pm_mantle_maxLowObstacleHeight("pm_mantle_maxLowObstacleHeight", "36.0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "The maximum height of obstacles over which a fast mantle can be performed", 0.0f, 60.0f);
+
+// Daft Mugi #5892: Mantle while carrying a body
+idCVar cv_pm_mantle_maxShoulderingObstacleHeight(
+ "pm_mantle_maxShoulderingObstacleHeight", "41", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE,
+ "The maximum height of obstacles allowed for a shouldering body mantle",
+ 0.0f, 100.0f
+);
+idCVar cv_pm_mantle_while_shouldering(
+ "pm_mantle_while_shouldering", "1", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE,
+ "Which restriction for mantle while shouldering?\n"
+ " 0 --- no mantling while shouldering a body (TDM original)\n"
+ " 1 --- restricted mantling while shouldering a body\n"
+ " 2 --- unrestricted mantling while shouldering a body (Cheat Mode)"
+);
+
idCVar cv_pm_mantle_fastMediumObstaclesCrouched("pm_mantle_fastMediumObstaclesCrouched", "1", CVAR_GAME | CVAR_BOOL, "If true, a faster mantle will be performed for medium-high obstacles in crouched state", 0, 1);
idCVar cv_pm_mantle_pullFast_msecs("pm_mantle_pullFast_msecs", "450.0", CVAR_GAME | CVAR_INTEGER |CVAR_ARCHIVE, "The duration it takes for a fast pull.", 0, 10000);
idCVar cv_pm_mantle_fallingFast_speedthreshold("pm_mantle_fallingFast_speedthreshold", "360.0", CVAR_GAME | CVAR_FLOAT, "If falling faster than this threshold, no fast mantles will be performed.", 0.0f, 100000.0f);
diff --git game/gamesys/SysCvar.h game/gamesys/SysCvar.h
index 0d558ff..e1c58e8 100644
--- game/gamesys/SysCvar.h
+++ game/gamesys/SysCvar.h
@@ -165,9 +165,6 @@ extern idCVar cv_tdm_footfalls_movetype_specific;
extern idCVar cv_pm_weightmod;
-// #5892: Mantle while carring a body
-extern idCVar cv_pm_mantle_while_shouldering;
-
extern idCVar cv_pm_mantle_height;
extern idCVar cv_pm_mantle_reach;
extern idCVar cv_pm_mantle_minflatness;
@@ -181,6 +178,11 @@ extern idCVar cv_pm_mantle_push_msecs;
extern idCVar cv_pm_mantle_pushNonCrouched_msecs;
extern idCVar cv_pm_mantle_fastLowObstaces;
extern idCVar cv_pm_mantle_maxLowObstacleHeight;
+
+// Daft Mugi #5892: Mantle while carrying a body
+extern idCVar cv_pm_mantle_maxShoulderingObstacleHeight;
+extern idCVar cv_pm_mantle_while_shouldering;
+
extern idCVar cv_pm_mantle_fastMediumObstaclesCrouched;
extern idCVar cv_pm_mantle_pullFast_msecs;
extern idCVar cv_pm_mantle_pushNonCrouched_playgrunt_speedthreshold;
diff --git game/physics/Physics_Player.cpp game/physics/Physics_Player.cpp
index e610f28..62c0944 100644
--- game/physics/Physics_Player.cpp
+++ game/physics/Physics_Player.cpp
@@ -5010,6 +5010,12 @@ void idPhysics_Player::PerformMantle()
return; // greebo: Mantling disabled by immobilization system
}
+ if (cv_pm_mantle_while_shouldering.GetInteger() == 0
+ && p_player->IsShoulderingBody())
+ {
+ return;
+ }
+
if (waterLevel >= WATERLEVEL_HEAD)
{
return; // STiFU: #1037: Do not mantle underwater
@@ -5106,14 +5112,26 @@ void idPhysics_Player::PerformMantle()
floorHeight = -floorPos * gravityNormal;
}
const float eyeHeight = -eyePos * gravityNormal;
+ const float feetHeight = -(GetOrigin() * gravityNormal);
+ const float obstacleHeight = mantleEndHeight - feetHeight;
+ const bool bPullOrHang = eyeHeight < mantleEndHeight;
const bool bFallingFast =
(current.velocity * gravityNormal) >
cv_pm_mantle_fallingFast_speedthreshold.GetFloat();
+ // Daft Mugi #5892: While shouldering a body, allow mantling at approximately waist height.
+ if (cv_pm_mantle_while_shouldering.GetInteger() == 1
+ && p_player->IsShoulderingBody()
+ && (bPullOrHang // no pull or hang allowed
+ || obstacleHeight > cv_pm_mantle_maxShoulderingObstacleHeight.GetFloat() // restrict max height
+ || bFallingFast)) // must not be falling fast
+ {
+ return;
+ }
+
if (cv_pm_mantle_fastLowObstaces.GetBool()) // STiFU #4930
{
- const float feetHeight = -(GetOrigin() * gravityNormal);
if ( IsMantleable == EMantleable_YesUpstraight // Upstraight mantle possible
&& !bFallingFast
&& (mantleEndHeight < floorHeight + cv_pm_mantle_maxLowObstacleHeight.GetFloat() // Only allow the full obstacle height when near the floor
@@ -5131,7 +5149,7 @@ void idPhysics_Player::PerformMantle()
if ( bIsCrouched
&& !bFallingFast
- && eyeHeight < mantleEndHeight // When endheight lower than eyes, use the regular push mantle
+ && bPullOrHang // When endheight lower than eyes, use the regular push mantle
&& mantleEndHeight < floorHeight + pm_normalviewheight.GetFloat())
{
// Do a fast pull-push mantle over medium sized obstacle
@@ -5139,7 +5157,7 @@ void idPhysics_Player::PerformMantle()
return;
}
}
- if (eyeHeight < mantleEndHeight)
+ if (bPullOrHang)
{
// Start with pull if on the ground, hang if not
if (groundPlane)
@stgatilov
Copy link

Would you mind if I delete the cv_pm_mantle_while_shouldering cvar and all the code around it, except for the case with "1 = restricted"?

I see no point in the "cheat mode", since we already have noclip for cheaters.
And "not allowed" mode can be reserved for the unlucky case when we just need to revert the whole change for some yet unforeseen reason.

@daftmugi
Copy link
Author

daftmugi commented Feb 5, 2023

@stgatilov I don't mind removing option 0 "no mantling while shouldering a body (TDM original)".

I think option 2 "Cheat Mode" should be kept, because it is for Thief players, but I couldn't call it "Thief Mode" due to copyright concerns (maybe). The options give the player a choice in how they want to play the game. Also, "Cheat Mode" signifies an unintended play option, so if the player finds that they break a mission (unlikely), it's their own fault. "noclip" would definitely be cheating and would break immersion. Also, it was useful during the creation and testing of option 1 "restricted".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment