- 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
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

View File

@ -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());
}
//==========================================================================
//
//

View File

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

View File

@ -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<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 "a_bossbrain.cpp"
#include "a_doomweaps.cpp"
#include "a_keen.cpp"
#include "a_lostsoul.cpp"
#include "a_painelemental.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)
{
PARAM_SELF_PROLOGUE(AActor);
A_Unblock(self, true);
PARAM_BOOL_DEF(drop);
A_Unblock(self, drop);
return 0;
}

View File

@ -227,7 +227,7 @@ class Actor : Thinker native
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_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);

View File

@ -1,6 +1,7 @@
class Object native
{
/*virtual*/ native void Destroy();
native class<Object> GetClass();
}
class Thinker : Object native
@ -14,8 +15,8 @@ class ThinkerIterator : Object native
MAX_STATNUM = 127
}
native static ThinkerIterator Create(class<Actor> type = "Actor", int statnum=MAX_STATNUM+1);
native Thinker Next();
native static ThinkerIterator Create(class<Object> 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;
*/

View File

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