diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index adc90444dc..9b4985a739 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -837,7 +837,6 @@ set( NOT_COMPILED_SOURCE_FILES sc_man_scanner.re g_doom/a_bossbrain.cpp g_doom/a_doomweaps.cpp - g_doom/a_keen.cpp g_doom/a_lostsoul.cpp g_doom/a_painelemental.cpp g_doom/a_revenant.cpp diff --git a/src/dobject.cpp b/src/dobject.cpp index 56d12787f4..d057a71d39 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -369,6 +369,12 @@ DEFINE_ACTION_FUNCTION(DObject, Destroy) return 0; } +DEFINE_ACTION_FUNCTION(DObject, GetClass) +{ + PARAM_SELF_PROLOGUE(DObject); + ACTION_RETURN_OBJECT(self->GetClass()); +} + //========================================================================== // // diff --git a/src/dthinker.cpp b/src/dthinker.cpp index 022e147da0..bacd53eee5 100644 --- a/src/dthinker.cpp +++ b/src/dthinker.cpp @@ -480,7 +480,7 @@ void FThinkerIterator::Reinit () m_SearchingFresh = false; } -DThinker *FThinkerIterator::Next () +DThinker *FThinkerIterator::Next (bool exact) { if (m_ParentType == NULL) { @@ -496,7 +496,11 @@ DThinker *FThinkerIterator::Next () { DThinker *thinker = m_CurrThinker; m_CurrThinker = thinker->NextThinker; - if (thinker->IsKindOf(m_ParentType)) + if (exact) + { + if (thinker->IsA(m_ParentType)) return thinker; + } + else if (thinker->IsKindOf(m_ParentType)) { return thinker; } diff --git a/src/dthinker.h b/src/dthinker.h index 3f96472977..95985c2fb4 100644 --- a/src/dthinker.h +++ b/src/dthinker.h @@ -121,7 +121,7 @@ private: public: FThinkerIterator (const PClass *type, int statnum=MAX_STATNUM+1); FThinkerIterator (const PClass *type, int statnum, DThinker *prev); - DThinker *Next (); + DThinker *Next (bool exact = false); void Reinit (); }; @@ -146,9 +146,9 @@ public: TThinkerIterator (const char *subclass, int statnum=MAX_STATNUM+1) : FThinkerIterator(PClass::FindClass(subclass), statnum) { } - T *Next () + T *Next (bool exact = false) { - return static_cast(FThinkerIterator::Next ()); + return static_cast(FThinkerIterator::Next (exact)); } }; diff --git a/src/g_doom/a_doommisc.cpp b/src/g_doom/a_doommisc.cpp index 31ee228f80..534ed400e7 100644 --- a/src/g_doom/a_doommisc.cpp +++ b/src/g_doom/a_doommisc.cpp @@ -24,7 +24,6 @@ // Include all the other Doom stuff here to reduce compile time #include "a_bossbrain.cpp" #include "a_doomweaps.cpp" -#include "a_keen.cpp" #include "a_lostsoul.cpp" #include "a_painelemental.cpp" #include "a_revenant.cpp" diff --git a/src/g_doom/a_keen.cpp b/src/g_doom/a_keen.cpp deleted file mode 100644 index b22f141b49..0000000000 --- a/src/g_doom/a_keen.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* -#include "actor.h" -#include "info.h" -#include "p_local.h" -#include "p_spec.h" -#include "p_enemy.h" -#include "a_action.h" -#include "vm.h" -*/ - -// -// A_KeenDie -// DOOM II special, map 32. -// Uses special tag 666 by default. -// - -DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KeenDie) -{ - PARAM_SELF_PROLOGUE(AActor); - PARAM_INT_DEF(doortag); - - A_Unblock(self, false); - - // scan the remaining thinkers to see if all Keens are dead - AActor *other; - TThinkerIterator iterator; - const PClass *matchClass = self->GetClass (); - - while ( (other = iterator.Next ()) ) - { - if (other != self && other->health > 0 && other->IsA (matchClass)) - { - // other Keen not dead - return 0; - } - } - - EV_DoDoor (DDoor::doorOpen, NULL, NULL, doortag, 2., 0, 0, 0); - return 0; -} - - diff --git a/src/g_shared/a_action.cpp b/src/g_shared/a_action.cpp index 0ec388de85..e1fa9a7fab 100644 --- a/src/g_shared/a_action.cpp +++ b/src/g_shared/a_action.cpp @@ -105,7 +105,8 @@ void A_Unblock(AActor *self, bool drop) DEFINE_ACTION_FUNCTION(AActor, A_NoBlocking) { PARAM_SELF_PROLOGUE(AActor); - A_Unblock(self, true); + PARAM_BOOL_DEF(drop); + A_Unblock(self, drop); return 0; } diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 091fba4b53..c6175b6f10 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -227,7 +227,7 @@ class Actor : Thinker native native void A_MonsterRail(); native void A_BFGSpray(class spraytype = "BFGExtra", int numrays = 40, int damagecount = 15, float angle = 90, float distance = 16*64, float vrange = 32, int damage = 0, int flags = 0); native void A_Pain(); - native void A_NoBlocking(); + native void A_NoBlocking(bool drop = true); void A_Fall() { A_NoBlocking(); } native void A_XScream(); native void A_Look(); @@ -241,7 +241,6 @@ class Actor : Thinker native native void A_BossDeath(); native void A_SkullAttack(float speed = 20); native void A_BetaSkullAttack(); - native void A_KeenDie(int doortag = 666); native void A_Detonate(); native bool A_CallSpecial(int special, int arg1=0, int arg2=0, int arg3=0, int arg4=0, int arg5=0); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index cca39f1e23..4564f0e86d 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -1,6 +1,7 @@ class Object native { /*virtual*/ native void Destroy(); + native class GetClass(); } class Thinker : Object native @@ -14,8 +15,8 @@ class ThinkerIterator : Object native MAX_STATNUM = 127 } - native static ThinkerIterator Create(class type = "Actor", int statnum=MAX_STATNUM+1); - native Thinker Next(); + native static ThinkerIterator Create(class type = "Actor", int statnum=MAX_STATNUM+1); + native Thinker Next(bool exact = false); native void Reinit(); } @@ -23,7 +24,7 @@ class DropItem : Object native { /* native fields listed for reference only for now native readonly DropItem Next; - native readonly name ItemName; // internally called 'name' which clashes with the type. + native readonly name Name; native readonly int Probability; native readonly int Amount; */ diff --git a/wadsrc/static/zscript/doom/keen.txt b/wadsrc/static/zscript/doom/keen.txt index a60e924eff..6d596c717a 100644 --- a/wadsrc/static/zscript/doom/keen.txt +++ b/wadsrc/static/zscript/doom/keen.txt @@ -42,3 +42,40 @@ class CommanderKeen : Actor Goto Spawn; } } + + +//=========================================================================== +// +// Code (must be attached to Actor) +// +//=========================================================================== + +extend class Actor +{ + + // + // A_KeenDie + // DOOM II special, map 32. + // Uses special tag 666 by default. + // + + void A_KeenDie(int doortag = 666) + { + A_NoBlocking(false); + + // scan the remaining thinkers to see if all Keens are dead + ThinkerIterator it = ThinkerIterator.Create(GetClass()); + Actor mo; + while (mo = Actor(it.Next(true))) + { + if (mo.health > 0 && mo != self) + { + // other Keen not dead + return; + } + } + Door_Open(doortag, 16); + } +} + +