mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-12-01 00:12:27 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
# Conflicts: # src/p_spec.cpp # src/r_bsp.cpp # src/r_defs.h
This commit is contained in:
commit
9c6e7753d8
29 changed files with 435 additions and 316 deletions
|
@ -576,7 +576,6 @@ public:
|
||||||
~AActor ();
|
~AActor ();
|
||||||
|
|
||||||
void Serialize (FArchive &arc);
|
void Serialize (FArchive &arc);
|
||||||
void PostSerialize();
|
|
||||||
|
|
||||||
static AActor *StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t allowreplacement, bool SpawningMapThing = false);
|
static AActor *StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t allowreplacement, bool SpawningMapThing = false);
|
||||||
|
|
||||||
|
|
|
@ -384,6 +384,15 @@ size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld)
|
||||||
changed += players[i].FixPointers (old, 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.
|
// Go through sectors.
|
||||||
if (sectors != NULL)
|
if (sectors != NULL)
|
||||||
{
|
{
|
||||||
|
@ -392,8 +401,6 @@ size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld)
|
||||||
#define SECTOR_CHECK(f,t) \
|
#define SECTOR_CHECK(f,t) \
|
||||||
if (sectors[i].f.p == static_cast<t *>(old)) { sectors[i].f = static_cast<t *>(notOld); changed++; }
|
if (sectors[i].f.p == static_cast<t *>(old)) { sectors[i].f = static_cast<t *>(notOld); changed++; }
|
||||||
SECTOR_CHECK( SoundTarget, AActor );
|
SECTOR_CHECK( SoundTarget, AActor );
|
||||||
SECTOR_CHECK( SkyBoxes[sector_t::ceiling], ASkyViewpoint );
|
|
||||||
SECTOR_CHECK( SkyBoxes[sector_t::floor], ASkyViewpoint );
|
|
||||||
SECTOR_CHECK( SecActTarget, ASectorAction );
|
SECTOR_CHECK( SecActTarget, ASectorAction );
|
||||||
SECTOR_CHECK( floordata, DSectorEffect );
|
SECTOR_CHECK( floordata, DSectorEffect );
|
||||||
SECTOR_CHECK( ceilingdata, DSectorEffect );
|
SECTOR_CHECK( ceilingdata, DSectorEffect );
|
||||||
|
|
|
@ -327,7 +327,10 @@ static void MarkRoot()
|
||||||
DThinker::MarkRoots();
|
DThinker::MarkRoots();
|
||||||
FCanvasTextureInfo::Mark();
|
FCanvasTextureInfo::Mark();
|
||||||
Mark(DACSThinker::ActiveThinker);
|
Mark(DACSThinker::ActiveThinker);
|
||||||
Mark(level.DefaultSkybox);
|
for (auto &s : sectorPortals)
|
||||||
|
{
|
||||||
|
Mark(s.mSkybox);
|
||||||
|
}
|
||||||
// Mark dead bodies.
|
// Mark dead bodies.
|
||||||
for (i = 0; i < BODYQUESIZE; ++i)
|
for (i = 0; i < BODYQUESIZE; ++i)
|
||||||
{
|
{
|
||||||
|
@ -680,8 +683,6 @@ size_t DSectorMarker::PropagateMark()
|
||||||
{
|
{
|
||||||
sector_t *sec = §ors[SecNum + i];
|
sector_t *sec = §ors[SecNum + i];
|
||||||
GC::Mark(sec->SoundTarget);
|
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->SecActTarget);
|
||||||
GC::Mark(sec->floordata);
|
GC::Mark(sec->floordata);
|
||||||
GC::Mark(sec->ceilingdata);
|
GC::Mark(sec->ceilingdata);
|
||||||
|
|
|
@ -69,7 +69,6 @@ public:
|
||||||
virtual ~DThinker ();
|
virtual ~DThinker ();
|
||||||
virtual void Tick ();
|
virtual void Tick ();
|
||||||
virtual void PostBeginPlay (); // Called just before the first tick
|
virtual void PostBeginPlay (); // Called just before the first tick
|
||||||
virtual void PostSerialize() {}
|
|
||||||
size_t PropagateMark();
|
size_t PropagateMark();
|
||||||
|
|
||||||
void ChangeStatNum (int statnum);
|
void ChangeStatNum (int statnum);
|
||||||
|
|
|
@ -298,6 +298,7 @@ template<> FArchive &operator<< (FArchive &arc, FStrifeDialogueNode *&node);
|
||||||
template<> FArchive &operator<< (FArchive &arc, FSwitchDef* &sw);
|
template<> FArchive &operator<< (FArchive &arc, FSwitchDef* &sw);
|
||||||
template<> FArchive &operator<< (FArchive &arc, FDoorAnimation* &da);
|
template<> FArchive &operator<< (FArchive &arc, FDoorAnimation* &da);
|
||||||
FArchive &operator<< (FArchive &arc, FLinePortal &da);
|
FArchive &operator<< (FArchive &arc, FLinePortal &da);
|
||||||
|
FArchive &operator<< (FArchive &arc, FSectorPortal &da);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1386,7 +1386,6 @@ void G_InitLevelLocals ()
|
||||||
NormalLight.ChangeFade (level.fadeto);
|
NormalLight.ChangeFade (level.fadeto);
|
||||||
|
|
||||||
level.DefaultEnvironment = info->DefaultEnvironment;
|
level.DefaultEnvironment = info->DefaultEnvironment;
|
||||||
level.DefaultSkybox = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1534,13 +1533,14 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
|
||||||
|
|
||||||
FBehavior::StaticSerializeModuleStates (arc);
|
FBehavior::StaticSerializeModuleStates (arc);
|
||||||
if (arc.IsLoading()) interpolator.ClearInterpolations();
|
if (arc.IsLoading()) interpolator.ClearInterpolations();
|
||||||
P_SerializeThinkers (arc, hubLoad);
|
|
||||||
P_SerializeWorld(arc);
|
P_SerializeWorld(arc);
|
||||||
|
P_SerializeThinkers (arc, hubLoad);
|
||||||
|
P_SerializeWorldActors(arc); // serializing actor pointers in the world data must be done after SerializeWorld has restored the entire sector state, otherwise LinkToWorld may fail.
|
||||||
P_SerializePolyobjs (arc);
|
P_SerializePolyobjs (arc);
|
||||||
P_SerializeSubsectors(arc);
|
P_SerializeSubsectors(arc);
|
||||||
StatusBar->Serialize (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?
|
// Does this level have custom translations?
|
||||||
FRemapTable *trans;
|
FRemapTable *trans;
|
||||||
|
@ -1582,13 +1582,6 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
|
||||||
P_SerializeSounds (arc);
|
P_SerializeSounds (arc);
|
||||||
if (arc.IsLoading())
|
if (arc.IsLoading())
|
||||||
{
|
{
|
||||||
FThinkerIterator it(RUNTIME_CLASS(DThinker));
|
|
||||||
DThinker *th;
|
|
||||||
while ((th = it.Next()))
|
|
||||||
{
|
|
||||||
th->PostSerialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < numsectors; i++)
|
for (i = 0; i < numsectors; i++)
|
||||||
{
|
{
|
||||||
P_Recalculate3DFloors(§ors[i]);
|
P_Recalculate3DFloors(§ors[i]);
|
||||||
|
|
|
@ -435,8 +435,6 @@ struct FLevelLocals
|
||||||
int airsupply;
|
int airsupply;
|
||||||
int DefaultEnvironment; // Default sound environment.
|
int DefaultEnvironment; // Default sound environment.
|
||||||
|
|
||||||
TObjPtr<class ASkyViewpoint> DefaultSkybox;
|
|
||||||
|
|
||||||
FSectorScrollValues *Scrolls; // NULL if no DScrollers in this level
|
FSectorScrollValues *Scrolls; // NULL if no DScrollers in this level
|
||||||
|
|
||||||
SBYTE WallVertLight; // Light diffs for vert/horiz walls
|
SBYTE WallVertLight; // Light diffs for vert/horiz walls
|
||||||
|
|
|
@ -91,14 +91,9 @@ public:
|
||||||
class ASkyViewpoint : public AActor
|
class ASkyViewpoint : public AActor
|
||||||
{
|
{
|
||||||
DECLARE_CLASS (ASkyViewpoint, AActor)
|
DECLARE_CLASS (ASkyViewpoint, AActor)
|
||||||
HAS_OBJECT_POINTERS
|
|
||||||
public:
|
public:
|
||||||
void Serialize (FArchive &arc);
|
|
||||||
void BeginPlay ();
|
void BeginPlay ();
|
||||||
void Destroy ();
|
void Destroy ();
|
||||||
bool bInSkybox;
|
|
||||||
bool bAlways;
|
|
||||||
TObjPtr<ASkyViewpoint> Mate;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// For an EE compatible linedef based definition.
|
// For an EE compatible linedef based definition.
|
||||||
|
|
|
@ -38,29 +38,22 @@
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
#include "r_sky.h"
|
#include "r_sky.h"
|
||||||
|
#include "portal.h"
|
||||||
|
|
||||||
// arg0 = Visibility*4 for this skybox
|
// arg0 = Visibility*4 for this skybox
|
||||||
|
|
||||||
IMPLEMENT_POINTY_CLASS (ASkyViewpoint)
|
IMPLEMENT_CLASS (ASkyViewpoint)
|
||||||
DECLARE_POINTER(Mate)
|
|
||||||
END_POINTERS
|
|
||||||
|
|
||||||
// If this actor has no TID, make it the default sky box
|
// If this actor has no TID, make it the default sky box
|
||||||
void ASkyViewpoint::BeginPlay ()
|
void ASkyViewpoint::BeginPlay ()
|
||||||
{
|
{
|
||||||
Super::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 ()
|
void ASkyViewpoint::Destroy ()
|
||||||
|
@ -68,19 +61,19 @@ void ASkyViewpoint::Destroy ()
|
||||||
// remove all sector references to ourselves.
|
// 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)
|
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);
|
||||||
|
}
|
||||||
|
for (auto &s : sectorPortals)
|
||||||
{
|
{
|
||||||
sectors[i].SkyBoxes[sector_t::floor] = NULL;
|
if (s.mSkybox == this) s.mSkybox = 0;
|
||||||
}
|
// This is necessary to entirely disable EE-style skyboxes
|
||||||
if (sectors[i].SkyBoxes[sector_t::ceiling] == this)
|
// if their viewpoint gets deleted.
|
||||||
{
|
s.mFlags |= PORTSF_SKYFLATONLY;
|
||||||
sectors[i].SkyBoxes[sector_t::ceiling] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (level.DefaultSkybox == this)
|
|
||||||
{
|
|
||||||
level.DefaultSkybox = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Super::Destroy();
|
Super::Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,10 +83,8 @@ void ASkyCamCompat::BeginPlay()
|
||||||
{
|
{
|
||||||
// Do not call the SkyViewpoint's super method because it would trash our setup
|
// Do not call the SkyViewpoint's super method because it would trash our setup
|
||||||
AActor::BeginPlay();
|
AActor::BeginPlay();
|
||||||
special1 = SKYBOX_SKYVIEWPOINT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// arg0 = tid of matching SkyViewpoint
|
// arg0 = tid of matching SkyViewpoint
|
||||||
|
@ -130,20 +121,18 @@ void ASkyPicker::PostBeginPlay ()
|
||||||
|
|
||||||
if (box == NULL && args[0] != 0)
|
if (box == NULL && args[0] != 0)
|
||||||
{
|
{
|
||||||
Printf ("Can't find SkyViewpoint %d for sector %td\n",
|
Printf ("Can't find SkyViewpoint %d for sector %td\n", args[0], Sector - sectors);
|
||||||
args[0], Sector - sectors);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int boxindex = P_GetSkyboxPortal(box);
|
||||||
if (0 == (args[1] & 2))
|
if (0 == (args[1] & 2))
|
||||||
{
|
{
|
||||||
Sector->SkyBoxes[sector_t::ceiling] = box;
|
Sector->Portals[sector_t::ceiling] = boxindex;
|
||||||
if (box == NULL) Sector->MoreFlags |= SECF_NOCEILINGSKYBOX; // sector should ignore the level's default skybox
|
|
||||||
}
|
}
|
||||||
if (0 == (args[1] & 1))
|
if (0 == (args[1] & 1))
|
||||||
{
|
{
|
||||||
Sector->SkyBoxes[sector_t::floor] = box;
|
Sector->Portals[sector_t::floor] = boxindex;
|
||||||
if (box == NULL) Sector->MoreFlags |= SECF_NOFLOORSKYBOX; // sector should ignore the level's default skybox
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Destroy ();
|
Destroy ();
|
||||||
|
@ -160,9 +149,6 @@ void AStackPoint::BeginPlay ()
|
||||||
{
|
{
|
||||||
// Skip SkyViewpoint's initialization
|
// Skip SkyViewpoint's initialization
|
||||||
AActor::BeginPlay ();
|
AActor::BeginPlay ();
|
||||||
|
|
||||||
bAlways = true;
|
|
||||||
special1 = SKYBOX_STACKEDSECTORTHING;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
|
@ -358,7 +358,7 @@ void P_PlayerOnSpecial3DFloor(player_t* player)
|
||||||
// Checks whether the player's feet touch a solid 3D floor in the sector
|
// Checks whether the player's feet touch a solid 3D floor in the sector
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
bool P_CheckFor3DFloorHit(AActor * mo)
|
bool P_CheckFor3DFloorHit(AActor * mo, double z)
|
||||||
{
|
{
|
||||||
if ((mo->player && (mo->player->cheats & CF_PREDICTING))) return false;
|
if ((mo->player && (mo->player->cheats & CF_PREDICTING))) return false;
|
||||||
|
|
||||||
|
@ -368,7 +368,7 @@ bool P_CheckFor3DFloorHit(AActor * mo)
|
||||||
|
|
||||||
if(rover->flags & FF_SOLID && rover->model->SecActTarget)
|
if(rover->flags & FF_SOLID && rover->model->SecActTarget)
|
||||||
{
|
{
|
||||||
if(mo->Z() == rover->top.plane->ZatPoint(mo))
|
if (fabs(z - rover->top.plane->ZatPoint(mo)) < EQUAL_EPSILON)
|
||||||
{
|
{
|
||||||
rover->model->SecActTarget->TriggerAction (mo, SECSPAC_HitFloor);
|
rover->model->SecActTarget->TriggerAction (mo, SECSPAC_HitFloor);
|
||||||
return true;
|
return true;
|
||||||
|
@ -384,7 +384,7 @@ bool P_CheckFor3DFloorHit(AActor * mo)
|
||||||
// Checks whether the player's head touches a solid 3D floor in the sector
|
// Checks whether the player's head touches a solid 3D floor in the sector
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
bool P_CheckFor3DCeilingHit(AActor * mo)
|
bool P_CheckFor3DCeilingHit(AActor * mo, double z)
|
||||||
{
|
{
|
||||||
if ((mo->player && (mo->player->cheats & CF_PREDICTING))) return false;
|
if ((mo->player && (mo->player->cheats & CF_PREDICTING))) return false;
|
||||||
|
|
||||||
|
@ -394,7 +394,7 @@ bool P_CheckFor3DCeilingHit(AActor * mo)
|
||||||
|
|
||||||
if(rover->flags & FF_SOLID && rover->model->SecActTarget)
|
if(rover->flags & FF_SOLID && rover->model->SecActTarget)
|
||||||
{
|
{
|
||||||
if(mo->Top() == rover->bottom.plane->ZatPoint(mo))
|
if(fabs(z - rover->bottom.plane->ZatPoint(mo)) < EQUAL_EPSILON)
|
||||||
{
|
{
|
||||||
rover->model->SecActTarget->TriggerAction (mo, SECSPAC_HitCeiling);
|
rover->model->SecActTarget->TriggerAction (mo, SECSPAC_HitCeiling);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -122,8 +122,8 @@ struct lightlist_t
|
||||||
class player_s;
|
class player_s;
|
||||||
void P_PlayerOnSpecial3DFloor(player_t* player);
|
void P_PlayerOnSpecial3DFloor(player_t* player);
|
||||||
|
|
||||||
bool P_CheckFor3DFloorHit(AActor * mo);
|
bool P_CheckFor3DFloorHit(AActor * mo, double z);
|
||||||
bool P_CheckFor3DCeilingHit(AActor * mo);
|
bool P_CheckFor3DCeilingHit(AActor * mo, double z);
|
||||||
void P_Recalculate3DFloors(sector_t *);
|
void P_Recalculate3DFloors(sector_t *);
|
||||||
void P_RecalculateAttached3DFloors(sector_t * sec);
|
void P_RecalculateAttached3DFloors(sector_t * sec);
|
||||||
void P_RecalculateLights(sector_t *sector);
|
void P_RecalculateLights(sector_t *sector);
|
||||||
|
|
|
@ -587,7 +587,7 @@ bool P_Move (AActor *actor)
|
||||||
{
|
{
|
||||||
actor->floorsector->SecActTarget->TriggerAction(actor, SECSPAC_HitFloor);
|
actor->floorsector->SecActTarget->TriggerAction(actor, SECSPAC_HitFloor);
|
||||||
}
|
}
|
||||||
P_CheckFor3DFloorHit(actor);
|
P_CheckFor3DFloorHit(actor, actor->Z());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1629,10 +1629,10 @@ int FPathTraverse::PortalRelocate(intercept_t *in, int flags, DVector3 *optpos)
|
||||||
return saved->getPortal()->mType == PORTT_LINKED? 1:-1;
|
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 hitx = trace.x + displacement.X;
|
||||||
double hity = trace.y + portalthing->Scale.Y;
|
double hity = trace.y + displacement.Y;
|
||||||
double endx = hitx + trace.dx;
|
double endx = hitx + trace.dx;
|
||||||
double endy = hity + trace.dy;
|
double endy = hity + trace.dy;
|
||||||
intercepts.Resize(intercept_index);
|
intercepts.Resize(intercept_index);
|
||||||
|
|
|
@ -373,7 +373,7 @@ public:
|
||||||
}
|
}
|
||||||
void init(double x1, double y1, double x2, double y2, int flags, double startfrac = 0);
|
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);
|
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();
|
virtual ~FPathTraverse();
|
||||||
const divline_t &Trace() const { return trace; }
|
const divline_t &Trace() const { return trace; }
|
||||||
|
|
||||||
|
|
|
@ -397,6 +397,9 @@ void AActor::Serialize(FArchive &arc)
|
||||||
|
|
||||||
if (arc.IsLoading ())
|
if (arc.IsLoading ())
|
||||||
{
|
{
|
||||||
|
touching_sectorlist = NULL;
|
||||||
|
LinkToWorld(false, Sector);
|
||||||
|
|
||||||
AddToHash ();
|
AddToHash ();
|
||||||
SetShade (fillcolor);
|
SetShade (fillcolor);
|
||||||
if (player)
|
if (player)
|
||||||
|
@ -413,16 +416,10 @@ void AActor::Serialize(FArchive &arc)
|
||||||
Speed = GetDefault()->Speed;
|
Speed = GetDefault()->Speed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AActor::PostSerialize()
|
|
||||||
{
|
|
||||||
touching_sectorlist = NULL;
|
|
||||||
LinkToWorld(false, Sector);
|
|
||||||
ClearInterpolation();
|
ClearInterpolation();
|
||||||
UpdateWaterLevel(false);
|
UpdateWaterLevel(false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AActor::AActor () throw()
|
AActor::AActor () throw()
|
||||||
{
|
{
|
||||||
|
@ -2399,7 +2396,7 @@ void P_ZMovement (AActor *mo, double oldfloorz)
|
||||||
{ // [RH] Let the sector do something to the actor
|
{ // [RH] Let the sector do something to the actor
|
||||||
mo->Sector->SecActTarget->TriggerAction (mo, SECSPAC_HitFloor);
|
mo->Sector->SecActTarget->TriggerAction (mo, SECSPAC_HitFloor);
|
||||||
}
|
}
|
||||||
P_CheckFor3DFloorHit(mo);
|
P_CheckFor3DFloorHit(mo, mo->floorz);
|
||||||
// [RH] Need to recheck this because the sector action might have
|
// [RH] Need to recheck this because the sector action might have
|
||||||
// teleported the actor so it is no longer below the floor.
|
// teleported the actor so it is no longer below the floor.
|
||||||
if (mo->Z() <= mo->floorz)
|
if (mo->Z() <= mo->floorz)
|
||||||
|
@ -2499,7 +2496,7 @@ void P_ZMovement (AActor *mo, double oldfloorz)
|
||||||
{ // [RH] Let the sector do something to the actor
|
{ // [RH] Let the sector do something to the actor
|
||||||
mo->Sector->SecActTarget->TriggerAction (mo, SECSPAC_HitCeiling);
|
mo->Sector->SecActTarget->TriggerAction (mo, SECSPAC_HitCeiling);
|
||||||
}
|
}
|
||||||
P_CheckFor3DCeilingHit(mo);
|
P_CheckFor3DCeilingHit(mo, mo->ceilingz);
|
||||||
// [RH] Need to recheck this because the sector action might have
|
// [RH] Need to recheck this because the sector action might have
|
||||||
// teleported the actor so it is no longer above the ceiling.
|
// teleported the actor so it is no longer above the ceiling.
|
||||||
if (mo->Top() > mo->ceilingz)
|
if (mo->Top() > mo->ceilingz)
|
||||||
|
@ -3861,11 +3858,11 @@ void AActor::CheckSectorTransition(sector_t *oldsec)
|
||||||
}
|
}
|
||||||
if (Z() == floorz)
|
if (Z() == floorz)
|
||||||
{
|
{
|
||||||
P_CheckFor3DFloorHit(this);
|
P_CheckFor3DFloorHit(this, Z());
|
||||||
}
|
}
|
||||||
if (Top() == ceilingz)
|
if (Top() == ceilingz)
|
||||||
{
|
{
|
||||||
P_CheckFor3DCeilingHit(this);
|
P_CheckFor3DCeilingHit(this, Top());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -363,13 +363,11 @@ void P_SerializeWorld (FArchive &arc)
|
||||||
arc << sec->damageamount;
|
arc << sec->damageamount;
|
||||||
arc << sec->damageinterval
|
arc << sec->damageinterval
|
||||||
<< sec->leakydamage
|
<< sec->leakydamage
|
||||||
<< sec->damagetype;
|
<< sec->damagetype
|
||||||
arc << sec->SoundTarget
|
|
||||||
<< sec->SecActTarget
|
|
||||||
<< sec->sky
|
<< sec->sky
|
||||||
<< sec->MoreFlags
|
<< sec->MoreFlags
|
||||||
<< sec->Flags
|
<< sec->Flags
|
||||||
<< sec->SkyBoxes[sector_t::floor] << sec->SkyBoxes[sector_t::ceiling]
|
<< sec->Portals[sector_t::floor] << sec->Portals[sector_t::ceiling]
|
||||||
<< sec->ZoneNumber;
|
<< sec->ZoneNumber;
|
||||||
arc << sec->interpolations[0]
|
arc << sec->interpolations[0]
|
||||||
<< sec->interpolations[1]
|
<< sec->interpolations[1]
|
||||||
|
@ -454,10 +452,26 @@ void P_SerializeWorld (FArchive &arc)
|
||||||
arc << zn->Environment;
|
arc << zn->Environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
arc << linePortals;
|
arc << linePortals << sectorPortals;
|
||||||
P_CollectLinkedPortals();
|
P_CollectLinkedPortals();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void P_SerializeWorldActors(FArchive &arc)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
sector_t *sec;
|
||||||
|
|
||||||
|
for (i = 0, sec = sectors; i < numsectors; i++, sec++)
|
||||||
|
{
|
||||||
|
arc << sec->SoundTarget
|
||||||
|
<< sec->SecActTarget;
|
||||||
|
}
|
||||||
|
for (auto &s : sectorPortals)
|
||||||
|
{
|
||||||
|
arc << s.mSkybox;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void extsector_t::Serialize(FArchive &arc)
|
void extsector_t::Serialize(FArchive &arc)
|
||||||
{
|
{
|
||||||
arc << FakeFloor.Sectors
|
arc << FakeFloor.Sectors
|
||||||
|
@ -570,22 +584,8 @@ void P_SerializePolyobjs (FArchive &arc)
|
||||||
I_Error ("UnarchivePolyobjs: Invalid polyobj tag");
|
I_Error ("UnarchivePolyobjs: Invalid polyobj tag");
|
||||||
}
|
}
|
||||||
arc << angle << delta << po->interpolation;
|
arc << angle << delta << po->interpolation;
|
||||||
if (SaveVersion >= 4537)
|
|
||||||
{
|
|
||||||
arc << po->bBlocked;
|
arc << po->bBlocked;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
po->bBlocked = false;
|
|
||||||
}
|
|
||||||
if (SaveVersion >= 4538)
|
|
||||||
{
|
|
||||||
arc << po->bHasPortals;
|
arc << po->bHasPortals;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
po->bHasPortals = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
po->RotatePolyobj (angle, true);
|
po->RotatePolyobj (angle, true);
|
||||||
delta -= po->StartSpot.pos;
|
delta -= po->StartSpot.pos;
|
||||||
|
|
|
@ -41,6 +41,7 @@ struct PNGHandle;
|
||||||
// These are the load / save game routines.
|
// These are the load / save game routines.
|
||||||
// Also see farchive.(h|cpp)
|
// Also see farchive.(h|cpp)
|
||||||
void P_SerializePlayers (FArchive &arc, bool fakeload);
|
void P_SerializePlayers (FArchive &arc, bool fakeload);
|
||||||
|
void P_SerializeWorldActors(FArchive &arc);
|
||||||
void P_SerializeWorld (FArchive &arc);
|
void P_SerializeWorld (FArchive &arc);
|
||||||
void P_SerializeThinkers (FArchive &arc, bool);
|
void P_SerializeThinkers (FArchive &arc, bool);
|
||||||
void P_SerializePolyobjs (FArchive &arc);
|
void P_SerializePolyobjs (FArchive &arc);
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "r_utility.h"
|
#include "r_utility.h"
|
||||||
#include "a_sharedglobal.h"
|
#include "a_sharedglobal.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "r_sky.h"
|
||||||
#include "r_data/colormaps.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]);
|
FSectorPortal *port = GetPortal(which);
|
||||||
if (MoreFlags & (SECF_NOFLOORSKYBOX << which)) return NULL;
|
if (port->mType == PORTS_SKYVIEWPOINT && port->mSkybox == nullptr) return nullptr; // A skybox without a viewpoint is just a regular sky.
|
||||||
return level.DefaultSkybox;
|
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,14 +876,14 @@ int sector_t::GetTerrain(int pos) const
|
||||||
|
|
||||||
void sector_t::CheckPortalPlane(int plane)
|
void sector_t::CheckPortalPlane(int plane)
|
||||||
{
|
{
|
||||||
AActor *portal = SkyBoxes[plane];
|
if (GetPortalType(plane) == PORTS_LINKEDPORTAL)
|
||||||
if (!portal || portal->special1 != SKYBOX_LINKEDPORTAL) return;
|
{
|
||||||
|
double portalh = GetPortalPlaneZ(plane);
|
||||||
double planeh = GetPlaneTexZF(plane);
|
double planeh = GetPlaneTexZF(plane);
|
||||||
int obstructed = PLANEF_OBSTRUCTED * (plane == sector_t::floor ?
|
int obstructed = PLANEF_OBSTRUCTED * (plane == sector_t::floor ? planeh > portalh : planeh < portalh);
|
||||||
planeh > portal->specialf1 : planeh < portal->specialf1);
|
|
||||||
planes[plane].Flags = (planes[plane].Flags & ~PLANEF_OBSTRUCTED) | obstructed;
|
planes[plane].Flags = (planes[plane].Flags & ~PLANEF_OBSTRUCTED) | obstructed;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
|
107
src/p_spec.cpp
107
src/p_spec.cpp
|
@ -838,12 +838,13 @@ static void SetupFloorPortal (AStackPoint *point)
|
||||||
NActorIterator it (NAME_LowerStackLookOnly, point->tid);
|
NActorIterator it (NAME_LowerStackLookOnly, point->tid);
|
||||||
sector_t *Sector = point->Sector;
|
sector_t *Sector = point->Sector;
|
||||||
ASkyViewpoint *skyv = static_cast<ASkyViewpoint*>(it.Next());
|
ASkyViewpoint *skyv = static_cast<ASkyViewpoint*>(it.Next());
|
||||||
Sector->SkyBoxes[sector_t::floor] = skyv;
|
if (skyv != NULL)
|
||||||
if (skyv != NULL && skyv->bAlways)
|
|
||||||
{
|
{
|
||||||
skyv->Mate = point;
|
skyv->target = point;
|
||||||
if (Sector->GetAlphaF(sector_t::floor) == 1.)
|
if (Sector->GetAlphaF(sector_t::floor) == 1.)
|
||||||
Sector->SetAlpha(sector_t::floor, clamp(point->args[0], 0, 255) / 255.);
|
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);
|
NActorIterator it (NAME_UpperStackLookOnly, point->tid);
|
||||||
sector_t *Sector = point->Sector;
|
sector_t *Sector = point->Sector;
|
||||||
ASkyViewpoint *skyv = static_cast<ASkyViewpoint*>(it.Next());
|
ASkyViewpoint *skyv = static_cast<ASkyViewpoint*>(it.Next());
|
||||||
Sector->SkyBoxes[sector_t::ceiling] = skyv;
|
if (skyv != NULL)
|
||||||
if (skyv != NULL && skyv->bAlways)
|
|
||||||
{
|
{
|
||||||
skyv->Mate = point;
|
skyv->target = point;
|
||||||
if (Sector->GetAlphaF(sector_t::ceiling) == 1.)
|
if (Sector->GetAlphaF(sector_t::ceiling) == 1.)
|
||||||
Sector->SetAlpha(sector_t::ceiling, clamp(point->args[0], 0, 255) / 255.);
|
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;
|
pt->special1 = 0;
|
||||||
points.Push(pt);
|
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
|
// plane: 0=floor, 1=ceiling, 2=both
|
||||||
if (plane > 0)
|
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.)
|
if (sector->GetAlphaF(sector_t::ceiling) == 1.)
|
||||||
sector->SetAlpha(sector_t::ceiling, alpha);
|
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 (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.)
|
if (sector->GetAlphaF(sector_t::floor) == 1.)
|
||||||
sector->SetAlpha(sector_t::floor, alpha);
|
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;
|
int s;
|
||||||
FSectorTagIterator itr(sectortag);
|
FSectorTagIterator itr(sectortag);
|
||||||
while ((s = itr.Next()) >= 0)
|
while ((s = itr.Next()) >= 0)
|
||||||
{
|
{
|
||||||
SetPortal(§ors[s], plane, origin, alpha);
|
SetPortal(§ors[s], plane, pnum, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j=0;j<numlines;j++)
|
for (int j=0;j<numlines;j++)
|
||||||
|
@ -930,14 +958,14 @@ static void CopyPortal(int sectortag, int plane, ASkyViewpoint *origin, double a
|
||||||
{
|
{
|
||||||
if (lines[j].args[0] == 0)
|
if (lines[j].args[0] == 0)
|
||||||
{
|
{
|
||||||
SetPortal(lines[j].frontsector, plane, origin, alpha);
|
SetPortal(lines[j].frontsector, plane, pnum, alpha);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FSectorTagIterator itr(lines[j].args[0]);
|
FSectorTagIterator itr(lines[j].args[0]);
|
||||||
while ((s = itr.Next()) >= 0)
|
while ((s = itr.Next()) >= 0)
|
||||||
{
|
{
|
||||||
SetPortal(§ors[s], plane, origin, alpha);
|
SetPortal(§ors[s], plane, pnum, alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -961,6 +989,7 @@ static void CopyPortal(int sectortag, int plane, ASkyViewpoint *origin, double a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void P_SpawnPortal(line_t *line, int sectortag, int plane, int bytealpha, int linked)
|
void P_SpawnPortal(line_t *line, int sectortag, int plane, int bytealpha, int linked)
|
||||||
{
|
{
|
||||||
if (plane < 0 || plane > 2 || (linked && plane == 2)) return;
|
if (plane < 0 || plane > 2 || (linked && plane == 2)) return;
|
||||||
|
@ -975,36 +1004,10 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int bytealpha, int li
|
||||||
lines[i].args[3] == 1)
|
lines[i].args[3] == 1)
|
||||||
{
|
{
|
||||||
// beware of overflows.
|
// beware of overflows.
|
||||||
DVector3 pos1((line->v1->fX() + line->v2->fX()) / 2, (line->v1->fY() + line->v2->fY()) / 2, 0);
|
DVector2 pos1 = line->v1->fPos() + line->Delta() / 2;
|
||||||
DVector3 pos2((lines[i].v1->fX() + lines[i].v2->fX()) / 2, (lines[i].v1->fY() + lines[i].v2->fY()) / 2, 0);
|
DVector2 pos2 = lines[i].v1->fPos() + lines[i].Delta() / 2;
|
||||||
double z = linked ? line->frontsector->GetPlaneTexZF(plane) : 0; // the map's sector height defines the portal plane for linked portals
|
unsigned pnum = P_GetPortal(linked ? PORTS_LINKEDPORTAL : PORTS_PORTAL, plane, line->frontsector, lines[i].frontsector, pos2 - pos1);
|
||||||
|
CopyPortal(sectortag, plane, pnum, bytealpha / 255., false);
|
||||||
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);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1029,7 +1032,8 @@ void P_SpawnSkybox(ASkyViewpoint *origin)
|
||||||
if (refline->special == Sector_SetPortal && refline->args[1] == 2)
|
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.
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1355,11 +1359,8 @@ void P_SpawnSpecials (void)
|
||||||
else if (lines[i].args[1] == 3 || lines[i].args[1] == 4)
|
else if (lines[i].args[1] == 3 || lines[i].args[1] == 4)
|
||||||
{
|
{
|
||||||
line_t *line = &lines[i];
|
line_t *line = &lines[i];
|
||||||
ASkyViewpoint *origin = Spawn<ASkyViewpoint>();
|
unsigned pnum = P_GetPortal(line->args[1] == 3 ? PORTS_PLANE : PORTS_HORIZON, line->args[2], line->frontsector, NULL, { 0,0 });
|
||||||
origin->Sector = line->frontsector;
|
CopyPortal(line->args[0], line->args[2], pnum, 0, true);
|
||||||
origin->special1 = line->args[1] == 3? SKYBOX_PLANE:SKYBOX_HORIZON;
|
|
||||||
|
|
||||||
CopyPortal(line->args[0], line->args[2], origin, 0, true);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ void FTraceInfo::EnterSectorPortal(FPathTraverse &pt, int position, double frac,
|
||||||
inshootthrough = true;
|
inshootthrough = true;
|
||||||
startfrac = frac;
|
startfrac = frac;
|
||||||
EnterDist = enterdist;
|
EnterDist = enterdist;
|
||||||
pt.PortalRelocate(entersec->SkyBoxes[position], ptflags, frac);
|
pt.PortalRelocate(entersec->GetPortal(position)->mDisplacement, ptflags, frac);
|
||||||
|
|
||||||
if ((TraceFlags & TRACE_ReportPortals) && TraceCallback != NULL)
|
if ((TraceFlags & TRACE_ReportPortals) && TraceCallback != NULL)
|
||||||
{
|
{
|
||||||
|
@ -321,7 +321,7 @@ void FTraceInfo::Setup3DFloors()
|
||||||
{
|
{
|
||||||
CurSector->floorplane = *rover->top.plane;
|
CurSector->floorplane = *rover->top.plane;
|
||||||
CurSector->SetTexture(sector_t::floor, *rover->top.texture, false);
|
CurSector->SetTexture(sector_t::floor, *rover->top.texture, false);
|
||||||
CurSector->SkyBoxes[sector_t::floor] = nullptr;
|
CurSector->ClearPortal(sector_t::floor);
|
||||||
bf = ff_top;
|
bf = ff_top;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,7 @@ void FTraceInfo::Setup3DFloors()
|
||||||
CurSector->ceilingplane = *rover->bottom.plane;
|
CurSector->ceilingplane = *rover->bottom.plane;
|
||||||
CurSector->SetTexture(sector_t::ceiling, *rover->bottom.texture, false);
|
CurSector->SetTexture(sector_t::ceiling, *rover->bottom.texture, false);
|
||||||
bc = ff_bottom;
|
bc = ff_bottom;
|
||||||
CurSector->SkyBoxes[sector_t::ceiling] = nullptr;
|
CurSector->ClearPortal(sector_t::ceiling);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -343,7 +343,7 @@ void FTraceInfo::Setup3DFloors()
|
||||||
{
|
{
|
||||||
CurSector->floorplane = *rover->bottom.plane;
|
CurSector->floorplane = *rover->bottom.plane;
|
||||||
CurSector->SetTexture(sector_t::floor, *rover->bottom.texture, false);
|
CurSector->SetTexture(sector_t::floor, *rover->bottom.texture, false);
|
||||||
CurSector->SkyBoxes[sector_t::floor] = nullptr;
|
CurSector->ClearPortal(sector_t::floor);
|
||||||
bf = ff_bottom;
|
bf = ff_bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +351,7 @@ void FTraceInfo::Setup3DFloors()
|
||||||
{
|
{
|
||||||
CurSector->ceilingplane = *rover->top.plane;
|
CurSector->ceilingplane = *rover->top.plane;
|
||||||
CurSector->SetTexture(sector_t::ceiling, *rover->top.texture, false);
|
CurSector->SetTexture(sector_t::ceiling, *rover->top.texture, false);
|
||||||
CurSector->SkyBoxes[sector_t::ceiling] = nullptr;
|
CurSector->ClearPortal(sector_t::ceiling);
|
||||||
bc = ff_top;
|
bc = ff_top;
|
||||||
}
|
}
|
||||||
inshootthrough = false;
|
inshootthrough = false;
|
||||||
|
@ -499,7 +499,7 @@ bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit)
|
||||||
{
|
{
|
||||||
entersector->floorplane = *rover->top.plane;
|
entersector->floorplane = *rover->top.plane;
|
||||||
entersector->SetTexture(sector_t::floor, *rover->top.texture, false);
|
entersector->SetTexture(sector_t::floor, *rover->top.texture, false);
|
||||||
entersector->SkyBoxes[sector_t::floor] = NULL;
|
entersector->ClearPortal(sector_t::floor);
|
||||||
bf = ff_top;
|
bf = ff_top;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -510,7 +510,7 @@ bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit)
|
||||||
{
|
{
|
||||||
entersector->ceilingplane = *rover->bottom.plane;
|
entersector->ceilingplane = *rover->bottom.plane;
|
||||||
entersector->SetTexture(sector_t::ceiling, *rover->bottom.texture, false);
|
entersector->SetTexture(sector_t::ceiling, *rover->bottom.texture, false);
|
||||||
entersector->SkyBoxes[sector_t::ceiling] = NULL;
|
entersector->ClearPortal(sector_t::ceiling);
|
||||||
bc = ff_bottom;
|
bc = ff_bottom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
167
src/portal.cpp
167
src/portal.cpp
|
@ -64,6 +64,8 @@ FPortalBlockmap PortalBlockmap;
|
||||||
TArray<FLinePortal> linePortals;
|
TArray<FLinePortal> linePortals;
|
||||||
TArray<FLinePortal*> linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups.
|
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.
|
// This is used to mark processed portals for some collection functions.
|
||||||
|
@ -213,6 +215,25 @@ FArchive &operator<< (FArchive &arc, FLinePortal &port)
|
||||||
return arc;
|
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;
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
|
@ -487,7 +508,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 +517,17 @@ void P_ClearPortals()
|
||||||
Displacements.Create(1);
|
Displacements.Create(1);
|
||||||
linePortals.Clear();
|
linePortals.Clear();
|
||||||
linkedPortals.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.
|
// check if this line is between portal and the viewer. clip away if it is.
|
||||||
|
@ -637,6 +666,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
|
// P_GetOffsetPosition
|
||||||
|
@ -756,35 +853,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 thisgroup = portal->mOrigin->PortalGroup;
|
||||||
int othergroup = portal->Sector->PortalGroup;
|
int othergroup = portal->mDestination->PortalGroup;
|
||||||
if (thisgroup == othergroup)
|
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);
|
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->special1 = portal->Mate->special1 = SKYBOX_PORTAL;
|
portal->mType = PORTS_PORTAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (thisgroup <= 0 || thisgroup >= Displacements.size || othergroup <= 0 || othergroup >= Displacements.size)
|
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);
|
Printf("Portal between sectors %d and %d has invalid group and will be disabled\n", portal->mOrigin->sectornum, portal->mDestination->sectornum);
|
||||||
portal->special1 = portal->Mate->special1 = SKYBOX_PORTAL;
|
portal->mType = PORTS_PORTAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FDisplacement & disp = Displacements(thisgroup, othergroup);
|
FDisplacement & disp = Displacements(thisgroup, othergroup);
|
||||||
if (!disp.isSet)
|
if (!disp.isSet)
|
||||||
{
|
{
|
||||||
disp.pos = portal->Scale;
|
disp.pos = portal->mDisplacement;
|
||||||
disp.isSet = true;
|
disp.isSet = true;
|
||||||
}
|
}
|
||||||
else
|
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);
|
Printf("Portal between sectors %d and %d has displacement mismatch and will be disabled\n", portal->mOrigin->sectornum, portal->mDestination->sectornum);
|
||||||
portal->special1 = portal->Mate->special1 = SKYBOX_PORTAL;
|
portal->mType = PORTS_PORTAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -895,26 +992,15 @@ static bool ConnectGroups()
|
||||||
|
|
||||||
void P_CreateLinkedPortals()
|
void P_CreateLinkedPortals()
|
||||||
{
|
{
|
||||||
TThinkerIterator<AStackPoint> it;
|
TArray<FSectorPortal *> orgs;
|
||||||
AStackPoint *mo;
|
|
||||||
TArray<AStackPoint *> orgs;
|
|
||||||
int id = 1;
|
int id = 1;
|
||||||
bool bogus = false;
|
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(&s);
|
||||||
{
|
|
||||||
orgs.Push(mo);
|
|
||||||
mo->reactiontime = ++id;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// this should never happen, but if it does, the portal needs to be removed
|
|
||||||
mo->Destroy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id = 1;
|
id = 1;
|
||||||
|
@ -924,14 +1010,13 @@ void P_CreateLinkedPortals()
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 2; j++)
|
for (int j = 0; j < 2; j++)
|
||||||
{
|
{
|
||||||
AActor *box = sectors[i].SkyBoxes[j];
|
if (sectors[i].GetPortalType(j) == PORTS_LINKEDPORTAL)
|
||||||
if (box != NULL && box->special1 == SKYBOX_LINKEDPORTAL)
|
|
||||||
{
|
{
|
||||||
secplane_t &plane = j == 0 ? sectors[i].floorplane : sectors[i].ceilingplane;
|
secplane_t &plane = j == 0 ? sectors[i].floorplane : sectors[i].ceilingplane;
|
||||||
if (plane.isSlope())
|
if (plane.isSlope())
|
||||||
{
|
{
|
||||||
// The engine cannot deal with portals on a sloped plane.
|
// The engine cannot deal with portals on a sloped plane.
|
||||||
sectors[i].SkyBoxes[j] = NULL;
|
sectors[i].ClearPortal(j);
|
||||||
Printf("Portal on %s of sector %d is sloped and will be disabled\n", j == 0 ? "floor" : "ceiling", i);
|
Printf("Portal on %s of sector %d is sloped and will be disabled\n", j == 0 ? "floor" : "ceiling", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -941,8 +1026,8 @@ void P_CreateLinkedPortals()
|
||||||
// Group all sectors, starting at each portal origin.
|
// Group all sectors, starting at each portal origin.
|
||||||
for (unsigned i = 0; i < orgs.Size(); i++)
|
for (unsigned i = 0; i < orgs.Size(); i++)
|
||||||
{
|
{
|
||||||
if (CollectSectors(id, orgs[i]->Sector)) id++;
|
if (CollectSectors(id, orgs[i]->mOrigin)) id++;
|
||||||
if (CollectSectors(id, orgs[i]->Mate->Sector)) id++;
|
if (CollectSectors(id, orgs[i]->mDestination)) id++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < linePortals.Size(); i++)
|
for (unsigned i = 0; i < linePortals.Size(); i++)
|
||||||
|
@ -960,17 +1045,9 @@ void P_CreateLinkedPortals()
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 2; j++)
|
for (int j = 0; j < 2; j++)
|
||||||
{
|
{
|
||||||
ASkyViewpoint *box = barrier_cast<ASkyViewpoint*>(sectors[i].SkyBoxes[j]);
|
if (sectors[i].GetPortalType(j) == PORTS_LINKEDPORTAL && sectors[i].PortalGroup == 0)
|
||||||
if (box != NULL)
|
|
||||||
{
|
{
|
||||||
if (box->special1 == SKYBOX_LINKEDPORTAL && sectors[i].PortalGroup == 0)
|
CollectSectors(sectors[i].GetOppositePortalGroup(j), §ors[i]);
|
||||||
{
|
|
||||||
// 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.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1060,11 +1137,11 @@ void P_CreateLinkedPortals()
|
||||||
double fp = sectors[i].floorplane.fD();
|
double fp = sectors[i].floorplane.fD();
|
||||||
if (cp < fp || fz == fp)
|
if (cp < fp || fz == fp)
|
||||||
{
|
{
|
||||||
sectors[i].SkyBoxes[sector_t::ceiling] = NULL;
|
sectors[i].ClearPortal(sector_t::ceiling);
|
||||||
}
|
}
|
||||||
else
|
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"
|
#include "m_bbox.h"
|
||||||
|
|
||||||
struct FPortalGroupArray;
|
struct FPortalGroupArray;
|
||||||
|
class ASkyViewpoint;
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// This table holds the offsets for the different parts of a map
|
// 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)
|
// 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;
|
DAngle mAngleDiff;
|
||||||
double mSinRot;
|
double mSinRot;
|
||||||
double mCosRot;
|
double mCosRot;
|
||||||
|
void *mRenderData;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern TArray<FLinePortal> linePortals;
|
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_ClearPortals();
|
||||||
void P_SpawnLinePortal(line_t* line);
|
void P_SpawnLinePortal(line_t* line);
|
||||||
void P_FinalizePortals();
|
void P_FinalizePortals();
|
||||||
|
@ -205,6 +255,9 @@ inline int P_NumPortalGroups()
|
||||||
{
|
{
|
||||||
return Displacements.size;
|
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 */
|
/* 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)
|
bool R_SkyboxCompare(sector_t *frontsector, sector_t *backsector)
|
||||||
{
|
{
|
||||||
AActor *frontc = frontsector->SkyBoxes[sector_t::ceiling];
|
FSectorPortal *frontc = frontsector->GetPortal(sector_t::ceiling);
|
||||||
AActor *frontf = frontsector->SkyBoxes[sector_t::floor];
|
FSectorPortal *frontf = frontsector->GetPortal(sector_t::floor);
|
||||||
AActor *backc = backsector->SkyBoxes[sector_t::ceiling];
|
FSectorPortal *backc = backsector->GetPortal(sector_t::ceiling);
|
||||||
AActor *backf = backsector->SkyBoxes[sector_t::floor];
|
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.
|
// 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.
|
// 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.)
|
// (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 (!frontc->MergeAllowed()) return (frontc != backc);
|
||||||
if (frontf != NULL && (frontf->special1 == SKYBOX_PORTAL || frontf->special1 == SKYBOX_LINKEDPORTAL)) return (frontf != backf);
|
if (!frontf->MergeAllowed()) return (frontf != backf);
|
||||||
if (backc != NULL && (backc->special1 == SKYBOX_PORTAL || backc->special1 == SKYBOX_LINKEDPORTAL)) return true;
|
if (!backc->MergeAllowed()) return true;
|
||||||
if (backf != NULL && (backf->special1 == SKYBOX_PORTAL || backf->special1 == SKYBOX_LINKEDPORTAL)) return true;
|
if (!backf->MergeAllowed()) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1046,7 +1046,7 @@ void R_Subsector (subsector_t *sub)
|
||||||
int ceilinglightlevel; // killough 4/11/98
|
int ceilinglightlevel; // killough 4/11/98
|
||||||
bool outersubsector;
|
bool outersubsector;
|
||||||
int fll, cll, position;
|
int fll, cll, position;
|
||||||
ASkyViewpoint *skybox;
|
FSectorPortal *portal;
|
||||||
|
|
||||||
// kg3D - fake floor stuff
|
// kg3D - fake floor stuff
|
||||||
visplane_t *backupfp;
|
visplane_t *backupfp;
|
||||||
|
@ -1114,12 +1114,11 @@ void R_Subsector (subsector_t *sub)
|
||||||
basecolormap = frontsector->ColorMap;
|
basecolormap = frontsector->ColorMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
skybox = frontsector->GetSkyBox(sector_t::ceiling);
|
portal = frontsector->ValidatePortal(sector_t::ceiling);
|
||||||
if (skybox != NULL && skybox->special1 >= SKYBOX_PLANE) skybox = NULL; // skip unsupported portal types
|
|
||||||
|
|
||||||
ceilingplane = frontsector->ceilingplane.PointOnSide(viewx, viewy, viewz) > 0 ||
|
ceilingplane = frontsector->ceilingplane.PointOnSide(viewx, viewy, viewz) > 0 ||
|
||||||
frontsector->GetTexture(sector_t::ceiling) == skyflatnum ||
|
frontsector->GetTexture(sector_t::ceiling) == skyflatnum ||
|
||||||
(skybox != NULL && skybox->bAlways) ||
|
portal != NULL ||
|
||||||
(frontsector->heightsec &&
|
(frontsector->heightsec &&
|
||||||
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
|
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
|
||||||
frontsector->heightsec->GetTexture(sector_t::floor) == skyflatnum) ?
|
frontsector->heightsec->GetTexture(sector_t::floor) == skyflatnum) ?
|
||||||
|
@ -1134,7 +1133,7 @@ void R_Subsector (subsector_t *sub)
|
||||||
frontsector->GetYScale(sector_t::ceiling),
|
frontsector->GetYScale(sector_t::ceiling),
|
||||||
frontsector->GetAngle(sector_t::ceiling),
|
frontsector->GetAngle(sector_t::ceiling),
|
||||||
frontsector->sky,
|
frontsector->sky,
|
||||||
skybox
|
portal
|
||||||
) : NULL;
|
) : NULL;
|
||||||
|
|
||||||
if (fixedlightlev < 0 && frontsector->e && frontsector->e->XFloor.lightlist.Size())
|
if (fixedlightlev < 0 && frontsector->e && frontsector->e->XFloor.lightlist.Size())
|
||||||
|
@ -1156,13 +1155,11 @@ void R_Subsector (subsector_t *sub)
|
||||||
// killough 3/7/98: Add (x,y) offsets to flats, add deep water check
|
// killough 3/7/98: Add (x,y) offsets to flats, add deep water check
|
||||||
// killough 3/16/98: add floorlightlevel
|
// killough 3/16/98: add floorlightlevel
|
||||||
// killough 10/98: add support for skies transferred from sidedefs
|
// killough 10/98: add support for skies transferred from sidedefs
|
||||||
|
portal = frontsector->ValidatePortal(sector_t::floor);
|
||||||
skybox = frontsector->GetSkyBox(sector_t::floor);
|
|
||||||
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
|
floorplane = frontsector->floorplane.PointOnSide(viewx, viewy, viewz) > 0 || // killough 3/7/98
|
||||||
frontsector->GetTexture(sector_t::floor) == skyflatnum ||
|
frontsector->GetTexture(sector_t::floor) == skyflatnum ||
|
||||||
(skybox != NULL && skybox->bAlways) ||
|
portal != NULL ||
|
||||||
(frontsector->heightsec &&
|
(frontsector->heightsec &&
|
||||||
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
|
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
|
||||||
frontsector->heightsec->GetTexture(sector_t::ceiling) == skyflatnum) ?
|
frontsector->heightsec->GetTexture(sector_t::ceiling) == skyflatnum) ?
|
||||||
|
@ -1177,7 +1174,7 @@ void R_Subsector (subsector_t *sub)
|
||||||
frontsector->GetYScale(sector_t::floor),
|
frontsector->GetYScale(sector_t::floor),
|
||||||
frontsector->GetAngle(sector_t::floor),
|
frontsector->GetAngle(sector_t::floor),
|
||||||
frontsector->sky,
|
frontsector->sky,
|
||||||
skybox
|
portal
|
||||||
) : NULL;
|
) : NULL;
|
||||||
|
|
||||||
// kg3D - fake planes rendering
|
// kg3D - fake planes rendering
|
||||||
|
|
46
src/r_defs.h
46
src/r_defs.h
|
@ -62,19 +62,6 @@ enum
|
||||||
extern size_t MaxDrawSegs;
|
extern size_t MaxDrawSegs;
|
||||||
struct FDisplacement;
|
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
|
// INTERNAL MAP TYPES
|
||||||
// used by play and refresh
|
// used by play and refresh
|
||||||
|
@ -529,8 +516,6 @@ enum
|
||||||
SECF_UNDERWATERMASK = 32+64,
|
SECF_UNDERWATERMASK = 32+64,
|
||||||
SECF_DRAWN = 128, // sector has been drawn at least once
|
SECF_DRAWN = 128, // sector has been drawn at least once
|
||||||
SECF_HIDDEN = 256, // Do not draw on textured automap
|
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
|
enum
|
||||||
|
@ -700,7 +685,7 @@ public:
|
||||||
|
|
||||||
DInterpolation *SetInterpolation(int position, bool attach);
|
DInterpolation *SetInterpolation(int position, bool attach);
|
||||||
|
|
||||||
ASkyViewpoint *GetSkyBox(int which);
|
FSectorPortal *ValidatePortal(int which);
|
||||||
void CheckPortalPlane(int plane);
|
void CheckPortalPlane(int plane);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -963,8 +948,7 @@ public:
|
||||||
|
|
||||||
bool PortalBlocksView(int plane)
|
bool PortalBlocksView(int plane)
|
||||||
{
|
{
|
||||||
if (SkyBoxes[plane] == NULL) return true;
|
if (GetPortalType(plane) != PORTS_LINKEDPORTAL) return false;
|
||||||
if (GetPortalType(plane) != SKYBOX_LINKEDPORTAL) return false;
|
|
||||||
return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -985,28 +969,37 @@ public:
|
||||||
|
|
||||||
bool PortalIsLinked(int plane)
|
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)
|
double GetPortalPlaneZ(int plane)
|
||||||
{
|
{
|
||||||
return SkyBoxes[plane]->specialf1;
|
return sectorPortals[Portals[plane]].mPlaneZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
DVector2 GetPortalDisplacement(int plane)
|
DVector2 GetPortalDisplacement(int plane)
|
||||||
{
|
{
|
||||||
return SkyBoxes[plane]->Scale;
|
return sectorPortals[Portals[plane]].mDisplacement;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetPortalType(int plane)
|
int GetPortalType(int plane)
|
||||||
{
|
{
|
||||||
return SkyBoxes[plane] == nullptr? -1 : SkyBoxes[plane]->special1;
|
return sectorPortals[Portals[plane]].mType;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetOppositePortalGroup(int plane)
|
int GetOppositePortalGroup(int plane)
|
||||||
{
|
{
|
||||||
return SkyBoxes[plane]->Sector->PortalGroup;
|
return sectorPortals[Portals[plane]].mDestination->PortalGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetVerticesDirty()
|
void SetVerticesDirty()
|
||||||
|
@ -1128,9 +1121,8 @@ public:
|
||||||
// occurs, SecActTarget's TriggerAction method is called.
|
// occurs, SecActTarget's TriggerAction method is called.
|
||||||
TObjPtr<ASectorAction> SecActTarget;
|
TObjPtr<ASectorAction> SecActTarget;
|
||||||
|
|
||||||
// [RH] The sky box to render for this sector. NULL means use a
|
// [RH] The portal or skybox to render for this sector.
|
||||||
// regular sky.
|
unsigned Portals[2];
|
||||||
TObjPtr<AActor> SkyBoxes[2];
|
|
||||||
int PortalGroup;
|
int PortalGroup;
|
||||||
|
|
||||||
int sectornum; // for comparing sector copies
|
int sectornum; // for comparing sector copies
|
||||||
|
|
|
@ -693,7 +693,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
fixed_t starty = viewy;
|
fixed_t starty = viewy;
|
||||||
fixed_t startz = viewz;
|
fixed_t startz = viewz;
|
||||||
DVector3 savedpath[2] = { ViewPath[0], ViewPath[1] };
|
DVector3 savedpath[2] = { ViewPath[0], ViewPath[1] };
|
||||||
int savedvisibility = camera->renderflags & RF_INVISIBLE;
|
int savedvisibility = camera? camera->renderflags & RF_INVISIBLE : 0;
|
||||||
|
|
||||||
CurrentPortalUniq++;
|
CurrentPortalUniq++;
|
||||||
|
|
||||||
|
@ -746,7 +746,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
viewz = FLOAT2FIXED(view.Z);
|
viewz = FLOAT2FIXED(view.Z);
|
||||||
viewangle = va.BAMs();
|
viewangle = va.BAMs();
|
||||||
|
|
||||||
if (!r_showviewer)
|
if (!r_showviewer && camera)
|
||||||
{
|
{
|
||||||
double distp = (ViewPath[0] - ViewPath[1]).Length();
|
double distp = (ViewPath[0] - ViewPath[1]).Length();
|
||||||
if (distp > EQUAL_EPSILON)
|
if (distp > EQUAL_EPSILON)
|
||||||
|
@ -802,11 +802,11 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
InSubsector = NULL;
|
InSubsector = NULL;
|
||||||
R_RenderBSPNode (nodes + numnodes - 1);
|
R_RenderBSPNode (nodes + numnodes - 1);
|
||||||
R_3D_ResetClip(); // reset clips (floor/ceiling)
|
R_3D_ResetClip(); // reset clips (floor/ceiling)
|
||||||
if (!savedvisibility) camera->renderflags &= ~RF_INVISIBLE;
|
if (!savedvisibility && camera) camera->renderflags &= ~RF_INVISIBLE;
|
||||||
|
|
||||||
PlaneCycles.Clock();
|
PlaneCycles.Clock();
|
||||||
R_DrawPlanes ();
|
R_DrawPlanes ();
|
||||||
R_DrawSkyBoxes ();
|
R_DrawPortals ();
|
||||||
PlaneCycles.Unclock();
|
PlaneCycles.Unclock();
|
||||||
|
|
||||||
fixed_t vzp = viewz;
|
fixed_t vzp = viewz;
|
||||||
|
@ -961,7 +961,7 @@ void R_RenderActorView (AActor *actor, bool dontmaplines)
|
||||||
{
|
{
|
||||||
PlaneCycles.Clock();
|
PlaneCycles.Clock();
|
||||||
R_DrawPlanes ();
|
R_DrawPlanes ();
|
||||||
R_DrawSkyBoxes ();
|
R_DrawPortals ();
|
||||||
PlaneCycles.Unclock();
|
PlaneCycles.Unclock();
|
||||||
|
|
||||||
// [RH] Walk through mirrors
|
// [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,
|
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 xoffs, fixed_t yoffs,
|
||||||
fixed_t xscale, fixed_t yscale, angle_t angle,
|
fixed_t xscale, fixed_t yscale, angle_t angle,
|
||||||
int sky, ASkyViewpoint *skybox)
|
int sky, FSectorPortal *portal)
|
||||||
{
|
{
|
||||||
secplane_t plane;
|
secplane_t plane;
|
||||||
visplane_t *check;
|
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 column but separated by a wall. If they both try to reside in the
|
||||||
// same visplane, then only the floor sky will be drawn.
|
// same visplane, then only the floor sky will be drawn.
|
||||||
plane.set(0., 0., height.fC(), 0.);
|
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;
|
plane = height;
|
||||||
isskybox = true;
|
isskybox = true;
|
||||||
|
@ -622,7 +622,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl
|
||||||
// and ->alpha is for stacked sectors
|
// and ->alpha is for stacked sectors
|
||||||
if (fake3D & (FAKE3D_FAKEFLOOR|FAKE3D_FAKECEILING)) sky = 0x80000000 | fakeAlpha;
|
if (fake3D & (FAKE3D_FAKEFLOOR|FAKE3D_FAKECEILING)) sky = 0x80000000 | fakeAlpha;
|
||||||
else sky = 0; // not skyflatnum so it can't be a sky
|
else sky = 0; // not skyflatnum so it can't be a sky
|
||||||
skybox = NULL;
|
portal = NULL;
|
||||||
alpha = OPAQUE;
|
alpha = OPAQUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,9 +633,9 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl
|
||||||
{
|
{
|
||||||
if (isskybox)
|
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
|
{ // This skybox is really a stacked sector, so we need to
|
||||||
// check even more.
|
// check even more.
|
||||||
if (check->extralight == stacked_extralight &&
|
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 &&
|
check->viewz == stacked_viewz &&
|
||||||
(
|
(
|
||||||
// headache inducing logic... :(
|
// headache inducing logic... :(
|
||||||
(!(skybox->flags & MF_JUSTATTACKED)) ||
|
(portal->mType != PORTS_STACKEDSECTORTHING) ||
|
||||||
(
|
(
|
||||||
check->Alpha == alpha &&
|
check->Alpha == alpha &&
|
||||||
check->Additive == additive &&
|
check->Additive == additive &&
|
||||||
|
@ -710,7 +710,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl
|
||||||
check->angle = angle;
|
check->angle = angle;
|
||||||
check->colormap = basecolormap; // [RH] Save colormap
|
check->colormap = basecolormap; // [RH] Save colormap
|
||||||
check->sky = sky;
|
check->sky = sky;
|
||||||
check->skybox = skybox;
|
check->portal = portal;
|
||||||
check->left = viewwidth; // Was SCREENWIDTH -- killough 11/98
|
check->left = viewwidth; // Was SCREENWIDTH -- killough 11/98
|
||||||
check->right = 0;
|
check->right = 0;
|
||||||
check->extralight = stacked_extralight;
|
check->extralight = stacked_extralight;
|
||||||
|
@ -781,7 +781,7 @@ visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop)
|
||||||
// make a new visplane
|
// make a new visplane
|
||||||
unsigned hash;
|
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;
|
hash = MAXVISPLANES;
|
||||||
}
|
}
|
||||||
|
@ -800,7 +800,7 @@ visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop)
|
||||||
new_pl->yscale = pl->yscale;
|
new_pl->yscale = pl->yscale;
|
||||||
new_pl->angle = pl->angle;
|
new_pl->angle = pl->angle;
|
||||||
new_pl->colormap = pl->colormap;
|
new_pl->colormap = pl->colormap;
|
||||||
new_pl->skybox = pl->skybox;
|
new_pl->portal = pl->portal;
|
||||||
new_pl->extralight = pl->extralight;
|
new_pl->extralight = pl->extralight;
|
||||||
new_pl->visibility = pl->visibility;
|
new_pl->visibility = pl->visibility;
|
||||||
new_pl->viewx = pl->viewx;
|
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.
|
// 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)
|
CVAR (Bool, r_skyboxes, true, 0)
|
||||||
static int numskyboxes;
|
static int numskyboxes;
|
||||||
|
|
||||||
void R_DrawSkyBoxes ()
|
void R_DrawPortals ()
|
||||||
{
|
{
|
||||||
static TArray<size_t> interestingStack;
|
static TArray<size_t> interestingStack;
|
||||||
static TArray<ptrdiff_t> drawsegStack;
|
static TArray<ptrdiff_t> drawsegStack;
|
||||||
|
@ -1221,7 +1221,7 @@ void R_DrawSkyBoxes ()
|
||||||
visplanes[MAXVISPLANES] = pl->next;
|
visplanes[MAXVISPLANES] = pl->next;
|
||||||
pl->next = NULL;
|
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);
|
R_DrawSinglePlane (pl, OPAQUE, false, false);
|
||||||
*freehead = pl;
|
*freehead = pl;
|
||||||
|
@ -1231,12 +1231,13 @@ void R_DrawSkyBoxes ()
|
||||||
|
|
||||||
numskyboxes++;
|
numskyboxes++;
|
||||||
|
|
||||||
ASkyViewpoint *sky = pl->skybox;
|
FSectorPortal *port = pl->portal;
|
||||||
ASkyViewpoint *mate = sky->Mate;
|
switch (port->mType)
|
||||||
|
{
|
||||||
if (mate == NULL)
|
case PORTS_SKYVIEWPOINT:
|
||||||
{
|
{
|
||||||
// Don't let gun flashes brighten the sky box
|
// Don't let gun flashes brighten the sky box
|
||||||
|
ASkyViewpoint *sky = barrier_cast<ASkyViewpoint*>(port->mSkybox);
|
||||||
extralight = 0;
|
extralight = 0;
|
||||||
R_SetVisibility(sky->args[0] * 0.25f);
|
R_SetVisibility(sky->args[0] * 0.25f);
|
||||||
|
|
||||||
|
@ -1247,23 +1248,40 @@ void R_DrawSkyBoxes ()
|
||||||
viewangle = savedangle + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * r_TicFracF).BAMs();
|
viewangle = savedangle + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * r_TicFracF).BAMs();
|
||||||
|
|
||||||
R_CopyStackedViewParameters();
|
R_CopyStackedViewParameters();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
case PORTS_STACKEDSECTORTHING:
|
||||||
|
case PORTS_PORTAL:
|
||||||
|
case PORTS_LINKEDPORTAL:
|
||||||
extralight = pl->extralight;
|
extralight = pl->extralight;
|
||||||
R_SetVisibility (pl->visibility);
|
R_SetVisibility (pl->visibility);
|
||||||
viewx = pl->viewx + FLOAT2FIXED(-sky->Mate->X() + sky->X());
|
viewx = pl->viewx + FLOAT2FIXED(port->mDisplacement.X);
|
||||||
viewy = pl->viewy + FLOAT2FIXED(-sky->Mate->Y() + sky->Y());
|
viewy = pl->viewy + FLOAT2FIXED(port->mDisplacement.Y);
|
||||||
viewz = pl->viewz;
|
viewz = pl->viewz;
|
||||||
viewangle = pl->viewangle;
|
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);
|
ViewAngle = AngleToFloat(viewangle);
|
||||||
ViewPos = { FIXED2DBL(viewx), FIXED2DBL(viewy), FIXED2DBL(viewz) };
|
ViewPos = { FIXED2DBL(viewx), FIXED2DBL(viewy), FIXED2DBL(viewz) };
|
||||||
|
|
||||||
sky->bInSkybox = true;
|
port->mFlags |= PORTSF_INSKYBOX;
|
||||||
if (mate != NULL) mate->bInSkybox = true;
|
if (port->mPartner > 0) sectorPortals[port->mPartner].mFlags |= PORTSF_INSKYBOX;
|
||||||
camera = sky;
|
camera = NULL;
|
||||||
viewsector = sky->Sector;
|
viewsector = port->mDestination;
|
||||||
|
assert(viewsector != NULL);
|
||||||
R_SetViewAngle ();
|
R_SetViewAngle ();
|
||||||
validcount++; // Make sure we see all sprites
|
validcount++; // Make sure we see all sprites
|
||||||
|
|
||||||
|
@ -1324,8 +1342,8 @@ void R_DrawSkyBoxes ()
|
||||||
R_3D_ResetClip(); // reset clips (floor/ceiling)
|
R_3D_ResetClip(); // reset clips (floor/ceiling)
|
||||||
R_DrawPlanes ();
|
R_DrawPlanes ();
|
||||||
|
|
||||||
sky->bInSkybox = false;
|
port->mFlags &= ~PORTSF_INSKYBOX;
|
||||||
if (mate != NULL) mate->bInSkybox = false;
|
if (port->mPartner > 0) sectorPortals[port->mPartner].mFlags &= ~PORTSF_INSKYBOX;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw all the masked textures in a second pass, in the reverse order they
|
// 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
|
fixed_t xscale, yscale; // [RH] Support flat scaling
|
||||||
angle_t angle; // [RH] Support flat rotation
|
angle_t angle; // [RH] Support flat rotation
|
||||||
int sky;
|
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
|
// [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
|
// 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);
|
void R_ClearPlanes (bool fullclear);
|
||||||
|
|
||||||
int R_DrawPlanes ();
|
int R_DrawPlanes ();
|
||||||
void R_DrawSkyBoxes ();
|
void R_DrawPortals ();
|
||||||
void R_DrawSkyPlane (visplane_t *pl);
|
void R_DrawSkyPlane (visplane_t *pl);
|
||||||
void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked);
|
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);
|
void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked);
|
||||||
|
@ -106,7 +106,7 @@ visplane_t *R_FindPlane
|
||||||
fixed_t yscale,
|
fixed_t yscale,
|
||||||
angle_t angle,
|
angle_t angle,
|
||||||
int sky,
|
int sky,
|
||||||
ASkyViewpoint *skybox);
|
FSectorPortal *portal);
|
||||||
|
|
||||||
visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop);
|
visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop);
|
||||||
|
|
||||||
|
|
|
@ -1536,6 +1536,7 @@ void R_DrawPlayerSprites ()
|
||||||
F3DFloor *rover;
|
F3DFloor *rover;
|
||||||
|
|
||||||
if (!r_drawplayersprites ||
|
if (!r_drawplayersprites ||
|
||||||
|
!camera ||
|
||||||
!camera->player ||
|
!camera->player ||
|
||||||
(players[consoleplayer].cheats & CF_CHASECAM) ||
|
(players[consoleplayer].cheats & CF_CHASECAM) ||
|
||||||
(r_deathcamera && camera->health <= 0))
|
(r_deathcamera && camera->health <= 0))
|
||||||
|
|
|
@ -72,11 +72,11 @@ const char *GetVersionString();
|
||||||
// SAVESIG should match SAVEVER.
|
// SAVESIG should match SAVEVER.
|
||||||
|
|
||||||
// MINSAVEVER is the minimum level snapshot version that can be loaded.
|
// MINSAVEVER is the minimum level snapshot version that can be loaded.
|
||||||
#define MINSAVEVER 4536
|
#define MINSAVEVER 4540
|
||||||
|
|
||||||
// Use 4500 as the base git save version, since it's higher than the
|
// Use 4500 as the base git save version, since it's higher than the
|
||||||
// SVN revision ever got.
|
// SVN revision ever got.
|
||||||
#define SAVEVER 4538
|
#define SAVEVER 4540
|
||||||
|
|
||||||
#define SAVEVERSTRINGIFY2(x) #x
|
#define SAVEVERSTRINGIFY2(x) #x
|
||||||
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)
|
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)
|
||||||
|
|
Loading…
Reference in a new issue