mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-18 15:42:34 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
# Conflicts: # src/p_spec.cpp # src/r_bsp.cpp # src/r_data/r_interpolate.cpp # wadsrc/static/xlat/eternity.txt
This commit is contained in:
commit
b60069bb26
14 changed files with 465 additions and 19 deletions
|
@ -106,11 +106,7 @@ class ASkyCamCompat : public ASkyViewpoint
|
|||
DECLARE_CLASS (ASkyCamCompat, ASkyViewpoint)
|
||||
|
||||
public:
|
||||
void BeginPlay ()
|
||||
{
|
||||
// Do not call the SkyViewpoint's super method because it would trash our setup
|
||||
AActor::BeginPlay();
|
||||
}
|
||||
void BeginPlay();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ void ASkyViewpoint::BeginPlay ()
|
|||
{
|
||||
level.DefaultSkybox = this;
|
||||
}
|
||||
special1 = SKYBOX_SKYVIEWPOINT;
|
||||
}
|
||||
|
||||
void ASkyViewpoint::Serialize (FArchive &arc)
|
||||
|
@ -85,6 +86,13 @@ void ASkyViewpoint::Destroy ()
|
|||
|
||||
IMPLEMENT_CLASS (ASkyCamCompat)
|
||||
|
||||
void ASkyCamCompat::BeginPlay()
|
||||
{
|
||||
// Do not call the SkyViewpoint's super method because it would trash our setup
|
||||
AActor::BeginPlay();
|
||||
special1 = SKYBOX_SKYVIEWPOINT;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
@ -154,6 +162,7 @@ void AStackPoint::BeginPlay ()
|
|||
AActor::BeginPlay ();
|
||||
|
||||
bAlways = true;
|
||||
special1 = SKYBOX_STACKEDSECTORTHING;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -104,6 +104,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightGoesOut)
|
|||
sec->floorplane.d = sec->floorplane.PointToDist (spot, newheight);
|
||||
fixed_t newtheight = sec->floorplane.Zat0();
|
||||
sec->ChangePlaneTexZ(sector_t::floor, newtheight - oldtheight);
|
||||
sec->CheckPortalPlane(sector_t::floor);
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
|
|
|
@ -2582,6 +2582,11 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates)
|
|||
abs(corpsehit->Y() - viletry.y) > maxdist)
|
||||
continue; // not actually touching
|
||||
// Let's check if there are floors in between the archvile and its target
|
||||
|
||||
// if in a different section of the map, only consider possible if a line of sight exists.
|
||||
if (corpsehit->Sector->PortalGroup != self->Sector->PortalGroup && !P_CheckSight(self, corpsehit))
|
||||
continue;
|
||||
|
||||
sector_t *vilesec = self->Sector;
|
||||
sector_t *corpsec = corpsehit->Sector;
|
||||
// We only need to test if at least one of the sectors has a 3D floor.
|
||||
|
|
|
@ -5532,6 +5532,7 @@ bool P_ChangeSector(sector_t *sector, int crunch, int amt, int floorOrCeil, bool
|
|||
}
|
||||
}
|
||||
} while (n);
|
||||
sec->CheckPortalPlane(!floorOrCeil);
|
||||
}
|
||||
}
|
||||
P_Recalculate3DFloors(sector); // Must recalculate the 3d floor and light lists
|
||||
|
@ -5595,6 +5596,8 @@ bool P_ChangeSector(sector_t *sector, int crunch, int amt, int floorOrCeil, bool
|
|||
}
|
||||
} while (n); // repeat from scratch until all things left are marked valid
|
||||
|
||||
sector->CheckPortalPlane(floorOrCeil); // check for portal obstructions after everything is done.
|
||||
|
||||
if (!cpos.nofit && !isreset /* && sector->MoreFlags & (SECF_UNDERWATERMASK)*/)
|
||||
{
|
||||
// If this is a control sector for a deep water transfer, all actors in affected
|
||||
|
|
|
@ -871,6 +871,19 @@ int sector_t::GetTerrain(int pos) const
|
|||
return terrainnum[pos] >= 0 ? terrainnum[pos] : TerrainTypes[GetTexture(pos)];
|
||||
}
|
||||
|
||||
void sector_t::CheckPortalPlane(int plane)
|
||||
{
|
||||
ASkyViewpoint *portal = SkyBoxes[plane];
|
||||
if (!portal || portal->special1 != SKYBOX_LINKEDPORTAL) return;
|
||||
|
||||
fixed_t planeh = planes[plane].TexZ;
|
||||
int obstructed = PLANEF_OBSTRUCTED * (plane == sector_t::floor ?
|
||||
planeh > portal->threshold : planeh < portal->threshold);
|
||||
planes[plane].Flags = (planes[plane].Flags & ~PLANEF_OBSTRUCTED) | obstructed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
FArchive &operator<< (FArchive &arc, secspecial_t &p)
|
||||
{
|
||||
if (SaveVersion < 4529)
|
||||
|
|
|
@ -1036,15 +1036,16 @@ static void CopyPortal(int sectortag, int plane, ASkyViewpoint *origin, fixed_t
|
|||
}
|
||||
}
|
||||
|
||||
void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha)
|
||||
void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha, int linked)
|
||||
{
|
||||
if (plane < 0 || plane > 2 || (linked && plane == 2)) return;
|
||||
for (int i=0;i<numlines;i++)
|
||||
{
|
||||
// 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.
|
||||
if (lines[i].special == Sector_SetPortal &&
|
||||
lines[i].args[0] == sectortag &&
|
||||
lines[i].args[1] == 0 &&
|
||||
lines[i].args[1] == linked &&
|
||||
lines[i].args[2] == plane &&
|
||||
lines[i].args[3] == 1)
|
||||
{
|
||||
|
@ -1053,10 +1054,18 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha)
|
|||
fixed_t y1 = fixed_t((SQWORD(line->v1->y) + SQWORD(line->v2->y)) >> 1);
|
||||
fixed_t x2 = fixed_t((SQWORD(lines[i].v1->x) + SQWORD(lines[i].v2->x)) >> 1);
|
||||
fixed_t y2 = fixed_t((SQWORD(lines[i].v1->y) + SQWORD(lines[i].v2->y)) >> 1);
|
||||
fixed_t z = linked ? line->frontsector->planes[plane].TexZ : 0; // the map's sector height defines the portal plane for linked portals
|
||||
|
||||
fixed_t alpha = Scale (lines[i].args[4], OPAQUE, 255);
|
||||
|
||||
AStackPoint *anchor = Spawn<AStackPoint>(x1, y1, 0, NO_REPLACE);
|
||||
AStackPoint *reference = Spawn<AStackPoint>(x2, y2, 0, NO_REPLACE);
|
||||
reference->special1 = linked ? SKYBOX_LINKEDPORTAL : SKYBOX_PORTAL;
|
||||
anchor->special1 = SKYBOX_ANCHOR;
|
||||
// store the portal displacement in the unused scaleX/Y members of the portal reference actor.
|
||||
anchor->scaleX = -(reference->scaleX = x2 - x1);
|
||||
anchor->scaleY = -(reference->scaleY = y2 - y1);
|
||||
anchor->threshold = reference->threshold = z;
|
||||
|
||||
reference->Mate = anchor;
|
||||
anchor->Mate = reference;
|
||||
|
@ -1445,15 +1454,17 @@ void P_SpawnSpecials (void)
|
|||
// - 0: normal (handled here)
|
||||
// - 1: copy (handled by the portal they copy)
|
||||
// - 2: EE-style skybox (handled by the camera object)
|
||||
// - 3: EE-style flat portal (HW renderer only for now)
|
||||
// - 4: EE-style horizon portal (HW renderer only for now)
|
||||
// - 3: EE-style flat portal (GZDoom HW renderer only for now)
|
||||
// - 4: EE-style horizon portal (GZDoom HW renderer only for now)
|
||||
// - 5: copy portal to line (GZDoom HW renderer only for now)
|
||||
// - 6: linked portal
|
||||
// other values reserved for later use
|
||||
// arg 2 = 0:floor, 1:ceiling, 2:both
|
||||
// arg 3 = 0: anchor, 1: reference line
|
||||
// arg 4 = for the anchor only: alpha
|
||||
if (lines[i].args[1] == 0 && lines[i].args[3] == 0)
|
||||
if ((lines[i].args[1] == 0 || lines[i].args[1] == 6) && lines[i].args[3] == 0)
|
||||
{
|
||||
P_SpawnPortal(&lines[i], lines[i].args[0], lines[i].args[2], lines[i].args[4]);
|
||||
P_SpawnPortal(&lines[i], lines[i].args[0], lines[i].args[2], lines[i].args[4], lines[i].args[1]);
|
||||
}
|
||||
else if (lines[i].args[1] == 3 || lines[i].args[1] == 4)
|
||||
{
|
||||
|
@ -1542,6 +1553,7 @@ void P_SpawnSpecials (void)
|
|||
// [RH] Start running any open scripts on this map
|
||||
FBehavior::StaticStartTypedScripts (SCRIPT_Open, NULL, false);
|
||||
P_FinalizePortals();
|
||||
P_CreateLinkedPortals();
|
||||
}
|
||||
|
||||
// killough 2/28/98:
|
||||
|
|
352
src/portal.cpp
352
src/portal.cpp
|
@ -8,10 +8,15 @@
|
|||
#include "p_tags.h"
|
||||
#include "farchive.h"
|
||||
#include "v_text.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "i_system.h"
|
||||
#include "c_dispatch.h"
|
||||
|
||||
// simulation recurions maximum
|
||||
CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
||||
|
||||
FDisplacementTable Displacements;
|
||||
|
||||
TArray<FLinePortal> linePortals;
|
||||
|
||||
|
||||
|
@ -148,7 +153,19 @@ void P_UpdatePortal(FLinePortal *port)
|
|||
else
|
||||
{
|
||||
port->mFlags = port->mDefFlags;
|
||||
}
|
||||
if (port->mType == PORTT_LINKED)
|
||||
{
|
||||
if (linePortals[port->mDestination->portalindex].mType != PORTT_LINKED)
|
||||
{
|
||||
port->mType = PORTT_INTERACTIVE; // linked portals must be two-way.
|
||||
}
|
||||
else
|
||||
{
|
||||
port->mXDisplacement = port->mDestination->v2->x - port->mOrigin->v1->x;
|
||||
port->mYDisplacement = port->mDestination->v2->y - port->mOrigin->v1->y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void P_FinalizePortals()
|
||||
|
@ -504,3 +521,336 @@ bool PortalTracer::TraceStep()
|
|||
return (oDepth != depth); // if a portal has been found, return false
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// CollectSectors
|
||||
//
|
||||
// Collects all sectors that are connected to any sector belonging to a portal
|
||||
// because they all will need the same displacement values
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
static bool CollectSectors(int groupid, sector_t *origin)
|
||||
{
|
||||
if (origin->PortalGroup != 0) return false; // already processed
|
||||
origin->PortalGroup = groupid;
|
||||
|
||||
TArray<sector_t *> list(16);
|
||||
list.Push(origin);
|
||||
|
||||
for (unsigned i = 0; i < list.Size(); i++)
|
||||
{
|
||||
sector_t *sec = list[i];
|
||||
|
||||
for (int j = 0; j < sec->linecount; j++)
|
||||
{
|
||||
line_t *line = sec->lines[j];
|
||||
sector_t *other = line->frontsector == sec ? line->backsector : line->frontsector;
|
||||
if (other != NULL && other != sec && other->PortalGroup != groupid)
|
||||
{
|
||||
other->PortalGroup = groupid;
|
||||
list.Push(other);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// AddDisplacementForPortal
|
||||
//
|
||||
// Adds the displacement for one portal to the displacement array
|
||||
// (one version for sector to sector plane, one for line to line portals)
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
static void AddDisplacementForPortal(AStackPoint *portal)
|
||||
{
|
||||
int thisgroup = portal->Mate->Sector->PortalGroup;
|
||||
int othergroup = portal->Sector->PortalGroup;
|
||||
if (thisgroup == othergroup)
|
||||
{
|
||||
Printf("Portal between sectors %d and %d has both sides in same group and will be disabled\n", portal->Sector->sectornum, portal->Mate->Sector->sectornum);
|
||||
portal->special1 = portal->Mate->special1 = SKYBOX_PORTAL;
|
||||
return;
|
||||
}
|
||||
if (thisgroup <= 0 || thisgroup >= Displacements.size || othergroup <= 0 || othergroup >= Displacements.size)
|
||||
{
|
||||
Printf("Portal between sectors %d and %d has invalid group and will be disabled\n", portal->Sector->sectornum, portal->Mate->Sector->sectornum);
|
||||
portal->special1 = portal->Mate->special1 = SKYBOX_PORTAL;
|
||||
return;
|
||||
}
|
||||
|
||||
FDisplacement & disp = Displacements(thisgroup, othergroup);
|
||||
if (!disp.isSet)
|
||||
{
|
||||
disp.x = portal->scaleX;
|
||||
disp.y = portal->scaleY;
|
||||
disp.isSet = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp.x != portal->scaleX || disp.y != portal->scaleY)
|
||||
{
|
||||
Printf("Portal between sectors %d and %d has displacement mismatch and will be disabled\n", portal->Sector->sectornum, portal->Mate->Sector->sectornum);
|
||||
portal->special1 = portal->Mate->special1 = SKYBOX_PORTAL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void AddDisplacementForPortal(FLinePortal *portal)
|
||||
{
|
||||
int thisgroup = portal->mOrigin->frontsector->PortalGroup;
|
||||
int othergroup = portal->mDestination->frontsector->PortalGroup;
|
||||
if (thisgroup == othergroup)
|
||||
{
|
||||
Printf("Portal between lines %d and %d has both sides in same group\n", int(portal->mOrigin-lines), int(portal->mDestination-lines));
|
||||
portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
|
||||
return;
|
||||
}
|
||||
if (thisgroup <= 0 || thisgroup >= Displacements.size || othergroup <= 0 || othergroup >= Displacements.size)
|
||||
{
|
||||
Printf("Portal between lines %d and %d has invalid group\n", int(portal->mOrigin - lines), int(portal->mDestination - lines));
|
||||
portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
|
||||
return;
|
||||
}
|
||||
|
||||
FDisplacement & disp = Displacements(thisgroup, othergroup);
|
||||
if (!disp.isSet)
|
||||
{
|
||||
disp.x = portal->mXDisplacement;
|
||||
disp.y = portal->mYDisplacement;
|
||||
disp.isSet = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp.x != portal->mXDisplacement || disp.y != portal->mYDisplacement)
|
||||
{
|
||||
Printf("Portal between lines %d and %d has displacement mismatch\n", int(portal->mOrigin - lines), int(portal->mDestination - lines));
|
||||
portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// ConnectGroups
|
||||
//
|
||||
// Do the indirect connections. This loop will run until it cannot find any new connections
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
static bool ConnectGroups()
|
||||
{
|
||||
// Now
|
||||
BYTE indirect = 1;
|
||||
bool bogus = false;
|
||||
bool changed;
|
||||
do
|
||||
{
|
||||
changed = false;
|
||||
for (int x = 1; x < Displacements.size; x++)
|
||||
{
|
||||
for (int y = 1; y < Displacements.size; y++)
|
||||
{
|
||||
FDisplacement &dispxy = Displacements(x, y);
|
||||
if (dispxy.isSet)
|
||||
{
|
||||
for (int z = 1; z < Displacements.size; z++)
|
||||
{
|
||||
FDisplacement &dispyz = Displacements(y, z);
|
||||
if (dispyz.isSet)
|
||||
{
|
||||
FDisplacement &dispxz = Displacements(x, z);
|
||||
if (dispxz.isSet)
|
||||
{
|
||||
if (dispxy.x + dispyz.x != dispxz.x || dispxy.y + dispyz.y != dispxz.y)
|
||||
{
|
||||
bogus = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dispxz.x = dispxy.x + dispyz.x;
|
||||
dispxz.y = dispxy.y + dispyz.y;
|
||||
dispxz.isSet = true;
|
||||
dispxz.indirect = indirect;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
indirect++;
|
||||
} while (changed);
|
||||
return bogus;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// P_CreateLinkedPortals
|
||||
//
|
||||
// Creates the data structures needed for linked portals
|
||||
// Removes portals from sloped sectors (as they cannot work on them)
|
||||
// Group all sectors connected to one side of the portal
|
||||
// Caclculate displacements between all created groups.
|
||||
//
|
||||
// Portals with the same offset but different anchors will not be merged.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void P_CreateLinkedPortals()
|
||||
{
|
||||
TThinkerIterator<AStackPoint> it;
|
||||
AStackPoint *mo;
|
||||
TArray<AStackPoint *> orgs;
|
||||
int id = 0;
|
||||
bool bogus = false;
|
||||
|
||||
while ((mo = it.Next()))
|
||||
{
|
||||
if (mo->special1 == SKYBOX_LINKEDPORTAL)
|
||||
{
|
||||
if (mo->Mate != NULL)
|
||||
{
|
||||
orgs.Push(mo);
|
||||
mo->reactiontime = ++id;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this should never happen, but if it does, the portal needs to be removed
|
||||
mo->Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (orgs.Size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < numsectors; i++)
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
ASkyViewpoint *box = sectors[i].SkyBoxes[j];
|
||||
if (box != NULL && box->special1 == SKYBOX_LINKEDPORTAL)
|
||||
{
|
||||
secplane_t &plane = j == 0 ? sectors[i].floorplane : sectors[i].ceilingplane;
|
||||
if (plane.a || plane.b)
|
||||
{
|
||||
// The engine cannot deal with portals on a sloped plane.
|
||||
sectors[i].SkyBoxes[j] = NULL;
|
||||
Printf("Portal on %s of sector %d is sloped and will be disabled\n", j==0? "floor":"ceiling", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Group all sectors, starting at each portal origin.
|
||||
id = 1;
|
||||
for (unsigned i = 0; i < orgs.Size(); i++)
|
||||
{
|
||||
if (CollectSectors(id, orgs[i]->Sector)) id++;
|
||||
if (CollectSectors(id, orgs[i]->Mate->Sector)) id++;
|
||||
}
|
||||
for (unsigned i = 0; i < linePortals.Size(); i++)
|
||||
{
|
||||
if (linePortals[i].mType == PORTT_LINKED)
|
||||
{
|
||||
if (CollectSectors(id, linePortals[i].mOrigin->frontsector)) id++;
|
||||
if (CollectSectors(id, linePortals[i].mDestination->frontsector)) id++;
|
||||
}
|
||||
}
|
||||
|
||||
Displacements.Create(id);
|
||||
// Check for leftover sectors that connect to a portal
|
||||
for (int i = 0; i<numsectors; i++)
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
ASkyViewpoint *box = sectors[i].SkyBoxes[j];
|
||||
if (box != NULL)
|
||||
{
|
||||
if (box->special1 == SKYBOX_LINKEDPORTAL && box->Sector->PortalGroup == 0)
|
||||
{
|
||||
CollectSectors(box->Sector->PortalGroup, box->Sector);
|
||||
box = box->Mate;
|
||||
if (box->special1 == SKYBOX_LINKEDPORTAL && box->Sector->PortalGroup == 0)
|
||||
{
|
||||
CollectSectors(box->Sector->PortalGroup, box->Sector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < orgs.Size(); i++)
|
||||
{
|
||||
AddDisplacementForPortal(orgs[i]);
|
||||
}
|
||||
for (unsigned i = 0; i < linePortals.Size(); i++)
|
||||
{
|
||||
if (linePortals[i].mType == PORTT_LINKED)
|
||||
{
|
||||
AddDisplacementForPortal(&linePortals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = 1; x < Displacements.size; x++)
|
||||
{
|
||||
for (int y = x + 1; y < Displacements.size; y++)
|
||||
{
|
||||
FDisplacement &dispxy = Displacements(x, y);
|
||||
FDisplacement &dispyx = Displacements(y, x);
|
||||
if (dispxy.isSet && dispyx.isSet &&
|
||||
(dispxy.x != -dispyx.x || dispxy.y != -dispyx.y))
|
||||
{
|
||||
Printf("Link offset mismatch between groups %d and %d\n", x, y); // need to find some sectors to report.
|
||||
bogus = true;
|
||||
}
|
||||
// todo: Find sectors that have no group but belong to a portal.
|
||||
}
|
||||
}
|
||||
bogus |= ConnectGroups();
|
||||
if (bogus)
|
||||
{
|
||||
// todo: disable all portals whose offsets do not match the associated groups
|
||||
}
|
||||
|
||||
// reject would just get in the way when checking sight through portals.
|
||||
if (rejectmatrix != NULL)
|
||||
{
|
||||
delete[] rejectmatrix;
|
||||
rejectmatrix = NULL;
|
||||
}
|
||||
// finally we must flag all planes which are obstructed by the sector's own ceiling or floor.
|
||||
for (int i = 0; i < numsectors; i++)
|
||||
{
|
||||
sectors[i].CheckPortalPlane(sector_t::floor);
|
||||
sectors[i].CheckPortalPlane(sector_t::ceiling);
|
||||
}
|
||||
//BuildBlockmap();
|
||||
}
|
||||
|
||||
CCMD(dumplinktable)
|
||||
{
|
||||
for (int x = 1; x < Displacements.size; x++)
|
||||
{
|
||||
for (int y = 1; y < Displacements.size; y++)
|
||||
{
|
||||
FDisplacement &disp = Displacements(x, y);
|
||||
Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, disp.x >> FRACBITS, disp.y >> FRACBITS);
|
||||
}
|
||||
Printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
25
src/portal.h
25
src/portal.h
|
@ -8,6 +8,30 @@
|
|||
#include "p_local.h"
|
||||
#include "m_bbox.h"
|
||||
|
||||
struct FDisplacement
|
||||
{
|
||||
fixed_t x, y;
|
||||
bool isSet;
|
||||
BYTE indirect; // just for illustration.
|
||||
};
|
||||
|
||||
struct FDisplacementTable
|
||||
{
|
||||
TArray<FDisplacement> data;
|
||||
int size;
|
||||
|
||||
void Create(int numgroups)
|
||||
{
|
||||
data.Resize(numgroups*numgroups);
|
||||
memset(&data[0], 0, numgroups*numgroups*sizeof(data[0]));
|
||||
size = numgroups;
|
||||
}
|
||||
|
||||
FDisplacement &operator()(int x, int y)
|
||||
{
|
||||
return data[x + size*y];
|
||||
}
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -53,6 +77,7 @@ extern TArray<FLinePortal> linePortals;
|
|||
void P_SpawnLinePortal(line_t* line);
|
||||
void P_FinalizePortals();
|
||||
bool P_ChangePortal(line_t *ln, int thisid, int destid);
|
||||
void P_CreateLinkedPortals();
|
||||
|
||||
|
||||
/* code ported from prototype */
|
||||
|
|
|
@ -1094,7 +1094,7 @@ void R_Subsector (subsector_t *sub)
|
|||
}
|
||||
|
||||
skybox = frontsector->GetSkyBox(sector_t::ceiling);
|
||||
if (skybox != NULL && skybox->special1 != SKYBOX_MAP) skybox = NULL; // HW renderer only.
|
||||
if (skybox != NULL && skybox->special1 >= SKYBOX_PLANE) skybox = NULL; // skip unsupported portal types
|
||||
|
||||
ceilingplane = frontsector->ceilingplane.PointOnSide(viewx, viewy, viewz) > 0 ||
|
||||
frontsector->GetTexture(sector_t::ceiling) == skyflatnum ||
|
||||
|
@ -1137,7 +1137,7 @@ void R_Subsector (subsector_t *sub)
|
|||
// killough 10/98: add support for skies transferred from sidedefs
|
||||
|
||||
skybox = frontsector->GetSkyBox(sector_t::floor);
|
||||
if (skybox != NULL && skybox->special1 != SKYBOX_MAP) skybox = NULL; // HW renderer only.
|
||||
if (skybox != NULL && skybox->special1 >= SKYBOX_PLANE) skybox = NULL; // skip unsupported portal types
|
||||
|
||||
floorplane = frontsector->floorplane.PointOnSide(viewx, viewy, viewz) > 0 || // killough 3/7/98
|
||||
frontsector->GetTexture(sector_t::floor) == skyflatnum ||
|
||||
|
|
|
@ -469,6 +469,7 @@ void DSectorPlaneInterpolation::Restore()
|
|||
sector->SetPlaneTexZ(sector_t::ceiling, baktexz, true);
|
||||
}
|
||||
P_RecalculateAttached3DFloors(sector);
|
||||
sector->CheckPortalPlane(ceiling? sector_t::ceiling : sector_t::floor);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -505,6 +506,7 @@ void DSectorPlaneInterpolation::Interpolate(fixed_t smoothratio)
|
|||
*pheight = oldheight + FixedMul(bakheight - oldheight, smoothratio);
|
||||
sector->SetPlaneTexZ(pos, oldtexz + FixedMul(baktexz - oldtexz, smoothratio), true);
|
||||
P_RecalculateAttached3DFloors(sector);
|
||||
sector->CheckPortalPlane(pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
30
src/r_defs.h
30
src/r_defs.h
|
@ -60,6 +60,18 @@ enum
|
|||
extern size_t MaxDrawSegs;
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
SKYBOX_ANCHOR = -1,
|
||||
SKYBOX_SKYVIEWPOINT = 0, // a regular skybox
|
||||
SKYBOX_STACKEDSECTORTHING, // stacked sectors with the thing method
|
||||
SKYBOX_PORTAL, // stacked sectors with Sector_SetPortal
|
||||
SKYBOX_LINKEDPORTAL, // linked portal (interactive)
|
||||
SKYBOX_PLANE, // EE-style plane portal (not implemented in SW renderer)
|
||||
SKYBOX_HORIZON, // EE-style horizon portal (not implemented in SW renderer)
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// INTERNAL MAP TYPES
|
||||
// used by play and refresh
|
||||
|
@ -545,6 +557,7 @@ struct sector_t
|
|||
DInterpolation *SetInterpolation(int position, bool attach);
|
||||
|
||||
ASkyViewpoint *GetSkyBox(int which);
|
||||
void CheckPortalPlane(int plane);
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -779,6 +792,22 @@ struct sector_t
|
|||
Flags &= ~SECF_SPECIALFLAGS;
|
||||
}
|
||||
|
||||
inline bool PortalBlocksView(int plane)
|
||||
{
|
||||
return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
inline bool PortalBlocksMovement(int plane)
|
||||
{
|
||||
return !!(planes[plane].Flags & (PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
inline bool PortalBlocksSound(int plane)
|
||||
{
|
||||
return !!(planes[plane].Flags & (PLANEF_BLOCKSOUND | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
|
||||
int GetTerrain(int pos) const;
|
||||
|
||||
void TransferSpecial(sector_t *model);
|
||||
|
@ -871,6 +900,7 @@ struct sector_t
|
|||
// [RH] The sky box to render for this sector. NULL means use a
|
||||
// regular sky.
|
||||
TObjPtr<ASkyViewpoint> SkyBoxes[2];
|
||||
int PortalGroup;
|
||||
|
||||
int sectornum; // for comparing sector copies
|
||||
|
||||
|
|
Binary file not shown.
|
@ -131,11 +131,11 @@ enum
|
|||
356 = 0, Polyobj_RotateLeft(0)
|
||||
357 = 0, Polyobj_OR_RotateLeft(0)
|
||||
|
||||
// Eternity's linked portals, vertical link version (floor-to-ceiling) (NOTE: Type needs changing!)
|
||||
358 = 0, Sector_SetPortal(tag, 0, 1, 1, 0) // "Portal_AnchoredCeiling"
|
||||
359 = 0, Sector_SetPortal(tag, 0, 0, 1, 0) // "Portal_AnchoredFloor"
|
||||
360 = 0, Sector_SetPortal(tag, 0, 1, 0, 0) // "Portal_AnchorLine"
|
||||
361 = 0, Sector_SetPortal(tag, 0, 0, 0, 0) // "Portal_AnchorLineFloor"
|
||||
// Eternity's linked portals, vertical link version (floor-to-ceiling)
|
||||
358 = 0, Sector_SetPortal(tag, 6, 1, 1, 0) // "Portal_AnchoredCeiling"
|
||||
359 = 0, Sector_SetPortal(tag, 6, 0, 1, 0) // "Portal_AnchoredFloor"
|
||||
360 = 0, Sector_SetPortal(tag, 6, 1, 0, 0) // "Portal_AnchorLine"
|
||||
361 = 0, Sector_SetPortal(tag, 6, 0, 0, 0) // "Portal_AnchorLineFloor"
|
||||
|
||||
// Even more parameterized linedefs
|
||||
362 = 0, Pillar_Build(0)
|
||||
|
|
Loading…
Reference in a new issue