diff --git a/src/info.cpp b/src/info.cpp index 4d3225344..e6bb0da03 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -141,7 +141,7 @@ void FActorInfo::StaticInit () void FActorInfo::StaticSetActorNums () { - memset (SpawnableThings, 0, sizeof(SpawnableThings)); + SpawnableThings.Clear(); DoomEdMap.Empty (); for (unsigned int i = 0; i < PClass::m_RuntimeActors.Size(); ++i) @@ -162,7 +162,7 @@ void FActorInfo::RegisterIDs () if (GameFilter == GAME_Any || (GameFilter & gameinfo.gametype)) { - if (SpawnID != 0) + if (SpawnID > 0) { SpawnableThings[SpawnID] = cls; if (cls != Class) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index ea65f1cca..c87f41816 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -2283,13 +2283,9 @@ int DLevelScript::ThingCount (int type, int stringid, int tid, int tag) int count = 0; bool replacemented = false; - if (type >= MAX_SPAWNABLES) + if (type > 0) { - return 0; - } - else if (type > 0) - { - kind = SpawnableThings[type]; + kind = P_GetSpawnableType(type); if (kind == NULL) return 0; } diff --git a/src/p_local.h b/src/p_local.h index bf7861561..a045f897b 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -155,8 +155,7 @@ void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheigh // // [RH] P_THINGS // -#define MAX_SPAWNABLES (256) -extern const PClass *SpawnableThings[MAX_SPAWNABLES]; +extern TMap SpawnableThings; bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, int newtid); bool P_Thing_Projectile (int tid, AActor *source, int type, const char * type_name, angle_t angle, diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index cc31358a8..79dd105f9 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -76,12 +76,7 @@ void ATeleportFog::PostBeginPlay () void P_SpawnTeleportFog(fixed_t x, fixed_t y, fixed_t z, int spawnid) { - const PClass *fog=NULL; - - if (spawnid > 0 && spawnid < MAX_SPAWNABLES && SpawnableThings[spawnid] != NULL) - { - fog = SpawnableThings[spawnid]; - } + const PClass *fog = P_GetSpawnableType(spawnid); if (fog == NULL) { diff --git a/src/p_things.cpp b/src/p_things.cpp index 74a6f0bcb..289e8835a 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -46,8 +46,8 @@ #include "templates.h" #include "g_level.h" -// List of spawnable things for the Thing_Spawn and Thing_Projectile specials. -const PClass *SpawnableThings[MAX_SPAWNABLES]; +// Set of spawnable things for the Thing_Spawn and Thing_Projectile specials. +TMap SpawnableThings; static FRandom pr_leadtarget ("LeadTarget"); @@ -494,23 +494,43 @@ const PClass *P_GetSpawnableType(int spawnnum) return PClass::FindClass(spawnname); } } - else if (spawnnum < countof(SpawnableThings)) + else { // A numbered arg from a Hexen or UDMF map - return SpawnableThings[spawnnum]; + const PClass **type = SpawnableThings.CheckKey(spawnnum); + if (type != NULL) + { + return *type; + } } return NULL; } -CCMD (dumpspawnables) -{ - int i; +typedef TMap::Pair SpawnablePair; - for (i = 0; i < MAX_SPAWNABLES; i++) - { - if (SpawnableThings[i] != NULL) - { - Printf ("%d %s\n", i, SpawnableThings[i]->TypeName.GetChars()); - } - } +static int STACK_ARGS SpawnableSort(const void *a, const void *b) +{ + return (*((SpawnablePair **)a))->Key - (*((SpawnablePair **)b))->Key; +} + +CCMD (dumpspawnables) +{ + TMapIterator it(SpawnableThings); + SpawnablePair *pair, **allpairs; + int i = 0; + + // Sort into numerical order, since their arrangement in the map can + // be in an unspecified order. + allpairs = new TMap::Pair *[SpawnableThings.CountUsed()]; + while (it.NextPair(pair)) + { + allpairs[i++] = pair; + } + qsort(allpairs, i, sizeof(*allpairs), SpawnableSort); + for (int j = 0; j < i; ++j) + { + pair = allpairs[j]; + Printf ("%d %s\n", pair->Key, pair->Value->TypeName.GetChars()); + } + delete[] allpairs; }