mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-01-18 14:41:40 +00:00
- refactored sector portal data so that it does not rely on actors.
This is necessary because otherwise the level data cannot be serialized before the actors.
This commit is contained in:
parent
3532dd9ea1
commit
082042818b
23 changed files with 410 additions and 284 deletions
|
@ -384,6 +384,15 @@ size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld)
|
|||
changed += players[i].FixPointers (old, notOld);
|
||||
}
|
||||
|
||||
for (auto &s : sectorPortals)
|
||||
{
|
||||
if (s.mSkybox == old)
|
||||
{
|
||||
s.mSkybox = static_cast<ASkyViewpoint*>(notOld);
|
||||
changed++;
|
||||
}
|
||||
}
|
||||
|
||||
// Go through sectors.
|
||||
if (sectors != NULL)
|
||||
{
|
||||
|
@ -392,8 +401,6 @@ size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld)
|
|||
#define SECTOR_CHECK(f,t) \
|
||||
if (sectors[i].f.p == static_cast<t *>(old)) { sectors[i].f = static_cast<t *>(notOld); changed++; }
|
||||
SECTOR_CHECK( SoundTarget, AActor );
|
||||
SECTOR_CHECK( SkyBoxes[sector_t::ceiling], ASkyViewpoint );
|
||||
SECTOR_CHECK( SkyBoxes[sector_t::floor], ASkyViewpoint );
|
||||
SECTOR_CHECK( SecActTarget, ASectorAction );
|
||||
SECTOR_CHECK( floordata, DSectorEffect );
|
||||
SECTOR_CHECK( ceilingdata, DSectorEffect );
|
||||
|
|
|
@ -327,7 +327,10 @@ static void MarkRoot()
|
|||
DThinker::MarkRoots();
|
||||
FCanvasTextureInfo::Mark();
|
||||
Mark(DACSThinker::ActiveThinker);
|
||||
Mark(level.DefaultSkybox);
|
||||
for (auto &s : sectorPortals)
|
||||
{
|
||||
Mark(s.mSkybox);
|
||||
}
|
||||
// Mark dead bodies.
|
||||
for (i = 0; i < BODYQUESIZE; ++i)
|
||||
{
|
||||
|
@ -680,8 +683,6 @@ size_t DSectorMarker::PropagateMark()
|
|||
{
|
||||
sector_t *sec = §ors[SecNum + i];
|
||||
GC::Mark(sec->SoundTarget);
|
||||
GC::Mark(sec->SkyBoxes[sector_t::ceiling]);
|
||||
GC::Mark(sec->SkyBoxes[sector_t::floor]);
|
||||
GC::Mark(sec->SecActTarget);
|
||||
GC::Mark(sec->floordata);
|
||||
GC::Mark(sec->ceilingdata);
|
||||
|
|
|
@ -298,6 +298,7 @@ template<> FArchive &operator<< (FArchive &arc, FStrifeDialogueNode *&node);
|
|||
template<> FArchive &operator<< (FArchive &arc, FSwitchDef* &sw);
|
||||
template<> FArchive &operator<< (FArchive &arc, FDoorAnimation* &da);
|
||||
FArchive &operator<< (FArchive &arc, FLinePortal &da);
|
||||
FArchive &operator<< (FArchive &arc, FSectorPortal &da);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1386,7 +1386,6 @@ void G_InitLevelLocals ()
|
|||
NormalLight.ChangeFade (level.fadeto);
|
||||
|
||||
level.DefaultEnvironment = info->DefaultEnvironment;
|
||||
level.DefaultSkybox = NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1538,7 +1537,7 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
|
|||
P_SerializeSubsectors(arc);
|
||||
StatusBar->Serialize (arc);
|
||||
|
||||
arc << level.DefaultSkybox << level.total_monsters << level.total_items << level.total_secrets;
|
||||
arc << level.total_monsters << level.total_items << level.total_secrets;
|
||||
|
||||
// Does this level have custom translations?
|
||||
FRemapTable *trans;
|
||||
|
|
|
@ -435,8 +435,6 @@ struct FLevelLocals
|
|||
int airsupply;
|
||||
int DefaultEnvironment; // Default sound environment.
|
||||
|
||||
TObjPtr<class ASkyViewpoint> DefaultSkybox;
|
||||
|
||||
FSectorScrollValues *Scrolls; // NULL if no DScrollers in this level
|
||||
|
||||
SBYTE WallVertLight; // Light diffs for vert/horiz walls
|
||||
|
|
|
@ -91,14 +91,9 @@ public:
|
|||
class ASkyViewpoint : public AActor
|
||||
{
|
||||
DECLARE_CLASS (ASkyViewpoint, AActor)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
void Serialize (FArchive &arc);
|
||||
void BeginPlay ();
|
||||
void Destroy ();
|
||||
bool bInSkybox;
|
||||
bool bAlways;
|
||||
TObjPtr<ASkyViewpoint> Mate;
|
||||
};
|
||||
|
||||
// For an EE compatible linedef based definition.
|
||||
|
|
|
@ -38,49 +38,42 @@
|
|||
#include "p_lnspec.h"
|
||||
#include "farchive.h"
|
||||
#include "r_sky.h"
|
||||
#include "portal.h"
|
||||
|
||||
// arg0 = Visibility*4 for this skybox
|
||||
|
||||
IMPLEMENT_POINTY_CLASS (ASkyViewpoint)
|
||||
DECLARE_POINTER(Mate)
|
||||
END_POINTERS
|
||||
IMPLEMENT_CLASS (ASkyViewpoint)
|
||||
|
||||
// If this actor has no TID, make it the default sky box
|
||||
void ASkyViewpoint::BeginPlay ()
|
||||
{
|
||||
Super::BeginPlay ();
|
||||
|
||||
if (tid == 0 && level.DefaultSkybox == NULL)
|
||||
if (tid == 0 && sectorPortals[0].mSkybox == nullptr)
|
||||
{
|
||||
level.DefaultSkybox = this;
|
||||
sectorPortals[0].mSkybox = this;
|
||||
sectorPortals[0].mDestination = Sector;
|
||||
}
|
||||
special1 = SKYBOX_SKYVIEWPOINT;
|
||||
}
|
||||
|
||||
void ASkyViewpoint::Serialize (FArchive &arc)
|
||||
{
|
||||
Super::Serialize (arc);
|
||||
arc << bInSkybox << bAlways << Mate;
|
||||
}
|
||||
|
||||
void ASkyViewpoint::Destroy ()
|
||||
{
|
||||
// remove all sector references to ourselves.
|
||||
for (int i = 0; i <numsectors; i++)
|
||||
for (int i = 0; i < numsectors; i++)
|
||||
{
|
||||
if (sectors[i].SkyBoxes[sector_t::floor] == this)
|
||||
{
|
||||
sectors[i].SkyBoxes[sector_t::floor] = NULL;
|
||||
}
|
||||
if (sectors[i].SkyBoxes[sector_t::ceiling] == this)
|
||||
{
|
||||
sectors[i].SkyBoxes[sector_t::ceiling] = NULL;
|
||||
}
|
||||
if (sectors[i].GetPortal(sector_t::floor)->mSkybox == this)
|
||||
sectors[i].ClearPortal(sector_t::floor);
|
||||
if (sectors[i].GetPortal(sector_t::ceiling)->mSkybox == this)
|
||||
sectors[i].ClearPortal(sector_t::ceiling);
|
||||
}
|
||||
if (level.DefaultSkybox == this)
|
||||
for (auto &s : sectorPortals)
|
||||
{
|
||||
level.DefaultSkybox = NULL;
|
||||
if (s.mSkybox == this) s.mSkybox = 0;
|
||||
// This is necessary to entirely disable EE-style skyboxes
|
||||
// if their viewpoint gets deleted.
|
||||
s.mFlags |= PORTSF_SKYFLATONLY;
|
||||
}
|
||||
|
||||
Super::Destroy();
|
||||
}
|
||||
|
||||
|
@ -90,10 +83,8 @@ void ASkyCamCompat::BeginPlay()
|
|||
{
|
||||
// Do not call the SkyViewpoint's super method because it would trash our setup
|
||||
AActor::BeginPlay();
|
||||
special1 = SKYBOX_SKYVIEWPOINT;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// arg0 = tid of matching SkyViewpoint
|
||||
|
@ -130,20 +121,18 @@ void ASkyPicker::PostBeginPlay ()
|
|||
|
||||
if (box == NULL && args[0] != 0)
|
||||
{
|
||||
Printf ("Can't find SkyViewpoint %d for sector %td\n",
|
||||
args[0], Sector - sectors);
|
||||
Printf ("Can't find SkyViewpoint %d for sector %td\n", args[0], Sector - sectors);
|
||||
}
|
||||
else
|
||||
{
|
||||
int boxindex = P_GetSkyboxPortal(box);
|
||||
if (0 == (args[1] & 2))
|
||||
{
|
||||
Sector->SkyBoxes[sector_t::ceiling] = box;
|
||||
if (box == NULL) Sector->MoreFlags |= SECF_NOCEILINGSKYBOX; // sector should ignore the level's default skybox
|
||||
Sector->Portals[sector_t::ceiling] = boxindex;
|
||||
}
|
||||
if (0 == (args[1] & 1))
|
||||
{
|
||||
Sector->SkyBoxes[sector_t::floor] = box;
|
||||
if (box == NULL) Sector->MoreFlags |= SECF_NOFLOORSKYBOX; // sector should ignore the level's default skybox
|
||||
Sector->Portals[sector_t::floor] = boxindex;
|
||||
}
|
||||
}
|
||||
Destroy ();
|
||||
|
@ -160,9 +149,6 @@ void AStackPoint::BeginPlay ()
|
|||
{
|
||||
// Skip SkyViewpoint's initialization
|
||||
AActor::BeginPlay ();
|
||||
|
||||
bAlways = true;
|
||||
special1 = SKYBOX_STACKEDSECTORTHING;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -1629,10 +1629,10 @@ int FPathTraverse::PortalRelocate(intercept_t *in, int flags, DVector3 *optpos)
|
|||
return saved->getPortal()->mType == PORTT_LINKED? 1:-1;
|
||||
}
|
||||
|
||||
void FPathTraverse::PortalRelocate(AActor *portalthing, int flags, double hitfrac)
|
||||
void FPathTraverse::PortalRelocate(const DVector2 &displacement, int flags, double hitfrac)
|
||||
{
|
||||
double hitx = trace.x + portalthing->Scale.X;
|
||||
double hity = trace.y + portalthing->Scale.Y;
|
||||
double hitx = trace.x + displacement.X;
|
||||
double hity = trace.y + displacement.Y;
|
||||
double endx = hitx + trace.dx;
|
||||
double endy = hity + trace.dy;
|
||||
intercepts.Resize(intercept_index);
|
||||
|
|
|
@ -373,7 +373,7 @@ public:
|
|||
}
|
||||
void init(double x1, double y1, double x2, double y2, int flags, double startfrac = 0);
|
||||
int PortalRelocate(intercept_t *in, int flags, DVector3 *optpos = NULL);
|
||||
void PortalRelocate(AActor *portalthing, int flags, double hitfrac);
|
||||
void PortalRelocate(const DVector2 &disp, int flags, double hitfrac);
|
||||
virtual ~FPathTraverse();
|
||||
const divline_t &Trace() const { return trace; }
|
||||
|
||||
|
|
|
@ -369,7 +369,7 @@ void P_SerializeWorld (FArchive &arc)
|
|||
<< sec->sky
|
||||
<< sec->MoreFlags
|
||||
<< sec->Flags
|
||||
<< sec->SkyBoxes[sector_t::floor] << sec->SkyBoxes[sector_t::ceiling]
|
||||
<< sec->Portals[sector_t::floor] << sec->Portals[sector_t::ceiling]
|
||||
<< sec->ZoneNumber;
|
||||
arc << sec->interpolations[0]
|
||||
<< sec->interpolations[1]
|
||||
|
@ -449,7 +449,7 @@ void P_SerializeWorld (FArchive &arc)
|
|||
arc << zn->Environment;
|
||||
}
|
||||
|
||||
arc << linePortals;
|
||||
arc << linePortals << sectorPortals;
|
||||
P_CollectLinkedPortals();
|
||||
}
|
||||
|
||||
|
@ -565,22 +565,8 @@ void P_SerializePolyobjs (FArchive &arc)
|
|||
I_Error ("UnarchivePolyobjs: Invalid polyobj tag");
|
||||
}
|
||||
arc << angle << delta << po->interpolation;
|
||||
if (SaveVersion >= 4537)
|
||||
{
|
||||
arc << po->bBlocked;
|
||||
}
|
||||
else
|
||||
{
|
||||
po->bBlocked = false;
|
||||
}
|
||||
if (SaveVersion >= 4538)
|
||||
{
|
||||
arc << po->bHasPortals;
|
||||
}
|
||||
else
|
||||
{
|
||||
po->bHasPortals = 0;
|
||||
}
|
||||
arc << po->bBlocked;
|
||||
arc << po->bHasPortals;
|
||||
|
||||
po->RotatePolyobj (angle, true);
|
||||
delta -= po->StartSpot.pos;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "r_utility.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "p_local.h"
|
||||
#include "r_sky.h"
|
||||
#include "r_data/colormaps.h"
|
||||
|
||||
|
||||
|
@ -803,11 +804,13 @@ int sector_t::GetCeilingLight () const
|
|||
}
|
||||
|
||||
|
||||
ASkyViewpoint *sector_t::GetSkyBox(int which)
|
||||
FSectorPortal *sector_t::ValidatePortal(int which)
|
||||
{
|
||||
if (SkyBoxes[which] != NULL) return barrier_cast<ASkyViewpoint*>(SkyBoxes[which]);
|
||||
if (MoreFlags & (SECF_NOFLOORSKYBOX << which)) return NULL;
|
||||
return level.DefaultSkybox;
|
||||
FSectorPortal *port = GetPortal(which);
|
||||
if (port->mType == PORTS_SKYVIEWPOINT && port->mSkybox == nullptr) return nullptr; // A skybox without a viewpoint is just a regular sky.
|
||||
if (PortalBlocksView(which)) return nullptr; // disabled or obstructed linked portal.
|
||||
if ((port->mFlags & PORTSF_SKYFLATONLY) && GetTexture(which) != skyflatnum) return nullptr; // Skybox without skyflat texture
|
||||
return port;
|
||||
}
|
||||
|
||||
|
||||
|
@ -873,13 +876,13 @@ int sector_t::GetTerrain(int pos) const
|
|||
|
||||
void sector_t::CheckPortalPlane(int plane)
|
||||
{
|
||||
AActor *portal = SkyBoxes[plane];
|
||||
if (!portal || portal->special1 != SKYBOX_LINKEDPORTAL) return;
|
||||
|
||||
double planeh = GetPlaneTexZF(plane);
|
||||
int obstructed = PLANEF_OBSTRUCTED * (plane == sector_t::floor ?
|
||||
planeh > portal->specialf1 : planeh < portal->specialf1);
|
||||
planes[plane].Flags = (planes[plane].Flags & ~PLANEF_OBSTRUCTED) | obstructed;
|
||||
if (GetPortalType(plane) == PORTS_LINKEDPORTAL)
|
||||
{
|
||||
double portalh = GetPortalPlaneZ(plane);
|
||||
double planeh = GetPlaneTexZF(plane);
|
||||
int obstructed = PLANEF_OBSTRUCTED * (plane == sector_t::floor ? planeh > portalh : planeh < portalh);
|
||||
planes[plane].Flags = (planes[plane].Flags & ~PLANEF_OBSTRUCTED) | obstructed;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
106
src/p_spec.cpp
106
src/p_spec.cpp
|
@ -838,12 +838,13 @@ static void SetupFloorPortal (AStackPoint *point)
|
|||
NActorIterator it (NAME_LowerStackLookOnly, point->tid);
|
||||
sector_t *Sector = point->Sector;
|
||||
ASkyViewpoint *skyv = static_cast<ASkyViewpoint*>(it.Next());
|
||||
Sector->SkyBoxes[sector_t::floor] = skyv;
|
||||
if (skyv != NULL && skyv->bAlways)
|
||||
if (skyv != NULL)
|
||||
{
|
||||
skyv->Mate = point;
|
||||
skyv->target = point;
|
||||
if (Sector->GetAlphaF(sector_t::floor) == 1.)
|
||||
Sector->SetAlpha(sector_t::floor, clamp(point->args[0], 0, 255) / 255.);
|
||||
|
||||
Sector->Portals[sector_t::floor] = P_GetStackPortal(skyv, sector_t::floor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -852,12 +853,13 @@ static void SetupCeilingPortal (AStackPoint *point)
|
|||
NActorIterator it (NAME_UpperStackLookOnly, point->tid);
|
||||
sector_t *Sector = point->Sector;
|
||||
ASkyViewpoint *skyv = static_cast<ASkyViewpoint*>(it.Next());
|
||||
Sector->SkyBoxes[sector_t::ceiling] = skyv;
|
||||
if (skyv != NULL && skyv->bAlways)
|
||||
if (skyv != NULL)
|
||||
{
|
||||
skyv->Mate = point;
|
||||
skyv->target = point;
|
||||
if (Sector->GetAlphaF(sector_t::ceiling) == 1.)
|
||||
Sector->SetAlpha(sector_t::ceiling, clamp(point->args[0], 0, 255) / 255.);
|
||||
|
||||
Sector->Portals[sector_t::ceiling] = P_GetStackPortal(skyv, sector_t::ceiling);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -881,42 +883,68 @@ void P_SetupPortals()
|
|||
pt->special1 = 0;
|
||||
points.Push(pt);
|
||||
}
|
||||
// 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 : sectorPortals)
|
||||
{
|
||||
if (s.mType == PORTS_STACKEDSECTORTHING && s.mSkybox)
|
||||
{
|
||||
for (auto &ss : sectorPortals)
|
||||
{
|
||||
if (ss.mType == PORTS_STACKEDSECTORTHING && ss.mSkybox == s.mSkybox->target)
|
||||
{
|
||||
s.mPartner = (&ss) - §orPortals[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now we can finally set the displacement and delete the stackpoint reference.
|
||||
for (auto &s : sectorPortals)
|
||||
{
|
||||
if (s.mType == PORTS_STACKEDSECTORTHING && s.mSkybox)
|
||||
{
|
||||
s.mDisplacement = s.mSkybox->Pos() - s.mSkybox->target->Pos();
|
||||
s.mSkybox = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SetPortal(sector_t *sector, int plane, ASkyViewpoint *portal, double alpha)
|
||||
static void SetPortal(sector_t *sector, int plane, unsigned pnum, double alpha)
|
||||
{
|
||||
// plane: 0=floor, 1=ceiling, 2=both
|
||||
if (plane > 0)
|
||||
{
|
||||
if (sector->SkyBoxes[sector_t::ceiling] == NULL || !barrier_cast<ASkyViewpoint*>(sector->SkyBoxes[sector_t::ceiling])->bAlways)
|
||||
if (sector->GetPortalType(sector_t::ceiling) == PORTS_SKYVIEWPOINT)
|
||||
{
|
||||
sector->SkyBoxes[sector_t::ceiling] = portal;
|
||||
sector->Portals[sector_t::ceiling] = pnum;
|
||||
if (sector->GetAlphaF(sector_t::ceiling) == 1.)
|
||||
sector->SetAlpha(sector_t::ceiling, alpha);
|
||||
|
||||
if (!portal->bAlways) sector->SetTexture(sector_t::ceiling, skyflatnum);
|
||||
if (sectorPortals[pnum].mFlags & PORTSF_SKYFLATONLY)
|
||||
sector->SetTexture(sector_t::ceiling, skyflatnum);
|
||||
}
|
||||
}
|
||||
if (plane == 2 || plane == 0)
|
||||
{
|
||||
if (sector->SkyBoxes[sector_t::floor] == NULL || !barrier_cast<ASkyViewpoint*>(sector->SkyBoxes[sector_t::floor])->bAlways)
|
||||
if (sector->GetPortalType(sector_t::floor) == PORTS_SKYVIEWPOINT)
|
||||
{
|
||||
sector->SkyBoxes[sector_t::floor] = portal;
|
||||
sector->Portals[sector_t::floor] = pnum;
|
||||
}
|
||||
if (sector->GetAlphaF(sector_t::floor) == 1.)
|
||||
sector->SetAlpha(sector_t::floor, alpha);
|
||||
|
||||
if (!portal->bAlways) sector->SetTexture(sector_t::floor, skyflatnum);
|
||||
if (sectorPortals[pnum].mFlags & PORTSF_SKYFLATONLY)
|
||||
sector->SetTexture(sector_t::floor, skyflatnum);
|
||||
}
|
||||
}
|
||||
|
||||
static void CopyPortal(int sectortag, int plane, ASkyViewpoint *origin, double alpha, bool tolines)
|
||||
static void CopyPortal(int sectortag, int plane, unsigned pnum, double alpha, bool tolines)
|
||||
{
|
||||
int s;
|
||||
FSectorTagIterator itr(sectortag);
|
||||
while ((s = itr.Next()) >= 0)
|
||||
{
|
||||
SetPortal(§ors[s], plane, origin, alpha);
|
||||
SetPortal(§ors[s], plane, pnum, alpha);
|
||||
}
|
||||
|
||||
for (int j=0;j<numlines;j++)
|
||||
|
@ -930,20 +958,21 @@ static void CopyPortal(int sectortag, int plane, ASkyViewpoint *origin, double a
|
|||
{
|
||||
if (lines[j].args[0] == 0)
|
||||
{
|
||||
SetPortal(lines[j].frontsector, plane, origin, alpha);
|
||||
SetPortal(lines[j].frontsector, plane, pnum, alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
FSectorTagIterator itr(lines[j].args[0]);
|
||||
while ((s = itr.Next()) >= 0)
|
||||
{
|
||||
SetPortal(§ors[s], plane, origin, alpha);
|
||||
SetPortal(§ors[s], plane, pnum, alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void P_SpawnPortal(line_t *line, int sectortag, int plane, int bytealpha, int linked)
|
||||
{
|
||||
if (plane < 0 || plane > 2 || (linked && plane == 2)) return;
|
||||
|
@ -958,36 +987,10 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int bytealpha, int li
|
|||
lines[i].args[3] == 1)
|
||||
{
|
||||
// beware of overflows.
|
||||
DVector3 pos1((line->v1->fX() + line->v2->fX()) / 2, (line->v1->fY() + line->v2->fY()) / 2, 0);
|
||||
DVector3 pos2((lines[i].v1->fX() + lines[i].v2->fX()) / 2, (lines[i].v1->fY() + lines[i].v2->fY()) / 2, 0);
|
||||
double z = linked ? line->frontsector->GetPlaneTexZF(plane) : 0; // the map's sector height defines the portal plane for linked portals
|
||||
|
||||
double alpha = bytealpha / 255.;
|
||||
|
||||
AStackPoint *anchor = Spawn<AStackPoint>(pos1, NO_REPLACE);
|
||||
AStackPoint *reference = Spawn<AStackPoint>(pos2, NO_REPLACE);
|
||||
|
||||
// In some situations it can happen that the sector here is not the frontsector of the anchor linedef,
|
||||
// because some colinear node line with opposite direction causes this to be positioned on the wrong side.
|
||||
// Fortunately these things will never move so it should be sufficient to set the intended sector directly.
|
||||
anchor->Sector = line->frontsector;
|
||||
reference->Sector = lines[i].frontsector;
|
||||
|
||||
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->Scale = -(reference->Scale = pos2 - pos1);
|
||||
anchor->specialf1 = reference->specialf1 = z;
|
||||
|
||||
reference->Mate = anchor;
|
||||
anchor->Mate = reference;
|
||||
|
||||
// This is so that the renderer can distinguish these portals from
|
||||
// the ones spawned with the '*StackLookOnly' things.
|
||||
reference->flags |= MF_JUSTATTACKED;
|
||||
anchor->flags |= MF_JUSTATTACKED;
|
||||
|
||||
CopyPortal(sectortag, plane, reference, alpha, false);
|
||||
DVector2 pos1 = line->v1->fPos() + line->Delta() / 2;
|
||||
DVector2 pos2 = lines[i].v1->fPos() + lines[i].Delta() / 2;
|
||||
unsigned pnum = P_GetPortal(linked ? PORTS_LINKEDPORTAL : PORTS_PORTAL, plane, line->frontsector, lines[i].frontsector, pos2 - pos1);
|
||||
CopyPortal(sectortag, plane, pnum, bytealpha / 255., false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1012,7 +1015,8 @@ void P_SpawnSkybox(ASkyViewpoint *origin)
|
|||
if (refline->special == Sector_SetPortal && refline->args[1] == 2)
|
||||
{
|
||||
// We found the setup linedef for this skybox, so let's use it for our init.
|
||||
CopyPortal(refline->args[0], refline->args[2], origin, 0, true);
|
||||
unsigned pnum = P_GetSkyboxPortal(origin);
|
||||
CopyPortal(refline->args[0], refline->args[2], pnum, 0, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1334,6 +1338,12 @@ void P_SpawnSpecials (void)
|
|||
{
|
||||
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)
|
||||
{
|
||||
line_t *line = &lines[i];
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
case Line_SetPortal:
|
||||
|
|
|
@ -216,7 +216,7 @@ void FTraceInfo::EnterSectorPortal(FPathTraverse &pt, int position, double frac,
|
|||
inshootthrough = true;
|
||||
startfrac = frac;
|
||||
EnterDist = enterdist;
|
||||
pt.PortalRelocate(entersec->SkyBoxes[position], ptflags, frac);
|
||||
pt.PortalRelocate(entersec->GetPortal(position)->mDisplacement, ptflags, frac);
|
||||
|
||||
if ((TraceFlags & TRACE_ReportPortals) && TraceCallback != NULL)
|
||||
{
|
||||
|
@ -321,7 +321,7 @@ void FTraceInfo::Setup3DFloors()
|
|||
{
|
||||
CurSector->floorplane = *rover->top.plane;
|
||||
CurSector->SetTexture(sector_t::floor, *rover->top.texture, false);
|
||||
CurSector->SkyBoxes[sector_t::floor] = nullptr;
|
||||
CurSector->ClearPortal(sector_t::floor);
|
||||
bf = ff_top;
|
||||
}
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ void FTraceInfo::Setup3DFloors()
|
|||
CurSector->ceilingplane = *rover->bottom.plane;
|
||||
CurSector->SetTexture(sector_t::ceiling, *rover->bottom.texture, false);
|
||||
bc = ff_bottom;
|
||||
CurSector->SkyBoxes[sector_t::ceiling] = nullptr;
|
||||
CurSector->ClearPortal(sector_t::ceiling);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -343,7 +343,7 @@ void FTraceInfo::Setup3DFloors()
|
|||
{
|
||||
CurSector->floorplane = *rover->bottom.plane;
|
||||
CurSector->SetTexture(sector_t::floor, *rover->bottom.texture, false);
|
||||
CurSector->SkyBoxes[sector_t::floor] = nullptr;
|
||||
CurSector->ClearPortal(sector_t::floor);
|
||||
bf = ff_bottom;
|
||||
}
|
||||
|
||||
|
@ -351,7 +351,7 @@ void FTraceInfo::Setup3DFloors()
|
|||
{
|
||||
CurSector->ceilingplane = *rover->top.plane;
|
||||
CurSector->SetTexture(sector_t::ceiling, *rover->top.texture, false);
|
||||
CurSector->SkyBoxes[sector_t::ceiling] = nullptr;
|
||||
CurSector->ClearPortal(sector_t::ceiling);
|
||||
bc = ff_top;
|
||||
}
|
||||
inshootthrough = false;
|
||||
|
@ -499,7 +499,7 @@ bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit)
|
|||
{
|
||||
entersector->floorplane = *rover->top.plane;
|
||||
entersector->SetTexture(sector_t::floor, *rover->top.texture, false);
|
||||
entersector->SkyBoxes[sector_t::floor] = NULL;
|
||||
entersector->ClearPortal(sector_t::floor);
|
||||
bf = ff_top;
|
||||
}
|
||||
}
|
||||
|
@ -510,7 +510,7 @@ bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit)
|
|||
{
|
||||
entersector->ceilingplane = *rover->bottom.plane;
|
||||
entersector->SetTexture(sector_t::ceiling, *rover->bottom.texture, false);
|
||||
entersector->SkyBoxes[sector_t::ceiling] = NULL;
|
||||
entersector->ClearPortal(sector_t::ceiling);
|
||||
bc = ff_bottom;
|
||||
}
|
||||
}
|
||||
|
|
192
src/portal.cpp
192
src/portal.cpp
|
@ -64,6 +64,8 @@ FPortalBlockmap PortalBlockmap;
|
|||
TArray<FLinePortal> linePortals;
|
||||
TArray<FLinePortal*> linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups.
|
||||
|
||||
TArray<FSectorPortal> sectorPortals;
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// This is used to mark processed portals for some collection functions.
|
||||
|
@ -213,6 +215,26 @@ FArchive &operator<< (FArchive &arc, FLinePortal &port)
|
|||
return arc;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Save a sector portal for savegames.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
FArchive &operator<< (FArchive &arc, FSectorPortal &port)
|
||||
{
|
||||
arc << port.mType
|
||||
<< port.mFlags
|
||||
<< port.mPartner
|
||||
<< port.mPlane
|
||||
<< port.mOrigin
|
||||
<< port.mDestination
|
||||
<< port.mDisplacement
|
||||
<< port.mPlaneZ
|
||||
<< port.mSkybox;
|
||||
return arc;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
|
@ -487,7 +509,7 @@ bool P_ChangePortal(line_t *ln, int thisid, int destid)
|
|||
|
||||
//============================================================================
|
||||
//
|
||||
// clears all portal dat for a new level start
|
||||
// clears all portal data for a new level start
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
|
@ -496,9 +518,17 @@ void P_ClearPortals()
|
|||
Displacements.Create(1);
|
||||
linePortals.Clear();
|
||||
linkedPortals.Clear();
|
||||
sectorPortals.Resize(2);
|
||||
// The first entry must always be the default skybox. This is what every sector gets by default.
|
||||
memset(§orPortals[0], 0, sizeof(sectorPortals[0]));
|
||||
sectorPortals[0].mType = PORTS_SKYVIEWPOINT;
|
||||
sectorPortals[0].mFlags = PORTSF_SKYFLATONLY;
|
||||
// The second entry will be the default sky. This is for forcing a regular sky through the skybox picker
|
||||
memset(§orPortals[1], 0, sizeof(sectorPortals[0]));
|
||||
sectorPortals[1].mType = PORTS_SKYVIEWPOINT;
|
||||
sectorPortals[1].mFlags = PORTSF_SKYFLATONLY;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// check if this line is between portal and the viewer. clip away if it is.
|
||||
|
@ -637,6 +667,74 @@ void P_TranslatePortalZ(line_t* src, double& z)
|
|||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// P_GetSkyboxPortal
|
||||
//
|
||||
// Gets a portal for a SkyViewpoint
|
||||
// If none exists yet, it will create a new one.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
unsigned P_GetSkyboxPortal(ASkyViewpoint *actor)
|
||||
{
|
||||
if (actor == NULL) return 1; // this means a regular sky.
|
||||
for (unsigned i = 0;i<sectorPortals.Size();i++)
|
||||
{
|
||||
if (sectorPortals[i].mSkybox == actor) return i;
|
||||
}
|
||||
unsigned i = sectorPortals.Reserve(1);
|
||||
memset(§orPortals[i], 0, sizeof(sectorPortals[i]));
|
||||
sectorPortals[i].mType = PORTS_SKYVIEWPOINT;
|
||||
sectorPortals[i].mFlags = actor->GetClass()->IsDescendantOf(RUNTIME_CLASS(ASkyCamCompat)) ? 0 : PORTSF_SKYFLATONLY;
|
||||
sectorPortals[i].mSkybox = actor;
|
||||
sectorPortals[i].mDestination = actor->Sector;
|
||||
return i;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// P_GetPortal
|
||||
//
|
||||
// Creates a portal struct for a linedef-based portal
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
unsigned P_GetPortal(int type, int plane, sector_t *from, sector_t *to, const DVector2 &displacement)
|
||||
{
|
||||
unsigned i = sectorPortals.Reserve(1);
|
||||
memset(§orPortals[i], 0, sizeof(sectorPortals[i]));
|
||||
sectorPortals[i].mType = type;
|
||||
sectorPortals[i].mPlane = plane;
|
||||
sectorPortals[i].mOrigin = from;
|
||||
sectorPortals[i].mDestination = to;
|
||||
sectorPortals[i].mDisplacement = displacement;
|
||||
sectorPortals[i].mPlaneZ = type == PORTS_LINKEDPORTAL? from->GetPlaneTexZF(plane) : FLT_MAX;
|
||||
return i;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// P_GetStackPortal
|
||||
//
|
||||
// Creates a portal for a stacked sector thing
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
unsigned P_GetStackPortal(AActor *point, int plane)
|
||||
{
|
||||
unsigned i = sectorPortals.Reserve(1);
|
||||
memset(§orPortals[i], 0, sizeof(sectorPortals[i]));
|
||||
sectorPortals[i].mType = PORTS_STACKEDSECTORTHING;
|
||||
sectorPortals[i].mPlane = plane;
|
||||
sectorPortals[i].mOrigin = point->target->Sector;
|
||||
sectorPortals[i].mDestination = point->Sector;
|
||||
sectorPortals[i].mPlaneZ = FLT_MAX;
|
||||
sectorPortals[i].mSkybox = point;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// P_GetOffsetPosition
|
||||
|
@ -756,35 +854,35 @@ static bool CollectSectors(int groupid, sector_t *origin)
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
static void AddDisplacementForPortal(AStackPoint *portal)
|
||||
static void AddDisplacementForPortal(FSectorPortal *portal)
|
||||
{
|
||||
int thisgroup = portal->Mate->Sector->PortalGroup;
|
||||
int othergroup = portal->Sector->PortalGroup;
|
||||
int thisgroup = portal->mOrigin->PortalGroup;
|
||||
int othergroup = portal->mDestination->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;
|
||||
Printf("Portal between sectors %d and %d has both sides in same group and will be disabled\n", portal->mOrigin->sectornum, portal->mDestination->sectornum);
|
||||
portal->mType = PORTS_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;
|
||||
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);
|
||||
if (!disp.isSet)
|
||||
{
|
||||
disp.pos = portal->Scale;
|
||||
disp.pos = portal->mDisplacement;
|
||||
disp.isSet = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp.pos != portal->Scale)
|
||||
if (disp.pos != portal->mDisplacement)
|
||||
{
|
||||
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;
|
||||
Printf("Portal between sectors %d and %d has displacement mismatch and will be disabled\n", portal->mOrigin->sectornum, portal->mDestination->sectornum);
|
||||
portal->mType = PORTS_PORTAL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -895,55 +993,43 @@ static bool ConnectGroups()
|
|||
|
||||
void P_CreateLinkedPortals()
|
||||
{
|
||||
TThinkerIterator<AStackPoint> it;
|
||||
AStackPoint *mo;
|
||||
TArray<AStackPoint *> orgs;
|
||||
TArray<FSectorPortal *> orgs;
|
||||
int id = 1;
|
||||
bool bogus = false;
|
||||
|
||||
while ((mo = it.Next()))
|
||||
for(auto &s : sectorPortals)
|
||||
{
|
||||
if (mo->special1 == SKYBOX_LINKEDPORTAL)
|
||||
if (s.mType == PORTS_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();
|
||||
}
|
||||
orgs.Push(&s);
|
||||
}
|
||||
}
|
||||
id = 1;
|
||||
if (orgs.Size() != 0)
|
||||
{
|
||||
for (int i = 0; i < numsectors; i++)
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
for (int i = 0; i < numsectors; i++)
|
||||
{
|
||||
AActor *box = sectors[i].SkyBoxes[j];
|
||||
if (box != NULL && box->special1 == SKYBOX_LINKEDPORTAL)
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
secplane_t &plane = j == 0 ? sectors[i].floorplane : sectors[i].ceilingplane;
|
||||
if (plane.isSlope())
|
||||
if (sectors[i].GetPortalType(j) == PORTS_LINKEDPORTAL)
|
||||
{
|
||||
// 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);
|
||||
secplane_t &plane = j == 0 ? sectors[i].floorplane : sectors[i].ceilingplane;
|
||||
if (plane.isSlope())
|
||||
{
|
||||
// The engine cannot deal with portals on a sloped plane.
|
||||
sectors[i].ClearPortal(j);
|
||||
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.
|
||||
for (unsigned i = 0; i < orgs.Size(); i++)
|
||||
{
|
||||
if (CollectSectors(id, orgs[i]->Sector)) id++;
|
||||
if (CollectSectors(id, orgs[i]->Mate->Sector)) id++;
|
||||
}
|
||||
// Group all sectors, starting at each portal origin.
|
||||
for (unsigned i = 0; i < orgs.Size(); i++)
|
||||
{
|
||||
if (CollectSectors(id, orgs[i]->mOrigin)) id++;
|
||||
if (CollectSectors(id, orgs[i]->mDestination)) id++;
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < linePortals.Size(); i++)
|
||||
{
|
||||
|
@ -960,17 +1046,9 @@ void P_CreateLinkedPortals()
|
|||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
ASkyViewpoint *box = barrier_cast<ASkyViewpoint*>(sectors[i].SkyBoxes[j]);
|
||||
if (box != NULL)
|
||||
if (sectors[i].GetPortalType(j) == PORTS_LINKEDPORTAL && sectors[i].PortalGroup == 0)
|
||||
{
|
||||
if (box->special1 == SKYBOX_LINKEDPORTAL && sectors[i].PortalGroup == 0)
|
||||
{
|
||||
// Note: the linked actor will be on the other side of the portal.
|
||||
// To get this side's group we will have to look at the mate object.
|
||||
CollectSectors(box->Mate->Sector->PortalGroup, §ors[i]);
|
||||
// We cannot process the backlink here because all we can access is the anchor object
|
||||
// If necessary that will have to be done for the other side's portal.
|
||||
}
|
||||
CollectSectors(sectors[i].GetOppositePortalGroup(j), §ors[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1060,11 +1138,11 @@ void P_CreateLinkedPortals()
|
|||
double fp = sectors[i].floorplane.fD();
|
||||
if (cp < fp || fz == fp)
|
||||
{
|
||||
sectors[i].SkyBoxes[sector_t::ceiling] = NULL;
|
||||
sectors[i].ClearPortal(sector_t::ceiling);
|
||||
}
|
||||
else
|
||||
{
|
||||
sectors[i].SkyBoxes[sector_t::floor] = NULL;
|
||||
sectors[i].ClearPortal(sector_t::floor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
57
src/portal.h
57
src/portal.h
|
@ -6,6 +6,7 @@
|
|||
#include "m_bbox.h"
|
||||
|
||||
struct FPortalGroupArray;
|
||||
class ASkyViewpoint;
|
||||
//============================================================================
|
||||
//
|
||||
// This table holds the offsets for the different parts of a map
|
||||
|
@ -173,8 +174,6 @@ enum
|
|||
//============================================================================
|
||||
//
|
||||
// All information about a line-to-line portal (all types)
|
||||
// There is no structure for sector plane portals because for historic
|
||||
// reasons those use actors to connect.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
|
@ -190,10 +189,61 @@ struct FLinePortal
|
|||
DAngle mAngleDiff;
|
||||
double mSinRot;
|
||||
double mCosRot;
|
||||
void *mRenderData;
|
||||
};
|
||||
|
||||
extern TArray<FLinePortal> linePortals;
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// All information about a sector plane portal
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
enum
|
||||
{
|
||||
PORTS_SKYVIEWPOINT = 0, // a regular skybox
|
||||
PORTS_STACKEDSECTORTHING, // stacked sectors with the thing method
|
||||
PORTS_PORTAL, // stacked sectors with Sector_SetPortal
|
||||
PORTS_LINKEDPORTAL, // linked portal (interactive)
|
||||
PORTS_PLANE, // EE-style plane portal (not implemented in SW renderer)
|
||||
PORTS_HORIZON, // EE-style horizon portal (not implemented in SW renderer)
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PORTSF_SKYFLATONLY = 1, // portal is only active on skyflatnum
|
||||
PORTSF_INSKYBOX = 2, // to avoid recursion
|
||||
};
|
||||
|
||||
struct FSectorPortal
|
||||
{
|
||||
int mType;
|
||||
int mFlags;
|
||||
unsigned mPartner;
|
||||
int mPlane;
|
||||
sector_t *mOrigin;
|
||||
sector_t *mDestination;
|
||||
DVector2 mDisplacement;
|
||||
double mPlaneZ;
|
||||
TObjPtr<AActor> mSkybox;
|
||||
void *mRenderData;
|
||||
|
||||
bool MergeAllowed() const
|
||||
{
|
||||
// For thing based stack sectors and regular skies the portal has no relevance for merging visplanes.
|
||||
return (mType == PORTS_STACKEDSECTORTHING || (mType == PORTS_SKYVIEWPOINT && (mFlags & PORTSF_SKYFLATONLY)));
|
||||
}
|
||||
};
|
||||
|
||||
extern TArray<FSectorPortal> sectorPortals;
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Functions
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void P_ClearPortals();
|
||||
void P_SpawnLinePortal(line_t* line);
|
||||
void P_FinalizePortals();
|
||||
|
@ -205,6 +255,9 @@ inline int P_NumPortalGroups()
|
|||
{
|
||||
return Displacements.size;
|
||||
}
|
||||
unsigned P_GetSkyboxPortal(ASkyViewpoint *actor);
|
||||
unsigned P_GetPortal(int type, int plane, sector_t *orgsec, sector_t *destsec, const DVector2 &displacement);
|
||||
unsigned P_GetStackPortal(AActor *point, int plane);
|
||||
|
||||
|
||||
/* code ported from prototype */
|
||||
|
|
|
@ -515,18 +515,18 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec,
|
|||
|
||||
bool R_SkyboxCompare(sector_t *frontsector, sector_t *backsector)
|
||||
{
|
||||
AActor *frontc = frontsector->SkyBoxes[sector_t::ceiling];
|
||||
AActor *frontf = frontsector->SkyBoxes[sector_t::floor];
|
||||
AActor *backc = backsector->SkyBoxes[sector_t::ceiling];
|
||||
AActor *backf = backsector->SkyBoxes[sector_t::floor];
|
||||
FSectorPortal *frontc = frontsector->GetPortal(sector_t::ceiling);
|
||||
FSectorPortal *frontf = frontsector->GetPortal(sector_t::floor);
|
||||
FSectorPortal *backc = backsector->GetPortal(sector_t::ceiling);
|
||||
FSectorPortal *backf = backsector->GetPortal(sector_t::floor);
|
||||
|
||||
// return true if any of the planes has a linedef-based portal (unless both sides have the same one.
|
||||
// Ideally this should also check thing based portals but the omission of this check had been abused to hell and back for those.
|
||||
// (Note: This may require a compatibility option if some maps ran into this for line based portals as well.)
|
||||
if (frontc != NULL && (frontc->special1 == SKYBOX_PORTAL || frontc->special1 == SKYBOX_LINKEDPORTAL)) return (frontc != backc);
|
||||
if (frontf != NULL && (frontf->special1 == SKYBOX_PORTAL || frontf->special1 == SKYBOX_LINKEDPORTAL)) return (frontf != backf);
|
||||
if (backc != NULL && (backc->special1 == SKYBOX_PORTAL || backc->special1 == SKYBOX_LINKEDPORTAL)) return true;
|
||||
if (backf != NULL && (backf->special1 == SKYBOX_PORTAL || backf->special1 == SKYBOX_LINKEDPORTAL)) return true;
|
||||
if (!frontc->MergeAllowed()) return (frontc != backc);
|
||||
if (!frontf->MergeAllowed()) return (frontf != backf);
|
||||
if (!backc->MergeAllowed()) return true;
|
||||
if (!backf->MergeAllowed()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1046,7 +1046,7 @@ void R_Subsector (subsector_t *sub)
|
|||
int ceilinglightlevel; // killough 4/11/98
|
||||
bool outersubsector;
|
||||
int fll, cll, position;
|
||||
ASkyViewpoint *skybox;
|
||||
FSectorPortal *portal;
|
||||
|
||||
// kg3D - fake floor stuff
|
||||
visplane_t *backupfp;
|
||||
|
@ -1114,12 +1114,11 @@ void R_Subsector (subsector_t *sub)
|
|||
basecolormap = frontsector->ColorMap;
|
||||
}
|
||||
|
||||
skybox = frontsector->GetSkyBox(sector_t::ceiling);
|
||||
if (skybox != NULL && skybox->special1 >= SKYBOX_PLANE) skybox = NULL; // skip unsupported portal types
|
||||
portal = frontsector->ValidatePortal(sector_t::ceiling);
|
||||
|
||||
ceilingplane = frontsector->ceilingplane.PointOnSide(viewx, viewy, viewz) > 0 ||
|
||||
frontsector->GetTexture(sector_t::ceiling) == skyflatnum ||
|
||||
(skybox != NULL && skybox->bAlways) ||
|
||||
portal != NULL ||
|
||||
(frontsector->heightsec &&
|
||||
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
|
||||
frontsector->heightsec->GetTexture(sector_t::floor) == skyflatnum) ?
|
||||
|
@ -1134,7 +1133,7 @@ void R_Subsector (subsector_t *sub)
|
|||
frontsector->GetYScale(sector_t::ceiling),
|
||||
frontsector->GetAngle(sector_t::ceiling),
|
||||
frontsector->sky,
|
||||
skybox
|
||||
portal
|
||||
) : NULL;
|
||||
|
||||
if (fixedlightlev < 0 && frontsector->e && frontsector->e->XFloor.lightlist.Size())
|
||||
|
@ -1156,12 +1155,11 @@ void R_Subsector (subsector_t *sub)
|
|||
// killough 3/7/98: Add (x,y) offsets to flats, add deep water check
|
||||
// killough 3/16/98: add floorlightlevel
|
||||
// killough 10/98: add support for skies transferred from sidedefs
|
||||
skybox = frontsector->GetSkyBox(sector_t::floor);
|
||||
if (skybox != NULL && skybox->special1 >= SKYBOX_PLANE) skybox = NULL; // skip unsupported portal types
|
||||
portal = frontsector->ValidatePortal(sector_t::floor);
|
||||
|
||||
floorplane = frontsector->floorplane.PointOnSide(viewx, viewy, viewz) > 0 || // killough 3/7/98
|
||||
frontsector->GetTexture(sector_t::floor) == skyflatnum ||
|
||||
(skybox != NULL && skybox->bAlways) ||
|
||||
portal != NULL ||
|
||||
(frontsector->heightsec &&
|
||||
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
|
||||
frontsector->heightsec->GetTexture(sector_t::ceiling) == skyflatnum) ?
|
||||
|
@ -1176,7 +1174,7 @@ void R_Subsector (subsector_t *sub)
|
|||
frontsector->GetYScale(sector_t::floor),
|
||||
frontsector->GetAngle(sector_t::floor),
|
||||
frontsector->sky,
|
||||
skybox
|
||||
portal
|
||||
) : NULL;
|
||||
|
||||
// kg3D - fake planes rendering
|
||||
|
|
46
src/r_defs.h
46
src/r_defs.h
|
@ -58,19 +58,6 @@ enum
|
|||
extern size_t MaxDrawSegs;
|
||||
struct FDisplacement;
|
||||
|
||||
|
||||
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
|
||||
|
@ -499,8 +486,6 @@ enum
|
|||
SECF_UNDERWATERMASK = 32+64,
|
||||
SECF_DRAWN = 128, // sector has been drawn at least once
|
||||
SECF_HIDDEN = 256, // Do not draw on textured automap
|
||||
SECF_NOFLOORSKYBOX = 512, // force use of regular sky
|
||||
SECF_NOCEILINGSKYBOX = 1024, // force use of regular sky (do not separate from NOFLOORSKYBOX!!!)
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -668,7 +653,7 @@ public:
|
|||
|
||||
DInterpolation *SetInterpolation(int position, bool attach);
|
||||
|
||||
ASkyViewpoint *GetSkyBox(int which);
|
||||
FSectorPortal *ValidatePortal(int which);
|
||||
void CheckPortalPlane(int plane);
|
||||
|
||||
enum
|
||||
|
@ -930,8 +915,7 @@ public:
|
|||
|
||||
bool PortalBlocksView(int plane)
|
||||
{
|
||||
if (SkyBoxes[plane] == NULL) return true;
|
||||
if (GetPortalType(plane) != SKYBOX_LINKEDPORTAL) return false;
|
||||
if (GetPortalType(plane) != PORTS_LINKEDPORTAL) return false;
|
||||
return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
|
@ -952,28 +936,37 @@ public:
|
|||
|
||||
bool PortalIsLinked(int plane)
|
||||
{
|
||||
return (SkyBoxes[plane] != NULL && GetPortalType(plane) == SKYBOX_LINKEDPORTAL);
|
||||
return (GetPortalType(plane) == PORTS_LINKEDPORTAL);
|
||||
}
|
||||
|
||||
void ClearPortal(int plane)
|
||||
{
|
||||
Portals[plane] = 0;
|
||||
}
|
||||
|
||||
FSectorPortal *GetPortal(int plane)
|
||||
{
|
||||
return §orPortals[Portals[plane]];
|
||||
}
|
||||
|
||||
// These intentionally do not validate the SkyBoxes pointers.
|
||||
double GetPortalPlaneZ(int plane)
|
||||
{
|
||||
return SkyBoxes[plane]->specialf1;
|
||||
return sectorPortals[Portals[plane]].mPlaneZ;
|
||||
}
|
||||
|
||||
DVector2 GetPortalDisplacement(int plane)
|
||||
{
|
||||
return SkyBoxes[plane]->Scale;
|
||||
return sectorPortals[Portals[plane]].mDisplacement;
|
||||
}
|
||||
|
||||
int GetPortalType(int plane)
|
||||
{
|
||||
return SkyBoxes[plane]->special1;
|
||||
return sectorPortals[Portals[plane]].mType;
|
||||
}
|
||||
|
||||
int GetOppositePortalGroup(int plane)
|
||||
{
|
||||
return SkyBoxes[plane]->Sector->PortalGroup;
|
||||
return sectorPortals[Portals[plane]].mDestination->PortalGroup;
|
||||
}
|
||||
|
||||
int GetTerrain(int pos) const;
|
||||
|
@ -1083,9 +1076,8 @@ public:
|
|||
// occurs, SecActTarget's TriggerAction method is called.
|
||||
TObjPtr<ASectorAction> SecActTarget;
|
||||
|
||||
// [RH] The sky box to render for this sector. NULL means use a
|
||||
// regular sky.
|
||||
TObjPtr<AActor> SkyBoxes[2];
|
||||
// [RH] The portal or skybox to render for this sector.
|
||||
unsigned Portals[2];
|
||||
int PortalGroup;
|
||||
|
||||
int sectornum; // for comparing sector copies
|
||||
|
|
|
@ -693,7 +693,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
|||
fixed_t starty = viewy;
|
||||
fixed_t startz = viewz;
|
||||
DVector3 savedpath[2] = { ViewPath[0], ViewPath[1] };
|
||||
int savedvisibility = camera->renderflags & RF_INVISIBLE;
|
||||
int savedvisibility = camera? camera->renderflags & RF_INVISIBLE : 0;
|
||||
|
||||
CurrentPortalUniq++;
|
||||
|
||||
|
@ -746,7 +746,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
|||
viewz = FLOAT2FIXED(view.Z);
|
||||
viewangle = va.BAMs();
|
||||
|
||||
if (!r_showviewer)
|
||||
if (!r_showviewer && camera)
|
||||
{
|
||||
double distp = (ViewPath[0] - ViewPath[1]).Length();
|
||||
if (distp > EQUAL_EPSILON)
|
||||
|
@ -802,11 +802,11 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
|||
InSubsector = NULL;
|
||||
R_RenderBSPNode (nodes + numnodes - 1);
|
||||
R_3D_ResetClip(); // reset clips (floor/ceiling)
|
||||
if (!savedvisibility) camera->renderflags &= ~RF_INVISIBLE;
|
||||
if (!savedvisibility && camera) camera->renderflags &= ~RF_INVISIBLE;
|
||||
|
||||
PlaneCycles.Clock();
|
||||
R_DrawPlanes ();
|
||||
R_DrawSkyBoxes ();
|
||||
R_DrawPortals ();
|
||||
PlaneCycles.Unclock();
|
||||
|
||||
fixed_t vzp = viewz;
|
||||
|
@ -961,7 +961,7 @@ void R_RenderActorView (AActor *actor, bool dontmaplines)
|
|||
{
|
||||
PlaneCycles.Clock();
|
||||
R_DrawPlanes ();
|
||||
R_DrawSkyBoxes ();
|
||||
R_DrawPortals ();
|
||||
PlaneCycles.Unclock();
|
||||
|
||||
// [RH] Walk through mirrors
|
||||
|
|
|
@ -584,7 +584,7 @@ static visplane_t *new_visplane (unsigned hash)
|
|||
visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightlevel, fixed_t alpha, bool additive,
|
||||
fixed_t xoffs, fixed_t yoffs,
|
||||
fixed_t xscale, fixed_t yscale, angle_t angle,
|
||||
int sky, ASkyViewpoint *skybox)
|
||||
int sky, FSectorPortal *portal)
|
||||
{
|
||||
secplane_t plane;
|
||||
visplane_t *check;
|
||||
|
@ -606,9 +606,9 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl
|
|||
// same column but separated by a wall. If they both try to reside in the
|
||||
// same visplane, then only the floor sky will be drawn.
|
||||
plane.set(0., 0., height.fC(), 0.);
|
||||
isskybox = skybox != NULL && !skybox->bInSkybox;
|
||||
isskybox = portal != NULL && !(portal->mFlags & PORTSF_INSKYBOX);
|
||||
}
|
||||
else if (skybox != NULL && skybox->bAlways && !skybox->bInSkybox)
|
||||
else if (portal != NULL && !(portal->mFlags & PORTSF_INSKYBOX))
|
||||
{
|
||||
plane = height;
|
||||
isskybox = true;
|
||||
|
@ -622,7 +622,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl
|
|||
// and ->alpha is for stacked sectors
|
||||
if (fake3D & (FAKE3D_FAKEFLOOR|FAKE3D_FAKECEILING)) sky = 0x80000000 | fakeAlpha;
|
||||
else sky = 0; // not skyflatnum so it can't be a sky
|
||||
skybox = NULL;
|
||||
portal = NULL;
|
||||
alpha = OPAQUE;
|
||||
}
|
||||
|
||||
|
@ -633,9 +633,9 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl
|
|||
{
|
||||
if (isskybox)
|
||||
{
|
||||
if (skybox == check->skybox && plane == check->height)
|
||||
if (portal == check->portal && plane == check->height)
|
||||
{
|
||||
if (skybox->Mate != NULL)
|
||||
if (portal->mType != PORTS_SKYVIEWPOINT)
|
||||
{ // This skybox is really a stacked sector, so we need to
|
||||
// check even more.
|
||||
if (check->extralight == stacked_extralight &&
|
||||
|
@ -645,7 +645,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl
|
|||
check->viewz == stacked_viewz &&
|
||||
(
|
||||
// headache inducing logic... :(
|
||||
(!(skybox->flags & MF_JUSTATTACKED)) ||
|
||||
(portal->mType != PORTS_STACKEDSECTORTHING) ||
|
||||
(
|
||||
check->Alpha == alpha &&
|
||||
check->Additive == additive &&
|
||||
|
@ -710,7 +710,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl
|
|||
check->angle = angle;
|
||||
check->colormap = basecolormap; // [RH] Save colormap
|
||||
check->sky = sky;
|
||||
check->skybox = skybox;
|
||||
check->portal = portal;
|
||||
check->left = viewwidth; // Was SCREENWIDTH -- killough 11/98
|
||||
check->right = 0;
|
||||
check->extralight = stacked_extralight;
|
||||
|
@ -781,7 +781,7 @@ visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop)
|
|||
// make a new visplane
|
||||
unsigned hash;
|
||||
|
||||
if (pl->skybox != NULL && !pl->skybox->bInSkybox && (pl->picnum == skyflatnum || pl->skybox->bAlways) && viewactive)
|
||||
if (pl->portal != NULL && !(pl->portal->mFlags & PORTSF_INSKYBOX) && viewactive)
|
||||
{
|
||||
hash = MAXVISPLANES;
|
||||
}
|
||||
|
@ -800,7 +800,7 @@ visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop)
|
|||
new_pl->yscale = pl->yscale;
|
||||
new_pl->angle = pl->angle;
|
||||
new_pl->colormap = pl->colormap;
|
||||
new_pl->skybox = pl->skybox;
|
||||
new_pl->portal = pl->portal;
|
||||
new_pl->extralight = pl->extralight;
|
||||
new_pl->visibility = pl->visibility;
|
||||
new_pl->viewx = pl->viewx;
|
||||
|
@ -1160,7 +1160,7 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_DrawSkyBoxes
|
||||
// R_DrawPortals
|
||||
//
|
||||
// Draws any recorded sky boxes and then frees them.
|
||||
//
|
||||
|
@ -1181,7 +1181,7 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
|
|||
CVAR (Bool, r_skyboxes, true, 0)
|
||||
static int numskyboxes;
|
||||
|
||||
void R_DrawSkyBoxes ()
|
||||
void R_DrawPortals ()
|
||||
{
|
||||
static TArray<size_t> interestingStack;
|
||||
static TArray<ptrdiff_t> drawsegStack;
|
||||
|
@ -1221,7 +1221,7 @@ void R_DrawSkyBoxes ()
|
|||
visplanes[MAXVISPLANES] = pl->next;
|
||||
pl->next = NULL;
|
||||
|
||||
if (pl->right < pl->left || !r_skyboxes || numskyboxes == MAX_SKYBOX_PLANES)
|
||||
if (pl->right < pl->left || !r_skyboxes || numskyboxes == MAX_SKYBOX_PLANES || pl->portal == NULL)
|
||||
{
|
||||
R_DrawSinglePlane (pl, OPAQUE, false, false);
|
||||
*freehead = pl;
|
||||
|
@ -1231,14 +1231,15 @@ void R_DrawSkyBoxes ()
|
|||
|
||||
numskyboxes++;
|
||||
|
||||
ASkyViewpoint *sky = pl->skybox;
|
||||
ASkyViewpoint *mate = sky->Mate;
|
||||
|
||||
if (mate == NULL)
|
||||
FSectorPortal *port = pl->portal;
|
||||
switch (port->mType)
|
||||
{
|
||||
case PORTS_SKYVIEWPOINT:
|
||||
{
|
||||
// Don't let gun flashes brighten the sky box
|
||||
ASkyViewpoint *sky = barrier_cast<ASkyViewpoint*>(port->mSkybox);
|
||||
extralight = 0;
|
||||
R_SetVisibility (sky->args[0] * 0.25f);
|
||||
R_SetVisibility(sky->args[0] * 0.25f);
|
||||
|
||||
DVector3 viewpos = sky->InterpolatedPosition(r_TicFracF);
|
||||
viewx = FLOAT2FIXED(viewpos.X);
|
||||
|
@ -1247,23 +1248,40 @@ void R_DrawSkyBoxes ()
|
|||
viewangle = savedangle + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * r_TicFracF).BAMs();
|
||||
|
||||
R_CopyStackedViewParameters();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
case PORTS_STACKEDSECTORTHING:
|
||||
case PORTS_PORTAL:
|
||||
case PORTS_LINKEDPORTAL:
|
||||
extralight = pl->extralight;
|
||||
R_SetVisibility (pl->visibility);
|
||||
viewx = pl->viewx + FLOAT2FIXED(-sky->Mate->X() + sky->X());
|
||||
viewy = pl->viewy + FLOAT2FIXED(-sky->Mate->Y() + sky->Y());
|
||||
viewx = pl->viewx + FLOAT2FIXED(port->mDisplacement.X);
|
||||
viewy = pl->viewy + FLOAT2FIXED(port->mDisplacement.Y);
|
||||
viewz = pl->viewz;
|
||||
viewangle = pl->viewangle;
|
||||
break;
|
||||
|
||||
case PORTS_HORIZON:
|
||||
case PORTS_PLANE:
|
||||
// not implemented yet
|
||||
|
||||
default:
|
||||
R_DrawSinglePlane(pl, OPAQUE, false, false);
|
||||
*freehead = pl;
|
||||
freehead = &pl->next;
|
||||
numskyboxes--;
|
||||
continue;
|
||||
}
|
||||
|
||||
ViewAngle = AngleToFloat(viewangle);
|
||||
ViewPos = { FIXED2DBL(viewx), FIXED2DBL(viewy), FIXED2DBL(viewz) };
|
||||
|
||||
sky->bInSkybox = true;
|
||||
if (mate != NULL) mate->bInSkybox = true;
|
||||
camera = sky;
|
||||
viewsector = sky->Sector;
|
||||
port->mFlags |= PORTSF_INSKYBOX;
|
||||
if (port->mPartner > 0) sectorPortals[port->mPartner].mFlags |= PORTSF_INSKYBOX;
|
||||
camera = NULL;
|
||||
viewsector = port->mDestination;
|
||||
assert(viewsector != NULL);
|
||||
R_SetViewAngle ();
|
||||
validcount++; // Make sure we see all sprites
|
||||
|
||||
|
@ -1324,8 +1342,8 @@ void R_DrawSkyBoxes ()
|
|||
R_3D_ResetClip(); // reset clips (floor/ceiling)
|
||||
R_DrawPlanes ();
|
||||
|
||||
sky->bInSkybox = false;
|
||||
if (mate != NULL) mate->bInSkybox = false;
|
||||
port->mFlags &= ~PORTSF_INSKYBOX;
|
||||
if (port->mPartner > 0) sectorPortals[port->mPartner].mFlags &= ~PORTSF_INSKYBOX;
|
||||
}
|
||||
|
||||
// Draw all the masked textures in a second pass, in the reverse order they
|
||||
|
|
|
@ -43,7 +43,7 @@ struct visplane_s
|
|||
fixed_t xscale, yscale; // [RH] Support flat scaling
|
||||
angle_t angle; // [RH] Support flat rotation
|
||||
int sky;
|
||||
ASkyViewpoint *skybox; // [RH] Support sky boxes
|
||||
FSectorPortal *portal; // [RH] Support sky boxes
|
||||
|
||||
// [RH] This set of variables copies information from the time when the
|
||||
// visplane is created. They are only used by stacks so that you can
|
||||
|
@ -88,7 +88,7 @@ void R_DeinitPlanes ();
|
|||
void R_ClearPlanes (bool fullclear);
|
||||
|
||||
int R_DrawPlanes ();
|
||||
void R_DrawSkyBoxes ();
|
||||
void R_DrawPortals ();
|
||||
void R_DrawSkyPlane (visplane_t *pl);
|
||||
void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked);
|
||||
void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked);
|
||||
|
@ -106,7 +106,7 @@ visplane_t *R_FindPlane
|
|||
fixed_t yscale,
|
||||
angle_t angle,
|
||||
int sky,
|
||||
ASkyViewpoint *skybox);
|
||||
FSectorPortal *portal);
|
||||
|
||||
visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop);
|
||||
|
||||
|
|
|
@ -1536,6 +1536,7 @@ void R_DrawPlayerSprites ()
|
|||
F3DFloor *rover;
|
||||
|
||||
if (!r_drawplayersprites ||
|
||||
!camera ||
|
||||
!camera->player ||
|
||||
(players[consoleplayer].cheats & CF_CHASECAM) ||
|
||||
(r_deathcamera && camera->health <= 0))
|
||||
|
|
|
@ -72,11 +72,11 @@ const char *GetVersionString();
|
|||
// SAVESIG should match SAVEVER.
|
||||
|
||||
// MINSAVEVER is the minimum level snapshot version that can be loaded.
|
||||
#define MINSAVEVER 4536
|
||||
#define MINSAVEVER 4539
|
||||
|
||||
// Use 4500 as the base git save version, since it's higher than the
|
||||
// SVN revision ever got.
|
||||
#define SAVEVER 4538
|
||||
#define SAVEVER 4539
|
||||
|
||||
#define SAVEVERSTRINGIFY2(x) #x
|
||||
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)
|
||||
|
|
|
@ -39,13 +39,13 @@ enum
|
|||
282 = 0, Sector_Attach3DMidtex(tag, 0, 1) // "3DMidTex_MoveWithCeiling"
|
||||
|
||||
// Plane portals are not supported in ZDoom, though they probably wouldn't be too hard to implement.
|
||||
283 = 0, Unsupported() // "Portal_PlaneCeiling"
|
||||
284 = 0, Unsupported() // "Portal_PlaneFloor"
|
||||
285 = 0, Unsupported() // "Portal_PlaneFloorCeiling"
|
||||
286 = 0, Unsupported() // "Portal_HorizonCeiling"
|
||||
287 = 0, Unsupported() // "Portal_HorizonFloor"
|
||||
288 = 0, Unsupported() // "Portal_HorizonFloorCeiling"
|
||||
289 = 0, Unsupported() // "Portal_LineTransfer"
|
||||
283 = 0, Sector_SetPortal(tag,3, 1, 0, 0) // "Portal_PlaneCeiling"
|
||||
284 = 0, Sector_SetPortal(tag,3, 0, 0, 0) // "Portal_PlaneFloor"
|
||||
285 = 0, Sector_SetPortal(tag,3, 2, 0, 0) // "Portal_PlaneFloorCeiling"
|
||||
286 = 0, Sector_SetPortal(tag,4, 1, 0, 0) // "Portal_HorizonCeiling"
|
||||
287 = 0, Sector_SetPortal(tag,4, 0, 0, 0) // "Portal_HorizonFloor"
|
||||
288 = 0, Sector_SetPortal(tag,4, 2, 0, 0) // "Portal_HorizonFloorCeiling"
|
||||
289 = 0, Sector_SetPortal(0, 5, 0, tag) // "Portal_LineTransfer"
|
||||
|
||||
// Skybox portals
|
||||
290 = 0, Sector_SetPortal(tag, 2, 1, 1, 0) // "Portal_SkyboxCeiling"
|
||||
|
|
Loading…
Reference in a new issue