From b898a773ab7e8d310014cef5bfc8b9e99eaaf442 Mon Sep 17 00:00:00 2001
From: MascaraSnake <jonassauer27@gmail.com>
Date: Tue, 21 Sep 2021 07:36:54 +0200
Subject: [PATCH] Adapt linedef types 425 and 442 to UDMF

---
 extras/conf/udb/Includes/SRB222_linedefs.cfg | 42 ++++++++++++++++
 src/p_setup.c                                | 30 +++++++++++-
 src/p_spec.c                                 | 50 +++++++++++---------
 3 files changed, 97 insertions(+), 25 deletions(-)

diff --git a/extras/conf/udb/Includes/SRB222_linedefs.cfg b/extras/conf/udb/Includes/SRB222_linedefs.cfg
index e6e26b5792..ad7109769f 100644
--- a/extras/conf/udb/Includes/SRB222_linedefs.cfg
+++ b/extras/conf/udb/Includes/SRB222_linedefs.cfg
@@ -2885,6 +2885,17 @@ udmf
 	{
 		title = "Linedef Executor (player/object)";
 
+		425
+		{
+			title = "Change Object State";
+			prefix = "(425)";
+			stringarg0
+			{
+				title = "State";
+				type = 2;
+			}
+		}
+
 		426
 		{
 			title = "Stop Object";
@@ -2966,6 +2977,37 @@ udmf
 			}
 		}
 
+		442
+		{
+			title = "Change Object Type State";
+			prefix = "(442)";
+			arg0
+			{
+				title = "Target sector tag";
+				type = 13;
+			}
+			arg1
+			{
+				title = "Change to";
+				type = 11;
+				enum
+				{
+					0 = "Specified state";
+					1 = "Next state";
+				}
+			}
+			stringarg0
+			{
+				title = "Object type";
+				type = 2;
+			}
+			stringarg1
+			{
+				title = "State";
+				type = 2;
+			}
+		}
+
 		460
 		{
 			title = "Award Rings";
diff --git a/src/p_setup.c b/src/p_setup.c
index 0ea997eda2..c05fa5aae2 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -1292,9 +1292,7 @@ static void P_LoadSidedefs(UINT8 *data)
 			case 334: // Trigger linedef executor: Object dye - Continuous
 			case 335: // Trigger linedef executor: Object dye - Each time
 			case 336: // Trigger linedef executor: Object dye - Once
-			case 425: // Calls P_SetMobjState on calling mobj
 			case 434: // Custom Power
-			case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
 			case 461: // Spawns an object on the map based on texture offsets
 			case 463: // Colorizes an object
 			{
@@ -1316,6 +1314,8 @@ static void P_LoadSidedefs(UINT8 *data)
 			case 331: // Trigger linedef executor: Skin - Continuous
 			case 332: // Trigger linedef executor: Skin - Each time
 			case 333: // Trigger linedef executor: Skin - Once
+			case 425: // Calls P_SetMobjState on calling mobj
+			case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
 			case 443: // Calls a named Lua function
 			case 459: // Control text prompt (named tag)
 			{
@@ -3780,6 +3780,13 @@ static void P_ConvertBinaryMap(void)
 			lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
 			lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB);
 			break;
+		case 425: //Change object state
+			if (sides[lines[i].sidenum[0]].text)
+			{
+				lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);
+				M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1);
+			}
+			break;
 		case 426: //Stop object
 			lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB);
 			break;
@@ -3835,6 +3842,25 @@ static void P_ConvertBinaryMap(void)
 		case 441: //Condition set trigger
 			lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
 			break;
+		case 442: //Change object type state
+			lines[i].args[0] = tag;
+			if (sides[lines[i].sidenum[0]].text)
+			{
+				lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);
+				M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1);
+			}
+			if (lines[i].sidenum[1] == 0xffff)
+				lines[i].args[1] = 1;
+			else
+			{
+				lines[i].args[1] = 0;
+				if (sides[lines[i].sidenum[1]].text)
+				{
+					lines[i].stringargs[1] = Z_Malloc(strlen(sides[lines[i].sidenum[1]].text) + 1, PU_LEVEL, NULL);
+					M_Memcpy(lines[i].stringargs[1], sides[lines[i].sidenum[1]].text, strlen(sides[lines[i].sidenum[1]].text) + 1);
+				}
+			}
+			break;
 		case 443: //Call Lua function
 			if (lines[i].text)
 			{
diff --git a/src/p_spec.c b/src/p_spec.c
index efc5bc8680..14363bb1d7 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -2576,7 +2576,11 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
 
 		case 425: // Calls P_SetMobjState on calling mobj
 			if (mo && !mo->player)
-				P_SetMobjState(mo, sides[line->sidenum[0]].toptexture); //P_AproxDistance(line->dx, line->dy)>>FRACBITS);
+			{
+				statenum_t state = line->stringargs[0] ? get_number(line->stringargs[0]) : S_NULL;
+				if (state >= 0 && state < NUMSTATES)
+					P_SetMobjState(mo, state);
+			}
 			break;
 
 		case 426: // Moves the mobj to its sector's soundorg and on the floor, and stops it
@@ -2838,37 +2842,37 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
 
 		case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
 		{
-			const mobjtype_t type = (mobjtype_t)sides[line->sidenum[0]].toptexture;
+			const mobjtype_t type = line->stringargs[0] ? get_number(line->stringargs[0]) : MT_NULL;
 			statenum_t state = NUMSTATES;
-			sector_t *sec;
 			mobj_t *thing;
 
-			if (line->sidenum[1] != 0xffff)
-				state = (statenum_t)sides[line->sidenum[1]].toptexture;
+			if (type < 0 || type >= NUMMOBJTYPES)
+				break;
 
-			TAG_ITER_SECTORS(tag, secnum)
+			if (!line->args[1])
+			{
+				state = line->stringargs[1] ? get_number(line->stringargs[1]) : S_NULL;
+
+				if (state < 0 || state >= NUMSTATES)
+					break;
+			}
+
+			TAG_ITER_SECTORS(line->args[0], secnum)
 			{
 				boolean tryagain;
-				sec = sectors + secnum;
 				do {
 					tryagain = false;
-					for (thing = sec->thinglist; thing; thing = thing->snext)
-						if (thing->type == type)
-						{
-							if (state != NUMSTATES)
-							{
-								if (!P_SetMobjState(thing, state)) // set state to specific state
-								{ // mobj was removed
-									tryagain = true; // snext is corrupt, we'll have to start over.
-									break;
-								}
-							}
-							else if (!P_SetMobjState(thing, thing->state->nextstate)) // set state to nextstate
-							{ // mobj was removed
-								tryagain = true; // snext is corrupt, we'll have to start over.
-								break;
-							}
+					for (thing = sectors[secnum].thinglist; thing; thing = thing->snext)
+					{
+						if (thing->type != type)
+							continue;
+
+						if (!P_SetMobjState(thing, line->args[1] ? thing->state->nextstate : state))
+						{ // mobj was removed
+							tryagain = true; // snext is corrupt, we'll have to start over.
+							break;
 						}
+					}
 				} while (tryagain);
 			}
 			break;
-- 
GitLab