- added: Let the kill CCMD also kill replacements of the monster that is specified.

- add a GetReplacement method to PClass to clean up some really ugly code
- Who wrote the 'kill' CCMD? The way it checked if two classes were identical was horrendously overcomplicated.

SVN r2601 (trunk)
This commit is contained in:
Christoph Oelckers 2010-08-26 20:59:15 +00:00
parent ffa58aadbe
commit 9102200771
10 changed files with 40 additions and 19 deletions

View File

@ -739,7 +739,7 @@ public:
if (bloodcls != NULL)
{
bloodcls = bloodcls->ActorInfo->GetReplacement()->Class;
bloodcls = bloodcls->GetReplacement();
}
return bloodcls;
}

View File

@ -1917,6 +1917,22 @@ BYTE *FDynamicBuffer::GetData (int *len)
}
static int KillAll(const PClass *cls)
{
AActor *actor;
int killcount = 0;
TThinkerIterator<AActor> iterator(cls);
while ( (actor = iterator.Next ()) )
{
if (actor->IsA(cls))
{
if (!(actor->flags2 & MF2_DORMANT) && (actor->flags3 & MF3_ISMONSTER))
killcount += actor->Massacre ();
}
}
return killcount;
}
// [RH] Execute a special "ticcmd". The type byte should
// have already been read, and the stream is positioned
// at the beginning of the command's actual data.
@ -2348,18 +2364,17 @@ void Net_DoCommand (int type, BYTE **stream, int player)
case DEM_KILLCLASSCHEAT:
{
AActor *actor;
TThinkerIterator<AActor> iterator;
char *classname = ReadString (stream);
int killcount = 0;
const PClass *cls = PClass::FindClass(classname);
while ( (actor = iterator.Next ()) )
if (classname != NULL)
{
if (!stricmp (actor->GetClass ()->TypeName.GetChars (), classname))
killcount = KillAll(cls);
const PClass *cls_rep = cls->GetReplacement();
if (cls != cls_rep)
{
if (!(actor->flags2 & MF2_DORMANT) && (actor->flags3 & MF3_ISMONSTER))
killcount += actor->Massacre ();
killcount += KillAll(cls_rep);
}
}

View File

@ -486,6 +486,11 @@ const PClass *PClass::NativeClass() const
return cls;
}
PClass *PClass::GetReplacement() const
{
return ActorInfo->GetReplacement()->Class;
}
// Symbol tables ------------------------------------------------------------
PSymbol::~PSymbol()

View File

@ -174,6 +174,7 @@ struct PClass
static const PClass *FindClass (ENamedName name) { return FindClass (FName (name)); }
static const PClass *FindClass (FName name);
const PClass *FindClassTentative (FName name); // not static!
PClass *GetReplacement() const;
static TArray<PClass *> m_Types;
static TArray<PClass *> m_RuntimeActors;

View File

@ -71,7 +71,7 @@ class ARandomSpawner : public AActor
cls = PClass::FindClass(di->Name);
if (cls != NULL)
{
const PClass *rep = cls->ActorInfo->GetReplacement()->Class;
const PClass *rep = cls->GetReplacement();
if (rep != NULL)
{
cls = rep;

View File

@ -754,8 +754,8 @@ void cht_Give (player_t *player, const char *name, int amount)
// Don't give replaced weapons unless the replacement was done by Dehacked.
if (type != RUNTIME_CLASS(AWeapon) &&
type->IsDescendantOf (RUNTIME_CLASS(AWeapon)) &&
(type->ActorInfo->GetReplacement() == type->ActorInfo ||
type->ActorInfo->GetReplacement()->Class->IsDescendantOf(RUNTIME_CLASS(ADehackedPickup))))
(type->GetReplacement() == type ||
type->GetReplacement()->IsDescendantOf(RUNTIME_CLASS(ADehackedPickup))))
{
// Give the weapon only if it belongs to the current game or

View File

@ -2136,7 +2136,7 @@ do_count:
{
// Again, with decorate replacements
replacemented = true;
PClass *newkind = kind->ActorInfo->GetReplacement()->Class;
PClass *newkind = kind->GetReplacement();
if (newkind != kind)
{
kind = newkind;

View File

@ -3352,7 +3352,7 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
(t1->player->ReadyWeapon->flags2 & MF2_THRUGHOST));
// We need to check the defaults of the replacement here
AActor *puffDefaults = GetDefaultByType(pufftype->ActorInfo->GetReplacement()->Class);
AActor *puffDefaults = GetDefaultByType(pufftype->GetReplacement());
// if the puff uses a non-standard damage type this will override default and melee damage type.
// All other explicitly passed damage types (currenty only MDK) will be preserved.
@ -3819,7 +3819,7 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color
int flags;
AActor *puffDefaults = puffclass == NULL?
NULL : GetDefaultByType (puffclass->ActorInfo->GetReplacement()->Class);
NULL : GetDefaultByType (puffclass->GetReplacement());
if (puffDefaults != NULL && puffDefaults->flags6 & MF6_NOTRIGGER) flags = 0;
else flags = TRACE_PCross|TRACE_Impact;

View File

@ -1011,7 +1011,7 @@ bool AActor::Grind(bool items)
if (i != NULL)
{
i = i->ActorInfo->GetReplacement()->Class;
i = i->GetReplacement();
const AActor *defaults = GetDefaultByType (i);
if (defaults->SpawnState == NULL ||
@ -3461,7 +3461,7 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
}
if (allowreplacement)
type = type->ActorInfo->GetReplacement()->Class;
type = type->GetReplacement();
AActor *actor;
@ -4297,7 +4297,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
{
// Handle decorate replacements explicitly here
// to check for missing frames in the replacement object.
i = i->ActorInfo->GetReplacement()->Class;
i = i->GetReplacement();
const AActor *defaults = GetDefaultByType (i);
if (defaults->SpawnState == NULL ||

View File

@ -65,7 +65,7 @@ bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog,
return false;
// Handle decorate replacements.
kind = kind->ActorInfo->GetReplacement()->Class;
kind = kind->GetReplacement();
if ((GetDefaultByType (kind)->flags3 & MF3_ISMONSTER) &&
((dmflags & DF_NO_MONSTERS) || (level.flags2 & LEVEL2_NOMONSTERS)))
@ -200,7 +200,7 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam
// Handle decorate replacements.
kind = kind->ActorInfo->GetReplacement()->Class;
kind = kind->GetReplacement();
defflags3 = GetDefaultByType (kind)->flags3;
if ((defflags3 & MF3_ISMONSTER) &&