- moved portal data into FLevelLocals.

This commit is contained in:
Christoph Oelckers 2018-04-01 20:17:39 +02:00
commit 8be788a9b3
19 changed files with 138 additions and 148 deletions

View file

@ -57,13 +57,6 @@
// simulation recurions maximum
CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO)
FDisplacementTable Displacements;
FPortalBlockmap PortalBlockmap;
TArray<FLinePortal> linePortals;
TArray<FLinePortal*> linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups.
DEFINE_FIELD(FSectorPortal, mType);
DEFINE_FIELD(FSectorPortal, mFlags);
DEFINE_FIELD(FSectorPortal, mPartner);
@ -117,14 +110,14 @@ static void BuildBlockmap()
auto bmapwidth = level.blockmap.bmapwidth;
auto bmapheight = level.blockmap.bmapheight;
PortalBlockmap.Clear();
PortalBlockmap.Create(bmapwidth, bmapheight);
level.PortalBlockmap.Clear();
level.PortalBlockmap.Create(bmapwidth, bmapheight);
for (int y = 0; y < bmapheight; y++)
{
for (int x = 0; x < bmapwidth; x++)
{
int *list = level.blockmap.GetLines(x, y);
FPortalBlock &block = PortalBlockmap(x, y);
FPortalBlock &block = level.PortalBlockmap(x, y);
while (*list != -1)
{
@ -132,14 +125,14 @@ static void BuildBlockmap()
FLinePortal *port = ld->getPortal();
if (port && port->mType != PORTT_VISUAL)
{
PortalBlockmap.containsLines = true;
level.PortalBlockmap.containsLines = true;
block.portallines.Push(ld);
block.neighborContainsLines = true;
if (ld->getPortal()->mType == PORTT_LINKED) block.containsLinkedPortals = true;
if (x > 0) PortalBlockmap(x - 1, y).neighborContainsLines = true;
if (y > 0) PortalBlockmap(x, y - 1).neighborContainsLines = true;
if (x < PortalBlockmap.dx - 1) PortalBlockmap(x + 1, y).neighborContainsLines = true;
if (y < PortalBlockmap.dy - 1) PortalBlockmap(x, y + 1).neighborContainsLines = true;
if (x > 0) level.PortalBlockmap(x - 1, y).neighborContainsLines = true;
if (y > 0) level.PortalBlockmap(x, y - 1).neighborContainsLines = true;
if (x < level.PortalBlockmap.dx - 1) level.PortalBlockmap(x + 1, y).neighborContainsLines = true;
if (y < level.PortalBlockmap.dy - 1) level.PortalBlockmap(x, y + 1).neighborContainsLines = true;
}
else
{
@ -150,7 +143,7 @@ static void BuildBlockmap()
yes |= ld->backsector->PortalIsLinked(sector_t::ceiling) || ld->backsector->PortalIsLinked(sector_t::floor);
}
block.containsLinkedPortals |= yes;
PortalBlockmap.hasLinkedSectorPortals |= yes;
level.PortalBlockmap.hasLinkedSectorPortals |= yes;
}
}
@ -168,9 +161,9 @@ static void BuildBlockmap()
void FLinePortalTraverse::AddLineIntercepts(int bx, int by)
{
if (by < 0 || by >= PortalBlockmap.dy || bx < 0 || bx >= PortalBlockmap.dx) return;
if (by < 0 || by >= level.PortalBlockmap.dy || bx < 0 || bx >= level.PortalBlockmap.dx) return;
FPortalBlock &block = PortalBlockmap(bx, by);
FPortalBlock &block = level.PortalBlockmap(bx, by);
for (unsigned i = 0; i<block.portallines.Size(); i++)
{
@ -284,8 +277,8 @@ void P_SpawnLinePortal(line_t* line)
{
dst = FindDestination(line, line->args[0]);
line->portalindex = linePortals.Reserve(1);
FLinePortal *port = &linePortals.Last();
line->portalindex = level.linePortals.Reserve(1);
FLinePortal *port = &level.linePortals.Last();
memset(port, 0, sizeof(FLinePortal));
port->mOrigin = line;
@ -321,8 +314,8 @@ void P_SpawnLinePortal(line_t* line)
{
if (tagManager.GetFirstLineID(&ln) == mytag && ln.args[0] == 1 && ln.special == Line_SetPortal)
{
line->portalindex = linePortals.Reserve(1);
FLinePortal *port = &linePortals.Last();
line->portalindex = level.linePortals.Reserve(1);
FLinePortal *port = &level.linePortals.Last();
memset(port, 0, sizeof(FLinePortal));
port->mOrigin = line;
@ -332,8 +325,8 @@ void P_SpawnLinePortal(line_t* line)
port->mDefFlags = PORTF_TYPEINTERACTIVE;
// we need to create the backlink here, too.
ln.portalindex = linePortals.Reserve(1);
port = &linePortals.Last();
ln.portalindex = level.linePortals.Reserve(1);
port = &level.linePortals.Last();
memset(port, 0, sizeof(FLinePortal));
port->mOrigin = &ln;
@ -388,7 +381,7 @@ void P_UpdatePortal(FLinePortal *port)
port->mFlags = port->mDefFlags;
if (port->mType == PORTT_LINKED)
{
if (linePortals[port->mDestination->portalindex].mType != PORTT_LINKED)
if (level.linePortals[port->mDestination->portalindex].mType != PORTT_LINKED)
{
port->mType = PORTT_INTERACTIVE; // linked portals must be two-way.
}
@ -412,13 +405,13 @@ void P_UpdatePortal(FLinePortal *port)
void P_CollectLinkedPortals()
{
linkedPortals.Clear();
for (unsigned i = 0; i < linePortals.Size(); i++)
level.linkedPortals.Clear();
for (unsigned i = 0; i < level.linePortals.Size(); i++)
{
FLinePortal * port = &linePortals[i];
FLinePortal * port = &level.linePortals[i];
if (port->mType == PORTT_LINKED)
{
linkedPortals.Push(port);
level.linkedPortals.Push(port);
}
}
}
@ -431,9 +424,9 @@ void P_CollectLinkedPortals()
void P_FinalizePortals()
{
for (unsigned i = 0; i < linePortals.Size(); i++)
for (unsigned i = 0; i < level.linePortals.Size(); i++)
{
FLinePortal * port = &linePortals[i];
FLinePortal * port = &level.linePortals[i];
P_UpdatePortal(port);
}
P_CollectLinkedPortals();
@ -449,8 +442,8 @@ void P_FinalizePortals()
static bool ChangePortalLine(line_t *line, int destid)
{
if (line->portalindex >= linePortals.Size()) return false;
FLinePortal *port = &linePortals[line->portalindex];
if (line->portalindex >= level.linePortals.Size()) return false;
FLinePortal *port = &level.linePortals[line->portalindex];
if (port->mType == PORTT_LINKED) return false; // linked portals cannot be changed.
if (destid == 0) port->mDestination = nullptr;
port->mDestination = FindDestination(line, destid);
@ -460,7 +453,7 @@ static bool ChangePortalLine(line_t *line, int destid)
}
else if (port->mType == PORTT_INTERACTIVE)
{
FLinePortal *portd = port->mDestination->portalindex < linePortals.Size()? &linePortals[port->mDestination->portalindex] : nullptr;
FLinePortal *portd = port->mDestination->portalindex < level.linePortals.Size()? &level.linePortals[port->mDestination->portalindex] : nullptr;
if (portd != nullptr && portd->mType == PORTT_INTERACTIVE && portd->mDestination == line)
{
// this is a 2-way interactive portal
@ -510,9 +503,9 @@ bool P_ChangePortal(line_t *ln, int thisid, int destid)
void P_ClearPortals()
{
Displacements.Create(1);
linePortals.Clear();
linkedPortals.Clear();
level.Displacements.Create(1);
level.linePortals.Clear();
level.linkedPortals.Clear();
level.sectorPortals.Resize(2);
// The first entry must always be the default skybox. This is what every sector gets by default.
memset(&level.sectorPortals[0], 0, sizeof(level.sectorPortals[0]));
@ -751,7 +744,7 @@ unsigned P_GetStackPortal(AActor *point, int plane)
DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy)
{
DVector2 dest(x + dx, y + dy);
if (PortalBlockmap.containsLines)
if (level.PortalBlockmap.containsLines)
{
double actx = x, acty = y;
// Try some easily discoverable early-out first. If we know that the trace cannot possibly find a portal, this saves us from calling the traverser completely for vast parts of the map.
@ -759,7 +752,7 @@ DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy)
{
int blockx = level.blockmap.GetBlockX(actx);
int blocky = level.blockmap.GetBlockY(acty);
if (blockx < 0 || blocky < 0 || blockx >= PortalBlockmap.dx || blocky >= PortalBlockmap.dy || !PortalBlockmap(blockx, blocky).neighborContainsLines) return dest;
if (blockx < 0 || blocky < 0 || blockx >= level.PortalBlockmap.dx || blocky >= level.PortalBlockmap.dy || !level.PortalBlockmap(blockx, blocky).neighborContainsLines) return dest;
}
bool repeat;
@ -867,14 +860,14 @@ static void AddDisplacementForPortal(FSectorPortal *portal)
portal->mType = PORTS_PORTAL;
return;
}
if (thisgroup <= 0 || thisgroup >= Displacements.size || othergroup <= 0 || othergroup >= Displacements.size)
if (thisgroup <= 0 || thisgroup >= level.Displacements.size || othergroup <= 0 || othergroup >= level.Displacements.size)
{
Printf("Portal between sectors %d and %d has invalid group and will be disabled\n", portal->mOrigin->sectornum, portal->mDestination->sectornum);
portal->mType = PORTS_PORTAL;
return;
}
FDisplacement & disp = Displacements(thisgroup, othergroup);
FDisplacement & disp = level.Displacements(thisgroup, othergroup);
if (!disp.isSet)
{
disp.pos = portal->mDisplacement;
@ -899,17 +892,17 @@ static void AddDisplacementForPortal(FLinePortal *portal)
if (thisgroup == othergroup)
{
Printf("Portal between lines %d and %d has both sides in same group\n", portal->mOrigin->Index(), portal->mDestination->Index());
portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
portal->mType = level.linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
return;
}
if (thisgroup <= 0 || thisgroup >= Displacements.size || othergroup <= 0 || othergroup >= Displacements.size)
if (thisgroup <= 0 || thisgroup >= level.Displacements.size || othergroup <= 0 || othergroup >= level.Displacements.size)
{
Printf("Portal between lines %d and %d has invalid group\n", portal->mOrigin->Index(), portal->mDestination->Index());
portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
portal->mType = level.linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
return;
}
FDisplacement & disp = Displacements(thisgroup, othergroup);
FDisplacement & disp = level.Displacements(thisgroup, othergroup);
if (!disp.isSet)
{
disp.pos = portal->mDisplacement;
@ -920,7 +913,7 @@ static void AddDisplacementForPortal(FLinePortal *portal)
if (disp.pos != portal->mDisplacement)
{
Printf("Portal between lines %d and %d has displacement mismatch\n", portal->mOrigin->Index(), portal->mDestination->Index());
portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
portal->mType = level.linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
return;
}
}
@ -943,19 +936,19 @@ static bool ConnectGroups()
do
{
changed = false;
for (int x = 1; x < Displacements.size; x++)
for (int x = 1; x < level.Displacements.size; x++)
{
for (int y = 1; y < Displacements.size; y++)
for (int y = 1; y < level.Displacements.size; y++)
{
FDisplacement &dispxy = Displacements(x, y);
FDisplacement &dispxy = level.Displacements(x, y);
if (dispxy.isSet)
{
for (int z = 1; z < Displacements.size; z++)
for (int z = 1; z < level.Displacements.size; z++)
{
FDisplacement &dispyz = Displacements(y, z);
FDisplacement &dispyz = level.Displacements(y, z);
if (dispyz.isSet)
{
FDisplacement &dispxz = Displacements(x, z);
FDisplacement &dispxz = level.Displacements(x, z);
if (dispxz.isSet)
{
if (dispxy.pos.X + dispyz.pos.X != dispxz.pos.X || dispxy.pos.Y + dispyz.pos.Y != dispxz.pos.Y)
@ -1034,25 +1027,25 @@ void P_CreateLinkedPortals()
if (CollectSectors(id, orgs[i]->mDestination)) id++;
}
}
for (unsigned i = 0; i < linePortals.Size(); i++)
for (unsigned i = 0; i < level.linePortals.Size(); i++)
{
if (linePortals[i].mType == PORTT_LINKED)
if (level.linePortals[i].mType == PORTT_LINKED)
{
if (linePortals[i].mDestination == nullptr)
if (level.linePortals[i].mDestination == nullptr)
{
Printf("Linked portal on line %d is unconnected and will be disabled\n", linePortals[i].mOrigin->Index());
linePortals[i].mOrigin->portalindex = UINT_MAX;
linePortals[i].mType = PORTT_VISUAL;
Printf("Linked portal on line %d is unconnected and will be disabled\n", level.linePortals[i].mOrigin->Index());
level.linePortals[i].mOrigin->portalindex = UINT_MAX;
level.linePortals[i].mType = PORTT_VISUAL;
}
else
{
if (CollectSectors(id, linePortals[i].mOrigin->frontsector)) id++;
if (CollectSectors(id, linePortals[i].mDestination->frontsector)) id++;
if (CollectSectors(id, level.linePortals[i].mOrigin->frontsector)) id++;
if (CollectSectors(id, level.linePortals[i].mDestination->frontsector)) id++;
}
}
}
Displacements.Create(id);
level.Displacements.Create(id);
// Check for leftover sectors that connect to a portal
for (auto &sec : level.sectors)
{
@ -1069,20 +1062,20 @@ void P_CreateLinkedPortals()
{
AddDisplacementForPortal(orgs[i]);
}
for (unsigned i = 0; i < linePortals.Size(); i++)
for (unsigned i = 0; i < level.linePortals.Size(); i++)
{
if (linePortals[i].mType == PORTT_LINKED)
if (level.linePortals[i].mType == PORTT_LINKED)
{
AddDisplacementForPortal(&linePortals[i]);
AddDisplacementForPortal(&level.linePortals[i]);
}
}
for (int x = 1; x < Displacements.size; x++)
for (int x = 1; x < level.Displacements.size; x++)
{
for (int y = x + 1; y < Displacements.size; y++)
for (int y = x + 1; y < level.Displacements.size; y++)
{
FDisplacement &dispxy = Displacements(x, y);
FDisplacement &dispyx = Displacements(y, x);
FDisplacement &dispxy = level.Displacements(x, y);
FDisplacement &dispyx = level.Displacements(y, x);
if (dispxy.isSet && dispyx.isSet &&
(dispxy.pos.X != -dispyx.pos.X || dispxy.pos.Y != -dispyx.pos.Y))
{
@ -1121,7 +1114,7 @@ void P_CreateLinkedPortals()
}
// reject would just get in the way when checking sight through portals.
if (Displacements.size > 1)
if (level.Displacements.size > 1)
{
level.rejectmatrix.Reset();
}
@ -1162,7 +1155,7 @@ void P_CreateLinkedPortals()
if (sec.PortalIsLinked(sector_t::floor)) sec.planes[sector_t::floor].Flags |= PLANEF_LINKED;
if (sec.PortalIsLinked(sector_t::ceiling)) sec.planes[sector_t::ceiling].Flags |= PLANEF_LINKED;
}
if (linkedPortals.Size() > 0)
if (level.linkedPortals.Size() > 0)
{
// We need to relink all actors that may touch a linked line portal
TThinkerIterator<AActor> it;
@ -1203,14 +1196,14 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
bool retval = false;
out.inited = true;
processMask.setSize(Displacements.size);
if (Displacements.size == 1)
processMask.setSize(level.Displacements.size);
if (level.Displacements.size == 1)
{
processMask.setBit(startgroup);
return false;
}
if (linkedPortals.Size() != 0)
if (level.linkedPortals.Size() != 0)
{
processMask.clear();
foundPortals.Clear();
@ -1219,17 +1212,17 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
processMask.setBit(thisgroup);
//out.Add(thisgroup);
for (unsigned i = 0; i < linkedPortals.Size(); i++)
for (unsigned i = 0; i < level.linkedPortals.Size(); i++)
{
line_t *ld = linkedPortals[i]->mOrigin;
line_t *ld = level.linkedPortals[i]->mOrigin;
int othergroup = ld->frontsector->PortalGroup;
FDisplacement &disp = Displacements(thisgroup, othergroup);
FDisplacement &disp = level.Displacements(thisgroup, othergroup);
if (!disp.isSet) continue; // no connection.
FBoundingBox box(position.X + disp.pos.X, position.Y + disp.pos.Y, checkradius);
if (!box.inRange(ld) || box.BoxOnLineSide(linkedPortals[i]->mOrigin) != -1) continue; // not touched
foundPortals.Push(linkedPortals[i]);
if (!box.inRange(ld) || box.BoxOnLineSide(level.linkedPortals[i]->mOrigin) != -1) continue; // not touched
foundPortals.Push(level.linkedPortals[i]);
}
bool foundone = true;
while (foundone)
@ -1256,7 +1249,7 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
while (!wsec->PortalBlocksMovement(sector_t::ceiling) && upperz > wsec->GetPortalPlaneZ(sector_t::ceiling))
{
int othergroup = wsec->GetOppositePortalGroup(sector_t::ceiling);
DVector2 pos = Displacements.getOffset(startgroup, othergroup) + position;
DVector2 pos = level.Displacements.getOffset(startgroup, othergroup) + position;
if (processMask.getBit(othergroup)) break;
processMask.setBit(othergroup);
out.Add(othergroup | FPortalGroupArray::UPPER);
@ -1267,21 +1260,21 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
while (!wsec->PortalBlocksMovement(sector_t::floor) && position.Z < wsec->GetPortalPlaneZ(sector_t::floor))
{
int othergroup = wsec->GetOppositePortalGroup(sector_t::floor);
DVector2 pos = Displacements.getOffset(startgroup, othergroup) + position;
DVector2 pos = level.Displacements.getOffset(startgroup, othergroup) + position;
if (processMask.getBit(othergroup)) break;
processMask.setBit(othergroup);
out.Add(othergroup | FPortalGroupArray::LOWER);
wsec = P_PointInSector(pos); // get lower sector at the exact spot we want to check and repeat
retval = true;
}
if (out.method == FPortalGroupArray::PGA_Full3d && PortalBlockmap.hasLinkedSectorPortals)
if (out.method == FPortalGroupArray::PGA_Full3d && level.PortalBlockmap.hasLinkedSectorPortals)
{
groupsToCheck.Clear();
groupsToCheck.Push(startgroup);
int thisgroup = startgroup;
for (unsigned i = 0; i < groupsToCheck.Size();i++)
{
DVector2 disp = Displacements.getOffset(startgroup, thisgroup & ~FPortalGroupArray::FLAT);
DVector2 disp = level.Displacements.getOffset(startgroup, thisgroup & ~FPortalGroupArray::FLAT);
FBoundingBox box(position.X + disp.X, position.Y + disp.Y, checkradius);
FBlockLinesIterator it(box);
line_t *ld;
@ -1344,11 +1337,11 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
CCMD(dumplinktable)
{
for (int x = 1; x < Displacements.size; x++)
for (int x = 1; x < level.Displacements.size; x++)
{
for (int y = 1; y < Displacements.size; y++)
for (int y = 1; y < level.Displacements.size; y++)
{
FDisplacement &disp = Displacements(x, y);
FDisplacement &disp = level.Displacements(x, y);
Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, int(disp.pos.X), int(disp.pos.Y));
}
Printf("\n");