- removed all level references in p_spec.cpp.

This commit is contained in:
Christoph Oelckers 2019-01-06 12:39:52 +01:00
parent 55339761f6
commit f93eb1ca7f
15 changed files with 116 additions and 97 deletions

View file

@ -54,6 +54,7 @@ struct FPortalGroupArray;
struct visstyle_t;
class FLightDefaults;
struct FSection;
struct FLevelLocals;
//
// NOTES: AActor
//
@ -642,6 +643,8 @@ public:
AActor &operator= (const AActor &other);
~AActor ();
FLevelLocals *__GetLevel(); // With double underscore so that it can be replaced later, once a permanent solution has been implemented.
virtual void OnDestroy() override;
virtual void Serialize(FSerializer &arc) override;
virtual void PostSerialize() override;

View file

@ -92,4 +92,10 @@ inline double AActor::AttackOffset(double offset)
return 8 + offset;
}
}
}
// Needs something more permanent.
inline FLevelLocals *AActor::__GetLevel()
{
return &level;
}

View file

@ -112,6 +112,7 @@ struct FLevelLocals : public FLevelData
void SetMusicVolume(float v);
void ClearLevelData();
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.
int time; // time in the hub

View file

@ -1029,6 +1029,7 @@ void MapLoader::LoadSectors (MapData *map, FMissingTextureTracker &missingtex)
for (unsigned i = 0; i < numsectors; i++, ss++, ms++)
{
ss->e = &sectors[0].e[i];
ss->Level = Level;
if (!map->HasBehavior) ss->Flags |= SECF_FLOORDROP;
ss->SetPlaneTexZ(sector_t::floor, (double)LittleShort(ms->floorheight));
ss->floorplane.set(0, 0, 1., -ss->GetPlaneTexZ(sector_t::floor));

View file

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

View file

@ -2278,6 +2278,7 @@ public:
for(unsigned i = 0; i < Level->sectors.Size(); i++)
{
Level->sectors[i].e = &Level->sectors[0].e[i];
Level->sectors[i].Level = Level;
}
// Now create the scrollers.
for (auto &scroll : UDMFScrollers)

View file

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

View file

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

View file

@ -1060,7 +1060,7 @@ FUNC(LS_Generic_Lift)
FUNC(LS_Exit_Normal)
// Exit_Normal (position)
{
if (CheckIfExitIsGood (it, FindLevelInfo(G_GetExitMap())))
if (level.CheckIfExitIsGood (it, FindLevelInfo(G_GetExitMap())))
{
G_ExitLevel (arg0, false);
return true;
@ -1071,7 +1071,7 @@ FUNC(LS_Exit_Normal)
FUNC(LS_Exit_Secret)
// Exit_Secret (position)
{
if (CheckIfExitIsGood (it, FindLevelInfo(G_GetSecretExitMap())))
if (level.CheckIfExitIsGood (it, FindLevelInfo(G_GetSecretExitMap())))
{
G_SecretExitLevel (arg0);
return true;
@ -1086,7 +1086,7 @@ FUNC(LS_Teleport_NewMap)
{
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);
return true;
@ -1181,7 +1181,7 @@ FUNC(LS_TeleportInSector)
FUNC(LS_Teleport_EndGame)
// Teleport_EndGame ()
{
if (!backSide && CheckIfExitIsGood (it, NULL))
if (!backSide && level.CheckIfExitIsGood (it, NULL))
{
G_ChangeLevel(NULL, 0, 0);
return true;
@ -2252,7 +2252,7 @@ FUNC(LS_Sector_SetCurrent)
FUNC(LS_Sector_SetFriction)
// Sector_SetFriction (tag, amount)
{
P_SetSectorFriction (arg0, arg1, true);
P_SetSectorFriction (&level, arg0, arg1, true);
return true;
}

View file

@ -107,21 +107,21 @@ EXTERN_CVAR(Bool, cl_predict_specials)
// killough 3/7/98: Initialize generalized scrolling
void P_SpawnScrollers();
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
// [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.
if (self == NULL)
return true;
// We must kill all monsters to exit the level.
if ((dmflags2 & DF2_KILL_MONSTERS) && level.killed_monsters != level.total_monsters)
// We must kill all monsters to exit the Level
if ((dmflags2 & DF2_KILL_MONSTERS) && killed_monsters != total_monsters)
return false;
// 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 &&
!multiplayer &&
info != NULL &&
info->cluster == level.cluster &&
(cluster = FindClusterInfo(level.cluster)) != NULL &&
cluster->flags & CLUSTER_HUB)
info->cluster == cluster &&
(clusterdef = FindClusterInfo(cluster)) != NULL &&
clusterdef->flags & CLUSTER_HUB)
{
return false;
}
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;
}
@ -204,7 +204,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType, DVe
}
// some old WADs use this method to create walls that change the texture when shot.
else if (activationType == SPAC_Impact && // only for shootable triggers
(level.flags2 & LEVEL2_DUMMYSWITCHES) && // this is only a compatibility setting for an old hack!
(line->frontsector->Level->flags2 & LEVEL2_DUMMYSWITCHES) && // this is only a compatibility setting for an old hack!
!repeat && // only non-repeatable triggers
(special<Generic_Floor || special>Generic_Crusher) && // not for Boom's generalized linedefs
special && // not for lines without a special
@ -315,7 +315,7 @@ bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType,
// lax activation checks, monsters can also activate certain lines
// even without them being marked as monster activate-able. This is
// the default for non-Hexen maps in Hexen format.
if (!(level.flags2 & LEVEL2_LAXMONSTERACTIVATION))
if (!(line->frontsector->Level->flags2 & LEVEL2_LAXMONSTERACTIVATION))
{
return false;
}
@ -438,6 +438,8 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
// Has hit ground.
AActor *ironfeet;
auto Level = sector->Level;
// [RH] Apply any customizable damage
if (sector->damageamount > 0)
{
@ -459,7 +461,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
player->hazardtype = sector->damagetype;
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 ((sector->Flags & SECF_ENDLEVEL) && player->health <= 10 && (!deathmatch || !(dmflags & DF_NO_EXIT)))
@ -475,7 +477,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
}
else if (sector->damageamount < 0)
{
if (level.time % sector->damageinterval == 0)
if (Level->time % sector->damageinterval == 0)
{
P_GiveBody(player->mo, -sector->damageamount, 100);
}
@ -484,7 +486,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
if (sector->isSecret())
{
sector->ClearSecret();
P_GiveSecret(player->mo, true, true, sector->Index());
P_GiveSecret(Level, player->mo, true, true, sector->Index());
}
}
@ -518,14 +520,14 @@ static void DoSectorDamage(AActor *actor, sector_t *sec, int amount, FName type,
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);
int secnum;
while ((secnum = itr.Next()) >= 0)
{
AActor *actor, *next;
sector_t *sec = &level.sectors[secnum];
sector_t *sec = &Level->sectors[secnum];
// Do for actors in this sector.
for (actor = sec->thinglist; actor != NULL; actor = next)
@ -579,7 +581,7 @@ void P_SectorDamage(int tag, int amount, FName type, PClassActor *protectClass,
CVAR(Bool, showsecretsector, false, 0)
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)
{
@ -610,16 +612,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);
}
}
level.found_secrets++;
Level->found_secrets++;
}
DEFINE_ACTION_FUNCTION(FLevelLocals, GiveSecret)
{
PARAM_PROLOGUE;
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_OBJECT(activator, AActor);
PARAM_BOOL(printmessage);
PARAM_BOOL(playsound);
P_GiveSecret(activator, printmessage, playsound, -1);
P_GiveSecret(self, activator, printmessage, playsound, -1);
return 0;
}
@ -631,8 +633,10 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, GiveSecret)
void P_PlayerOnSpecialFlat (player_t *player, int floorType)
{
auto Level = player->mo->__GetLevel();
if (Terrains[floorType].DamageAmount &&
!(level.time & Terrains[floorType].DamageTimeMask))
!(Level->time & Terrains[floorType].DamageTimeMask))
{
AActor *ironfeet = NULL;
@ -669,12 +673,12 @@ void P_PlayerOnSpecialFlat (player_t *player, int floorType)
//
EXTERN_CVAR (Float, timelimit)
void P_UpdateSpecials ()
void P_UpdateSpecials (FLevelLocals *Level)
{
// LEVEL TIMER
if (deathmatch && timelimit)
{
if (level.maptime >= (int)(timelimit * TICRATE * 60))
if (Level->maptime >= (int)(timelimit * TICRATE * 60))
{
Printf ("%s\n", GStrings("TXT_TIMELIMIT"));
G_ExitLevel(0, false);
@ -692,7 +696,8 @@ CUSTOM_CVAR (Bool, forcewater, false, CVAR_ARCHIVE|CVAR_SERVERINFO)
{
if (gamestate == GS_LEVEL)
{
for (auto &sec : level.sectors)
auto Level = players[consoleplayer].mo->__GetLevel();
for (auto &sec : Level->sectors)
{
sector_t *hsec = sec.GetHeightSec();
if (hsec && !(hsec->MoreFlags & SECMF_UNDERWATER))
@ -721,7 +726,7 @@ public:
void Tick ();
protected:
static void DoTransfer (int level, int target, bool floor);
void DoTransfer (int level, int target, bool floor);
sector_t *Source;
int TargetTag;
@ -749,17 +754,18 @@ DLightTransfer::DLightTransfer (sector_t *srcSec, int target, bool copyFloor)
CopyFloor = copyFloor;
DoTransfer (LastLight = srcSec->lightlevel, target, copyFloor);
auto Level = Source->Level;
if (copyFloor)
{
FSectorTagIterator itr(target);
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
{
FSectorTagIterator itr(target);
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);
}
@ -779,17 +785,18 @@ void DLightTransfer::DoTransfer (int llevel, int target, bool floor)
{
int secnum;
auto Level = Source->Level;
if (floor)
{
FSectorTagIterator itr(target);
while ((secnum = itr.Next()) >= 0)
level.sectors[secnum].SetPlaneLight(sector_t::floor, llevel);
Level->sectors[secnum].SetPlaneLight(sector_t::floor, llevel);
}
else
{
FSectorTagIterator itr(target);
while ((secnum = itr.Next()) >= 0)
level.sectors[secnum].SetPlaneLight(sector_t::ceiling, llevel);
Level->sectors[secnum].SetPlaneLight(sector_t::ceiling, llevel);
}
}
@ -811,7 +818,7 @@ public:
void Tick ();
protected:
static void DoTransfer (short level, int target, uint8_t flags);
void DoTransfer (short level, int target, uint8_t flags);
sector_t *Source;
int TargetID;
@ -850,16 +857,17 @@ DWallLightTransfer::DWallLightTransfer (sector_t *srcSec, int target, uint8_t fl
}
FLineIdIterator itr(target);
auto Level = Source->Level;
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);
@ -880,10 +888,11 @@ void DWallLightTransfer::DoTransfer (short lightlevel, int target, uint8_t flags
{
int linenum;
auto Level = Source->Level;
FLineIdIterator itr(target);
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)
{
@ -936,7 +945,7 @@ static void SetupCeilingPortal (AActor *point)
}
}
void P_SetupPortals()
void P_SetupPortals(FLevelLocals *Level)
{
TThinkerIterator<AActor> it("StackPoint");
AActor *pt;
@ -958,21 +967,21 @@ void P_SetupPortals()
}
// 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.
for (auto &s : level.sectorPortals)
for (auto &s : Level->sectorPortals)
{
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)
{
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.
for (auto &s : level.sectorPortals)
for (auto &s : Level->sectorPortals)
{
if (s.mType == PORTS_STACKEDSECTORTHING && s.mSkybox)
{
@ -993,7 +1002,7 @@ static void SetPortal(sector_t *sector, int plane, unsigned pnum, double alpha)
if (sector->GetAlpha(sector_t::ceiling) == 1.)
sector->SetAlpha(sector_t::ceiling, alpha);
if (level.sectorPortals[pnum].mFlags & PORTSF_SKYFLATONLY)
if (sector->Level->sectorPortals[pnum].mFlags & PORTSF_SKYFLATONLY)
sector->SetTexture(sector_t::ceiling, skyflatnum);
}
}
@ -1006,21 +1015,21 @@ static void SetPortal(sector_t *sector, int plane, unsigned pnum, double alpha)
if (sector->GetAlpha(sector_t::floor) == 1.)
sector->SetAlpha(sector_t::floor, alpha);
if (level.sectorPortals[pnum].mFlags & PORTSF_SKYFLATONLY)
if (sector->Level->sectorPortals[pnum].mFlags & PORTSF_SKYFLATONLY)
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;
FSectorTagIterator itr(sectortag);
while ((s = itr.Next()) >= 0)
{
SetPortal(&level.sectors[s], plane, pnum, alpha);
SetPortal(&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
// This must be done here to ensure that it gets done only after the portal is set up
@ -1038,7 +1047,7 @@ static void CopyPortal(int sectortag, int plane, unsigned pnum, double alpha, bo
FSectorTagIterator itr(line.args[0]);
while ((s = itr.Next()) >= 0)
{
SetPortal(&level.sectors[s], plane, pnum, alpha);
SetPortal(&Level->sectors[s], plane, pnum, alpha);
}
}
}
@ -1055,7 +1064,7 @@ static void CopyPortal(int sectortag, int plane, unsigned pnum, double alpha, bo
FLineIdIterator itr(line.args[0]);
while ((s = itr.Next()) >= 0)
{
level.lines[s].portaltransferred = pnum;
Level->lines[s].portaltransferred = pnum;
}
}
}
@ -1063,10 +1072,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;
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
// which is not a good idea.
@ -1080,7 +1089,7 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int bytealpha, int li
DVector2 pos1 = line->v1->fPos() + line->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);
CopyPortal(sectortag, plane, pnum, bytealpha / 255., false);
CopyPortal(Level, sectortag, plane, pnum, bytealpha / 255., false);
return;
}
}
@ -1104,7 +1113,7 @@ void P_SpawnSkybox(AActor *origin)
{
// We found the setup linedef for this skybox, so let's use it for our init.
unsigned pnum = P_GetSkyboxPortal(origin);
CopyPortal(refline->args[0], refline->args[2], pnum, 0, true);
CopyPortal(Sector->Level, refline->args[0], refline->args[2], pnum, 0, true);
return;
}
}
@ -1146,7 +1155,7 @@ void P_InitSectorSpecial(sector_t *sector, int special)
if (sector->special & SECRET_MASK)
{
sector->Flags |= SECF_SECRET | SECF_WASSECRET;
level.total_secrets++;
sector->Level->total_secrets++;
}
if (sector->special & FRICTION_MASK)
{
@ -1300,9 +1309,10 @@ void P_InitSectorSpecial(sector_t *sector, int special)
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)
continue;
@ -1318,7 +1328,7 @@ void P_SpawnSpecials (MapLoader *ml)
// Init other misc stuff
P_SpawnScrollers(); // 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
TThinkerIterator<AActor> it2("SkyCamCompat");
@ -1328,7 +1338,7 @@ void P_SpawnSpecials (MapLoader *ml)
P_SpawnSkybox(pt2);
}
for (auto &line : level.lines)
for (auto &line : Level->lines)
{
switch (line.special)
{
@ -1361,7 +1371,7 @@ void P_SpawnSpecials (MapLoader *ml)
{
sec->MoreFlags |= SECMF_IGNOREHEIGHTSEC;
}
else level.HasHeightSecs = true;
else Level->HasHeightSecs = true;
if (line.args[1] & 32)
{
sec->MoreFlags |= SECMF_NOFAKELIGHT;
@ -1369,10 +1379,10 @@ void P_SpawnSpecials (MapLoader *ml)
FSectorTagIterator itr(line.args[0]);
while ((s = itr.Next()) >= 0)
{
level.sectors[s].heightsec = sec;
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].AdjustFloorClip();
Level->sectors[s].heightsec = sec;
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].AdjustFloorClip();
}
break;
}
@ -1422,12 +1432,12 @@ void P_SpawnSpecials (MapLoader *ml)
// arg 4 = for the anchor only: alpha
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)
{
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;
@ -1444,7 +1454,7 @@ void P_SpawnSpecials (MapLoader *ml)
double grav = line.Delta().Length() / 100.;
FSectorTagIterator itr(line.args[0]);
while ((s = itr.Next()) >= 0)
level.sectors[s].gravity = grav;
Level->sectors[s].gravity = grav;
}
break;
@ -1457,7 +1467,7 @@ void P_SpawnSpecials (MapLoader *ml)
FSectorTagIterator itr(line.args[0]);
while ((s = itr.Next()) >= 0)
{
sector_t *sec = &level.sectors[s];
sector_t *sec = &Level->sectors[s];
sec->damageamount = damage;
sec->damagetype = NAME_None;
if (sec->damageamount < 20)
@ -1497,7 +1507,7 @@ void P_SpawnSpecials (MapLoader *ml)
{
FSectorTagIterator itr(line.args[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;
}
}
@ -1561,11 +1571,11 @@ void P_SpawnSpecials (MapLoader *ml)
//
// 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)
{
@ -1580,13 +1590,13 @@ static void P_SpawnFriction(void)
length = int(l->Delta().Length());
}
P_SetSectorFriction (l->args[0], length, false);
P_SetSectorFriction (Level, l->args[0], length, false);
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;
double friction, movefactor;
@ -1616,19 +1626,19 @@ void P_SetSectorFriction (int tag, int amount, bool alterFlag)
// drag on CPU. New code adjusts friction of sector only once
// at level startup, and then uses this friction value.
level.sectors[s].friction = friction;
level.sectors[s].movefactor = movefactor;
Level->sectors[s].friction = friction;
Level->sectors[s].movefactor = movefactor;
if (alterFlag)
{
// When used inside a script, the sectors' friction flags
// can be enabled and disabled at will.
if (friction == ORIG_FRICTION)
{
level.sectors[s].Flags &= ~SECF_FRICTION;
Level->sectors[s].Flags &= ~SECF_FRICTION;
}
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
// [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;
// at map load
void P_SpawnSpecials (MapLoader *ml);
// every tic
void P_UpdateSpecials (void);
void P_UpdateSpecials (FLevelLocals *);
// when needed
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_PlayerOnSpecialFlat (player_t *player, int floorType);
void P_SectorDamage(int tag, int amount, FName type, PClassActor *protectClass, int flags);
void P_SetSectorFriction (int tag, int amount, bool alterFlag);
void P_SectorDamage(FLevelLocals *Level, int tag, int amount, FName type, PClassActor *protectClass, int flags);
void P_SetSectorFriction (FLevelLocals *level, int tag, int amount, bool alterFlag);
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()

View file

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

View file

@ -652,6 +652,7 @@ struct sector_t
splane planes[2];
FLevelLocals * Level; // To have access to the current level from gepmetry data. The sector can be accessed by all other elements so they won't need this info.
extsector_t * e; // This stores data that requires construction/destruction. Such data must not be copied by R_FakeFlat.
secplane_t floorplane, ceilingplane; // [RH] store floor and ceiling planes instead of heights

View file

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

View file

@ -678,7 +678,7 @@ struct LevelLocals native
native int GetUDMFInt(int type, int index, Name key);
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 static void GiveSecret(Actor activator, bool printmsg = true, bool playsound = true);
native void GiveSecret(Actor activator, bool printmsg = true, bool playsound = true);
native static void StartSlideshow(Name whichone = 'none');
native static void WorldDone();
native static void RemoveAllBots(bool fromlist);