From bd3f4e7347206ae406f06143f2c206bd67cdbe9a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 19 Apr 2020 19:03:25 +0200 Subject: [PATCH 1/2] - relax pointer substitution restriction for morphed monsters. --- src/playsim/p_mobj.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 6945bc9a55..de0ff1b6b9 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -4943,9 +4943,12 @@ void StaticPointerSubstitution(AActor* old, AActor* notOld) if (old == nullptr) return; - // This is only allowed to replace players. For everything else the results are undefined. - if (!old->IsKindOf(NAME_PlayerPawn) || (notOld != nullptr && !notOld->IsKindOf(NAME_PlayerPawn))) return; - + // This is only allowed to replace players or swap out morphed monsters + if (!old->IsKindOf(NAME_PlayerPawn) || (notOld != nullptr && !notOld->IsKindOf(NAME_PlayerPawn))) + { + if (notOld == nullptr) return; + if (!old->IsKindOf(NAME_MorphedMonster) && !notOld->IsKindOf(NAME_MorphedMonster)) return; + } // Go through all objects. i = 0; DObject* last = 0; for (probe = GC::Root; probe != NULL; probe = probe->ObjNext) From 4fb6b7c7d41f015e41b75bac896c1f17c71aa124 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 19 Apr 2020 21:06:51 +0200 Subject: [PATCH 2/2] - block off the Substitute function by making it private to the 3 classes that really need it. --- src/scripting/vmthunks_actors.cpp | 16 ++++++++++++++++ wadsrc/static/zscript/actors/actor.zs | 2 +- .../static/zscript/actors/player/player_morph.zs | 4 ++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/scripting/vmthunks_actors.cpp b/src/scripting/vmthunks_actors.cpp index 8f233fc777..9ada1dffb4 100644 --- a/src/scripting/vmthunks_actors.cpp +++ b/src/scripting/vmthunks_actors.cpp @@ -1614,6 +1614,22 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, Substitute, StaticPointerSubstitution) return 0; } +DEFINE_ACTION_FUNCTION_NATIVE(_PlayerPawn, Substitute, StaticPointerSubstitution) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_OBJECT(replace, AActor); + StaticPointerSubstitution(self, replace); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_MorphedMonster, Substitute, StaticPointerSubstitution) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_OBJECT(replace, AActor); + StaticPointerSubstitution(self, replace); + return 0; +} + DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetSpawnableType, P_GetSpawnableType) { PARAM_PROLOGUE; diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index cade8322da..0b3841a19c 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -459,7 +459,7 @@ class Actor : Thinker native virtual native void Die(Actor source, Actor inflictor, int dmgflags = 0, Name MeansOfDeath = 'none'); virtual native bool Slam(Actor victim); virtual native void Touch(Actor toucher); - native void Substitute(Actor replacement); + private native void Substitute(Actor replacement); native ui void DisplayNameTag(); // Called by inventory items to see if this actor is capable of touching them. diff --git a/wadsrc/static/zscript/actors/player/player_morph.zs b/wadsrc/static/zscript/actors/player/player_morph.zs index 66fd0f1d81..391be4a063 100644 --- a/wadsrc/static/zscript/actors/player/player_morph.zs +++ b/wadsrc/static/zscript/actors/player/player_morph.zs @@ -1,5 +1,7 @@ extend class PlayerPawn { + private native void Substitute(PlayerPawn replacement); + //=========================================================================== // // EndAllPowerupEffects @@ -503,6 +505,8 @@ class MorphedMonster : Actor +FLOORCLIP } + private native void Substitute(Actor replacement); + override void OnDestroy () { if (UnmorphedMe != NULL)