- added a level iterator for operations that need to make changes to all open levels.

Since currently there is only one level, this will obvciously only run once on that level for the time being.

This is mainly used for CCMDs and CVARs which either print some diagnostics or change some user-settable configuration.
This commit is contained in:
Christoph Oelckers 2019-01-28 02:41:29 +01:00
parent 64e9f7e43b
commit d941dea005
23 changed files with 198 additions and 126 deletions

View file

@ -1061,7 +1061,8 @@ CCMD(changesky)
FTextureID newsky = TexMan.GetTextureID(sky1name, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); FTextureID newsky = TexMan.GetTextureID(sky1name, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
if (newsky.Exists()) if (newsky.Exists())
{ {
sky1texture = level.skytexture1 = newsky; // This only alters the primary level's sky setting.
sky1texture = currentUILevel->skytexture1 = newsky;
} }
else else
{ {

View file

@ -746,12 +746,15 @@ void D_Display ()
//E_RenderFrame(); //E_RenderFrame();
// //
for (auto Level : AllLevels())
{
// Check for the presence of dynamic lights at the start of the frame once. // Check for the presence of dynamic lights at the start of the frame once.
if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4)) if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4))
{ {
level.HasDynamicLights = !!level.lights; Level->HasDynamicLights = !!level.lights;
}
else Level->HasDynamicLights = false; // lights are off so effectively we have none.
} }
else level.HasDynamicLights = false; // lights are off so effectively we have none.
viewsec = screen->RenderView(&players[consoleplayer]); viewsec = screen->RenderView(&players[consoleplayer]);
screen->Begin2D(); screen->Begin2D();

View file

@ -489,6 +489,8 @@ void DObject::StaticPointerSubstitution (AActor *old, AActor *notOld)
size_t changed = 0; size_t changed = 0;
int i; int i;
if (old == nullptr) return;
// Go through all objects. // Go through all objects.
i = 0;DObject *last=0; i = 0;DObject *last=0;
for (probe = GC::Root; probe != NULL; probe = probe->ObjNext) for (probe = GC::Root; probe != NULL; probe = probe->ObjNext)
@ -515,8 +517,8 @@ void DObject::StaticPointerSubstitution (AActor *old, AActor *notOld)
} }
} }
// Go through sectors. // Go through sectors. Only the level this actor belongs to is relevant.
for (auto &sec : level.sectors) for (auto &sec : old->Level->sectors)
{ {
if (sec.SoundTarget == old) sec.SoundTarget = notOld; if (sec.SoundTarget == old) sec.SoundTarget = notOld;
} }

View file

@ -306,7 +306,8 @@ static void MarkRoot()
DThinker::MarkRoots(); DThinker::MarkRoots();
Mark(E_FirstEventHandler); Mark(E_FirstEventHandler);
Mark(E_LastEventHandler); Mark(E_LastEventHandler);
level.Mark(); for (auto Level : AllLevels())
Level->Mark();
// Mark players. // Mark players.
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)

View file

@ -50,14 +50,21 @@ CVAR (Bool, alwaysapplydmflags, false, CVAR_SERVERINFO);
CUSTOM_CVAR (Float, teamdamage, 0.f, CVAR_SERVERINFO) CUSTOM_CVAR (Float, teamdamage, 0.f, CVAR_SERVERINFO)
{ {
level.teamdamage = self; for (auto Level : AllLevels())
{
Level->teamdamage = self;
}
} }
CUSTOM_CVAR (String, language, "auto", CVAR_ARCHIVE) CUSTOM_CVAR (String, language, "auto", CVAR_ARCHIVE)
{ {
SetLanguageIDs (); SetLanguageIDs ();
GStrings.LoadStrings (false); GStrings.LoadStrings (false);
if (level.info != NULL) level.LevelName = level.info->LookupLevelName(); for (auto Level : AllLevels())
{
// does this even make sense on secondary levels...?
if (Level->info != nullptr) Level->LevelName = Level->info->LookupLevelName();
}
} }
// [RH] Network arbitrator // [RH] Network arbitrator

View file

@ -769,7 +769,7 @@ void G_AddViewPitch (int look, bool mouse)
return; return;
} }
look = LookAdjust(look); look = LookAdjust(look);
if (!level.IsFreelookAllowed()) if (!currentUILevel->IsFreelookAllowed())
{ {
LocalViewPitch = 0; LocalViewPitch = 0;
} }

View file

@ -109,17 +109,26 @@ void G_VerifySkill();
CUSTOM_CVAR(Bool, gl_brightfog, false, CVAR_ARCHIVE | CVAR_NOINITCALL) CUSTOM_CVAR(Bool, gl_brightfog, false, CVAR_ARCHIVE | CVAR_NOINITCALL)
{ {
if (level.info == nullptr || level.info->brightfog == -1) level.brightfog = self; for (auto Level : AllLevels())
{
if (Level->info == nullptr || Level->info->brightfog == -1) Level->brightfog = self;
}
} }
CUSTOM_CVAR(Bool, gl_lightadditivesurfaces, false, CVAR_ARCHIVE | CVAR_NOINITCALL) CUSTOM_CVAR(Bool, gl_lightadditivesurfaces, false, CVAR_ARCHIVE | CVAR_NOINITCALL)
{ {
if (level.info == nullptr || level.info->lightadditivesurfaces == -1) level.lightadditivesurfaces = self; for (auto Level : AllLevels())
{
if (Level->info == nullptr || Level->info->lightadditivesurfaces == -1) Level->lightadditivesurfaces = self;
}
} }
CUSTOM_CVAR(Bool, gl_notexturefill, false, CVAR_NOINITCALL) CUSTOM_CVAR(Bool, gl_notexturefill, false, CVAR_NOINITCALL)
{ {
if (level.info == nullptr || level.info->notexturefill == -1) level.notexturefill = self; for (auto Level : AllLevels())
{
if (Level->info == nullptr || Level->info->notexturefill == -1) Level->notexturefill = self;
}
} }
CUSTOM_CVAR(Int, gl_lightmode, 3, CVAR_ARCHIVE | CVAR_NOINITCALL) CUSTOM_CVAR(Int, gl_lightmode, 3, CVAR_ARCHIVE | CVAR_NOINITCALL)
@ -129,7 +138,10 @@ CUSTOM_CVAR(Int, gl_lightmode, 3, CVAR_ARCHIVE | CVAR_NOINITCALL)
else if (newself > 4) newself = 8; else if (newself > 4) newself = 8;
else if (newself < 0) newself = 0; else if (newself < 0) newself = 0;
if (self != newself) self = newself; if (self != newself) self = newself;
else if ((level.info == nullptr || level.info->lightmode == ELightMode::NotSet)) level.lightMode = (ELightMode)*self; else for (auto Level : AllLevels())
{
if ((level.info == nullptr || level.info->lightmode == ELightMode::NotSet)) level.lightMode = (ELightMode)*self;
}
} }
@ -202,7 +214,7 @@ CCMD (map)
if (argv.argc() > 1) if (argv.argc() > 1)
{ {
const char *mapname = argv[1]; const char *mapname = argv[1];
if (!strcmp(mapname, "*")) mapname = level.MapName.GetChars(); if (!strcmp(mapname, "*")) mapname = currentUILevel->MapName.GetChars();
try try
{ {
@ -252,7 +264,7 @@ UNSAFE_CCMD(recordmap)
if (argv.argc() > 2) if (argv.argc() > 2)
{ {
const char *mapname = argv[2]; const char *mapname = argv[2];
if (!strcmp(mapname, "*")) mapname = level.MapName.GetChars(); if (!strcmp(mapname, "*")) mapname = currentUILevel->MapName.GetChars();
try try
{ {
@ -2180,7 +2192,8 @@ CCMD(skyfog)
{ {
if (argv.argc()>1) if (argv.argc()>1)
{ {
level.skyfog = MAX(0, (int)strtoull(argv[1], NULL, 0)); // Do this only on the primary level.
currentUILevel->skyfog = MAX(0, (int)strtoull(argv[1], NULL, 0));
} }
} }

View file

@ -635,3 +635,10 @@ inline AActor *P_SpawnPlayer(FPlayerStart *mthing, int playernum, int flags = 0)
{ {
return level.SpawnPlayer(mthing, playernum, flags); return level.SpawnPlayer(mthing, playernum, flags);
} }
// This must later be extended to return an array with all levels.
// It is meant for code that needs to iterate over all levels to make some global changes, e.g. configuation CCMDs.
inline TArrayView<FLevelLocals *> AllLevels()
{
return TArrayView<FLevelLocals *>(&currentUILevel, 1);
}

View file

@ -92,7 +92,9 @@ CUSTOM_CVAR(Int, sv_corpsequeuesize, 64, CVAR_ARCHIVE|CVAR_SERVERINFO)
{ {
if (self > 0) if (self > 0)
{ {
auto &corpsequeue = level.CorpseQueue; for (auto Level : AllLevels())
{
auto &corpsequeue = Level->CorpseQueue;
while (corpsequeue.Size() > (unsigned)self) while (corpsequeue.Size() > (unsigned)self)
{ {
AActor *corpse = corpsequeue[0]; AActor *corpse = corpsequeue[0];
@ -100,6 +102,7 @@ CUSTOM_CVAR(Int, sv_corpsequeuesize, 64, CVAR_ARCHIVE|CVAR_SERVERINFO)
corpsequeue.Delete(0); corpsequeue.Delete(0);
} }
} }
}
} }

View file

@ -538,9 +538,9 @@ CUSTOM_CVAR (Int, cl_maxdecals, 1024, CVAR_ARCHIVE)
{ {
self = 0; self = 0;
} }
else else for (auto Level : AllLevels())
{ {
while (level.ImpactDecalCount > self) while (Level->ImpactDecalCount > self)
{ {
DThinker *thinker = DThinker::FirstThinker(STAT_AUTODECAL); DThinker *thinker = DThinker::FirstThinker(STAT_AUTODECAL);
if (thinker != NULL) if (thinker != NULL)
@ -553,13 +553,13 @@ CUSTOM_CVAR (Int, cl_maxdecals, 1024, CVAR_ARCHIVE)
void DImpactDecal::CheckMax () void DImpactDecal::CheckMax ()
{ {
if (++level.ImpactDecalCount >= cl_maxdecals) if (++Level->ImpactDecalCount >= cl_maxdecals)
{ {
DThinker *thinker = DThinker::FirstThinker (STAT_AUTODECAL); DThinker *thinker = DThinker::FirstThinker (STAT_AUTODECAL);
if (thinker != NULL) if (thinker != NULL)
{ {
thinker->Destroy(); thinker->Destroy();
level.ImpactDecalCount--; Level->ImpactDecalCount--;
} }
} }
} }

View file

@ -881,7 +881,10 @@ CCMD(listlights)
int i=0, shadowcount = 0; int i=0, shadowcount = 0;
FDynamicLight * dl; FDynamicLight * dl;
for (dl = level.lights; dl; dl = dl->next) for (auto Level : AllLevels())
{
Printf("Lights for %s\n", Level->MapName.GetChars());
for (dl = Level->lights; dl; dl = dl->next)
{ {
walls=0; walls=0;
sectors=0; sectors=0;
@ -923,5 +926,6 @@ CCMD(listlights)
} }
Printf("%i dynamic lights, %d shadowmapped, %d walls, %d sectors\n\n\n", i, shadowcount, allwalls, allsectors); Printf("%i dynamic lights, %d shadowmapped, %d walls, %d sectors\n\n\n", i, shadowcount, allwalls, allsectors);
}
} }

View file

@ -368,7 +368,7 @@ static void HU_DrawTimeRemaining (int y)
if (deathmatch && timelimit && gamestate == GS_LEVEL) if (deathmatch && timelimit && gamestate == GS_LEVEL)
{ {
char str[80]; char str[80];
int timeleft = (int)(timelimit * TICRATE * 60) - level.maptime; int timeleft = (int)(timelimit * TICRATE * 60) - currentUILevel->maptime;
int hours, minutes, seconds; int hours, minutes, seconds;
if (timeleft < 0) if (timeleft < 0)

View file

@ -83,9 +83,9 @@ CUSTOM_CVAR(Int, gl_shadowmap_quality, 512, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CUSTOM_CVAR (Bool, gl_light_shadowmap, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CUSTOM_CVAR (Bool, gl_light_shadowmap, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{ {
if (!self) if (!self) for (auto Level : AllLevels())
{ {
auto light = level.lights; auto light = Level->lights;
while (light) while (light)
{ {
light->mShadowmapIndex = 1024; light->mShadowmapIndex = 1024;

View file

@ -287,7 +287,10 @@ void cht_DoCheat (player_t *player, int cheat)
if (i == 4) if (i == 4)
{ {
level.flags2 ^= LEVEL2_ALLMAP; for (auto Level : AllLevels())
{
Level->flags2 ^= LEVEL2_ALLMAP;
}
} }
else if (player->mo != NULL && player->health >= 0) else if (player->mo != NULL && player->health >= 0)
{ {

View file

@ -867,13 +867,15 @@ CCMD (dump3df)
{ {
if (argv.argc() > 1) if (argv.argc() > 1)
{ {
// Print 3D floor info for a single sector.
// This only checks the primary level.
int sec = (int)strtoll(argv[1], NULL, 10); int sec = (int)strtoll(argv[1], NULL, 10);
if ((unsigned)sec >= level.sectors.Size()) if ((unsigned)sec >= currentUILevel->sectors.Size())
{ {
Printf("Sector %d does not exist.\n", sec); Printf("Sector %d does not exist.\n", sec);
return; return;
} }
sector_t *sector = &level.sectors[sec]; sector_t *sector = &currentUILevel->sectors[sec];
TArray<F3DFloor*> & ffloors=sector->e->XFloor.ffloors; TArray<F3DFloor*> & ffloors=sector->e->XFloor.ffloors;
for (unsigned int i = 0; i < ffloors.Size(); i++) for (unsigned int i = 0; i < ffloors.Size(); i++)

View file

@ -147,7 +147,10 @@ FRandom pr_spawnmobj ("SpawnActor");
CUSTOM_CVAR (Float, sv_gravity, 800.f, CVAR_SERVERINFO|CVAR_NOSAVE) CUSTOM_CVAR (Float, sv_gravity, 800.f, CVAR_SERVERINFO|CVAR_NOSAVE)
{ {
level.gravity = self; for (auto Level : AllLevels())
{
Level->gravity = self;
}
} }
CVAR (Bool, cl_missiledecals, true, CVAR_ARCHIVE) CVAR (Bool, cl_missiledecals, true, CVAR_ARCHIVE)
@ -3021,9 +3024,11 @@ int FLevelLocals::FindUniqueTID(int start_tid, int limit)
CCMD(utid) CCMD(utid)
{ {
Printf("%d\n", for (auto Level : AllLevels())
level.FindUniqueTID(argv.argc() > 1 ? atoi(argv[1]) : 0, {
Printf("%s, %d\n", Level->MapName.GetChars(), Level->FindUniqueTID(argv.argc() > 1 ? atoi(argv[1]) : 0,
(argv.argc() > 2 && atoi(argv[2]) >= 0) ? atoi(argv[2]) : 0)); (argv.argc() > 2 && atoi(argv[2]) >= 0) ? atoi(argv[2]) : 0));
}
} }
//========================================================================== //==========================================================================

View file

@ -466,7 +466,7 @@ FBlockNode *FBlockNode::Create(AActor *who, int x, int y, int group)
{ {
block = (FBlockNode *)secnodearena.Alloc(sizeof(FBlockNode)); block = (FBlockNode *)secnodearena.Alloc(sizeof(FBlockNode));
} }
block->BlockIndex = x + y * level.blockmap.bmapwidth; block->BlockIndex = x + y * who->Level->blockmap.bmapwidth;
block->Me = who; block->Me = who;
block->NextActor = nullptr; block->NextActor = nullptr;
block->PrevActor = nullptr; block->PrevActor = nullptr;

View file

@ -594,7 +594,10 @@ static void P_Shutdown ()
CCMD(dumpgeometry) CCMD(dumpgeometry)
{ {
for (auto &sector : level.sectors) for (auto Level : AllLevels())
{
Printf("Geometry for %s\n", Level->MapName.GetChars());
for (auto &sector : Level->sectors)
{ {
Printf(PRINT_LOG, "Sector %d\n", sector.sectornum); Printf(PRINT_LOG, "Sector %d\n", sector.sectornum);
for (int j = 0; j<sector.subsectorcount; j++) for (int j = 0; j<sector.subsectorcount; j++)
@ -630,6 +633,7 @@ CCMD(dumpgeometry)
} }
} }
} }
}
} }
//========================================================================== //==========================================================================
@ -640,9 +644,12 @@ CCMD(dumpgeometry)
CCMD(listmapsections) CCMD(listmapsections)
{ {
for (auto Level : AllLevels())
{
Printf("Map sections for %s:\n", Level->MapName.GetChars());
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
{ {
for (auto &sub : level.subsectors) for (auto &sub : Level->subsectors)
{ {
if (sub.mapsection == i) if (sub.mapsection == i)
{ {
@ -651,6 +658,7 @@ CCMD(listmapsections)
} }
} }
} }
}
} }
//========================================================================== //==========================================================================
@ -661,9 +669,8 @@ CCMD(listmapsections)
CUSTOM_CVAR(Bool, forcewater, false, CVAR_ARCHIVE | CVAR_SERVERINFO) CUSTOM_CVAR(Bool, forcewater, false, CVAR_ARCHIVE | CVAR_SERVERINFO)
{ {
if (gamestate == GS_LEVEL) if (gamestate == GS_LEVEL) for (auto Level : AllLevels())
{ {
auto Level = currentUILevel;
for (auto &sec : Level->sectors) for (auto &sec : Level->sectors)
{ {
sector_t *hsec = sec.GetHeightSec(); sector_t *hsec = sec.GetHeightSec();

View file

@ -316,7 +316,10 @@ void FTagManager::DumpTags()
CCMD(dumptags) CCMD(dumptags)
{ {
level.tagManager.DumpTags(); for (auto Level : AllLevels())
{
Level->tagManager.DumpTags();
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -369,7 +372,7 @@ int FSectorTagIterator::NextCompat(bool compat, int start)
for (unsigned i = start + 1; i < tagManager.Level->sectors.Size(); i++) for (unsigned i = start + 1; i < tagManager.Level->sectors.Size(); i++)
{ {
if (level.SectorHasTag(i, searchtag)) return i; if (tagManager.Level->SectorHasTag(i, searchtag)) return i;
} }
return -1; return -1;
} }

View file

@ -1208,15 +1208,19 @@ bool FLevelLocals::CollectConnectedGroups(int startgroup, const DVector3 &positi
CCMD(dumplinktable) CCMD(dumplinktable)
{ {
for (int x = 1; x < level.Displacements.size; x++) for (auto Level : AllLevels())
{ {
for (int y = 1; y < level.Displacements.size; y++) Printf("Portal displacements for %s:\n", Level->MapName.GetChars());
for (int x = 1; x < Level->Displacements.size; x++)
{ {
FDisplacement &disp = level.Displacements(x, y); for (int y = 1; y < Level->Displacements.size; y++)
{
FDisplacement &disp = Level->Displacements(x, y);
Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, int(disp.pos.X), int(disp.pos.Y)); Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, int(disp.pos.X), int(disp.pos.Y));
} }
Printf("\n"); Printf("\n");
} }
}
} }

View file

@ -813,9 +813,10 @@ public:
// //
//============================================================================= //=============================================================================
void PrintSections(FSectionContainer &container) void PrintSections(FLevelLocals *Level)
{ {
auto Level = &level; FSectionContainer &container = Level->sections;
Printf("Sections for %s\n", Level->MapName.GetChars());
for (unsigned i = 0; i < container.allSections.Size(); i++) for (unsigned i = 0; i < container.allSections.Size(); i++)
{ {
auto &section = container.allSections[i]; auto &section = container.allSections[i];
@ -852,7 +853,7 @@ void PrintSections(FSectionContainer &container)
} }
} }
} }
Printf(PRINT_LOG, "%d sectors, %d subsectors, %d sections\n", Level->sectors.Size(), Level->subsectors.Size(), container.allSections.Size()); Printf(PRINT_LOG, "%d sectors, %d subsectors, %d sections\n\n", Level->sectors.Size(), Level->subsectors.Size(), container.allSections.Size());
} }
@ -876,7 +877,10 @@ void CreateSections(FLevelLocals *Level)
CCMD(printsections) CCMD(printsections)
{ {
PrintSections(level.sections); for (auto Level : AllLevels())
{
PrintSections(Level);
}
} }

View file

@ -1029,7 +1029,7 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor
// However, to set up a projection matrix this needs to be adjusted. // However, to set up a projection matrix this needs to be adjusted.
double radPitch = viewpoint.Angles.Pitch.Normalized180().Radians(); double radPitch = viewpoint.Angles.Pitch.Normalized180().Radians();
double angx = cos(radPitch); double angx = cos(radPitch);
double angy = sin(radPitch) * level.info->pixelstretch; double angy = sin(radPitch) * actor->Level->info->pixelstretch;
double alen = sqrt(angx*angx + angy*angy); double alen = sqrt(angx*angx + angy*angy);
viewpoint.HWAngles.Pitch = RAD2DEG((float)asin(angy / alen)); viewpoint.HWAngles.Pitch = RAD2DEG((float)asin(angy / alen));

View file

@ -524,7 +524,10 @@ CCMD (testfade)
{ {
color = V_GetColorFromString (NULL, argv[1]); color = V_GetColorFromString (NULL, argv[1]);
} }
level.fadeto = color; for (auto Level : AllLevels())
{
Level->fadeto = color;
}
NormalLight.ChangeFade (color); NormalLight.ChangeFade (color);
} }
} }