From 02811b72f62e51a80a20c5816d2936e417cc7656 Mon Sep 17 00:00:00 2001 From: Hanicef 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 e75a911ee..d6f125bbd 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 0bcd6da1d..7e4741ffd 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 55be8e54f..c6f437c9a 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;