# HG changeset patch
# User Binary Code
# Date 1704731852 28800
#      Mon Jan 08 08:37:32 2024 -0800
# Node ID ec589e766849b517b91c4b6ede7cf2c7b3043df9
# Parent  4f775318d2ecf6db1d7e93a967964defdea7eb19
Added +NOMORPHLIMITATIONS flag from Q-Zandronum, allowing morphs to switch weapons, play sounds, and be affected by speed powerups.

diff -r 4f775318d2ec -r ec589e766849 docs/zandronum-history.txt
--- a/docs/zandronum-history.txt	Wed Dec 20 22:00:46 2023 -0500
+++ b/docs/zandronum-history.txt	Mon Jan 08 08:37:32 2024 -0800
@@ -18,6 +18,7 @@
 *+	- Added the new AUTHINFO lump, allowing modders to define their own list of lumps to be authenticated. [Kaminsky]
 *+	- Revamped the scoreboard, and added the new SCORINFO lump that allows full customization of the scoreboard. [Kaminsky]
 *+	- Added support for custom vote types using the new VOTEINFO lump. [Dusk]
++	- Added the +NOMORPHLIMITATIONS flag, allowing morphs to switch weapons, play sounds, and be affected by speed powerups. [geNia/Binary]
 +	- Added CVars: "con_interpolate" and "con_speed" which interpolates and controls how fast the console moves. Based on featues from ZCC. [Kaminsky]
 +	- Added ACS functions: "GetCurrentMapPosition", "GetEventResult", "GetActorSectorLocation", and "ChangeTeamScore". [Kaminsky]
 +	- Added an optional parameter to the ACS function GetChatMessage to let color codes to stay in chat messages. [Kaminsky]
diff -r 4f775318d2ec -r ec589e766849 src/cl_main.cpp
--- a/src/cl_main.cpp	Wed Dec 20 22:00:46 2023 -0500
+++ b/src/cl_main.cpp	Mon Jan 08 08:37:32 2024 -0800
@@ -7252,7 +7252,8 @@
 	}
 */
 	// [BB] Prevent the client from trying to switch to a different weapon while morphed.
-	if ( players[ulPlayer].morphTics )
+	// [geNia] unless +NOMORPHLIMITATIONS is used
+	if ( player->morphTics && !( player->mo && (player->mo->PlayerFlags & PPF_NOMORPHLIMITATIONS) ) )
 		players[ulPlayer].PendingWeapon = WP_NOCHANGE;
 
 	// Since an item displayed on the HUD may have been given, refresh the HUD.
diff -r 4f775318d2ec -r ec589e766849 src/d_player.h
--- a/src/d_player.h	Wed Dec 20 22:00:46 2023 -0500
+++ b/src/d_player.h	Mon Jan 08 08:37:32 2024 -0800
@@ -192,6 +192,7 @@
 	PPF_NOTHRUSTWHENINVUL = 1,	// Attacks do not thrust the player if they are invulnerable.
 	PPF_CANSUPERMORPH = 2,		// Being remorphed into this class can give you a Tome of Power
 	PPF_CROUCHABLEMORPH = 4,	// This morphed player can crouch
+	PPF_NOMORPHLIMITATIONS = 8,	// [geNia] Removes morph limitations, like not playing land sounds, switching weapons, or using speed powerups.
 };
 
 //
diff -r 4f775318d2ec -r ec589e766849 src/g_shared/a_morph.cpp
--- a/src/g_shared/a_morph.cpp	Wed Dec 20 22:00:46 2023 -0500
+++ b/src/g_shared/a_morph.cpp	Mon Jan 08 08:37:32 2024 -0800
@@ -97,6 +97,14 @@
 	p->PremorphWeapon = p->ReadyWeapon;
 	morphed->special2 = actor->flags & ~MF_JUSTHIT;
 	morphed->player = p;
+	// [Binary] Keep movement if +NOMORPHLIMITATIONS is used.
+	if (morphed->PlayerFlags & PPF_NOMORPHLIMITATIONS)
+	{
+		morphed->velx = actor->velx;
+		morphed->vely = actor->vely;
+		morphed->velz = actor->velz;
+		morphed->pitch = actor->pitch;
+	}
 	if (actor->renderflags & RF_INVISIBLE)
 	{
 		morphed->special2 |= MF_JUSTHIT;
@@ -127,7 +135,11 @@
 	p->MorphExitFlash = (exit_flash) ? exit_flash : RUNTIME_CLASS(ATeleportFog);
 	p->health = morphed->health;
 	p->mo = morphed;
-	p->velx = p->vely = 0;
+	// [Binary] Keep movement if +NOMORPHLIMITATIONS is used.
+	if (!(morphed->PlayerFlags & PPF_NOMORPHLIMITATIONS))
+	{
+		p->velx = p->vely = 0;
+	}
 	morphed->ObtainInventory (actor);
 	// Remove all armor
 	for (item = morphed->Inventory; item != NULL; )
@@ -178,6 +190,12 @@
 		SERVERCOMMANDS_SetThingFlags( morphed, FLAGSET_FLAGS3 );
 		if ( morphed->tid != 0 )
 			SERVERCOMMANDS_SetThingTID( morphed );
+		// [Binary] Keep movement if +NOMORPHLIMITATIONS is used.
+		if ( morphed->PlayerFlags & PPF_NOMORPHLIMITATIONS )
+		{
+			SERVERCOMMANDS_MoveLocalPlayer( ulPlayer );
+			SERVERCOMMANDS_MovePlayer( ulPlayer, ulPlayer, SVCF_SKIPTHISCLIENT );
+		}
 	}
 
 	return true;
@@ -253,10 +271,21 @@
 	mo->player = player;
 	mo->reactiontime = 18;
 	mo->flags = pmo->special2 & ~MF_JUSTHIT;
-	mo->velx = 0;
-	mo->vely = 0;
-	player->velx = 0;
-	player->vely = 0;
+	// [Binary] Keep movement if +NOMORPHLIMITATIONS is used.
+	if (pmo->PlayerFlags & PPF_NOMORPHLIMITATIONS)
+	{
+		mo->velx = pmo->velx;
+		mo->vely = pmo->vely;
+		mo->velz = pmo->velz;
+		mo->pitch = pmo->pitch;
+	}
+	else
+	{
+		mo->velx = 0;
+		mo->vely = 0;
+		player->velx = 0;
+		player->vely = 0;
+	}
 	mo->velz = pmo->velz;
 	if (!(pmo->special2 & MF_JUSTHIT))
 	{
diff -r 4f775318d2ec -r ec589e766849 src/p_mobj.cpp
--- a/src/p_mobj.cpp	Wed Dec 20 22:00:46 2023 -0500
+++ b/src/p_mobj.cpp	Mon Jan 08 08:37:32 2024 -0800
@@ -3354,7 +3354,9 @@
 
 	// [RH] only make noise if alive
 	// [WS/BB] As client only play the sound for the consoleplayer.
-	if (!mo->player->morphTics && mo->health > 0 && NETWORK_IsConsolePlayerOrNotInClientMode( mo->player ))
+	// [Binary] Allow morphs to play sounds if +NOMORPHLIMITATIONS is used.
+	bool canPlayLandSound = ( !mo->player->morphTics || (mo->player->mo && mo->player->mo->PlayerFlags & PPF_NOMORPHLIMITATIONS) );
+	if ( canPlayLandSound && mo->health > 0 && NETWORK_IsConsolePlayerOrNotInClientMode( mo->player ))
 	{
 		grunted = false;
 		// Why should this number vary by gravity?
diff -r 4f775318d2ec -r ec589e766849 src/p_pspr.cpp
--- a/src/p_pspr.cpp	Wed Dec 20 22:00:46 2023 -0500
+++ b/src/p_pspr.cpp	Mon Jan 08 08:37:32 2024 -0800
@@ -858,7 +858,8 @@
 		return;
 	}
 	if ((player->WeaponState & WF_DISABLESWITCH) || // Weapon changing has been disabled.
-		player->morphTics != 0)					// Morphed classes cannot change weapons.
+		( player->morphTics != 0 && // Morphed classes cannot change weapons.
+		!( player->mo && (player->mo->PlayerFlags & PPF_NOMORPHLIMITATIONS) ) )) // [geNia] unless +NOMORPHLIMITATIONS is used
 	{ // ...so throw away any pending weapon requests.
 		player->PendingWeapon = WP_NOCHANGE;
 	}
@@ -1016,7 +1017,8 @@
 		return;
 	}
 
-	if (player->morphTics || player->cheats & CF_INSTANTWEAPSWITCH)
+	// [Binary] Allow morphs to switch weapons if +NOMORPHLIMITATIONS is used.
+	if ( ( player->morphTics && !( player->mo && (player->mo->PlayerFlags & PPF_NOMORPHLIMITATIONS) ) ) || player->cheats & CF_INSTANTWEAPSWITCH)
 	{
 		psp->sy = WEAPONBOTTOM;
 	}
diff -r 4f775318d2ec -r ec589e766849 src/p_user.cpp
--- a/src/p_user.cpp	Wed Dec 20 22:00:46 2023 -0500
+++ b/src/p_user.cpp	Mon Jan 08 08:37:32 2024 -0800
@@ -2266,7 +2266,8 @@
 	}
 
 	// [BC] This comes out to 50%, so we can use this for the turbosphere.
-	if (!player->morphTics && Inventory != NULL)
+	// [Binary] Allow morphs to use turbosphere / speed powerups with +NOMORPHLIMITATIONS.
+	if (( !player->morphTics || ( PlayerFlags & PPF_NOMORPHLIMITATIONS ) ) && Inventory != NULL)
 	{
 		fixed_t factor = Inventory->GetSpeedFactor ();
 		forward = FixedMul(forward, factor);
diff -r 4f775318d2ec -r ec589e766849 src/sv_main.cpp
--- a/src/sv_main.cpp	Wed Dec 20 22:00:46 2023 -0500
+++ b/src/sv_main.cpp	Mon Jan 08 08:37:32 2024 -0800
@@ -6278,7 +6278,8 @@
 	}
 
 	// [BB] Morph workaround: If the player is morphed, he can't change his weapon.
-	if ( players[ulClient].morphTics )
+	// [Binary] Unless +NOMORPHLIMITATIONS is used
+	if ( players[ulClient].morphTics && !( players[ulClient].mo && (players[ulClient].mo->PlayerFlags & PPF_NOMORPHLIMITATIONS) ) )
 		return false;
 
 	// [BB] Since the server is not giving the player a weapon while spawning, P_BringUpWeapon doesn't call A_Raise for
diff -r 4f775318d2ec -r ec589e766849 src/thingdef/thingdef_data.cpp
--- a/src/thingdef/thingdef_data.cpp	Wed Dec 20 22:00:46 2023 -0500
+++ b/src/thingdef/thingdef_data.cpp	Mon Jan 08 08:37:32 2024 -0800
@@ -393,6 +393,7 @@
 	DEFINE_FLAG(PPF, NOTHRUSTWHENINVUL, APlayerPawn, PlayerFlags),
 	DEFINE_FLAG(PPF, CANSUPERMORPH, APlayerPawn, PlayerFlags),
 	DEFINE_FLAG(PPF, CROUCHABLEMORPH, APlayerPawn, PlayerFlags),
+	DEFINE_FLAG(PPF, NOMORPHLIMITATIONS, APlayerPawn, PlayerFlags), // [Binary] Define +NOMORPHLIMITATIONS flag.
 };
 
 static FFlagDef PowerSpeedFlags[] =
