- scriptified A_KeenDie.

- added an 'exact' parameter to FThinkerIterator's Next function. This is mainly for scripting which allows to do a lot more checks natively when running the iterator while looking for one specific class.
This commit is contained in:
Christoph Oelckers 2016-11-05 01:19:41 +01:00
parent b6633bc489
commit 010fd038be
10 changed files with 59 additions and 55 deletions

View file

@ -837,7 +837,6 @@ set( NOT_COMPILED_SOURCE_FILES
sc_man_scanner.re sc_man_scanner.re
g_doom/a_bossbrain.cpp g_doom/a_bossbrain.cpp
g_doom/a_doomweaps.cpp g_doom/a_doomweaps.cpp
g_doom/a_keen.cpp
g_doom/a_lostsoul.cpp g_doom/a_lostsoul.cpp
g_doom/a_painelemental.cpp g_doom/a_painelemental.cpp
g_doom/a_revenant.cpp g_doom/a_revenant.cpp

View file

@ -369,6 +369,12 @@ DEFINE_ACTION_FUNCTION(DObject, Destroy)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DObject, GetClass)
{
PARAM_SELF_PROLOGUE(DObject);
ACTION_RETURN_OBJECT(self->GetClass());
}
//========================================================================== //==========================================================================
// //
// //

View file

@ -480,7 +480,7 @@ void FThinkerIterator::Reinit ()
m_SearchingFresh = false; m_SearchingFresh = false;
} }
DThinker *FThinkerIterator::Next () DThinker *FThinkerIterator::Next (bool exact)
{ {
if (m_ParentType == NULL) if (m_ParentType == NULL)
{ {
@ -496,7 +496,11 @@ DThinker *FThinkerIterator::Next ()
{ {
DThinker *thinker = m_CurrThinker; DThinker *thinker = m_CurrThinker;
m_CurrThinker = thinker->NextThinker; 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; return thinker;
} }

View file

@ -121,7 +121,7 @@ private:
public: public:
FThinkerIterator (const PClass *type, int statnum=MAX_STATNUM+1); FThinkerIterator (const PClass *type, int statnum=MAX_STATNUM+1);
FThinkerIterator (const PClass *type, int statnum, DThinker *prev); FThinkerIterator (const PClass *type, int statnum, DThinker *prev);
DThinker *Next (); DThinker *Next (bool exact = false);
void Reinit (); void Reinit ();
}; };
@ -146,9 +146,9 @@ public:
TThinkerIterator (const char *subclass, int statnum=MAX_STATNUM+1) : FThinkerIterator(PClass::FindClass(subclass), statnum) TThinkerIterator (const char *subclass, int statnum=MAX_STATNUM+1) : FThinkerIterator(PClass::FindClass(subclass), statnum)
{ {
} }
T *Next () T *Next (bool exact = false)
{ {
return static_cast<T *>(FThinkerIterator::Next ()); return static_cast<T *>(FThinkerIterator::Next (exact));
} }
}; };

View file

@ -24,7 +24,6 @@
// Include all the other Doom stuff here to reduce compile time // Include all the other Doom stuff here to reduce compile time
#include "a_bossbrain.cpp" #include "a_bossbrain.cpp"
#include "a_doomweaps.cpp" #include "a_doomweaps.cpp"
#include "a_keen.cpp"
#include "a_lostsoul.cpp" #include "a_lostsoul.cpp"
#include "a_painelemental.cpp" #include "a_painelemental.cpp"
#include "a_revenant.cpp" #include "a_revenant.cpp"

View file

@ -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<AActor> 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;
}

View file

@ -105,7 +105,8 @@ void A_Unblock(AActor *self, bool drop)
DEFINE_ACTION_FUNCTION(AActor, A_NoBlocking) DEFINE_ACTION_FUNCTION(AActor, A_NoBlocking)
{ {
PARAM_SELF_PROLOGUE(AActor); PARAM_SELF_PROLOGUE(AActor);
A_Unblock(self, true); PARAM_BOOL_DEF(drop);
A_Unblock(self, drop);
return 0; return 0;
} }

View file

@ -227,7 +227,7 @@ class Actor : Thinker native
native void A_MonsterRail(); native void A_MonsterRail();
native void A_BFGSpray(class<Actor> 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_BFGSpray(class<Actor> 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_Pain();
native void A_NoBlocking(); native void A_NoBlocking(bool drop = true);
void A_Fall() { A_NoBlocking(); } void A_Fall() { A_NoBlocking(); }
native void A_XScream(); native void A_XScream();
native void A_Look(); native void A_Look();
@ -241,7 +241,6 @@ class Actor : Thinker native
native void A_BossDeath(); native void A_BossDeath();
native void A_SkullAttack(float speed = 20); native void A_SkullAttack(float speed = 20);
native void A_BetaSkullAttack(); native void A_BetaSkullAttack();
native void A_KeenDie(int doortag = 666);
native void A_Detonate(); 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); native bool A_CallSpecial(int special, int arg1=0, int arg2=0, int arg3=0, int arg4=0, int arg5=0);

View file

@ -1,6 +1,7 @@
class Object native class Object native
{ {
/*virtual*/ native void Destroy(); /*virtual*/ native void Destroy();
native class<Object> GetClass();
} }
class Thinker : Object native class Thinker : Object native
@ -14,8 +15,8 @@ class ThinkerIterator : Object native
MAX_STATNUM = 127 MAX_STATNUM = 127
} }
native static ThinkerIterator Create(class<Actor> type = "Actor", int statnum=MAX_STATNUM+1); native static ThinkerIterator Create(class<Object> type = "Actor", int statnum=MAX_STATNUM+1);
native Thinker Next(); native Thinker Next(bool exact = false);
native void Reinit(); native void Reinit();
} }
@ -23,7 +24,7 @@ class DropItem : Object native
{ {
/* native fields listed for reference only for now /* native fields listed for reference only for now
native readonly DropItem Next; 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 Probability;
native readonly int Amount; native readonly int Amount;
*/ */

View file

@ -42,3 +42,40 @@ class CommanderKeen : Actor
Goto Spawn; 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);
}
}