- made the automap an object.

This simplifies handling a lot because it allows to make the level the owner of its map.
This commit is contained in:
Christoph Oelckers 2019-01-26 15:21:20 +01:00
commit 05830455e7
14 changed files with 839 additions and 791 deletions

View file

@ -71,6 +71,7 @@
#include "a_specialspot.h"
#include "maploader/maploader.h"
#include "p_acs.h"
#include "am_map.h"
#include "fragglescript/t_script.h"
void P_ClearUDMFKeys();
@ -260,6 +261,8 @@ void FLevelLocals::ClearPortals()
void FLevelLocals::ClearLevelData()
{
ClearAllSubsectorLinks(); // can't be done as part of the polyobj deletion process.
total_monsters = total_items = total_secrets =
killed_monsters = found_items = found_secrets =
wminfo.maxfrags = 0;
@ -348,7 +351,6 @@ void P_FreeLevelData ()
P_ClearUDMFKeys();
interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh level.
level.ClearAllSubsectorLinks(); // can't be done as part of the polyobj deletion process.
SN_StopAllSequences ();
DThinker::DestroyAllThinkers ();
@ -363,20 +365,20 @@ void P_FreeLevelData ()
//
//===========================================================================
void P_SetupLevel(const char *lumpname, int position, bool newGame)
void P_SetupLevel(FLevelLocals *Level, int position, bool newGame)
{
int i;
level.ShaderStartTime = I_msTimeFS(); // indicate to the shader system that the level just started
Level->ShaderStartTime = I_msTimeFS(); // indicate to the shader system that the level just started
// This is motivated as follows:
level.maptype = MAPTYPE_UNKNOWN;
Level->maptype = MAPTYPE_UNKNOWN;
wminfo.partime = 180;
if (!savegamerestore)
{
level.SetMusicVolume(level.MusicVolume);
Level->SetMusicVolume(Level->MusicVolume);
for (i = 0; i < MAXPLAYERS; ++i)
{
players[i].killcount = players[i].secretcount
@ -411,10 +413,10 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
// Free all level data from the previous map
P_FreeLevelData();
MapData *map = P_OpenMapData(lumpname, true);
MapData *map = P_OpenMapData(Level->MapName, true);
if (map == nullptr)
{
I_Error("Unable to open map '%s'\n", lumpname);
I_Error("Unable to open map '%s'\n", Level->MapName.GetChars());
}
// [ZZ] init per-map static handlers. we need to call this before everything is set up because otherwise scripts don't receive PlayerEntered event
@ -422,17 +424,17 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
E_InitStaticHandlers(true);
// generate a checksum for the level, to be included and checked with savegames.
map->GetChecksum(level.md5);
map->GetChecksum(Level->md5);
// find map num
level.lumpnum = map->lumpnum;
Level->lumpnum = map->lumpnum;
if (newGame)
{
E_NewGame(EventHandlerType::PerMap);
}
MapLoader loader(&level);
loader.LoadLevel(map, lumpname, position);
MapLoader loader(Level);
loader.LoadLevel(map, Level->MapName.GetChars(), position);
delete map;
// if deathmatch, randomly spawn the active players
@ -448,7 +450,7 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
}
}
// the same, but for random single/coop player starts
else if (level.flags2 & LEVEL2_RANDOMPLAYERSTARTS)
else if (Level->flags2 & LEVEL2_RANDOMPLAYERSTARTS)
{
for (i = 0; i < MAXPLAYERS; ++i)
{
@ -456,14 +458,14 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
{
players[i].mo = nullptr;
FPlayerStart *mthing = G_PickPlayerStart(i);
P_SpawnPlayer(mthing, i, (level.flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0);
P_SpawnPlayer(mthing, i, (Level->flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0);
}
}
}
// [SP] move unfriendly players around
// horribly hacky - yes, this needs rewritten.
if (level.deathmatchstarts.Size() > 0)
if (Level->deathmatchstarts.Size() > 0)
{
for (i = 0; i < MAXPLAYERS; ++i)
{
@ -522,7 +524,7 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
// This check was previously done at run time each time the heightsec was checked.
// However, since 3D floors are static data, we can easily precalculate this and store it in the sector's flags for quick access.
for (auto &s : level.sectors)
for (auto &s : Level->sectors)
{
if (s.heightsec != nullptr)
{
@ -537,17 +539,18 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
}
}
P_ResetSightCounters(true);
// Create a backup of the map data so the savegame code can toss out all fields that haven't changed in order to reduce processing time and file size.
// Note that we want binary identity here, so assignment is not sufficient because it won't initialize any padding bytes.
// Note that none of these structures may contain non POD fields anyway.
level.loadsectors.Resize(level.sectors.Size());
memcpy(&level.loadsectors[0], &level.sectors[0], level.sectors.Size() * sizeof(level.sectors[0]));
level.loadlines.Resize(level.lines.Size());
memcpy(&level.loadlines[0], &level.lines[0], level.lines.Size() * sizeof(level.lines[0]));
level.loadsides.Resize(level.sides.Size());
memcpy(&level.loadsides[0], &level.sides[0], level.sides.Size() * sizeof(level.sides[0]));
Level->loadsectors.Resize(Level->sectors.Size());
memcpy(&Level->loadsectors[0], &Level->sectors[0], Level->sectors.Size() * sizeof(Level->sectors[0]));
Level->loadlines.Resize(Level->lines.Size());
memcpy(&Level->loadlines[0], &Level->lines[0], Level->lines.Size() * sizeof(Level->lines[0]));
Level->loadsides.Resize(Level->sides.Size());
memcpy(&Level->loadsides[0], &Level->sides[0], Level->sides.Size() * sizeof(Level->sides[0]));
Level->automap = AM_Create(Level);
Level->automap->LevelInit();
}
//