From 435e7dddcd14ab364095e28bcd9961104de728fa Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 5 Nov 2022 09:43:06 +0100 Subject: [PATCH] - fixed: P_SpawnMapThing may not call playsim code. There was one special case allowing to let an actor die on spawn, but this could call script code on an incompletely set up map which resulted in crashes. --- src/namedef_custom.h | 1 + src/playsim/p_mobj.cpp | 7 ++++++- wadsrc/static/zscript/actors/actor.zs | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/namedef_custom.h b/src/namedef_custom.h index b05bed0af..371e94377 100644 --- a/src/namedef_custom.h +++ b/src/namedef_custom.h @@ -347,6 +347,7 @@ xx(Greetings) xx(Idle) xx(GenericFreezeDeath) xx(GenericCrush) +xx(DieFromSpawn) // Bounce state names xx(Bounce) diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 82287ddb4..35e604d91 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -5776,7 +5776,12 @@ AActor *FLevelLocals::SpawnMapThing (FMapThing *mthing, int position) else mobj->health = -int(mthing->Health); if (mthing->Health == 0) - mobj->CallDie(NULL, NULL); + { + // We cannot call 'Die' here directly because the level is not yet fully set up. + // This needs to be delayed by one tic. + auto state = mobj->FindState(NAME_DieFromSpawn); + if (state) mobj->SetState(state, true); + } else if (mthing->Health != 1) mobj->StartHealth = mobj->health; diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index 0552d1bb9..99e0940d1 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -1360,6 +1360,9 @@ class Actor : Thinker native GenericCrush: POL5 A -1; Stop; + DieFromSpawn: + TNT1 A 1; + TNT1 A 1 { self.Die(null, null); } } // Internal functions