mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-18 10:11:11 +00:00
- the next batch of 'level' removals.
Untested, may not work!
This commit is contained in:
parent
80427b72e9
commit
72d09c0338
20 changed files with 181 additions and 149 deletions
|
@ -644,22 +644,26 @@ CUSTOM_CVAR (Int, am_showalllines, -1, 0) // This is a cheat so don't save it.
|
|||
{
|
||||
int flagged = 0;
|
||||
int total = 0;
|
||||
if (self > 0 && level.lines.Size() > 0)
|
||||
{
|
||||
for(auto &line : level.lines)
|
||||
|
||||
ForAllLevels([&](FLevelLocals *Level) {
|
||||
for(auto &line : Level->lines)
|
||||
{
|
||||
// disregard intra-sector lines
|
||||
if (line.frontsector == line.backsector) continue;
|
||||
|
||||
if (line.frontsector == line.backsector) continue;
|
||||
|
||||
// disregard control sectors for deep water
|
||||
if (line.frontsector->e->FakeFloor.Sectors.Size() > 0) continue;
|
||||
|
||||
if (line.frontsector->e->FakeFloor.Sectors.Size() > 0) continue;
|
||||
|
||||
// disregard control sectors for 3D-floors
|
||||
if (line.frontsector->e->XFloor.attached.Size() > 0) continue;
|
||||
|
||||
if (line.frontsector->e->XFloor.attached.Size() > 0) continue;
|
||||
|
||||
total++;
|
||||
if (line.flags & ML_DONTDRAW) flagged++;
|
||||
}
|
||||
});
|
||||
|
||||
if (self > 0 && total > 0)
|
||||
{
|
||||
am_showallenabled = (flagged * 100 / total >= self);
|
||||
}
|
||||
else if (self == 0)
|
||||
|
@ -1065,12 +1069,12 @@ bool AM_addMark ()
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
static void AM_findMinMaxBoundaries ()
|
||||
static void AM_findMinMaxBoundaries (FLevelLocals *Level)
|
||||
{
|
||||
min_x = min_y = FLT_MAX;
|
||||
max_x = max_y = FIXED_MIN;
|
||||
|
||||
for (auto &vert : level.vertexes)
|
||||
for (auto &vert : Level->vertexes)
|
||||
{
|
||||
if (vert.fX() < min_x)
|
||||
min_x = vert.fX();
|
||||
|
@ -1363,20 +1367,20 @@ bool AM_clearMarks ()
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
void AM_LevelInit ()
|
||||
void AM_LevelInit (FLevelLocals *Level)
|
||||
{
|
||||
if (level.info->MapBackground.Len() == 0)
|
||||
if (Level->info->MapBackground.Len() == 0)
|
||||
{
|
||||
mapback = TexMan.CheckForTexture("AUTOPAGE", ETextureType::MiscPatch);
|
||||
}
|
||||
else
|
||||
{
|
||||
mapback = TexMan.CheckForTexture(level.info->MapBackground, ETextureType::MiscPatch);
|
||||
mapback = TexMan.CheckForTexture(Level->info->MapBackground, ETextureType::MiscPatch);
|
||||
}
|
||||
|
||||
AM_clearMarks();
|
||||
|
||||
AM_findMinMaxBoundaries();
|
||||
AM_findMinMaxBoundaries(Level);
|
||||
scale_mtof = min_scale_mtof / 0.7;
|
||||
if (scale_mtof > max_scale_mtof)
|
||||
scale_mtof = min_scale_mtof;
|
||||
|
@ -1867,15 +1871,15 @@ inline void AM_drawMline (mline_t *ml, int colorindex)
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
void AM_drawGrid (int color)
|
||||
void AM_drawGrid (FLevelLocals *Level, int color)
|
||||
{
|
||||
double x, y;
|
||||
double start, end;
|
||||
mline_t ml;
|
||||
double minlen, extx, exty;
|
||||
double minx, miny;
|
||||
auto bmaporgx = level.blockmap.bmaporgx;
|
||||
auto bmaporgy = level.blockmap.bmaporgy;
|
||||
auto bmaporgx = Level->blockmap.bmaporgx;
|
||||
auto bmaporgy = Level->blockmap.bmaporgy;
|
||||
|
||||
// [RH] Calculate a minimum for how long the grid lines should be so that
|
||||
// they cover the screen at any rotation.
|
||||
|
@ -2052,7 +2056,7 @@ sector_t * AM_FakeFlat(AActor *viewer, sector_t * sec, sector_t * dest)
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
void AM_drawSubsectors()
|
||||
void AM_drawSubsectors(FLevelLocals *Level)
|
||||
{
|
||||
static TArray<FVector2> points;
|
||||
std::vector<uint32_t> indices;
|
||||
|
@ -2066,7 +2070,7 @@ void AM_drawSubsectors()
|
|||
PalEntry flatcolor;
|
||||
mpoint_t originpt;
|
||||
|
||||
auto &subsectors = level.subsectors;
|
||||
auto &subsectors = Level->subsectors;
|
||||
for (unsigned i = 0; i < subsectors.Size(); ++i)
|
||||
{
|
||||
auto sub = &subsectors[i];
|
||||
|
@ -2206,7 +2210,7 @@ void AM_drawSubsectors()
|
|||
colormap.Desaturation = 255 - (255 - colormap.Desaturation) / 4;
|
||||
}
|
||||
// make table based fog visible on the automap as well.
|
||||
if (level.flags & LEVEL_HASFADETABLE)
|
||||
if (Level->flags & LEVEL_HASFADETABLE)
|
||||
{
|
||||
colormap.FadeColor = PalEntry(0, 128, 128, 128);
|
||||
}
|
||||
|
@ -2243,7 +2247,7 @@ void AM_drawSubsectors()
|
|||
colormap,
|
||||
flatcolor,
|
||||
floorlight,
|
||||
level.lightMode,
|
||||
Level->lightMode,
|
||||
f_y + f_h,
|
||||
indices.data(), indices.size());
|
||||
}
|
||||
|
@ -2303,7 +2307,7 @@ void AM_drawSeg(seg_t *seg, const AMColor &color)
|
|||
AM_drawMline(&l, color);
|
||||
}
|
||||
|
||||
void AM_drawPolySeg(FPolySeg *seg, const AMColor &color)
|
||||
void AM_drawPolySeg(FLevelLocals *Level, FPolySeg *seg, const AMColor &color)
|
||||
{
|
||||
mline_t l;
|
||||
l.a.x = seg->v1.pos.X;
|
||||
|
@ -2319,22 +2323,22 @@ void AM_drawPolySeg(FPolySeg *seg, const AMColor &color)
|
|||
AM_drawMline(&l, color);
|
||||
}
|
||||
|
||||
void AM_showSS()
|
||||
void AM_showSS(FLevelLocals *Level)
|
||||
{
|
||||
if (am_showsubsector >= 0 && (unsigned)am_showsubsector < level.subsectors.Size())
|
||||
if (am_showsubsector >= 0 && (unsigned)am_showsubsector < Level->subsectors.Size())
|
||||
{
|
||||
AMColor yellow;
|
||||
yellow.FromRGB(255,255,0);
|
||||
AMColor red;
|
||||
red.FromRGB(255,0,0);
|
||||
|
||||
subsector_t *sub = &level.subsectors[am_showsubsector];
|
||||
subsector_t *sub = &Level->subsectors[am_showsubsector];
|
||||
for (unsigned int i = 0; i < sub->numlines; i++)
|
||||
{
|
||||
AM_drawSeg(sub->firstline + i, yellow);
|
||||
}
|
||||
|
||||
for (auto &poly : level.Polyobjects)
|
||||
for (auto &poly : Level->Polyobjects)
|
||||
{
|
||||
FPolyNode *pnode = poly.subsectorlinks;
|
||||
|
||||
|
@ -2344,7 +2348,7 @@ void AM_showSS()
|
|||
{
|
||||
for (unsigned j = 0; j < pnode->segs.Size(); j++)
|
||||
{
|
||||
AM_drawPolySeg(&pnode->segs[j], red);
|
||||
AM_drawPolySeg(Level, &pnode->segs[j], red);
|
||||
}
|
||||
}
|
||||
pnode = pnode->snext;
|
||||
|
@ -2572,19 +2576,19 @@ bool AM_isLockBoundary (line_t &line, int *lockptr = NULL)
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
void AM_drawWalls (bool allmap)
|
||||
void AM_drawWalls (FLevelLocals *Level, bool allmap)
|
||||
{
|
||||
static mline_t l;
|
||||
int lock, color;
|
||||
|
||||
int numportalgroups = am_portaloverlay ? level.Displacements.size : 0;
|
||||
int numportalgroups = am_portaloverlay ? Level->Displacements.size : 0;
|
||||
|
||||
for (int p = numportalgroups - 1; p >= -1; p--)
|
||||
{
|
||||
if (p == MapPortalGroup) continue;
|
||||
|
||||
|
||||
for (auto &line : level.lines)
|
||||
for (auto &line : Level->lines)
|
||||
{
|
||||
int pg;
|
||||
|
||||
|
@ -2601,7 +2605,7 @@ void AM_drawWalls (bool allmap)
|
|||
bool portalmode = numportalgroups > 0 && pg != MapPortalGroup;
|
||||
if (pg == p)
|
||||
{
|
||||
offset = level.Displacements.getOffset(pg, MapPortalGroup);
|
||||
offset = Level->Displacements.getOffset(pg, MapPortalGroup);
|
||||
}
|
||||
else if (p == -1 && (pg == MapPortalGroup || !am_portaloverlay))
|
||||
{
|
||||
|
@ -2979,14 +2983,14 @@ void AM_drawKeys ()
|
|||
//
|
||||
//
|
||||
//=============================================================================
|
||||
void AM_drawThings ()
|
||||
void AM_drawThings (FLevelLocals *Level)
|
||||
{
|
||||
AMColor color;
|
||||
AActor* t;
|
||||
mpoint_t p;
|
||||
DAngle angle;
|
||||
|
||||
for (auto &sec : level.sectors)
|
||||
for (auto &sec : Level->sectors)
|
||||
{
|
||||
t = sec.thinglist;
|
||||
while (t)
|
||||
|
@ -3239,12 +3243,12 @@ void AM_drawCrosshair (const AMColor &color)
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
void AM_Drawer (int bottom)
|
||||
void AM_Drawer (FLevelLocals *Level, int bottom)
|
||||
{
|
||||
if (!automapactive)
|
||||
return;
|
||||
|
||||
bool allmap = (level.flags2 & LEVEL2_ALLMAP) != 0;
|
||||
bool allmap = (Level->flags2 & LEVEL2_ALLMAP) != 0;
|
||||
bool allthings = allmap && players[consoleplayer].mo->FindInventory(NAME_PowerScanner, true) != nullptr;
|
||||
|
||||
if (am_portaloverlay)
|
||||
|
@ -3277,17 +3281,17 @@ void AM_Drawer (int bottom)
|
|||
AM_activateNewScale();
|
||||
|
||||
if (am_textured && textured && !viewactive)
|
||||
AM_drawSubsectors();
|
||||
AM_drawSubsectors(Level);
|
||||
|
||||
if (grid)
|
||||
AM_drawGrid(AMColors.GridColor);
|
||||
AM_drawGrid(Level, AMColors.GridColor);
|
||||
|
||||
AM_drawWalls(allmap);
|
||||
AM_drawWalls(Level, allmap);
|
||||
AM_drawPlayers();
|
||||
if (G_SkillProperty(SKILLP_EasyKey))
|
||||
AM_drawKeys();
|
||||
if ((am_cheat >= 2 && am_cheat != 4) || allthings)
|
||||
AM_drawThings();
|
||||
AM_drawThings(Level);
|
||||
|
||||
AM_drawAuthorMarkers();
|
||||
|
||||
|
@ -3296,7 +3300,7 @@ void AM_Drawer (int bottom)
|
|||
|
||||
AM_drawMarks();
|
||||
|
||||
AM_showSS();
|
||||
AM_showSS(Level);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
struct event_t;
|
||||
class FSerializer;
|
||||
struct FLevelLocals;
|
||||
|
||||
|
||||
void AM_StaticInit();
|
||||
|
@ -37,7 +38,7 @@ void AM_Ticker (void);
|
|||
|
||||
// Called by main loop,
|
||||
// called instead of view drawer if automap active.
|
||||
void AM_Drawer (int bottom);
|
||||
void AM_Drawer (FLevelLocals *Level, int bottom);
|
||||
|
||||
// Called to force the automap to quit
|
||||
// if the level is completed while it is up.
|
||||
|
@ -45,7 +46,7 @@ void AM_Stop (void);
|
|||
|
||||
void AM_NewResolution ();
|
||||
void AM_ToggleMap ();
|
||||
void AM_LevelInit ();
|
||||
void AM_LevelInit (FLevelLocals *Level);
|
||||
void AM_SerializeMarkers(FSerializer &arc);
|
||||
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ void FCajunMaster::End ()
|
|||
{
|
||||
int i;
|
||||
|
||||
//Arrange wanted botnum and their names, so they can be spawned next level.
|
||||
//Arrange wanted botnum and their names, so they can be spawned next map.
|
||||
getspawned.Clear();
|
||||
if (deathmatch)
|
||||
{
|
||||
|
|
|
@ -507,22 +507,22 @@ int ii_compatflags, ii_compatflags2, ib_compatflags;
|
|||
|
||||
EXTERN_CVAR(Int, compatmode)
|
||||
|
||||
static int GetCompatibility(int mask)
|
||||
static int GetCompatibility(FLevelLocals *Level, int mask)
|
||||
{
|
||||
if (level.info == NULL) return mask;
|
||||
else return (mask & ~level.info->compatmask) | (level.info->compatflags & level.info->compatmask);
|
||||
if (Level->info == nullptr) return mask;
|
||||
else return (mask & ~Level->info->compatmask) | (Level->info->compatflags & Level->info->compatmask);
|
||||
}
|
||||
|
||||
static int GetCompatibility2(int mask)
|
||||
static int GetCompatibility2(FLevelLocals *Level, int mask)
|
||||
{
|
||||
return (level.info == NULL) ? mask
|
||||
: (mask & ~level.info->compatmask2) | (level.info->compatflags2 & level.info->compatmask2);
|
||||
return (Level->info == nullptr) ? mask
|
||||
: (mask & ~Level->info->compatmask2) | (Level->info->compatflags2 & Level->info->compatmask2);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR (Int, compatflags, 0, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
||||
{
|
||||
int old = i_compatflags;
|
||||
i_compatflags = GetCompatibility(self) | ii_compatflags;
|
||||
i_compatflags = GetCompatibility(&level, self) | ii_compatflags;
|
||||
if ((old ^ i_compatflags) & COMPATF_POLYOBJ)
|
||||
{
|
||||
level.ClearAllSubsectorLinks();
|
||||
|
@ -531,7 +531,7 @@ CUSTOM_CVAR (Int, compatflags, 0, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
|||
|
||||
CUSTOM_CVAR (Int, compatflags2, 0, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
||||
{
|
||||
i_compatflags2 = GetCompatibility2(self) | ii_compatflags2;
|
||||
i_compatflags2 = GetCompatibility2(&level, self) | ii_compatflags2;
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL)
|
||||
|
@ -746,19 +746,21 @@ void D_Display ()
|
|||
//E_RenderFrame();
|
||||
//
|
||||
|
||||
// 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))
|
||||
{
|
||||
level.HasDynamicLights = !!level.lights;
|
||||
}
|
||||
else level.HasDynamicLights = false; // lights are off so effectively we have none.
|
||||
|
||||
ForAllLevels([](FLevelLocals *Level) {
|
||||
// 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))
|
||||
{
|
||||
Level->HasDynamicLights = !!Level->lights;
|
||||
}
|
||||
else Level->HasDynamicLights = false; // lights are off so effectively we have none.
|
||||
});
|
||||
|
||||
viewsec = screen->RenderView(&players[consoleplayer]);
|
||||
screen->Begin2D();
|
||||
screen->DrawBlend(viewsec);
|
||||
if (automapactive)
|
||||
{
|
||||
AM_Drawer (hud_althud? viewheight : StatusBar->GetTopOfStatusbar());
|
||||
AM_Drawer (&level, hud_althud? viewheight : StatusBar->GetTopOfStatusbar());
|
||||
}
|
||||
|
||||
// for timing the statusbar code.
|
||||
|
@ -2580,7 +2582,9 @@ void D_DoomMain (void)
|
|||
// [RH] Run any saved commands from the command line or autoexec.cfg now.
|
||||
gamestate = GS_FULLCONSOLE;
|
||||
Net_NewMakeTic ();
|
||||
DThinker::RunThinkers ();
|
||||
ForAllLevels([](FLevelLocals *Level) {
|
||||
DThinker::RunThinkers (Level);
|
||||
});
|
||||
gamestate = GS_STARTUP;
|
||||
|
||||
if (!restart)
|
||||
|
|
|
@ -2341,7 +2341,7 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
|
|||
{
|
||||
if (spawned->CountsAsKill())
|
||||
{
|
||||
level.total_monsters--;
|
||||
source->Level->total_monsters--;
|
||||
}
|
||||
spawned->FriendPlayer = player + 1;
|
||||
spawned->flags |= MF_FRIENDLY;
|
||||
|
@ -2702,7 +2702,7 @@ static void RunScript(uint8_t **stream, AActor *pawn, int snum, int argn, int al
|
|||
arg[i] = argval;
|
||||
}
|
||||
}
|
||||
P_StartScript(&level, pawn, NULL, snum, level.MapName, arg, MIN<int>(countof(arg), argn), ACS_NET | always);
|
||||
P_StartScript(pawn->Level, pawn, NULL, snum, pawn->Level->MapName, arg, MIN<int>(countof(arg), argn), ACS_NET | always);
|
||||
}
|
||||
|
||||
void Net_SkipCommand (int type, uint8_t **stream)
|
||||
|
|
|
@ -50,7 +50,9 @@ CVAR (Bool, alwaysapplydmflags, false, CVAR_SERVERINFO);
|
|||
|
||||
CUSTOM_CVAR (Float, teamdamage, 0.f, CVAR_SERVERINFO)
|
||||
{
|
||||
level.teamdamage = self;
|
||||
ForAllLevels([&](FLevelLocals *Level) {
|
||||
Level->teamdamage = self;
|
||||
});
|
||||
}
|
||||
|
||||
CUSTOM_CVAR (String, language, "auto", CVAR_ARCHIVE)
|
||||
|
|
|
@ -597,7 +597,7 @@ struct ProfileInfo
|
|||
TMap<FName, ProfileInfo> Profiles;
|
||||
|
||||
|
||||
void DThinker::RunThinkers ()
|
||||
void DThinker::RunThinkers (FLevelLocals *Level)
|
||||
{
|
||||
int i, count;
|
||||
|
||||
|
@ -627,7 +627,7 @@ void DThinker::RunThinkers ()
|
|||
}
|
||||
} while (count != 0);
|
||||
|
||||
for (auto light = level.lights; light;)
|
||||
for (auto light = Level->lights; light;)
|
||||
{
|
||||
auto next = light->next;
|
||||
light->Tick();
|
||||
|
@ -656,7 +656,7 @@ void DThinker::RunThinkers ()
|
|||
// Also profile the internal dynamic lights, even though they are not implemented as thinkers.
|
||||
auto &prof = Profiles[NAME_InternalDynamicLight];
|
||||
prof.timer.Clock();
|
||||
for (auto light = level.lights; light;)
|
||||
for (auto light = Level->lights; light;)
|
||||
{
|
||||
prof.numcalls++;
|
||||
auto next = light->next;
|
||||
|
|
|
@ -80,7 +80,7 @@ public:
|
|||
|
||||
void ChangeStatNum (int statnum);
|
||||
|
||||
static void RunThinkers ();
|
||||
static void RunThinkers (FLevelLocals *Level);
|
||||
static void RunThinkers (int statnum);
|
||||
static void DestroyAllThinkers ();
|
||||
static void DestroyThinkersInList(int statnum)
|
||||
|
|
140
src/g_game.cpp
140
src/g_game.cpp
|
@ -759,7 +759,7 @@ void G_AddViewPitch (int look, bool mouse)
|
|||
return;
|
||||
}
|
||||
look = LookAdjust(look);
|
||||
if (!level.IsFreelookAllowed())
|
||||
if (!players[consoleplayer].mo->Level->IsFreelookAllowed())
|
||||
{
|
||||
LocalViewPitch = 0;
|
||||
}
|
||||
|
@ -1212,7 +1212,7 @@ void G_Ticker ()
|
|||
|
||||
//
|
||||
// G_PlayerFinishLevel
|
||||
// Called when a player completes a level.
|
||||
// Called when a player completes a map.
|
||||
//
|
||||
// flags is checked for RESETINVENTORY and RESETHEALTH only.
|
||||
|
||||
|
@ -1325,7 +1325,7 @@ bool G_CheckSpot (FLevelLocals *Level, int playernum, FPlayerStart *mthing)
|
|||
|
||||
spot = mthing->pos;
|
||||
|
||||
if (!(level.flags & LEVEL_USEPLAYERSTARTZ))
|
||||
if (!(Level->flags & LEVEL_USEPLAYERSTARTZ))
|
||||
{
|
||||
spot.Z = 0;
|
||||
}
|
||||
|
@ -1388,7 +1388,7 @@ static double PlayersRangeFromSpot (FPlayerStart *spot)
|
|||
}
|
||||
|
||||
// [RH] Select the deathmatch spawn spot farthest from everyone.
|
||||
static FPlayerStart *SelectFarthestDeathmatchSpot (size_t selections)
|
||||
static FPlayerStart *SelectFarthestDeathmatchSpot (FLevelLocals *Level, size_t selections)
|
||||
{
|
||||
double bestdistance = 0;
|
||||
FPlayerStart *bestspot = NULL;
|
||||
|
@ -1396,12 +1396,12 @@ static FPlayerStart *SelectFarthestDeathmatchSpot (size_t selections)
|
|||
|
||||
for (i = 0; i < selections; i++)
|
||||
{
|
||||
double distance = PlayersRangeFromSpot (&level.deathmatchstarts[i]);
|
||||
double distance = PlayersRangeFromSpot (&Level->deathmatchstarts[i]);
|
||||
|
||||
if (distance > bestdistance)
|
||||
{
|
||||
bestdistance = distance;
|
||||
bestspot = &level.deathmatchstarts[i];
|
||||
bestspot = &Level->deathmatchstarts[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1416,7 +1416,7 @@ static FPlayerStart *SelectRandomDeathmatchSpot (FLevelLocals *Level, int player
|
|||
for (j = 0; j < 20; j++)
|
||||
{
|
||||
i = pr_dmspawn() % selections;
|
||||
if (G_CheckSpot (Level, playernum, &level.deathmatchstarts[i]) )
|
||||
if (G_CheckSpot (Level, playernum, &Level->deathmatchstarts[i]) )
|
||||
{
|
||||
return &Level->deathmatchstarts[i];
|
||||
}
|
||||
|
@ -1471,7 +1471,7 @@ void G_DeathMatchSpawnPlayer (FLevelLocals *Level, int playernum)
|
|||
// so we always use the random deathmatch spawn. During the game,
|
||||
// though, we use whatever dmflags specifies.
|
||||
if ((dmflags & DF_SPAWN_FARTHEST) && players[playernum].mo)
|
||||
spot = SelectFarthestDeathmatchSpot (selections);
|
||||
spot = SelectFarthestDeathmatchSpot (Level, selections);
|
||||
else
|
||||
spot = SelectRandomDeathmatchSpot (Level, playernum, selections);
|
||||
|
||||
|
@ -1479,14 +1479,14 @@ void G_DeathMatchSpawnPlayer (FLevelLocals *Level, int playernum)
|
|||
{ // No good spot, so the player will probably get stuck.
|
||||
// We were probably using select farthest above, and all
|
||||
// the spots were taken.
|
||||
spot = G_PickPlayerStart(playernum, PPS_FORCERANDOM);
|
||||
if (!G_CheckSpot(&level, playernum, spot))
|
||||
spot = G_PickPlayerStart(Level, playernum, PPS_FORCERANDOM);
|
||||
if (!G_CheckSpot(Level, playernum, spot))
|
||||
{ // This map doesn't have enough coop spots for this player
|
||||
// to use one.
|
||||
spot = SelectRandomDeathmatchSpot(Level, playernum, selections);
|
||||
if (spot == NULL)
|
||||
{ // We have a player 1 start, right?
|
||||
spot = &level.playerstarts[0];
|
||||
spot = &Level->playerstarts[0];
|
||||
if (spot->type == 0)
|
||||
{ // Fine, whatever.
|
||||
spot = &Level->deathmatchstarts[0];
|
||||
|
@ -1502,15 +1502,15 @@ void G_DeathMatchSpawnPlayer (FLevelLocals *Level, int playernum)
|
|||
//
|
||||
// G_PickPlayerStart
|
||||
//
|
||||
FPlayerStart *G_PickPlayerStart(int playernum, int flags)
|
||||
FPlayerStart *G_PickPlayerStart(FLevelLocals *Level, int playernum, int flags)
|
||||
{
|
||||
if (level.AllPlayerStarts.Size() == 0) // No starts to pick
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((level.flags2 & LEVEL2_RANDOMPLAYERSTARTS) || (flags & PPS_FORCERANDOM) ||
|
||||
level.playerstarts[playernum].type == 0)
|
||||
if ((Level->flags2 & LEVEL2_RANDOMPLAYERSTARTS) || (flags & PPS_FORCERANDOM) ||
|
||||
Level->playerstarts[playernum].type == 0)
|
||||
{
|
||||
if (!(flags & PPS_NOBLOCKINGCHECK))
|
||||
{
|
||||
|
@ -1518,9 +1518,9 @@ FPlayerStart *G_PickPlayerStart(int playernum, int flags)
|
|||
unsigned int i;
|
||||
|
||||
// Find all unblocked player starts.
|
||||
for (i = 0; i < level.AllPlayerStarts.Size(); ++i)
|
||||
for (i = 0; i < Level->AllPlayerStarts.Size(); ++i)
|
||||
{
|
||||
if (G_CheckSpot(&level, playernum, &level.AllPlayerStarts[i]))
|
||||
if (G_CheckSpot(Level, playernum, &Level->AllPlayerStarts[i]))
|
||||
{
|
||||
good_starts.Push(&level.AllPlayerStarts[i]);
|
||||
}
|
||||
|
@ -1531,7 +1531,7 @@ FPlayerStart *G_PickPlayerStart(int playernum, int flags)
|
|||
}
|
||||
}
|
||||
// Pick a spot at random, whether it's open or not.
|
||||
return &level.AllPlayerStarts[pr_pspawn(level.AllPlayerStarts.Size())];
|
||||
return &Level->AllPlayerStarts[pr_pspawn(Level->AllPlayerStarts.Size())];
|
||||
}
|
||||
return &level.playerstarts[playernum];
|
||||
}
|
||||
|
@ -1541,7 +1541,7 @@ DEFINE_ACTION_FUNCTION(DObject, G_PickPlayerStart)
|
|||
PARAM_PROLOGUE;
|
||||
PARAM_INT(playernum);
|
||||
PARAM_INT(flags);
|
||||
auto ps = G_PickPlayerStart(playernum, flags);
|
||||
auto ps = G_PickPlayerStart(&level, playernum, flags);
|
||||
if (numret > 1)
|
||||
{
|
||||
ret[1].SetInt(ps? ps->angle : 0);
|
||||
|
@ -1559,15 +1559,16 @@ DEFINE_ACTION_FUNCTION(DObject, G_PickPlayerStart)
|
|||
//
|
||||
static void G_QueueBody (AActor *body)
|
||||
{
|
||||
auto Level = body->Level;
|
||||
// flush an old corpse if needed
|
||||
int modslot = level.bodyqueslot%level.BODYQUESIZE;
|
||||
level.bodyqueslot = modslot + 1;
|
||||
int modslot = level.bodyqueslot % FLevelLocals::BODYQUESIZE;
|
||||
Level->bodyqueslot = modslot + 1;
|
||||
|
||||
if (level.bodyqueslot >= level.BODYQUESIZE && level.bodyque[modslot] != NULL)
|
||||
if (Level->bodyqueslot >= FLevelLocals::BODYQUESIZE && Level->bodyque[modslot] != NULL)
|
||||
{
|
||||
level.bodyque[modslot]->Destroy ();
|
||||
Level->bodyque[modslot]->Destroy ();
|
||||
}
|
||||
level.bodyque[modslot] = body;
|
||||
Level->bodyque[modslot] = body;
|
||||
|
||||
// Copy the player's translation, so that if they change their color later, only
|
||||
// their current body will change and not all their old corpses.
|
||||
|
@ -1599,7 +1600,8 @@ static void G_QueueBody (AActor *body)
|
|||
EXTERN_CVAR(Bool, sv_singleplayerrespawn)
|
||||
void G_DoReborn (int playernum, bool freshbot)
|
||||
{
|
||||
if (!multiplayer && !(level.flags2 & LEVEL2_ALLOWRESPAWN) && !sv_singleplayerrespawn &&
|
||||
auto Level = &level;
|
||||
if (!multiplayer && !(Level->flags2 & LEVEL2_ALLOWRESPAWN) && !sv_singleplayerrespawn &&
|
||||
!G_SkillProperty(SKILLP_PlayerRespawn))
|
||||
{
|
||||
if (BackupSaveName.Len() > 0 && FileExists (BackupSaveName.GetChars()))
|
||||
|
@ -1611,7 +1613,7 @@ void G_DoReborn (int playernum, bool freshbot)
|
|||
{ // Reload the level from scratch
|
||||
bool indemo = demoplayback;
|
||||
BackupSaveName = "";
|
||||
G_InitNew (level.MapName, false);
|
||||
G_InitNew (Level->MapName, false);
|
||||
demoplayback = indemo;
|
||||
// gameaction = ga_loadlevel;
|
||||
}
|
||||
|
@ -1629,23 +1631,23 @@ void G_DoReborn (int playernum, bool freshbot)
|
|||
}
|
||||
|
||||
// spawn at random spot if in deathmatch
|
||||
if ((deathmatch || isUnfriendly) && (level.deathmatchstarts.Size () > 0))
|
||||
if ((deathmatch || isUnfriendly) && (Level->deathmatchstarts.Size () > 0))
|
||||
{
|
||||
G_DeathMatchSpawnPlayer (&level, playernum);
|
||||
G_DeathMatchSpawnPlayer (Level, playernum);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(level.flags2 & LEVEL2_RANDOMPLAYERSTARTS) &&
|
||||
level.playerstarts[playernum].type != 0 &&
|
||||
G_CheckSpot (&level, playernum, &level.playerstarts[playernum]))
|
||||
if (!(Level->flags2 & LEVEL2_RANDOMPLAYERSTARTS) &&
|
||||
Level->playerstarts[playernum].type != 0 &&
|
||||
G_CheckSpot (Level, playernum, &Level->playerstarts[playernum]))
|
||||
{
|
||||
AActor *mo = P_SpawnPlayer(&level, &level.playerstarts[playernum], playernum);
|
||||
AActor *mo = P_SpawnPlayer(Level, &Level->playerstarts[playernum], playernum);
|
||||
if (mo != NULL) P_PlayerStartStomp(mo, true);
|
||||
}
|
||||
else
|
||||
{ // try to spawn at any random player's spot
|
||||
FPlayerStart *start = G_PickPlayerStart(playernum, PPS_FORCERANDOM);
|
||||
AActor *mo = P_SpawnPlayer(&level, start, playernum);
|
||||
FPlayerStart *start = G_PickPlayerStart(Level, playernum, PPS_FORCERANDOM);
|
||||
AActor *mo = P_SpawnPlayer(Level, start, playernum);
|
||||
if (mo != NULL) P_PlayerStartStomp(mo, true);
|
||||
}
|
||||
}
|
||||
|
@ -2048,13 +2050,15 @@ static void PutSaveWads (FSerializer &arc)
|
|||
// Name of IWAD
|
||||
name = Wads.GetWadName (Wads.GetIwadNum());
|
||||
arc.AddString("Game WAD", name);
|
||||
|
||||
// Name of wad the map resides in
|
||||
if (Wads.GetLumpFile (level.lumpnum) > Wads.GetIwadNum())
|
||||
{
|
||||
name = Wads.GetWadName (Wads.GetLumpFile (level.lumpnum));
|
||||
arc.AddString("Map WAD", name);
|
||||
}
|
||||
|
||||
ForAllLevels([&](FLevelLocals *Level) {
|
||||
// Name of wad the map resides in
|
||||
if (Wads.GetLumpFile (Level->lumpnum) > Wads.GetIwadNum())
|
||||
{
|
||||
name = Wads.GetWadName (Wads.GetLumpFile (Level->lumpnum));
|
||||
arc.AddString(FStringf("Map WAD %s", Level->MapName.GetChars()), name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void PutSaveComment (FSerializer &arc)
|
||||
|
@ -2069,10 +2073,12 @@ static void PutSaveComment (FSerializer &arc)
|
|||
comment.Format("%.10s%.5s%.9s", readableTime, &readableTime[19], &readableTime[10]);
|
||||
|
||||
arc.AddString("Creation Time", comment);
|
||||
|
||||
// Get level name
|
||||
//strcpy (comment, level.level_name);
|
||||
comment.Format("%s - %s\n", level.MapName.GetChars(), level.LevelName.GetChars());
|
||||
|
||||
comment = "";
|
||||
ForAllLevels([&](FLevelLocals *Level) {
|
||||
// Get level name
|
||||
comment.AppendFormat("%s - %s\n", Level->MapName.GetChars(), Level->LevelName.GetChars());
|
||||
});
|
||||
|
||||
// Append elapsed time
|
||||
levelTime = level.time / TICRATE;
|
||||
|
@ -2101,13 +2107,17 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
|
|||
TArray<FString> savegame_filenames;
|
||||
|
||||
char buf[100];
|
||||
|
||||
// Do not even try, if we're not in a level. (Can happen after
|
||||
// a demo finishes playback.)
|
||||
if (level.lines.Size() == 0 || level.sectors.Size() == 0 || gamestate != GS_LEVEL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool checkok = gamestate != GS_LEVEL;
|
||||
|
||||
ForAllLevels([&](FLevelLocals *Level) {
|
||||
|
||||
// Do not even try, if we're not in a map. (Can happen after a demo finishes playback.)
|
||||
if (Level->lines.Size() == 0 || level.sectors.Size() == 0)
|
||||
{
|
||||
checkok = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (demoplayback)
|
||||
{
|
||||
|
@ -2155,15 +2165,24 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
|
|||
// put some basic info into the PNG so that this isn't lost when the image gets extracted.
|
||||
M_AppendPNGText(&savepic, "Software", buf);
|
||||
M_AppendPNGText(&savepic, "Title", description);
|
||||
M_AppendPNGText(&savepic, "Current Map", level.MapName);
|
||||
ForAllLevels([&](FLevelLocals *Level) {
|
||||
M_AppendPNGText(&savepic, "Current Map", Level->MapName);
|
||||
});
|
||||
M_FinishPNG(&savepic);
|
||||
|
||||
int ver = SAVEVER;
|
||||
savegameinfo.AddString("Software", buf)
|
||||
.AddString("Engine", GAMESIG)
|
||||
("Save Version", ver)
|
||||
.AddString("Title", description)
|
||||
.AddString("Current Map", level.MapName);
|
||||
.AddString("Title", description);
|
||||
|
||||
if (savegameinfo.BeginArray("Current Maps"))
|
||||
{
|
||||
ForAllLevels([&](FLevelLocals *Level) {
|
||||
savegameinfo.AddString(nullptr, Level->MapName);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
PutSaveWads (savegameinfo);
|
||||
|
@ -2848,17 +2867,18 @@ bool G_CheckDemoStatus (void)
|
|||
return false;
|
||||
}
|
||||
|
||||
void G_StartSlideshow(FName whichone)
|
||||
void G_StartSlideshow(FLevelLocals *Level, int _whichone)
|
||||
{
|
||||
FName whichone = ENamedName(_whichone);
|
||||
gameaction = ga_slideshow;
|
||||
SelectedSlideshow = whichone == NAME_None ? level.info->slideshow : whichone;
|
||||
SelectedSlideshow = whichone == NAME_None ? Level->info->slideshow : whichone;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, StartSlideshow)
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, StartSlideshow, G_StartSlideshow)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_NAME(whichone);
|
||||
G_StartSlideshow(whichone);
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
PARAM_INT(whichone);
|
||||
G_StartSlideshow(self, whichone);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ struct FLevelLocals;
|
|||
//
|
||||
void G_DeathMatchSpawnPlayer (FLevelLocals *Level, int playernum);
|
||||
|
||||
struct FPlayerStart *G_PickPlayerStart (int playernum, int flags = 0);
|
||||
struct FPlayerStart *G_PickPlayerStart (FLevelLocals *Level, int playernum, int flags = 0);
|
||||
enum
|
||||
{
|
||||
PPS_FORCERANDOM = 1,
|
||||
|
@ -74,7 +74,7 @@ void G_Ticker (void);
|
|||
bool G_Responder (event_t* ev);
|
||||
|
||||
void G_ScreenShot (char *filename);
|
||||
void G_StartSlideshow(FName whichone);
|
||||
void G_StartSlideshow(FLevelLocals *level, int whichone);
|
||||
|
||||
FString G_BuildSaveName (const char *prefix, int slot);
|
||||
|
||||
|
|
|
@ -1039,7 +1039,7 @@ void G_DoLoadLevel (int position, bool autosave, bool newGame)
|
|||
|
||||
P_SetupLevel (&level, level.MapName, position, newGame);
|
||||
|
||||
AM_LevelInit();
|
||||
AM_LevelInit(&level);
|
||||
|
||||
// [RH] Start lightning, if MAPINFO tells us to
|
||||
if (level.flags & LEVEL_STARTLIGHTNING)
|
||||
|
@ -1370,7 +1370,7 @@ int G_FinishTravel ()
|
|||
pawndup = pawn->player->mo;
|
||||
assert (pawn != pawndup);
|
||||
|
||||
start = G_PickPlayerStart(pnum, 0);
|
||||
start = G_PickPlayerStart(&level, pnum, 0);
|
||||
if (start == NULL)
|
||||
{
|
||||
if (pawndup != nullptr)
|
||||
|
|
|
@ -48,7 +48,7 @@ DLightningThinker::DLightningThinker ()
|
|||
LightningFlashCount = 0;
|
||||
NextLightningFlash = ((pr_lightning()&15)+5)*35; // don't flash at level start
|
||||
|
||||
LightningLightLevels.Resize(level.sectors.Size());
|
||||
LightningLightLevels.Resize(Level->sectors.Size());
|
||||
fillshort(&LightningLightLevels[0], LightningLightLevels.Size(), SHRT_MAX);
|
||||
}
|
||||
|
||||
|
|
|
@ -6657,7 +6657,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
return ScriptCall(activator, argCount, args);
|
||||
|
||||
case ACSF_StartSlideshow:
|
||||
G_StartSlideshow(FName(Level->Behaviors.LookupString(args[0])));
|
||||
G_StartSlideshow(Level, FName(Level->Behaviors.LookupString(args[0])).GetIndex());
|
||||
break;
|
||||
|
||||
case ACSF_GetSectorHealth:
|
||||
|
|
|
@ -167,12 +167,12 @@ void P_ClearParticles (FLevelLocals *Level)
|
|||
|
||||
void P_FindParticleSubsectors (FLevelLocals *Level)
|
||||
{
|
||||
if (Level->ParticlesInSubsec.Size() < level.subsectors.Size())
|
||||
if (Level->ParticlesInSubsec.Size() < Level->subsectors.Size())
|
||||
{
|
||||
Level->ParticlesInSubsec.Reserve (level.subsectors.Size() - Level->ParticlesInSubsec.Size());
|
||||
Level->ParticlesInSubsec.Reserve (Level->subsectors.Size() - Level->ParticlesInSubsec.Size());
|
||||
}
|
||||
|
||||
fillshort (&Level->ParticlesInSubsec[0], level.subsectors.Size(), NO_PARTICLE);
|
||||
fillshort (&Level->ParticlesInSubsec[0], Level->subsectors.Size(), NO_PARTICLE);
|
||||
|
||||
if (!r_particles)
|
||||
{
|
||||
|
@ -236,7 +236,7 @@ void P_ThinkParticles (FLevelLocals *Level)
|
|||
{
|
||||
particle = &Level->Particles[i];
|
||||
i = particle->tnext;
|
||||
if (!particle->notimefreeze && ((level.freeze) || (level.flags2 & LEVEL2_FROZEN)))
|
||||
if (!particle->notimefreeze && ((Level->freeze) || (Level->flags2 & LEVEL2_FROZEN)))
|
||||
{
|
||||
prev = particle;
|
||||
continue;
|
||||
|
@ -323,7 +323,7 @@ void P_RunEffects (FLevelLocals *Level)
|
|||
{
|
||||
if (players[consoleplayer].camera == NULL) return;
|
||||
|
||||
int pnum = players[consoleplayer].camera->Sector->Index() * level.sectors.Size();
|
||||
int pnum = players[consoleplayer].camera->Sector->Index() * Level->sectors.Size();
|
||||
|
||||
AActor *actor;
|
||||
TThinkerIterator<AActor> iterator;
|
||||
|
@ -372,7 +372,7 @@ static void MakeFountain (AActor *actor, int color1, int color2)
|
|||
{
|
||||
particle_t *particle;
|
||||
|
||||
if (!(level.time & 1))
|
||||
if (!(actor->Level->maptime & 1))
|
||||
return;
|
||||
|
||||
particle = JitterParticle (actor->Level, 51);
|
||||
|
|
|
@ -1962,8 +1962,8 @@ subsector_t *P_PointInSubsector(FLevelLocals *Level, double x, double y)
|
|||
sector_t *P_PointInSectorBuggy(FLevelLocals *Level, double x, double y)
|
||||
{
|
||||
// single subsector is a special case
|
||||
auto node = level.HeadGamenode();
|
||||
if (node == nullptr) return level.subsectors[0].sector;
|
||||
auto node = Level->HeadGamenode();
|
||||
if (node == nullptr) return Level->subsectors[0].sector;
|
||||
do
|
||||
{
|
||||
// Use original buggy point-on-side test when spawning
|
||||
|
|
|
@ -274,8 +274,8 @@ void FLevelLocals::ClearLevelData()
|
|||
DialogueRoots.Clear();
|
||||
ClassRoots.Clear();
|
||||
|
||||
level.interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh level.
|
||||
level.ClearAllSubsectorLinks(); // can't be done as part of the polyobj deletion process.
|
||||
interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh map.
|
||||
ClearAllSubsectorLinks(); // can't be done as part of the polyobj deletion process.
|
||||
DThinker::DestroyAllThinkers();
|
||||
|
||||
// delete allocated data in the level arrays.
|
||||
|
@ -457,7 +457,7 @@ void P_SetupLevel(FLevelLocals *Level, const char *lumpname, int position, bool
|
|||
if (playeringame[i])
|
||||
{
|
||||
players[i].mo = nullptr;
|
||||
FPlayerStart *mthing = G_PickPlayerStart(i);
|
||||
FPlayerStart *mthing = G_PickPlayerStart(Level, i);
|
||||
P_SpawnPlayer(Level, mthing, i, (Level->flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ class FSectorTagIterator
|
|||
protected:
|
||||
int searchtag;
|
||||
int start;
|
||||
FLevelLocals *Level;
|
||||
FTagManager &tagManager;
|
||||
|
||||
FSectorTagIterator(FTagManager &manager) : tagManager(manager)
|
||||
|
|
|
@ -149,7 +149,7 @@ void P_Ticker (void)
|
|||
memset(&Level->Scrolls[0], 0, sizeof(Level->Scrolls[0]) * Level->Scrolls.Size());
|
||||
}
|
||||
|
||||
DThinker::RunThinkers();
|
||||
DThinker::RunThinkers(Level);
|
||||
|
||||
//if added by MC: Freeze mode.
|
||||
if (!Level->freeze && !(Level->flags2 & LEVEL2_FROZEN))
|
||||
|
|
|
@ -519,7 +519,7 @@ void R_InterpolateView (FRenderViewpoint &viewpoint, player_t *player, double Fr
|
|||
}
|
||||
else
|
||||
{
|
||||
DVector2 disp = level.Displacements.getOffset(oldgroup, newgroup);
|
||||
DVector2 disp = Level->Displacements.getOffset(oldgroup, newgroup);
|
||||
viewpoint.Pos = iview->Old.Pos + (iview->New.Pos - iview->Old.Pos - disp) * Frac;
|
||||
viewpoint.Path[0] = viewpoint.Path[1] = iview->New.Pos;
|
||||
}
|
||||
|
@ -1033,7 +1033,7 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor
|
|||
// However, to set up a projection matrix this needs to be adjusted.
|
||||
double radPitch = viewpoint.Angles.Pitch.Normalized180().Radians();
|
||||
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);
|
||||
viewpoint.HWAngles.Pitch = RAD2DEG((float)asin(angy / alen));
|
||||
|
||||
|
|
|
@ -698,7 +698,7 @@ struct LevelLocals native
|
|||
native double GetUDMFFloat(int type, int index, Name key);
|
||||
native bool ExecuteSpecial(int special, Actor activator, line linedef, bool lineside, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0, int arg5 = 0);
|
||||
native void GiveSecret(Actor activator, bool printmsg = true, bool playsound = true);
|
||||
native static void StartSlideshow(Name whichone = 'none');
|
||||
native void StartSlideshow(Name whichone = 'none');
|
||||
native static void WorldDone();
|
||||
native static void RemoveAllBots(bool fromlist);
|
||||
native static Vector2 GetAutomapPosition();
|
||||
|
|
Loading…
Reference in a new issue