From 02811b72f62e51a80a20c5816d2936e417cc7656 Mon Sep 17 00:00:00 2001
From: Hanicef <gustaf@hanicef.me>
Date: Tue, 23 Jan 2024 22:43:25 +0100
Subject: [PATCH] Fix segfault when trying to spawn an MT_PLAYER from Lua

---
 src/lua_baselib.c |  4 ++--
 src/p_local.h     |  2 +-
 src/p_mobj.c      | 18 ++++++++++++++++--
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index e75a911eef..d6f125bbde 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -641,7 +641,7 @@ static int lib_pSpawnMobj(lua_State *L)
 	NOHUD
 	INLEVEL
 	NOSPAWNNULL
-	LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ);
+	LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type, NULL), META_MOBJ);
 	return 1;
 }
 
@@ -657,7 +657,7 @@ static int lib_pSpawnMobjFromMobj(lua_State *L)
 	NOSPAWNNULL
 	if (!actor)
 		return LUA_ErrInvalid(L, "mobj_t");
-	LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type), META_MOBJ);
+	LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type, NULL), META_MOBJ);
 	return 1;
 }
 
diff --git a/src/p_local.h b/src/p_local.h
index 0bcd6da1dd..7e4741ffd5 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -328,7 +328,7 @@ boolean P_CheckDeathPitCollide(mobj_t *mo);
 boolean P_CheckSolidLava(ffloor_t *rover);
 void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype);
 
-mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type);
+mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type, ...);
 
 mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type);
 mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type, fixed_t x, fixed_t y, fixed_t z);
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 55be8e54fc..c6f437c9a1 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -14420,15 +14420,29 @@ void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration)
 // Spawns an object with offsets relative to the position of another object.
 // Scale, gravity flip, etc. is taken into account automatically.
 //
-mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type)
+mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type, ...)
 {
+	va_list args;
 	mobj_t *newmobj;
 
 	xofs = FixedMul(xofs, mobj->scale);
 	yofs = FixedMul(yofs, mobj->scale);
 	zofs = FixedMul(zofs, mobj->scale);
 
-	newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type);
+	if (type == MT_PLAYER)
+	{
+		player_t *player;
+		// MT_PLAYER requires an additional parameter for the player, so pass that forth.
+		va_start(args, type);
+		player = va_arg(args, player_t *);
+		va_end(args);
+		newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type, player);
+	}
+	else
+	{
+		newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type);
+	}
+
 	if (!newmobj)
 		return NULL;
 
-- 
GitLab