- 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) if (bloodcls != NULL)
{ {
bloodcls = bloodcls->ActorInfo->GetReplacement()->Class; bloodcls = bloodcls->GetReplacement();
} }
return bloodcls; 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 // [RH] Execute a special "ticcmd". The type byte should
// have already been read, and the stream is positioned // have already been read, and the stream is positioned
// at the beginning of the command's actual data. // 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: case DEM_KILLCLASSCHEAT:
{ {
AActor *actor;
TThinkerIterator<AActor> iterator;
char *classname = ReadString (stream); char *classname = ReadString (stream);
int killcount = 0; 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 += KillAll(cls_rep);
killcount += actor->Massacre ();
} }
} }

View file

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

View file

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

View file

@ -71,7 +71,7 @@ class ARandomSpawner : public AActor
cls = PClass::FindClass(di->Name); cls = PClass::FindClass(di->Name);
if (cls != NULL) if (cls != NULL)
{ {
const PClass *rep = cls->ActorInfo->GetReplacement()->Class; const PClass *rep = cls->GetReplacement();
if (rep != NULL) if (rep != NULL)
{ {
cls = rep; 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. // Don't give replaced weapons unless the replacement was done by Dehacked.
if (type != RUNTIME_CLASS(AWeapon) && if (type != RUNTIME_CLASS(AWeapon) &&
type->IsDescendantOf (RUNTIME_CLASS(AWeapon)) && type->IsDescendantOf (RUNTIME_CLASS(AWeapon)) &&
(type->ActorInfo->GetReplacement() == type->ActorInfo || (type->GetReplacement() == type ||
type->ActorInfo->GetReplacement()->Class->IsDescendantOf(RUNTIME_CLASS(ADehackedPickup)))) type->GetReplacement()->IsDescendantOf(RUNTIME_CLASS(ADehackedPickup))))
{ {
// Give the weapon only if it belongs to the current game or // Give the weapon only if it belongs to the current game or

View file

@ -2136,7 +2136,7 @@ do_count:
{ {
// Again, with decorate replacements // Again, with decorate replacements
replacemented = true; replacemented = true;
PClass *newkind = kind->ActorInfo->GetReplacement()->Class; PClass *newkind = kind->GetReplacement();
if (newkind != kind) if (newkind != kind)
{ {
kind = newkind; 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)); (t1->player->ReadyWeapon->flags2 & MF2_THRUGHOST));
// We need to check the defaults of the replacement here // 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. // 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. // 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; int flags;
AActor *puffDefaults = puffclass == NULL? AActor *puffDefaults = puffclass == NULL?
NULL : GetDefaultByType (puffclass->ActorInfo->GetReplacement()->Class); NULL : GetDefaultByType (puffclass->GetReplacement());
if (puffDefaults != NULL && puffDefaults->flags6 & MF6_NOTRIGGER) flags = 0; if (puffDefaults != NULL && puffDefaults->flags6 & MF6_NOTRIGGER) flags = 0;
else flags = TRACE_PCross|TRACE_Impact; else flags = TRACE_PCross|TRACE_Impact;

View file

@ -1011,7 +1011,7 @@ bool AActor::Grind(bool items)
if (i != NULL) if (i != NULL)
{ {
i = i->ActorInfo->GetReplacement()->Class; i = i->GetReplacement();
const AActor *defaults = GetDefaultByType (i); const AActor *defaults = GetDefaultByType (i);
if (defaults->SpawnState == NULL || if (defaults->SpawnState == NULL ||
@ -3461,7 +3461,7 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
} }
if (allowreplacement) if (allowreplacement)
type = type->ActorInfo->GetReplacement()->Class; type = type->GetReplacement();
AActor *actor; AActor *actor;
@ -4297,7 +4297,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
{ {
// Handle decorate replacements explicitly here // Handle decorate replacements explicitly here
// to check for missing frames in the replacement object. // to check for missing frames in the replacement object.
i = i->ActorInfo->GetReplacement()->Class; i = i->GetReplacement();
const AActor *defaults = GetDefaultByType (i); const AActor *defaults = GetDefaultByType (i);
if (defaults->SpawnState == NULL || 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; return false;
// Handle decorate replacements. // Handle decorate replacements.
kind = kind->ActorInfo->GetReplacement()->Class; kind = kind->GetReplacement();
if ((GetDefaultByType (kind)->flags3 & MF3_ISMONSTER) && if ((GetDefaultByType (kind)->flags3 & MF3_ISMONSTER) &&
((dmflags & DF_NO_MONSTERS) || (level.flags2 & LEVEL2_NOMONSTERS))) ((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. // Handle decorate replacements.
kind = kind->ActorInfo->GetReplacement()->Class; kind = kind->GetReplacement();
defflags3 = GetDefaultByType (kind)->flags3; defflags3 = GetDefaultByType (kind)->flags3;
if ((defflags3 & MF3_ISMONSTER) && if ((defflags3 & MF3_ISMONSTER) &&