View Issue Details

IDProjectCategoryView StatusLast Update
0005962The Dark ModFeature proposalpublic09.12.2022 03:30
ReporterDaft Mugi Assigned Tostgatilov  
PrioritynormalSeveritynormalReproducibilityhave not tried
Status resolvedResolutionfixed 
Product VersionSVN 
Target VersionTDM 2.11Fixed in VersionTDM 2.11 
Summary0005962: Add "new toggle crouch"
DescriptionSome players have requested that toggle crouch happen on key press rather than key release, which would make it behave like Thief and other games. When using toggle crouch on key release, a noticeable delay before crouching can be felt if the player does not quickly tap the crouch key. This has felt like a bug to some players who have not realized that crouching happens on key release.

https://forums.thedarkmod.com/index.php?/topic/21315-toggle-crouch-is-not-as-responsive/

NOTE(stgatilov): "keydown vs keyup" difference is covered by 0005973.

I propose a cvar "tdm_new_toggle_crouch" be added to toggle between two different implementations of toggle crouch. When enabled, toggle crouch happens on key press and implements changes for climbing ropes/ladders, which behaves more similarly to regular crouch. This will be enabled by default as players, especially new players, will likely prefer it. When disabled, toggle crouch uses the traditional code path, which some veteran players may prefer.

https://forums.thedarkmod.com/index.php?/topic/21403-add-option-to-toggle-crouch-on-key-press/

--------------------------------------------------------------

Written below, I tried to clearly document the changes that "new toggle crouch" introduces and how it compares to other crouch rules, so others may more easily reason about the changes. There's quite a bit of interactions between game state and player intentions.

With regular crouch, the player is always in the standing position while climbing. This has two notable behaviors:

1. When mantling a platform from a rope/ladder, the player will end the mantle in the standing position.
2. When sliding, the player will end the slide in the crouching position. The player will change to the standing position on crouch key release.

With traditional toggle crouch, the crouching position does not change on rope/ladder attachment. This has two notable behaviors:

1. To mantle a platform from a rope/ladder and end the mantle in a standing position, the player must toggle crouch to the standing position while on the rope/ladder before initiating the mantle.
2. To slide and land in the crouching position, the player must toggle crouch to the crouching position while on the rope/ladder before initiating the slide. The player will change to the standing position on toggle crouch key release.

With Thief/New Dark toggle crouch, the player is always in the standing position while climbing. This has two notable behaviors:

1. On rope/ladder attachment, the crouching position is automatically changed to the standing position. This is fine for moving upwards, but it can be a bit jarring for moving downwards as the view jerks upwards.
2. On rope/ladder detachment either mantling on a platform or dropping off (unmount) to the ground, the player will end in the standing position.

With "new toggle crouch", the rules are a combination of Thief, TDM regular crouch, and TDM traditional toggle crouch. This has the following notable behaviors:

1. While on a rope/ladder and moving upwards, the crouching position is automatically changed to the standing position. (Like Thief)
2. While on a rope/ladder and moving downwards, the crouching position is the same as prior to the attachment. Therefore, a player in the crouching position and moving downwards will stay in the crouching position and will not experience a jarring upwards view change. (Like TDM traditional toggle crouch) Note: If the player moves upwards before moving downwards, the player will be in the standing position.
3. When mantling a platform from a rope/ladder, the player will likely end the mantle in the standing position because of some prior upwards movement. (Like TDM regular crouch)
4. When sliding, the player will end the slide in the crouching position. The player will change to the standing position on toggle crouch key release. (Like TDM regular crouch)
Tagscrouch

Relationships

related to 0005961 resolved Fix rope/ladder speed while crouched 
related to 0004247 resolvedstgatilov Using the crouch key when climbing a ladder or a pipe 
related to 0001746 resolvedstgatilov Climbing physics should use crouched player bounding box 
related to 0005973 resolvedstgatilov Change crouch state on key down with crouch toggle 

Activities

Daft Mugi

Daft Mugi

16.05.2022 21:41

developer   ~0014831

This patch was created using `git diff --no-prefix`. I hope it works out ok and can be easily merged with SVN.

It's based on r9920.
new-toggle-crouch-v1-r9920.diff (6,533 bytes)   
diff --git game/Player.cpp game/Player.cpp
index b82a3c6..79482fc 100644
--- game/Player.cpp
+++ game/Player.cpp
@@ -702,6 +702,7 @@ idPlayer::idPlayer() :
 
 	m_IdealCrouchState		= false;
 	m_CrouchIntent			= false;
+	m_CrouchToggleBypassed		= false;
 
 	m_LeanButtonTimeStamp	= 0;
 	m_InventoryOverlay		= -1;
@@ -5606,9 +5607,40 @@ void idPlayer::PerformImpulse( int impulse ) {
 
 		case IMPULSE_CROUCH:		// Crouch
 		{
-			if (!cv_tdm_crouch_toggle.GetBool())
+			// Daft Mugi: NOTE - The code paths for new and old toggle
+			// crouch were purposely separated for clarity and ease of
+			// comparison rather than reducing overall conditional logic.
+			if (cv_tdm_new_crouch_toggle.GetBool())
 			{
-				m_CrouchIntent = true;
+				if (cv_tdm_crouch_toggle.GetBool())
+				{
+					if (physicsObj.OnRope() || physicsObj.OnLadder())
+					{
+						// Climbing; use regular crouch behavior
+						m_CrouchToggleBypassed = true;
+						m_CrouchIntent = true;
+					}
+					else
+					{
+						// Not climbing; toggle crouch
+						if (entityNumber == gameLocal.localClientNum)
+						{
+							m_CrouchToggleBypassed = false;
+							m_CrouchIntent = !m_CrouchIntent;
+						}
+					}
+				}
+				else
+				{
+					m_CrouchIntent = true;
+				}
+			}
+			else	// Old toggle crouch path
+			{
+				if (!cv_tdm_crouch_toggle.GetBool())
+				{
+					m_CrouchIntent = true;
+				}
 			}
 			
 			m_ButtonStateTracker.StartTracking(impulse);
@@ -5933,16 +5965,37 @@ void idPlayer::PerformKeyRelease(int impulse, int holdTime)
 	switch (impulse)
 	{
 		case IMPULSE_CROUCH:		// TDM crouch
-			if (cv_tdm_crouch_toggle.GetBool())
+			// Daft Mugi: NOTE - The code paths for new and old toggle
+			// crouch were purposely separated for clarity and ease of
+			// comparison rather than reducing overall conditional logic.
+			if (cv_tdm_new_crouch_toggle.GetBool())
 			{
-				if ( entityNumber == gameLocal.localClientNum )
+				if (cv_tdm_crouch_toggle.GetBool())
 				{
-					m_CrouchIntent = !m_CrouchIntent;
+					if (physicsObj.OnRope() || physicsObj.OnLadder() || m_CrouchToggleBypassed)
+					{
+						// Climbing or initiated crouch while climbing; use regular crouch behavior
+						m_CrouchIntent = false;
+					}
 				}
-			}		
-			else
+				else
+				{
+					m_CrouchIntent = false;
+				}
+			}
+			else	// Old toggle crouch path
 			{
-				m_CrouchIntent = false;
+				if (cv_tdm_crouch_toggle.GetBool())
+				{
+					if ( entityNumber == gameLocal.localClientNum )
+					{
+						m_CrouchIntent = !m_CrouchIntent;
+					}
+				}
+				else
+				{
+					m_CrouchIntent = false;
+				}
 			}
 
 			// clear climb detach or slide intent when crouch is released
diff --git game/Player.h game/Player.h
index 370dbf8..21864ce 100644
--- game/Player.h
+++ game/Player.h
@@ -392,6 +392,10 @@ public:
 	// or toggle crouch is active
 	bool					m_CrouchIntent;
 
+	// Daft Mugi: For new toggle crouch, this is set to true when the
+	// player has pressed toggle crouch while on a rope or ladder/vine.
+	bool					m_CrouchToggleBypassed;
+
 	// STiFU: FrobHelper alpha calculation
 	CFrobHelper				m_FrobHelper;
 
diff --git game/gamesys/SysCvar.cpp game/gamesys/SysCvar.cpp
index 3beba14..4b23c30 100644
--- game/gamesys/SysCvar.cpp
+++ game/gamesys/SysCvar.cpp
@@ -237,6 +237,8 @@ idCVar cv_tdm_footfalls_movetype_specific( "tdm_footfall_sounds_movetype_specifi
 
 // Dark Mod crouching
 idCVar cv_tdm_crouch_toggle(			"tdm_toggle_crouch",			"1",			CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Set to 1 to make crouching toggleable." );
+// Daft Mugi: New Toggle Crouch
+idCVar cv_tdm_new_crouch_toggle(			"tdm_new_toggle_crouch",			"1",			CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "Set to 1 to make toggle crouch on key press instead of key release." );
 idCVar cv_tdm_crouch_toggle_hold_time(	"tdm_crouch_toggle_hold_time",	"400",			CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "The time in milliseconds to hold crouch while on a rope/ladder for starting to slide down." );
 idCVar cv_tdm_reattach_delay(			"tdm_reattach_delay",			"100",			CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "Delay (in ms) for reattaching to ropes/ladders after detaching using crouch." );
 
diff --git game/gamesys/SysCvar.h game/gamesys/SysCvar.h
index 7d657e6..9040639 100644
--- game/gamesys/SysCvar.h
+++ game/gamesys/SysCvar.h
@@ -211,6 +211,7 @@ extern idCVar cv_savegame_compress;
 
 // angua: TDM toggle crouch
 extern idCVar cv_tdm_crouch_toggle;
+extern idCVar cv_tdm_new_crouch_toggle;
 extern idCVar cv_tdm_crouch_toggle_hold_time;
 extern idCVar cv_tdm_reattach_delay;
 
diff --git game/physics/Physics_Player.cpp game/physics/Physics_Player.cpp
index 6c54d3f..a28c89d 100644
--- game/physics/Physics_Player.cpp
+++ game/physics/Physics_Player.cpp
@@ -1532,6 +1532,15 @@ void idPhysics_Player::RopeMove( void )
 	wishspeed = wishvel.Normalize();
 	idPhysics_Player::Accelerate( wishvel, wishspeed, PM_ACCELERATE );
 
+	// Daft Mugi: Uncrouch if moving up a rope. (new toggle crouch)
+	if (cv_tdm_new_crouch_toggle.GetBool() && cv_tdm_crouch_toggle.GetBool())
+	{
+		// upscale: looking up?, wishspeed: moving?
+		if (upscale < 0 && wishspeed > 0) {
+			player->m_CrouchIntent = false;
+		}
+	}
+
 	// cap the climb velocity
 	upscale = current.velocity * -climbDir;
 	if ( upscale < -PM_ROPESPEED ) 
@@ -1662,6 +1671,7 @@ void idPhysics_Player::LadderMove( void )
 	float	upscale(0.0f), horizscale(0.0f), NormalDot(0.0f);
 	trace_t SurfTrace;
 	bool	bMoveAllowed( true );
+	idPlayer *player = static_cast<idPlayer *>(self);
 
 
 	// jump off the climbable surface if they jump, or fall off if they hit crouch
@@ -1870,6 +1880,15 @@ void idPhysics_Player::LadderMove( void )
 	wishspeed = wishvel.Normalize();
 	idPhysics_Player::Accelerate( wishvel, wishspeed, accel );
 
+	// Daft Mugi: Uncrouch if moving up a ladder or vine. (new toggle crouch)
+	if (cv_tdm_new_crouch_toggle.GetBool() && cv_tdm_crouch_toggle.GetBool())
+	{
+		// lenVert2: looking up?, wishspeed: moving?
+		if (lenVert2 > 0 && wishspeed > 0) {
+			player->m_CrouchIntent = false;
+		}
+	}
+
 	// don't apply friction on the wishdir direction
 	idPhysics_Player::Friction( wishdir );
 
@@ -2198,10 +2217,13 @@ void idPhysics_Player::CheckDuck( void ) {
 			}
 		}
 
-		// TODO_CROUCH: don't use crouch speed while climbing
 		if ( current.movementFlags & PMF_DUCKED ) 
 		{
-			playerSpeed = crouchSpeed;
+			// #5961 - Don't use crouch speed while climbing
+			if (!(OnRope() || OnLadder()))
+			{
+				playerSpeed = crouchSpeed;
+			}
 			maxZ = pm_crouchheight.GetFloat();
 		}
 		else 
Daft Mugi

Daft Mugi

16.05.2022 22:03

developer   ~0014832

The patch can close 0005961. Crouch speed is no longer used on ropes/ladders.
Daft Mugi

Daft Mugi

16.05.2022 22:05

developer   ~0014833

The patch can likely close 0004247.

The patch can likely close 0001746 unless we want to make the player always be in the crouching position while climbing. That would have the behavior of always ending a mantle onto a platform in the crouching position unless mantle code was changed.
Daft Mugi

Daft Mugi

07.08.2022 07:10

developer   ~0015144

I think this can be closed now. Toggle crouch on keydown was added. See 0005973.

Issue History

Date Modified Username Field Change
16.05.2022 20:51 Daft Mugi New Issue
16.05.2022 20:51 Daft Mugi Tag Attached: crouch
16.05.2022 20:52 Daft Mugi Relationship added related to 0005961
16.05.2022 20:53 Daft Mugi Relationship added related to 0004247
16.05.2022 20:53 Daft Mugi Relationship added related to 0001746
16.05.2022 21:41 Daft Mugi Note Added: 0014831
16.05.2022 21:41 Daft Mugi File Added: new-toggle-crouch-v1-r9920.diff
16.05.2022 22:03 Daft Mugi Note Added: 0014832
16.05.2022 22:05 Daft Mugi Note Added: 0014833
12.06.2022 19:42 stgatilov Relationship added related to 0005973
12.06.2022 19:50 stgatilov Description Updated
07.08.2022 07:10 Daft Mugi Note Added: 0015144
07.08.2022 08:01 Dragofer Assigned To => stgatilov
07.08.2022 08:01 Dragofer Status new => closed
07.08.2022 08:01 Dragofer Resolution open => fixed
09.12.2022 03:30 nbohr1more Status closed => resolved
09.12.2022 03:30 nbohr1more Product Version => SVN
09.12.2022 03:30 nbohr1more Fixed in Version => TDM 2.11
09.12.2022 03:30 nbohr1more Target Version => TDM 2.11