- re-applied the changes for p_spec.cpp

This is mostly map loader code which really should not operate on the global level.
This commit is contained in:
Christoph Oelckers 2019-01-24 00:02:51 +01:00
parent 83d464d1be
commit ac7a9183aa
12 changed files with 114 additions and 114 deletions

View file

@ -54,6 +54,7 @@ struct FPortalGroupArray;
struct visstyle_t; struct visstyle_t;
class FLightDefaults; class FLightDefaults;
struct FSection; struct FSection;
struct FLevelLocals;
// //
// NOTES: AActor // NOTES: AActor
// //
@ -637,8 +638,8 @@ class AActor : public DThinker
DECLARE_CLASS_WITH_META (AActor, DThinker, PClassActor) DECLARE_CLASS_WITH_META (AActor, DThinker, PClassActor)
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
public: public:
AActor () throw(); AActor() = default;
AActor (const AActor &other) throw(); AActor(const AActor &other) = delete; // Calling this would be disastrous.
AActor &operator= (const AActor &other); AActor &operator= (const AActor &other);
~AActor (); ~AActor ();

View file

@ -92,4 +92,5 @@ inline double AActor::AttackOffset(double offset)
return 8 + offset; return 8 + offset;
} }
} }

View file

@ -112,6 +112,7 @@ struct FLevelLocals : public FLevelData
void SetMusicVolume(float v); void SetMusicVolume(float v);
void ClearLevelData(); void ClearLevelData();
void ClearPortals(); void ClearPortals();
bool CheckIfExitIsGood(AActor *self, level_info_t *newmap);
uint8_t md5[16]; // for savegame validation. If the MD5 does not match the savegame won't be loaded. uint8_t md5[16]; // for savegame validation. If the MD5 does not match the savegame won't be loaded.
int time; // time in the hub int time; // time in the hub

View file

@ -96,7 +96,9 @@ class MapLoader
{ {
friend class UDMFParser; friend class UDMFParser;
void *level; // this is to hide the global variable and produce an error for referencing it. void *level; // this is to hide the global variable and produce an error for referencing it.
public:
FLevelLocals *Level; FLevelLocals *Level;
private:
int firstglvertex; // helpers for loading GL nodes from GWA files. int firstglvertex; // helpers for loading GL nodes from GWA files.
bool format5; bool format5;

View file

@ -332,8 +332,7 @@ void P_PlayerOnSpecial3DFloor(player_t* player)
P_PlayerInSpecialSector(player, rover->model); P_PlayerInSpecialSector(player, rover->model);
// Apply flat specials (using the ceiling!) // Apply flat specials (using the ceiling!)
P_PlayerOnSpecialFlat( P_PlayerOnSpecialFlat(player, rover->model->GetTerrain(rover->top.isceiling));
player, rover->model->GetTerrain(rover->top.isceiling));
break; break;
} }

View file

@ -9928,7 +9928,7 @@ scriptwait:
int flags = STACK(1); int flags = STACK(1);
sp -= 5; sp -= 5;
P_SectorDamage(tag, amount, type, protectClass, flags); P_SectorDamage(&level, tag, amount, type, protectClass, flags);
} }
break; break;

View file

@ -1060,7 +1060,7 @@ FUNC(LS_Generic_Lift)
FUNC(LS_Exit_Normal) FUNC(LS_Exit_Normal)
// Exit_Normal (position) // Exit_Normal (position)
{ {
if (CheckIfExitIsGood (it, FindLevelInfo(G_GetExitMap()))) if (level.CheckIfExitIsGood (it, FindLevelInfo(G_GetExitMap())))
{ {
G_ExitLevel (arg0, false); G_ExitLevel (arg0, false);
return true; return true;
@ -1071,7 +1071,7 @@ FUNC(LS_Exit_Normal)
FUNC(LS_Exit_Secret) FUNC(LS_Exit_Secret)
// Exit_Secret (position) // Exit_Secret (position)
{ {
if (CheckIfExitIsGood (it, FindLevelInfo(G_GetSecretExitMap()))) if (level.CheckIfExitIsGood (it, FindLevelInfo(G_GetSecretExitMap())))
{ {
G_SecretExitLevel (arg0); G_SecretExitLevel (arg0);
return true; return true;
@ -1086,7 +1086,7 @@ FUNC(LS_Teleport_NewMap)
{ {
level_info_t *info = FindLevelByNum (arg0); level_info_t *info = FindLevelByNum (arg0);
if (info && CheckIfExitIsGood (it, info)) if (info && level.CheckIfExitIsGood (it, info))
{ {
G_ChangeLevel(info->MapName, arg1, arg2 ? CHANGELEVEL_KEEPFACING : 0); G_ChangeLevel(info->MapName, arg1, arg2 ? CHANGELEVEL_KEEPFACING : 0);
return true; return true;
@ -1181,7 +1181,7 @@ FUNC(LS_TeleportInSector)
FUNC(LS_Teleport_EndGame) FUNC(LS_Teleport_EndGame)
// Teleport_EndGame () // Teleport_EndGame ()
{ {
if (!backSide && CheckIfExitIsGood (it, NULL)) if (!backSide && level.CheckIfExitIsGood (it, NULL))
{ {
G_ChangeLevel(NULL, 0, 0); G_ChangeLevel(NULL, 0, 0);
return true; return true;
@ -2252,7 +2252,7 @@ FUNC(LS_Sector_SetCurrent)
FUNC(LS_Sector_SetFriction) FUNC(LS_Sector_SetFriction)
// Sector_SetFriction (tag, amount) // Sector_SetFriction (tag, amount)
{ {
P_SetSectorFriction (arg0, arg1, true); P_SetSectorFriction (&level, arg0, arg1, true);
return true; return true;
} }

View file

@ -401,16 +401,6 @@ void AActor::PostSerialize()
AActor::AActor () throw()
{
}
AActor::AActor (const AActor &other) throw()
: DThinker()
{
memcpy (&snext, &other.snext, (uint8_t *)&this[1] - (uint8_t *)&snext);
}
AActor &AActor::operator= (const AActor &other) AActor &AActor::operator= (const AActor &other)
{ {
memcpy (&snext, &other.snext, (uint8_t *)&this[1] - (uint8_t *)&snext); memcpy (&snext, &other.snext, (uint8_t *)&this[1] - (uint8_t *)&snext);

View file

@ -107,21 +107,21 @@ EXTERN_CVAR(Bool, cl_predict_specials)
// killough 3/7/98: Initialize generalized scrolling // killough 3/7/98: Initialize generalized scrolling
void P_SpawnScrollers(FLevelLocals *Level); void P_SpawnScrollers(FLevelLocals *Level);
static void P_SpawnFriction (); // phares 3/16/98 static void P_SpawnFriction (FLevelLocals *l); // phares 3/16/98
void P_SpawnPushers (); // phares 3/20/98 void P_SpawnPushers (); // phares 3/20/98
// [RH] Check dmflags for noexit and respond accordingly // [RH] Check dmflags for noexit and respond accordingly
bool CheckIfExitIsGood (AActor *self, level_info_t *info) bool FLevelLocals::CheckIfExitIsGood (AActor *self, level_info_t *info)
{ {
cluster_info_t *cluster; cluster_info_t *clusterdef;
// The world can always exit itself. // The world can always exit itself.
if (self == NULL) if (self == NULL)
return true; return true;
// We must kill all monsters to exit the level. // We must kill all monsters to exit the Level
if ((dmflags2 & DF2_KILL_MONSTERS) && level.killed_monsters != level.total_monsters) if ((dmflags2 & DF2_KILL_MONSTERS) && killed_monsters != total_monsters)
return false; return false;
// Is this a deathmatch game and we're not allowed to exit? // Is this a deathmatch game and we're not allowed to exit?
@ -134,15 +134,15 @@ bool CheckIfExitIsGood (AActor *self, level_info_t *info)
if (self->health <= 0 && if (self->health <= 0 &&
!multiplayer && !multiplayer &&
info != NULL && info != NULL &&
info->cluster == level.cluster && info->cluster == cluster &&
(cluster = FindClusterInfo(level.cluster)) != NULL && (clusterdef = FindClusterInfo(cluster)) != NULL &&
cluster->flags & CLUSTER_HUB) clusterdef->flags & CLUSTER_HUB)
{ {
return false; return false;
} }
if (deathmatch && gameaction != ga_completed) if (deathmatch && gameaction != ga_completed)
{ {
Printf ("%s exited the level.\n", self->player->userinfo.GetName()); Printf ("%s exited the level\n", self->player->userinfo.GetName());
} }
return true; return true;
} }
@ -253,6 +253,7 @@ DEFINE_ACTION_FUNCTION(_Line, RemoteActivate)
bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType, DVector3 *optpos) bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType, DVector3 *optpos)
{ {
auto Level = &level;
int lineActivation = line->activation; int lineActivation = line->activation;
if (line->flags & ML_FIRSTSIDEONLY && side == 1) if (line->flags & ML_FIRSTSIDEONLY && side == 1)
@ -315,7 +316,7 @@ bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType,
// lax activation checks, monsters can also activate certain lines // lax activation checks, monsters can also activate certain lines
// even without them being marked as monster activate-able. This is // even without them being marked as monster activate-able. This is
// the default for non-Hexen maps in Hexen format. // the default for non-Hexen maps in Hexen format.
if (!(level.flags2 & LEVEL2_LAXMONSTERACTIVATION)) if (!(Level->flags2 & LEVEL2_LAXMONSTERACTIVATION))
{ {
return false; return false;
} }
@ -438,6 +439,8 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
// Has hit ground. // Has hit ground.
AActor *ironfeet; AActor *ironfeet;
auto Level = &level;
// [RH] Apply any customizable damage // [RH] Apply any customizable damage
if (sector->damageamount > 0) if (sector->damageamount > 0)
{ {
@ -459,7 +462,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
player->hazardtype = sector->damagetype; player->hazardtype = sector->damagetype;
player->hazardinterval = sector->damageinterval; player->hazardinterval = sector->damageinterval;
} }
else if (level.time % sector->damageinterval == 0) else if (Level->time % sector->damageinterval == 0)
{ {
if (!(player->cheats & (CF_GODMODE|CF_GODMODE2))) P_DamageMobj(player->mo, NULL, NULL, sector->damageamount, sector->damagetype); if (!(player->cheats & (CF_GODMODE|CF_GODMODE2))) P_DamageMobj(player->mo, NULL, NULL, sector->damageamount, sector->damagetype);
if ((sector->Flags & SECF_ENDLEVEL) && player->health <= 10 && (!deathmatch || !(dmflags & DF_NO_EXIT))) if ((sector->Flags & SECF_ENDLEVEL) && player->health <= 10 && (!deathmatch || !(dmflags & DF_NO_EXIT)))
@ -475,7 +478,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
} }
else if (sector->damageamount < 0) else if (sector->damageamount < 0)
{ {
if (level.time % sector->damageinterval == 0) if (Level->time % sector->damageinterval == 0)
{ {
P_GiveBody(player->mo, -sector->damageamount, 100); P_GiveBody(player->mo, -sector->damageamount, 100);
} }
@ -484,7 +487,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
if (sector->isSecret()) if (sector->isSecret())
{ {
sector->ClearSecret(); sector->ClearSecret();
P_GiveSecret(player->mo, true, true, sector->Index()); P_GiveSecret(Level, player->mo, true, true, sector->Index());
} }
} }
@ -518,14 +521,14 @@ static void DoSectorDamage(AActor *actor, sector_t *sec, int amount, FName type,
P_DamageMobj (actor, NULL, NULL, amount, type, dflags); P_DamageMobj (actor, NULL, NULL, amount, type, dflags);
} }
void P_SectorDamage(int tag, int amount, FName type, PClassActor *protectClass, int flags) void P_SectorDamage(FLevelLocals *Level, int tag, int amount, FName type, PClassActor *protectClass, int flags)
{ {
FSectorTagIterator itr(tag); FSectorTagIterator itr(tag);
int secnum; int secnum;
while ((secnum = itr.Next()) >= 0) while ((secnum = itr.Next()) >= 0)
{ {
AActor *actor, *next; AActor *actor, *next;
sector_t *sec = &level.sectors[secnum]; sector_t *sec = &Level->sectors[secnum];
// Do for actors in this sector. // Do for actors in this sector.
for (actor = sec->thinglist; actor != NULL; actor = next) for (actor = sec->thinglist; actor != NULL; actor = next)
@ -579,7 +582,7 @@ void P_SectorDamage(int tag, int amount, FName type, PClassActor *protectClass,
CVAR(Bool, showsecretsector, false, 0) CVAR(Bool, showsecretsector, false, 0)
CVAR(Bool, cl_showsecretmessage, true, CVAR_ARCHIVE) CVAR(Bool, cl_showsecretmessage, true, CVAR_ARCHIVE)
void P_GiveSecret(AActor *actor, bool printmessage, bool playsound, int sectornum) void P_GiveSecret(FLevelLocals *Level, AActor *actor, bool printmessage, bool playsound, int sectornum)
{ {
if (actor != NULL) if (actor != NULL)
{ {
@ -610,16 +613,16 @@ void P_GiveSecret(AActor *actor, bool printmessage, bool playsound, int sectornu
if (playsound) S_Sound (CHAN_AUTO | CHAN_UI, "misc/secret", 1, ATTN_NORM); if (playsound) S_Sound (CHAN_AUTO | CHAN_UI, "misc/secret", 1, ATTN_NORM);
} }
} }
level.found_secrets++; Level->found_secrets++;
} }
DEFINE_ACTION_FUNCTION(FLevelLocals, GiveSecret) DEFINE_ACTION_FUNCTION(FLevelLocals, GiveSecret)
{ {
PARAM_PROLOGUE; PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_OBJECT(activator, AActor); PARAM_OBJECT(activator, AActor);
PARAM_BOOL(printmessage); PARAM_BOOL(printmessage);
PARAM_BOOL(playsound); PARAM_BOOL(playsound);
P_GiveSecret(activator, printmessage, playsound, -1); P_GiveSecret(self, activator, printmessage, playsound, -1);
return 0; return 0;
} }
@ -631,8 +634,10 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, GiveSecret)
void P_PlayerOnSpecialFlat (player_t *player, int floorType) void P_PlayerOnSpecialFlat (player_t *player, int floorType)
{ {
auto Level = &level;
if (Terrains[floorType].DamageAmount && if (Terrains[floorType].DamageAmount &&
!(level.time & Terrains[floorType].DamageTimeMask)) !(Level->time & Terrains[floorType].DamageTimeMask))
{ {
AActor *ironfeet = NULL; AActor *ironfeet = NULL;
@ -669,12 +674,12 @@ void P_PlayerOnSpecialFlat (player_t *player, int floorType)
// //
EXTERN_CVAR (Float, timelimit) EXTERN_CVAR (Float, timelimit)
void P_UpdateSpecials () void P_UpdateSpecials (FLevelLocals *Level)
{ {
// LEVEL TIMER // LEVEL TIMER
if (deathmatch && timelimit) if (deathmatch && timelimit)
{ {
if (level.maptime >= (int)(timelimit * TICRATE * 60)) if (Level->maptime >= (int)(timelimit * TICRATE * 60))
{ {
Printf ("%s\n", GStrings("TXT_TIMELIMIT")); Printf ("%s\n", GStrings("TXT_TIMELIMIT"));
G_ExitLevel(0, false); G_ExitLevel(0, false);
@ -692,7 +697,8 @@ CUSTOM_CVAR (Bool, forcewater, false, CVAR_ARCHIVE|CVAR_SERVERINFO)
{ {
if (gamestate == GS_LEVEL) if (gamestate == GS_LEVEL)
{ {
for (auto &sec : level.sectors) auto Level = &level;
for (auto &sec : Level->sectors)
{ {
sector_t *hsec = sec.GetHeightSec(); sector_t *hsec = sec.GetHeightSec();
if (hsec && !(hsec->MoreFlags & SECMF_UNDERWATER)) if (hsec && !(hsec->MoreFlags & SECMF_UNDERWATER))
@ -721,7 +727,7 @@ public:
void Tick (); void Tick ();
protected: protected:
static void DoTransfer (int level, int target, bool floor); void DoTransfer (int level, int target, bool floor);
sector_t *Source; sector_t *Source;
int TargetTag; int TargetTag;
@ -749,17 +755,18 @@ DLightTransfer::DLightTransfer (sector_t *srcSec, int target, bool copyFloor)
CopyFloor = copyFloor; CopyFloor = copyFloor;
DoTransfer (LastLight = srcSec->lightlevel, target, copyFloor); DoTransfer (LastLight = srcSec->lightlevel, target, copyFloor);
auto Level = &level;
if (copyFloor) if (copyFloor)
{ {
FSectorTagIterator itr(target); FSectorTagIterator itr(target);
while ((secnum = itr.Next()) >= 0) while ((secnum = itr.Next()) >= 0)
level.sectors[secnum].ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING); Level->sectors[secnum].ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING);
} }
else else
{ {
FSectorTagIterator itr(target); FSectorTagIterator itr(target);
while ((secnum = itr.Next()) >= 0) while ((secnum = itr.Next()) >= 0)
level.sectors[secnum].ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING); Level->sectors[secnum].ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING);
} }
ChangeStatNum (STAT_LIGHTTRANSFER); ChangeStatNum (STAT_LIGHTTRANSFER);
} }
@ -779,17 +786,18 @@ void DLightTransfer::DoTransfer (int llevel, int target, bool floor)
{ {
int secnum; int secnum;
auto Level = &level;
if (floor) if (floor)
{ {
FSectorTagIterator itr(target); FSectorTagIterator itr(target);
while ((secnum = itr.Next()) >= 0) while ((secnum = itr.Next()) >= 0)
level.sectors[secnum].SetPlaneLight(sector_t::floor, llevel); Level->sectors[secnum].SetPlaneLight(sector_t::floor, llevel);
} }
else else
{ {
FSectorTagIterator itr(target); FSectorTagIterator itr(target);
while ((secnum = itr.Next()) >= 0) while ((secnum = itr.Next()) >= 0)
level.sectors[secnum].SetPlaneLight(sector_t::ceiling, llevel); Level->sectors[secnum].SetPlaneLight(sector_t::ceiling, llevel);
} }
} }
@ -811,7 +819,7 @@ public:
void Tick (); void Tick ();
protected: protected:
static void DoTransfer (short level, int target, uint8_t flags); void DoTransfer (short level, int target, uint8_t flags);
sector_t *Source; sector_t *Source;
int TargetID; int TargetID;
@ -850,16 +858,17 @@ DWallLightTransfer::DWallLightTransfer (sector_t *srcSec, int target, uint8_t fl
} }
FLineIdIterator itr(target); FLineIdIterator itr(target);
auto Level = &level;
while ((linenum = itr.Next()) >= 0) while ((linenum = itr.Next()) >= 0)
{ {
if (flags & WLF_SIDE1 && level.lines[linenum].sidedef[0] != NULL) if (flags & WLF_SIDE1 && Level->lines[linenum].sidedef[0] != NULL)
{ {
level.lines[linenum].sidedef[0]->Flags |= wallflags; Level->lines[linenum].sidedef[0]->Flags |= wallflags;
} }
if (flags & WLF_SIDE2 && level.lines[linenum].sidedef[1] != NULL) if (flags & WLF_SIDE2 && Level->lines[linenum].sidedef[1] != NULL)
{ {
level.lines[linenum].sidedef[1]->Flags |= wallflags; Level->lines[linenum].sidedef[1]->Flags |= wallflags;
} }
} }
ChangeStatNum(STAT_LIGHTTRANSFER); ChangeStatNum(STAT_LIGHTTRANSFER);
@ -880,10 +889,11 @@ void DWallLightTransfer::DoTransfer (short lightlevel, int target, uint8_t flags
{ {
int linenum; int linenum;
auto Level = &level;
FLineIdIterator itr(target); FLineIdIterator itr(target);
while ((linenum = itr.Next()) >= 0) while ((linenum = itr.Next()) >= 0)
{ {
line_t *line = &level.lines[linenum]; line_t *line = &Level->lines[linenum];
if (flags & WLF_SIDE1 && line->sidedef[0] != NULL) if (flags & WLF_SIDE1 && line->sidedef[0] != NULL)
{ {
@ -936,7 +946,7 @@ static void SetupCeilingPortal (AActor *point)
} }
} }
void P_SetupPortals() void P_SetupPortals(FLevelLocals *Level)
{ {
TThinkerIterator<AActor> it("StackPoint"); TThinkerIterator<AActor> it("StackPoint");
AActor *pt; AActor *pt;
@ -958,21 +968,21 @@ void P_SetupPortals()
} }
// the semantics here are incredibly lax so the final setup can only be done once all portals have been created, // the semantics here are incredibly lax so the final setup can only be done once all portals have been created,
// because later stackpoints will happily overwrite info in older ones, if there are multiple links. // because later stackpoints will happily overwrite info in older ones, if there are multiple links.
for (auto &s : level.sectorPortals) for (auto &s : Level->sectorPortals)
{ {
if (s.mType == PORTS_STACKEDSECTORTHING && s.mSkybox) if (s.mType == PORTS_STACKEDSECTORTHING && s.mSkybox)
{ {
for (auto &ss : level.sectorPortals) for (auto &ss : Level->sectorPortals)
{ {
if (ss.mType == PORTS_STACKEDSECTORTHING && ss.mSkybox == s.mSkybox->target) if (ss.mType == PORTS_STACKEDSECTORTHING && ss.mSkybox == s.mSkybox->target)
{ {
s.mPartner = unsigned((&ss) - &level.sectorPortals[0]); s.mPartner = unsigned((&ss) - &Level->sectorPortals[0]);
} }
} }
} }
} }
// Now we can finally set the displacement and delete the stackpoint reference. // Now we can finally set the displacement and delete the stackpoint reference.
for (auto &s : level.sectorPortals) for (auto &s : Level->sectorPortals)
{ {
if (s.mType == PORTS_STACKEDSECTORTHING && s.mSkybox) if (s.mType == PORTS_STACKEDSECTORTHING && s.mSkybox)
{ {
@ -982,7 +992,7 @@ void P_SetupPortals()
} }
} }
static void SetPortal(sector_t *sector, int plane, unsigned pnum, double alpha) static void SetPortal(FLevelLocals *Level, sector_t *sector, int plane, unsigned pnum, double alpha)
{ {
// plane: 0=floor, 1=ceiling, 2=both // plane: 0=floor, 1=ceiling, 2=both
if (plane > 0) if (plane > 0)
@ -993,7 +1003,7 @@ static void SetPortal(sector_t *sector, int plane, unsigned pnum, double alpha)
if (sector->GetAlpha(sector_t::ceiling) == 1.) if (sector->GetAlpha(sector_t::ceiling) == 1.)
sector->SetAlpha(sector_t::ceiling, alpha); sector->SetAlpha(sector_t::ceiling, alpha);
if (level.sectorPortals[pnum].mFlags & PORTSF_SKYFLATONLY) if (Level->sectorPortals[pnum].mFlags & PORTSF_SKYFLATONLY)
sector->SetTexture(sector_t::ceiling, skyflatnum); sector->SetTexture(sector_t::ceiling, skyflatnum);
} }
} }
@ -1006,21 +1016,21 @@ static void SetPortal(sector_t *sector, int plane, unsigned pnum, double alpha)
if (sector->GetAlpha(sector_t::floor) == 1.) if (sector->GetAlpha(sector_t::floor) == 1.)
sector->SetAlpha(sector_t::floor, alpha); sector->SetAlpha(sector_t::floor, alpha);
if (level.sectorPortals[pnum].mFlags & PORTSF_SKYFLATONLY) if (Level->sectorPortals[pnum].mFlags & PORTSF_SKYFLATONLY)
sector->SetTexture(sector_t::floor, skyflatnum); sector->SetTexture(sector_t::floor, skyflatnum);
} }
} }
static void CopyPortal(int sectortag, int plane, unsigned pnum, double alpha, bool tolines) static void CopyPortal(FLevelLocals *Level, int sectortag, int plane, unsigned pnum, double alpha, bool tolines)
{ {
int s; int s;
FSectorTagIterator itr(sectortag); FSectorTagIterator itr(sectortag);
while ((s = itr.Next()) >= 0) while ((s = itr.Next()) >= 0)
{ {
SetPortal(&level.sectors[s], plane, pnum, alpha); SetPortal(Level, &Level->sectors[s], plane, pnum, alpha);
} }
for (auto &line : level.lines) for (auto &line : Level->lines)
{ {
// Check if this portal needs to be copied to other sectors // Check if this portal needs to be copied to other sectors
// This must be done here to ensure that it gets done only after the portal is set up // This must be done here to ensure that it gets done only after the portal is set up
@ -1031,14 +1041,14 @@ static void CopyPortal(int sectortag, int plane, unsigned pnum, double alpha, bo
{ {
if (line.args[0] == 0) if (line.args[0] == 0)
{ {
SetPortal(line.frontsector, plane, pnum, alpha); SetPortal(Level, line.frontsector, plane, pnum, alpha);
} }
else else
{ {
FSectorTagIterator itr(line.args[0]); FSectorTagIterator itr(line.args[0]);
while ((s = itr.Next()) >= 0) while ((s = itr.Next()) >= 0)
{ {
SetPortal(&level.sectors[s], plane, pnum, alpha); SetPortal(Level, &Level->sectors[s], plane, pnum, alpha);
} }
} }
} }
@ -1055,7 +1065,7 @@ static void CopyPortal(int sectortag, int plane, unsigned pnum, double alpha, bo
FLineIdIterator itr(line.args[0]); FLineIdIterator itr(line.args[0]);
while ((s = itr.Next()) >= 0) while ((s = itr.Next()) >= 0)
{ {
level.lines[s].portaltransferred = pnum; Level->lines[s].portaltransferred = pnum;
} }
} }
} }
@ -1063,10 +1073,10 @@ static void CopyPortal(int sectortag, int plane, unsigned pnum, double alpha, bo
} }
void P_SpawnPortal(line_t *line, int sectortag, int plane, int bytealpha, int linked) void P_SpawnPortal(FLevelLocals *Level, line_t *line, int sectortag, int plane, int bytealpha, int linked)
{ {
if (plane < 0 || plane > 2 || (linked && plane == 2)) return; if (plane < 0 || plane > 2 || (linked && plane == 2)) return;
for (auto &oline : level.lines) for (auto &oline : Level->lines)
{ {
// We must look for the reference line with a linear search unless we want to waste the line ID for it // We must look for the reference line with a linear search unless we want to waste the line ID for it
// which is not a good idea. // which is not a good idea.
@ -1080,7 +1090,7 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int bytealpha, int li
DVector2 pos1 = line->v1->fPos() + line->Delta() / 2; DVector2 pos1 = line->v1->fPos() + line->Delta() / 2;
DVector2 pos2 = oline.v1->fPos() + oline.Delta() / 2; DVector2 pos2 = oline.v1->fPos() + oline.Delta() / 2;
unsigned pnum = P_GetPortal(linked ? PORTS_LINKEDPORTAL : PORTS_PORTAL, plane, line->frontsector, oline.frontsector, pos2 - pos1); unsigned pnum = P_GetPortal(linked ? PORTS_LINKEDPORTAL : PORTS_PORTAL, plane, line->frontsector, oline.frontsector, pos2 - pos1);
CopyPortal(sectortag, plane, pnum, bytealpha / 255., false); CopyPortal(Level, sectortag, plane, pnum, bytealpha / 255., false);
return; return;
} }
} }
@ -1088,7 +1098,7 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int bytealpha, int li
// This searches the viewpoint's sector // This searches the viewpoint's sector
// for a skybox line special, gets its tag and transfers the skybox to all tagged sectors. // for a skybox line special, gets its tag and transfers the skybox to all tagged sectors.
void P_SpawnSkybox(AActor *origin) void P_SpawnSkybox(FLevelLocals *Level, AActor *origin)
{ {
sector_t *Sector = origin->Sector; sector_t *Sector = origin->Sector;
if (Sector == NULL) if (Sector == NULL)
@ -1104,7 +1114,7 @@ void P_SpawnSkybox(AActor *origin)
{ {
// We found the setup linedef for this skybox, so let's use it for our init. // We found the setup linedef for this skybox, so let's use it for our init.
unsigned pnum = P_GetSkyboxPortal(origin); unsigned pnum = P_GetSkyboxPortal(origin);
CopyPortal(refline->args[0], refline->args[2], pnum, 0, true); CopyPortal(Level, refline->args[0], refline->args[2], pnum, 0, true);
return; return;
} }
} }
@ -1140,13 +1150,13 @@ static void P_SetupSectorDamage(sector_t *sector, int damage, int interval, int
// //
void P_SpawnLights(sector_t *sector); void P_SpawnLights(sector_t *sector);
void P_InitSectorSpecial(sector_t *sector, int special) void P_InitSectorSpecial(FLevelLocals *Level, sector_t *sector, int special)
{ {
// [RH] All secret sectors are marked with a BOOM-ish bitfield // [RH] All secret sectors are marked with a BOOM-ish bitfield
if (sector->special & SECRET_MASK) if (sector->special & SECRET_MASK)
{ {
sector->Flags |= SECF_SECRET | SECF_WASSECRET; sector->Flags |= SECF_SECRET | SECF_WASSECRET;
level.total_secrets++; Level->total_secrets++;
} }
if (sector->special & FRICTION_MASK) if (sector->special & FRICTION_MASK)
{ {
@ -1298,14 +1308,15 @@ void P_InitSectorSpecial(sector_t *sector, int special)
void P_SpawnSpecials (MapLoader *ml) void P_SpawnSpecials (MapLoader *ml)
{ {
P_SetupPortals(); auto Level = ml->Level;
P_SetupPortals(Level);
for (auto &sec : level.sectors) for (auto &sec : Level->sectors)
{ {
if (sec.special == 0) if (sec.special == 0)
continue; continue;
P_InitSectorSpecial(&sec, sec.special); P_InitSectorSpecial(Level, &sec, sec.special);
} }
#ifndef NO_EDATA #ifndef NO_EDATA
@ -1315,18 +1326,18 @@ void P_SpawnSpecials (MapLoader *ml)
// Init other misc stuff // Init other misc stuff
P_SpawnScrollers(&level); // killough 3/7/98: Add generalized scrollers P_SpawnScrollers(Level); // killough 3/7/98: Add generalized scrollers
P_SpawnFriction(); // phares 3/12/98: New friction model using linedefs P_SpawnFriction(Level); // phares 3/12/98: New friction model using linedefs
P_SpawnPushers(); // phares 3/20/98: New pusher model using linedefs P_SpawnPushers(); // phares 3/20/98: New pusher model using linedefs
TThinkerIterator<AActor> it2("SkyCamCompat"); TThinkerIterator<AActor> it2("SkyCamCompat");
AActor *pt2; AActor *pt2;
while ((pt2 = it2.Next())) while ((pt2 = it2.Next()))
{ {
P_SpawnSkybox(pt2); P_SpawnSkybox(Level, pt2);
} }
for (auto &line : level.lines) for (auto &line : Level->lines)
{ {
switch (line.special) switch (line.special)
{ {
@ -1359,7 +1370,7 @@ void P_SpawnSpecials (MapLoader *ml)
{ {
sec->MoreFlags |= SECMF_IGNOREHEIGHTSEC; sec->MoreFlags |= SECMF_IGNOREHEIGHTSEC;
} }
else level.HasHeightSecs = true; else Level->HasHeightSecs = true;
if (line.args[1] & 32) if (line.args[1] & 32)
{ {
sec->MoreFlags |= SECMF_NOFAKELIGHT; sec->MoreFlags |= SECMF_NOFAKELIGHT;
@ -1367,10 +1378,10 @@ void P_SpawnSpecials (MapLoader *ml)
FSectorTagIterator itr(line.args[0]); FSectorTagIterator itr(line.args[0]);
while ((s = itr.Next()) >= 0) while ((s = itr.Next()) >= 0)
{ {
level.sectors[s].heightsec = sec; Level->sectors[s].heightsec = sec;
sec->e->FakeFloor.Sectors.Push(&level.sectors[s]); sec->e->FakeFloor.Sectors.Push(&Level->sectors[s]);
level.sectors[s].MoreFlags |= (sec->MoreFlags & SECMF_IGNOREHEIGHTSEC); // copy this to the destination sector for easier checking. Level->sectors[s].MoreFlags |= (sec->MoreFlags & SECMF_IGNOREHEIGHTSEC); // copy this to the destination sector for easier checking.
level.sectors[s].AdjustFloorClip(); Level->sectors[s].AdjustFloorClip();
} }
break; break;
} }
@ -1420,12 +1431,12 @@ void P_SpawnSpecials (MapLoader *ml)
// arg 4 = for the anchor only: alpha // arg 4 = for the anchor only: alpha
if ((line.args[1] == 0 || line.args[1] == 6) && line.args[3] == 0) if ((line.args[1] == 0 || line.args[1] == 6) && line.args[3] == 0)
{ {
P_SpawnPortal(&line, line.args[0], line.args[2], line.args[4], line.args[1]); P_SpawnPortal(Level, &line, line.args[0], line.args[2], line.args[4], line.args[1]);
} }
else if (line.args[1] == 3 || line.args[1] == 4) else if (line.args[1] == 3 || line.args[1] == 4)
{ {
unsigned pnum = P_GetPortal(line.args[1] == 3 ? PORTS_PLANE : PORTS_HORIZON, line.args[2], line.frontsector, NULL, { 0,0 }); unsigned pnum = P_GetPortal(line.args[1] == 3 ? PORTS_PLANE : PORTS_HORIZON, line.args[2], line.frontsector, NULL, { 0,0 });
CopyPortal(line.args[0], line.args[2], pnum, 0, true); CopyPortal(Level, line.args[0], line.args[2], pnum, 0, true);
} }
break; break;
@ -1442,7 +1453,7 @@ void P_SpawnSpecials (MapLoader *ml)
double grav = line.Delta().Length() / 100.; double grav = line.Delta().Length() / 100.;
FSectorTagIterator itr(line.args[0]); FSectorTagIterator itr(line.args[0]);
while ((s = itr.Next()) >= 0) while ((s = itr.Next()) >= 0)
level.sectors[s].gravity = grav; Level->sectors[s].gravity = grav;
} }
break; break;
@ -1455,7 +1466,7 @@ void P_SpawnSpecials (MapLoader *ml)
FSectorTagIterator itr(line.args[0]); FSectorTagIterator itr(line.args[0]);
while ((s = itr.Next()) >= 0) while ((s = itr.Next()) >= 0)
{ {
sector_t *sec = &level.sectors[s]; sector_t *sec = &Level->sectors[s];
sec->damageamount = damage; sec->damageamount = damage;
sec->damagetype = NAME_None; sec->damagetype = NAME_None;
if (sec->damageamount < 20) if (sec->damageamount < 20)
@ -1495,7 +1506,7 @@ void P_SpawnSpecials (MapLoader *ml)
{ {
FSectorTagIterator itr(line.args[0]); FSectorTagIterator itr(line.args[0]);
while ((s = itr.Next()) >= 0) while ((s = itr.Next()) >= 0)
level.sectors[s].sky = (line.Index() + 1) | PL_SKYFLAT; Level->sectors[s].sky = (line.Index() + 1) | PL_SKYFLAT;
break; break;
} }
} }
@ -1559,11 +1570,11 @@ void P_SpawnSpecials (MapLoader *ml)
// //
// Initialize the sectors where friction is increased or decreased // Initialize the sectors where friction is increased or decreased
static void P_SpawnFriction(void) static void P_SpawnFriction(FLevelLocals *Level)
{ {
line_t *l = &level.lines[0]; line_t *l = &Level->lines[0];
for (unsigned i = 0 ; i < level.lines.Size() ; i++,l++) for (unsigned i = 0 ; i < Level->lines.Size() ; i++,l++)
{ {
if (l->special == Sector_SetFriction) if (l->special == Sector_SetFriction)
{ {
@ -1578,13 +1589,13 @@ static void P_SpawnFriction(void)
length = int(l->Delta().Length()); length = int(l->Delta().Length());
} }
P_SetSectorFriction (l->args[0], length, false); P_SetSectorFriction (Level, l->args[0], length, false);
l->special = 0; l->special = 0;
} }
} }
} }
void P_SetSectorFriction (int tag, int amount, bool alterFlag) void P_SetSectorFriction (FLevelLocals *Level, int tag, int amount, bool alterFlag)
{ {
int s; int s;
double friction, movefactor; double friction, movefactor;
@ -1614,19 +1625,19 @@ void P_SetSectorFriction (int tag, int amount, bool alterFlag)
// drag on CPU. New code adjusts friction of sector only once // drag on CPU. New code adjusts friction of sector only once
// at level startup, and then uses this friction value. // at level startup, and then uses this friction value.
level.sectors[s].friction = friction; Level->sectors[s].friction = friction;
level.sectors[s].movefactor = movefactor; Level->sectors[s].movefactor = movefactor;
if (alterFlag) if (alterFlag)
{ {
// When used inside a script, the sectors' friction flags // When used inside a script, the sectors' friction flags
// can be enabled and disabled at will. // can be enabled and disabled at will.
if (friction == ORIG_FRICTION) if (friction == ORIG_FRICTION)
{ {
level.sectors[s].Flags &= ~SECF_FRICTION; Level->sectors[s].Flags &= ~SECF_FRICTION;
} }
else else
{ {
level.sectors[s].Flags |= SECF_FRICTION; Level->sectors[s].Flags |= SECF_FRICTION;
} }
} }
} }

View file

@ -87,17 +87,12 @@ const double CARRYFACTOR = 3 / 32.;
#define DAMAGE_NO_ARMOR 16 #define DAMAGE_NO_ARMOR 16
// [RH] If a deathmatch game, checks to see if noexit is enabled.
// If so, it kills the player and returns false. Otherwise,
// it returns true, and the player is allowed to live.
bool CheckIfExitIsGood (AActor *self, level_info_t *info);
class MapLoader; class MapLoader;
// at map load // at map load
void P_SpawnSpecials (MapLoader *ml); void P_SpawnSpecials (MapLoader *ml);
// every tic // every tic
void P_UpdateSpecials (void); void P_UpdateSpecials (FLevelLocals *);
// when needed // when needed
bool P_ActivateLine (line_t *ld, AActor *mo, int side, int activationType, DVector3 *optpos = NULL); bool P_ActivateLine (line_t *ld, AActor *mo, int side, int activationType, DVector3 *optpos = NULL);
@ -106,10 +101,10 @@ bool P_PredictLine (line_t *ld, AActor *mo, int side, int activationType);
void P_PlayerInSpecialSector (player_t *player, sector_t * sector=NULL); void P_PlayerInSpecialSector (player_t *player, sector_t * sector=NULL);
void P_PlayerOnSpecialFlat (player_t *player, int floorType); void P_PlayerOnSpecialFlat (player_t *player, int floorType);
void P_SectorDamage(int tag, int amount, FName type, PClassActor *protectClass, int flags); void P_SectorDamage(FLevelLocals *Level, int tag, int amount, FName type, PClassActor *protectClass, int flags);
void P_SetSectorFriction (int tag, int amount, bool alterFlag); void P_SetSectorFriction (FLevelLocals *level, int tag, int amount, bool alterFlag);
double FrictionToMoveFactor(double friction); double FrictionToMoveFactor(double friction);
void P_GiveSecret(AActor *actor, bool printmessage, bool playsound, int sectornum); void P_GiveSecret(FLevelLocals *Level, AActor *actor, bool printmessage, bool playsound, int sectornum);
// //
// getNextSector() // getNextSector()

View file

@ -144,7 +144,7 @@ void P_Ticker (void)
//if added by MC: Freeze mode. //if added by MC: Freeze mode.
if (!bglobal.freeze && !(level.flags2 & LEVEL2_FROZEN)) if (!bglobal.freeze && !(level.flags2 & LEVEL2_FROZEN))
{ {
P_UpdateSpecials (); P_UpdateSpecials (&level);
P_RunEffects (); // [RH] Run particle effects P_RunEffects (); // [RH] Run particle effects
} }

View file

@ -1325,7 +1325,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckSight, P_CheckSight)
static void GiveSecret(AActor *self, bool printmessage, bool playsound) static void GiveSecret(AActor *self, bool printmessage, bool playsound)
{ {
P_GiveSecret(self, printmessage, playsound, -1); P_GiveSecret(&level, self, printmessage, playsound, -1);
} }
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GiveSecret, GiveSecret) DEFINE_ACTION_FUNCTION_NATIVE(AActor, GiveSecret, GiveSecret)
@ -1333,7 +1333,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, GiveSecret, GiveSecret)
PARAM_SELF_PROLOGUE(AActor); PARAM_SELF_PROLOGUE(AActor);
PARAM_BOOL(printmessage); PARAM_BOOL(printmessage);
PARAM_BOOL(playsound); PARAM_BOOL(playsound);
P_GiveSecret(self, printmessage, playsound, -1); GiveSecret(self, printmessage, playsound);
return 0; return 0;
} }