mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-16 01:02:03 +00:00
- some header dependency cleanup so that it is no longer needed to include portal.h to get the inline functions. Portal.h has been reduced of most dependencies now so that including it is cheap and can be done in other headers.
- some consolidation in p_map.cpp. PIT_CheckLine and PIT_FindFloorCeiling had quite a bit of redundancy which has been merged. - čontinued work on FMultiBlockLinesIterator. It's still not completely finished.
This commit is contained in:
parent
15040c955e
commit
02d7572343
25 changed files with 269 additions and 293 deletions
10
src/actor.h
10
src/actor.h
|
@ -40,6 +40,7 @@
|
|||
#include "memarena.h"
|
||||
#include "g_level.h"
|
||||
#include "tflags.h"
|
||||
#include "portal.h"
|
||||
|
||||
struct subsector_t;
|
||||
class PClassAmmo;
|
||||
|
@ -1182,9 +1183,9 @@ public:
|
|||
}
|
||||
fixedvec3 Pos() const
|
||||
{
|
||||
fixedvec3 ret = { X(), Y(), Z() };
|
||||
return ret;
|
||||
return __pos;
|
||||
}
|
||||
|
||||
fixedvec3 PosRelative(AActor *other) const;
|
||||
fixedvec3 PosRelative(sector_t *sec) const;
|
||||
fixedvec3 PosRelative(line_t *line) const;
|
||||
|
@ -1366,11 +1367,6 @@ inline fixedvec2 Vec2Angle(fixed_t length, angle_t angle)
|
|||
return ret;
|
||||
}
|
||||
|
||||
inline fixedvec3 PosRelative(const fixedvec3 &pos, line_t *line, sector_t *refsec = NULL)
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
void PrintMiscActorInfo(AActor * query);
|
||||
AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, ActorFlags actorMask, DWORD wallMask);
|
||||
|
||||
|
|
|
@ -126,6 +126,12 @@ inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec3 &v2)
|
|||
return v;
|
||||
}
|
||||
|
||||
inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec2 &v2)
|
||||
{
|
||||
fixedvec3 v = { v1.x + v2.x, v1.y + v2.y, v1.z };
|
||||
return v;
|
||||
}
|
||||
|
||||
#define FIXED_MAX (signed)(0x7fffffff)
|
||||
#define FIXED_MIN (signed)(0x80000000)
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FBoundingBox::FBoundingBox(fixed_t x, fixed_t y, fixed_t radius)
|
||||
void FBoundingBox::setBox(fixed_t x, fixed_t y, fixed_t radius)
|
||||
{
|
||||
m_Box[BOXTOP] = (fixed_t)MIN<SQWORD>((SQWORD)y + radius, FIXED_MAX);
|
||||
m_Box[BOXLEFT] = (fixed_t)MAX<SQWORD>((SQWORD)x - radius, FIXED_MIN);
|
||||
|
|
|
@ -43,7 +43,12 @@ public:
|
|||
m_Box[BOXBOTTOM] = bottom;
|
||||
}
|
||||
|
||||
FBoundingBox(fixed_t x, fixed_t y, fixed_t radius);
|
||||
FBoundingBox(fixed_t x, fixed_t y, fixed_t radius)
|
||||
{
|
||||
setBox(x, y, radius);
|
||||
}
|
||||
|
||||
void setBox(fixed_t x, fixed_t y, fixed_t radius);
|
||||
|
||||
void ClearBox ()
|
||||
{
|
||||
|
|
|
@ -76,7 +76,6 @@
|
|||
#include "actorptrselect.h"
|
||||
#include "farchive.h"
|
||||
#include "decallib.h"
|
||||
#include "portal.h"
|
||||
#include "p_terrain.h"
|
||||
#include "version.h"
|
||||
#include "p_effect.h"
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "g_level.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "gi.h"
|
||||
#include "portal.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
#include "d_net.h"
|
||||
#include "d_event.h"
|
||||
#include "gstrings.h"
|
||||
#include "portal.h"
|
||||
#include "po_man.h"
|
||||
#include "d_player.h"
|
||||
#include "r_utility.h"
|
||||
|
|
|
@ -288,6 +288,8 @@ enum
|
|||
FFCF_ONLY3DFLOORS = 4, // includes 3D midtexes
|
||||
FFCF_3DRESTRICT = 8, // ignore 3D midtexes and floors whose floorz are above thing's z
|
||||
FFCF_NOPORTALS = 16, // ignore portals (considers them impassable.)
|
||||
FFCF_NOFLOOR = 32,
|
||||
FFCF_NOCEILING = 64,
|
||||
};
|
||||
void P_FindFloorCeiling (AActor *actor, int flags=0);
|
||||
|
||||
|
|
252
src/p_map.cpp
252
src/p_map.cpp
|
@ -80,6 +80,7 @@ TArray<line_t *> spechit;
|
|||
// Temporary holder for thing_sectorlist threads
|
||||
msecnode_t* sector_list = NULL; // phares 3/16/98
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetCoefficientClosestPointInLine24
|
||||
|
@ -91,8 +92,9 @@ msecnode_t* sector_list = NULL; // phares 3/16/98
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static fixed_t GetCoefficientClosestPointInLine24(line_t *ld, FCheckPosition &tm)
|
||||
static inline fixed_t GetCoefficientClosestPointInLine24(line_t *ld, fixedvec2 pos)
|
||||
{
|
||||
#ifndef USE_FLOAT
|
||||
// [EP] Use 64 bit integers in order to keep the exact result of the
|
||||
// multiplication, because in the case the vertexes have both the
|
||||
// distance coordinates equal to the map limit (32767 units, which is
|
||||
|
@ -102,8 +104,8 @@ static fixed_t GetCoefficientClosestPointInLine24(line_t *ld, FCheckPosition &tm
|
|||
// fixed_t notation, which is 1.52587890625e-05 in float notation), the
|
||||
// product and the sum can be 1 in the worst case, which is very tiny.
|
||||
|
||||
SQWORD r_num = ((SQWORD(tm.x - ld->v1->x)*ld->dx) +
|
||||
(SQWORD(tm.y - ld->v1->y)*ld->dy));
|
||||
SQWORD r_num = ((SQWORD(pos.x - ld->v1->x)*ld->dx) +
|
||||
(SQWORD(pos.y - ld->v1->y)*ld->dy));
|
||||
|
||||
// The denominator is always positive. Use this to avoid useless
|
||||
// calculations.
|
||||
|
@ -131,16 +133,58 @@ static fixed_t GetCoefficientClosestPointInLine24(line_t *ld, FCheckPosition &tm
|
|||
// Thanks to the fact that in this code path the denominator is greater
|
||||
// than the numerator, it's possible to avoid this bad situation by
|
||||
// just checking the last 24 bits of the numerator.
|
||||
if ((r_num >> (63-24)) != 0) {
|
||||
if ((r_num >> (63 - 24)) != 0) {
|
||||
// [EP] In fact, if the numerator is greater than
|
||||
// (1 << (63-24)), the denominator must be greater than
|
||||
// (1 << (63-24)), hence the denominator won't be zero after
|
||||
// the right shift by 24 places.
|
||||
return (fixed_t)(r_num/(r_den >> 24));
|
||||
return (fixed_t)(r_num / (r_den >> 24));
|
||||
}
|
||||
// [EP] Having the last 24 bits all zero allows left shifting
|
||||
// the numerator by 24 bits without overflow.
|
||||
return (fixed_t)((r_num << 24)/r_den);
|
||||
return (fixed_t)((r_num << 24) / r_den);
|
||||
#else
|
||||
double dx = ld->dx;
|
||||
double dy = ld->dy;
|
||||
return xs_CRoundToInt(((double)(pos.x - ld->v1->x) * dx + (double)(pos.y - ld->v1->y) * dy) / (dx*dx + dy*dy) * 16777216.f);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FindRefPoint
|
||||
//
|
||||
// Finds the point on the line closest to the given coordinate
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static inline fixedvec2 FindRefPoint(line_t *ld, fixedvec2 pos)
|
||||
{
|
||||
if (!((((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) |
|
||||
(ld->backsector->floorplane.a | ld->backsector->floorplane.b) |
|
||||
(ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) |
|
||||
(ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0)
|
||||
&& ld->backsector->e->XFloor.ffloors.Size() == 0 && ld->frontsector->e->XFloor.ffloors.Size() == 0))
|
||||
{
|
||||
fixed_t r = GetCoefficientClosestPointInLine24(ld, pos);
|
||||
if (r <= 0)
|
||||
{
|
||||
pos.x = ld->v1->x;
|
||||
pos.y = ld->v1->y;
|
||||
}
|
||||
else if (r >= (1 << 24))
|
||||
{
|
||||
pos.x = ld->v2->x;
|
||||
pos.y = ld->v2->y;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.x = ld->v1->x + MulScale24(r, ld->dx);
|
||||
pos.y = ld->v1->y + MulScale24(r, ld->dy);
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -151,8 +195,10 @@ static fixed_t GetCoefficientClosestPointInLine24(line_t *ld, FCheckPosition &tm
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static bool PIT_FindFloorCeiling(line_t *ld, const FBoundingBox &box, FCheckPosition &tmf, int flags)
|
||||
static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator::CheckResult &cres, const FBoundingBox &box, FCheckPosition &tmf, int flags)
|
||||
{
|
||||
line_t *ld = cres.line;
|
||||
|
||||
if (box.Right() <= ld->bbox[BOXLEFT]
|
||||
|| box.Left() >= ld->bbox[BOXRIGHT]
|
||||
|| box.Top() <= ld->bbox[BOXBOTTOM]
|
||||
|
@ -169,76 +215,52 @@ static bool PIT_FindFloorCeiling(line_t *ld, const FBoundingBox &box, FCheckPosi
|
|||
return true;
|
||||
}
|
||||
|
||||
fixed_t sx, sy;
|
||||
fixedvec2 refpoint = FindRefPoint(ld, cres.position);
|
||||
FLineOpening open;
|
||||
|
||||
// set openrange, opentop, openbottom
|
||||
if ((((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) |
|
||||
(ld->backsector->floorplane.a | ld->backsector->floorplane.b) |
|
||||
(ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) |
|
||||
(ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0)
|
||||
&& ld->backsector->e->XFloor.ffloors.Size() == 0 && ld->frontsector->e->XFloor.ffloors.Size() == 0)
|
||||
{
|
||||
P_LineOpening(open, tmf.thing, ld, sx = tmf.x, sy = tmf.y, tmf.x, tmf.y, flags);
|
||||
}
|
||||
else
|
||||
{ // Find the point on the line closest to the actor's center, and use
|
||||
// that to calculate openings
|
||||
double dx = ld->dx;
|
||||
double dy = ld->dy;
|
||||
fixed_t r = xs_CRoundToInt(((double)(tmf.x - ld->v1->x) * dx +
|
||||
(double)(tmf.y - ld->v1->y) * dy) /
|
||||
(dx*dx + dy*dy) * 16777216.f);
|
||||
if (r <= 0)
|
||||
{
|
||||
P_LineOpening(open, tmf.thing, ld, sx = ld->v1->x, sy = ld->v1->y, tmf.x, tmf.y, flags);
|
||||
}
|
||||
else if (r >= (1 << 24))
|
||||
{
|
||||
P_LineOpening(open, tmf.thing, ld, sx = ld->v2->x, sy = ld->v2->y, tmf.thing->X(), tmf.thing->Y(), flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
P_LineOpening(open, tmf.thing, ld, sx = ld->v1->x + MulScale24(r, ld->dx),
|
||||
sy = ld->v1->y + MulScale24(r, ld->dy), tmf.x, tmf.y, flags);
|
||||
}
|
||||
}
|
||||
P_LineOpening(open, tmf.thing, ld, refpoint.x, refpoint.y, cres.position.x, cres.position.y, flags);
|
||||
|
||||
// adjust floor / ceiling heights
|
||||
if (open.top < tmf.ceilingz)
|
||||
if (!(flags & FFCF_NOCEILING))
|
||||
{
|
||||
tmf.ceilingz = open.top;
|
||||
if (open.top < tmf.ceilingz)
|
||||
{
|
||||
tmf.ceilingz = open.top;
|
||||
}
|
||||
}
|
||||
|
||||
if (open.bottom > tmf.floorz)
|
||||
if (!(flags & FFCF_NOFLOOR))
|
||||
{
|
||||
tmf.floorz = open.bottom;
|
||||
if (open.bottomsec != NULL) tmf.floorsector = open.bottomsec;
|
||||
tmf.touchmidtex = open.touchmidtex;
|
||||
tmf.abovemidtex = open.abovemidtex;
|
||||
}
|
||||
else if (open.bottom == tmf.floorz)
|
||||
{
|
||||
tmf.touchmidtex |= open.touchmidtex;
|
||||
tmf.abovemidtex |= open.abovemidtex;
|
||||
}
|
||||
|
||||
if (open.lowfloor < tmf.dropoffz)
|
||||
tmf.dropoffz = open.lowfloor;
|
||||
if (open.bottom > tmf.floorz)
|
||||
{
|
||||
tmf.floorz = open.bottom;
|
||||
if (open.bottomsec != NULL) tmf.floorsector = open.bottomsec;
|
||||
tmf.touchmidtex = open.touchmidtex;
|
||||
tmf.abovemidtex = open.abovemidtex;
|
||||
}
|
||||
else if (open.bottom == tmf.floorz)
|
||||
{
|
||||
tmf.touchmidtex |= open.touchmidtex;
|
||||
tmf.abovemidtex |= open.abovemidtex;
|
||||
}
|
||||
|
||||
if (open.lowfloor < tmf.dropoffz)
|
||||
tmf.dropoffz = open.lowfloor;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
// calculates the actual floor and ceiling position at a given
|
||||
// coordinate. Traverses through portals unless being told not to.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags)
|
||||
{
|
||||
sector_t *sec = !(flags & FFCF_SAMESECTOR) ? P_PointInSector(tmf.x, tmf.y) : tmf.thing->Sector;
|
||||
sector_t *sec = (!(flags & FFCF_SAMESECTOR) || tmf.thing->Sector == NULL)? P_PointInSector(tmf.x, tmf.y) : tmf.thing->Sector;
|
||||
|
||||
if (flags & FFCF_NOPORTALS)
|
||||
{
|
||||
|
@ -268,17 +290,20 @@ void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags)
|
|||
|
||||
if (ff_top > tmf.floorz)
|
||||
{
|
||||
if (ff_top <= tmf.z || (!(flags & FFCF_3DRESTRICT) && (tmf.thing != NULL && ff_bottom < tmf.z && ff_top < tmf.z + tmf.thing->MaxStepHeight)))
|
||||
// either with feet above the 3D floor or feet with less than 'stepheight' map units inside
|
||||
if (ff_top <= tmf.z || (!(flags & FFCF_3DRESTRICT) && (ff_bottom < tmf.z && ff_top < tmf.z + tmf.thing->MaxStepHeight)))
|
||||
{
|
||||
tmf.dropoffz = tmf.floorz = ff_top;
|
||||
tmf.floorpic = *rover->top.texture;
|
||||
tmf.floorterrain = rover->model->GetTerrain(rover->top.isceiling);
|
||||
tmf.floorsector = sec;
|
||||
}
|
||||
}
|
||||
if (ff_bottom <= tmf.ceilingz && ff_bottom > tmf.z + tmf.thing->height)
|
||||
{
|
||||
tmf.ceilingz = ff_bottom;
|
||||
tmf.ceilingpic = *rover->bottom.texture;
|
||||
tmf.ceilingsector = sec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -303,6 +328,7 @@ void P_FindFloorCeiling(AActor *actor, int flags)
|
|||
flags |= FFCF_3DRESTRICT;
|
||||
}
|
||||
P_GetFloorCeilingZ(tmf, flags);
|
||||
assert(tmf.thing->Sector != NULL);
|
||||
|
||||
actor->floorz = tmf.floorz;
|
||||
actor->dropoffz = tmf.dropoffz;
|
||||
|
@ -313,44 +339,44 @@ void P_FindFloorCeiling(AActor *actor, int flags)
|
|||
actor->ceilingpic = tmf.ceilingpic;
|
||||
actor->ceilingsector = tmf.ceilingsector;
|
||||
|
||||
FBoundingBox box(tmf.x, tmf.y, actor->radius);
|
||||
|
||||
tmf.touchmidtex = false;
|
||||
tmf.abovemidtex = false;
|
||||
validcount++;
|
||||
|
||||
FBlockLinesIterator it(box);
|
||||
line_t *ld;
|
||||
FPortalGroupArray grouplist;
|
||||
FMultiBlockLinesIterator mit(grouplist, actor, tmf.x, tmf.y, actor->radius);
|
||||
FMultiBlockLinesIterator::CheckResult cres;
|
||||
|
||||
while ((ld = it.Next()))
|
||||
// if we already have a valid floor/ceiling sector within the current sector,
|
||||
// we do not need to iterate through plane portals to find a floor or ceiling.
|
||||
if (actor->floorsector == actor->Sector) mit.StopDown();
|
||||
if (actor->ceilingsector == actor->Sector) mit.StopUp();
|
||||
|
||||
while ((mit.Next(&cres)))
|
||||
{
|
||||
PIT_FindFloorCeiling(ld, box, tmf, flags);
|
||||
PIT_FindFloorCeiling(cres, mit.Box(), tmf, flags|cres.portalflags);
|
||||
}
|
||||
|
||||
if (tmf.touchmidtex) tmf.dropoffz = tmf.floorz;
|
||||
|
||||
if (!(flags & FFCF_ONLYSPAWNPOS) || (tmf.abovemidtex && (tmf.floorz <= actor->Z())))
|
||||
bool usetmf = !(flags & FFCF_ONLYSPAWNPOS) || (tmf.abovemidtex && (tmf.floorz <= actor->Z()));
|
||||
|
||||
// when actual floor or ceiling are beyond a portal plane we also need to use the result of the blockmap iterator, regardless of the flags being specified.
|
||||
if (usetmf || tmf.floorsector->PortalGroup != actor->Sector->PortalGroup)
|
||||
{
|
||||
actor->floorz = tmf.floorz;
|
||||
actor->dropoffz = tmf.dropoffz;
|
||||
actor->ceilingz = tmf.ceilingz;
|
||||
actor->floorpic = tmf.floorpic;
|
||||
actor->floorterrain = tmf.floorterrain;
|
||||
actor->floorsector = tmf.floorsector;
|
||||
}
|
||||
|
||||
if (usetmf || tmf.ceilingsector->PortalGroup != actor->Sector->PortalGroup)
|
||||
{
|
||||
actor->ceilingz = tmf.ceilingz;
|
||||
actor->ceilingpic = tmf.ceilingpic;
|
||||
actor->ceilingsector = tmf.ceilingsector;
|
||||
}
|
||||
else
|
||||
{
|
||||
actor->floorsector = actor->ceilingsector = actor->Sector;
|
||||
// [BB] Don't forget to update floorpic and ceilingpic.
|
||||
if (actor->Sector != NULL)
|
||||
{
|
||||
actor->floorpic = actor->Sector->GetTexture(sector_t::floor);
|
||||
actor->floorterrain = actor->Sector->GetTerrain(sector_t::floor);
|
||||
actor->ceilingpic = actor->Sector->GetTexture(sector_t::ceiling);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -392,16 +418,17 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra
|
|||
|
||||
bool StompAlwaysFrags = ((thing->flags2 & MF2_TELESTOMP) || (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag) && !(thing->flags7 & MF7_NOTELESTOMP);
|
||||
|
||||
FBoundingBox box(x, y, thing->radius);
|
||||
FBlockLinesIterator it(box);
|
||||
line_t *ld;
|
||||
|
||||
// P_LineOpening requires the thing's z to be the destination z in order to work.
|
||||
fixed_t savedz = thing->Z();
|
||||
thing->SetZ(z);
|
||||
while ((ld = it.Next()))
|
||||
|
||||
FPortalGroupArray grouplist;
|
||||
FMultiBlockLinesIterator mit(grouplist, thing, tmf.x, tmf.y, thing->radius);
|
||||
FMultiBlockLinesIterator::CheckResult cres;
|
||||
|
||||
while (mit.Next(&cres))
|
||||
{
|
||||
PIT_FindFloorCeiling(ld, box, tmf, 0);
|
||||
PIT_FindFloorCeiling(cres, mit.Box(), tmf, 0);
|
||||
}
|
||||
thing->SetZ(savedz);
|
||||
|
||||
|
@ -714,6 +741,7 @@ int P_GetMoveFactor(const AActor *mo, int *frictionp)
|
|||
return movefactor;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// MOVEMENT ITERATOR FUNCTIONS
|
||||
//
|
||||
|
@ -825,56 +853,18 @@ bool PIT_CheckLine(line_t *ld, const FBoundingBox &box, FCheckPosition &tm)
|
|||
}
|
||||
}
|
||||
|
||||
fixed_t sx = 0, sy = 0;
|
||||
fixedvec2 rpos = { tm.x, tm.y };
|
||||
fixedvec2 ref = FindRefPoint(ld, rpos);
|
||||
FLineOpening open;
|
||||
|
||||
// set openrange, opentop, openbottom
|
||||
if ((((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) |
|
||||
(ld->backsector->floorplane.a | ld->backsector->floorplane.b) |
|
||||
(ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) |
|
||||
(ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0)
|
||||
&& ld->backsector->e->XFloor.ffloors.Size() == 0 && ld->frontsector->e->XFloor.ffloors.Size() == 0)
|
||||
// the floorplane on both sides is identical with the current one
|
||||
// so don't mess around with the z-position.
|
||||
if (ld->frontsector->floorplane == ld->backsector->floorplane &&
|
||||
ld->frontsector->floorplane == tm.thing->Sector->floorplane &&
|
||||
!ld->frontsector->e->XFloor.ffloors.Size() && !ld->backsector->e->XFloor.ffloors.Size() &&
|
||||
!open.abovemidtex)
|
||||
{
|
||||
P_LineOpening(open, tm.thing, ld, sx = tm.x, sy = tm.y, tm.x, tm.y);
|
||||
}
|
||||
else
|
||||
{ // Find the point on the line closest to the actor's center, and use
|
||||
// that to calculate openings
|
||||
fixed_t r = GetCoefficientClosestPointInLine24(ld, tm);
|
||||
|
||||
/* Printf ("%d:%d: %d (%d %d %d %d) (%d %d %d %d)\n", level.time, ld-lines, r,
|
||||
ld->frontsector->floorplane.a,
|
||||
ld->frontsector->floorplane.b,
|
||||
ld->frontsector->floorplane.c,
|
||||
ld->frontsector->floorplane.ic,
|
||||
ld->backsector->floorplane.a,
|
||||
ld->backsector->floorplane.b,
|
||||
ld->backsector->floorplane.c,
|
||||
ld->backsector->floorplane.ic);*/
|
||||
if (r <= 0)
|
||||
{
|
||||
P_LineOpening(open, tm.thing, ld, sx = ld->v1->x, sy = ld->v1->y, tm.x, tm.y);
|
||||
}
|
||||
else if (r >= (1 << 24))
|
||||
{
|
||||
P_LineOpening(open, tm.thing, ld, sx = ld->v2->x, sy = ld->v2->y, pos.x, pos.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
P_LineOpening(open, tm.thing, ld, sx = ld->v1->x + MulScale24(r, ld->dx),
|
||||
sy = ld->v1->y + MulScale24(r, ld->dy), tm.x, tm.y);
|
||||
}
|
||||
|
||||
// the floorplane on both sides is identical with the current one
|
||||
// so don't mess around with the z-position
|
||||
if (ld->frontsector->floorplane == ld->backsector->floorplane &&
|
||||
ld->frontsector->floorplane == tm.thing->Sector->floorplane &&
|
||||
!ld->frontsector->e->XFloor.ffloors.Size() && !ld->backsector->e->XFloor.ffloors.Size() &&
|
||||
!open.abovemidtex)
|
||||
{
|
||||
open.bottom = INT_MIN;
|
||||
}
|
||||
/* Printf (" %d %d %d\n", sx, sy, openbottom);*/
|
||||
open.bottom = INT_MIN;
|
||||
}
|
||||
|
||||
if (rail &&
|
||||
|
@ -886,7 +876,7 @@ bool PIT_CheckLine(line_t *ld, const FBoundingBox &box, FCheckPosition &tm)
|
|||
// from either side. How long until somebody reports this as a bug and I'm
|
||||
// forced to say, "It's not a bug. It's a feature?" Ugh.
|
||||
(!(level.flags2 & LEVEL2_RAILINGHACK) ||
|
||||
open.bottom == tm.thing->Sector->floorplane.ZatPoint(sx, sy)))
|
||||
open.bottom == tm.thing->Sector->floorplane.ZatPoint(ref.x, ref.y)))
|
||||
{
|
||||
open.bottom += 32 * FRACUNIT;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include "p_3dmidtex.h"
|
||||
#include "p_blockmap.h"
|
||||
#include "r_utility.h"
|
||||
#include "portal.h"
|
||||
|
||||
// State.
|
||||
#include "r_state.h"
|
||||
|
@ -694,7 +693,8 @@ line_t *FBlockLinesIterator::Next()
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
FMultiBlockLinesIterator::FMultiBlockLinesIterator(AActor *origin, fixed_t checkx, fixed_t checky, fixed_t checkradius)
|
||||
FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkx, fixed_t checky, fixed_t checkradius)
|
||||
: checklist(check)
|
||||
{
|
||||
checkpoint = origin->Pos();
|
||||
if (checkx != FIXED_MAX) checkpoint.x = checkx;
|
||||
|
@ -712,7 +712,7 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item)
|
|||
{
|
||||
item->line = line;
|
||||
item->position = offset;
|
||||
item->portalposition = portalposition;
|
||||
item->portalflags = portalflags;
|
||||
return true;
|
||||
}
|
||||
else if (checklist[index] & FPortalGroupArray::UPPER)
|
||||
|
@ -723,6 +723,7 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item)
|
|||
if (!sector->PortalBlocksMovement(sector_t::ceiling))
|
||||
{
|
||||
startIteratorForGroup(sector->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup);
|
||||
portalflags = FFCF_NOFLOOR;
|
||||
return Next(item);
|
||||
}
|
||||
}
|
||||
|
@ -735,13 +736,28 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item)
|
|||
if (!sector->PortalBlocksMovement(sector_t::floor))
|
||||
{
|
||||
startIteratorForGroup(sector->SkyBoxes[sector_t::floor]->Sector->PortalGroup);
|
||||
portalflags = FFCF_NOCEILING;
|
||||
return Next(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
if (index >= checklist.Size()) return false;
|
||||
startIteratorForGroup(checklist[index]);
|
||||
startIteratorForGroup(checklist[index] & ~FPortalGroupArray::FLAT);
|
||||
switch (checklist[index] & FPortalGroupArray::FLAT)
|
||||
{
|
||||
case FPortalGroupArray::UPPER:
|
||||
portalflags = FFCF_NOFLOOR;
|
||||
break;
|
||||
|
||||
case FPortalGroupArray::LOWER:
|
||||
portalflags = FFCF_NOCEILING;
|
||||
break;
|
||||
|
||||
default:
|
||||
portalflags = 0;
|
||||
}
|
||||
|
||||
return Next(item);
|
||||
}
|
||||
|
||||
|
@ -750,15 +766,15 @@ void FMultiBlockLinesIterator::startIteratorForGroup(int group)
|
|||
offset = Displacements(basegroup, group);
|
||||
offset.x += checkpoint.x;
|
||||
offset.y += checkpoint.y;
|
||||
FBoundingBox box(offset.x, offset.y, checkpoint.z);
|
||||
blockIterator.init(box);
|
||||
bbox.setBox(offset.x, offset.y, checkpoint.z);
|
||||
blockIterator.init(bbox);
|
||||
}
|
||||
|
||||
void FMultiBlockLinesIterator::Reset()
|
||||
{
|
||||
continueup = continueup = true;
|
||||
index = -1;
|
||||
portalposition = PP_ORIGIN;
|
||||
portalflags = 0;
|
||||
startIteratorForGroup(basegroup);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "r_defs.h"
|
||||
#include "doomstat.h"
|
||||
#include "m_bbox.h"
|
||||
|
||||
extern int validcount;
|
||||
|
||||
|
@ -141,12 +142,14 @@ struct FPortalGroupArray
|
|||
FPortalGroupArray()
|
||||
{
|
||||
varused = 0;
|
||||
inited = false;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
data.Clear();
|
||||
varused = 0;
|
||||
inited = false;
|
||||
}
|
||||
|
||||
void Add(DWORD num)
|
||||
|
@ -165,9 +168,11 @@ struct FPortalGroupArray
|
|||
return index < MAX_STATIC ? entry[index] : data[index - MAX_STATIC];
|
||||
}
|
||||
|
||||
bool inited;
|
||||
|
||||
private:
|
||||
WORD entry[MAX_STATIC];
|
||||
unsigned varused;
|
||||
BYTE varused;
|
||||
TArray<WORD> data;
|
||||
};
|
||||
|
||||
|
@ -195,36 +200,29 @@ public:
|
|||
|
||||
class FMultiBlockLinesIterator
|
||||
{
|
||||
FPortalGroupArray &checklist;
|
||||
fixedvec3 checkpoint;
|
||||
fixedvec2 offset;
|
||||
short basegroup;
|
||||
short portalposition;
|
||||
short portalflags;
|
||||
WORD index;
|
||||
bool continueup;
|
||||
bool continuedown;
|
||||
FBlockLinesIterator blockIterator;
|
||||
FPortalGroupArray checklist;
|
||||
FBoundingBox bbox;
|
||||
|
||||
void startIteratorForGroup(int group);
|
||||
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
PP_ORIGIN,
|
||||
PP_ABOVE,
|
||||
PP_BELOW,
|
||||
PP_THROUGHLINE
|
||||
};
|
||||
|
||||
struct CheckResult
|
||||
{
|
||||
line_t *line;
|
||||
fixedvec2 position;
|
||||
int portalposition;
|
||||
int portalflags;
|
||||
};
|
||||
|
||||
FMultiBlockLinesIterator(AActor *origin, fixed_t checkx = FIXED_MAX, fixed_t checky = FIXED_MAX, fixed_t checkradius = -1);
|
||||
FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkx = FIXED_MAX, fixed_t checky = FIXED_MAX, fixed_t checkradius = -1);
|
||||
bool Next(CheckResult *item);
|
||||
void Reset();
|
||||
// for stopping group traversal through portals. Only the calling code can decide whether this is needed so this needs to be set from the outside.
|
||||
|
@ -236,6 +234,10 @@ public:
|
|||
{
|
||||
continuedown = false;
|
||||
}
|
||||
const FBoundingBox &Box() const
|
||||
{
|
||||
return bbox;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
#include "p_lnspec.h"
|
||||
#include "p_acs.h"
|
||||
#include "p_terrain.h"
|
||||
#include "portal.h"
|
||||
|
||||
static void CopyPlayer (player_t *dst, player_t *src, const char *name);
|
||||
static void ReadOnePlayer (FArchive &arc, bool skipload);
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include "po_man.h"
|
||||
#include "farchive.h"
|
||||
#include "r_utility.h"
|
||||
#include "portal.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "r_data/colormaps.h"
|
||||
|
||||
|
@ -806,7 +805,7 @@ int sector_t::GetCeilingLight () const
|
|||
|
||||
ASkyViewpoint *sector_t::GetSkyBox(int which)
|
||||
{
|
||||
if (SkyBoxes[which] != NULL) return SkyBoxes[which];
|
||||
if (SkyBoxes[which] != NULL) return barrier_cast<ASkyViewpoint*>(SkyBoxes[which]);
|
||||
if (MoreFlags & (SECF_NOFLOORSKYBOX << which)) return NULL;
|
||||
return level.DefaultSkybox;
|
||||
}
|
||||
|
@ -874,7 +873,7 @@ int sector_t::GetTerrain(int pos) const
|
|||
|
||||
void sector_t::CheckPortalPlane(int plane)
|
||||
{
|
||||
ASkyViewpoint *portal = SkyBoxes[plane];
|
||||
AActor *portal = SkyBoxes[plane];
|
||||
if (!portal || portal->special1 != SKYBOX_LINKEDPORTAL) return;
|
||||
|
||||
fixed_t planeh = planes[plane].TexZ;
|
||||
|
|
|
@ -69,7 +69,6 @@
|
|||
#include "po_man.h"
|
||||
#include "r_renderer.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "portal.h"
|
||||
#include "p_blockmap.h"
|
||||
#include "r_utility.h"
|
||||
#include "p_spec.h"
|
||||
|
|
|
@ -67,7 +67,6 @@
|
|||
#include "c_dispatch.h"
|
||||
#include "r_sky.h"
|
||||
#include "d_player.h"
|
||||
#include "portal.h"
|
||||
#include "p_maputl.h"
|
||||
#include "p_blockmap.h"
|
||||
#ifndef NO_EDATA
|
||||
|
@ -919,10 +918,11 @@ static void SetupFloorPortal (AStackPoint *point)
|
|||
{
|
||||
NActorIterator it (NAME_LowerStackLookOnly, point->tid);
|
||||
sector_t *Sector = point->Sector;
|
||||
Sector->SkyBoxes[sector_t::floor] = static_cast<ASkyViewpoint*>(it.Next());
|
||||
if (Sector->SkyBoxes[sector_t::floor] != NULL && Sector->SkyBoxes[sector_t::floor]->bAlways)
|
||||
ASkyViewpoint *skyv = static_cast<ASkyViewpoint*>(it.Next());
|
||||
Sector->SkyBoxes[sector_t::floor] = skyv;
|
||||
if (skyv != NULL && skyv->bAlways)
|
||||
{
|
||||
Sector->SkyBoxes[sector_t::floor]->Mate = point;
|
||||
skyv->Mate = point;
|
||||
if (Sector->GetAlpha(sector_t::floor) == OPAQUE)
|
||||
Sector->SetAlpha(sector_t::floor, Scale (point->args[0], OPAQUE, 255));
|
||||
}
|
||||
|
@ -932,12 +932,13 @@ static void SetupCeilingPortal (AStackPoint *point)
|
|||
{
|
||||
NActorIterator it (NAME_UpperStackLookOnly, point->tid);
|
||||
sector_t *Sector = point->Sector;
|
||||
Sector->SkyBoxes[sector_t::ceiling] = static_cast<ASkyViewpoint*>(it.Next());
|
||||
if (Sector->SkyBoxes[sector_t::ceiling] != NULL && Sector->SkyBoxes[sector_t::ceiling]->bAlways)
|
||||
ASkyViewpoint *skyv = static_cast<ASkyViewpoint*>(it.Next());
|
||||
Sector->SkyBoxes[sector_t::ceiling] = skyv;
|
||||
if (skyv != NULL && skyv->bAlways)
|
||||
{
|
||||
Sector->SkyBoxes[sector_t::ceiling]->Mate = point;
|
||||
skyv->Mate = point;
|
||||
if (Sector->GetAlpha(sector_t::ceiling) == OPAQUE)
|
||||
Sector->SetAlpha(sector_t::ceiling, Scale (point->args[0], OPAQUE, 255));
|
||||
Sector->SetAlpha(sector_t::ceiling, Scale(point->args[0], OPAQUE, 255));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -968,7 +969,7 @@ static void SetPortal(sector_t *sector, int plane, ASkyViewpoint *portal, fixed_
|
|||
// plane: 0=floor, 1=ceiling, 2=both
|
||||
if (plane > 0)
|
||||
{
|
||||
if (sector->SkyBoxes[sector_t::ceiling] == NULL || !sector->SkyBoxes[sector_t::ceiling]->bAlways)
|
||||
if (sector->SkyBoxes[sector_t::ceiling] == NULL || !barrier_cast<ASkyViewpoint*>(sector->SkyBoxes[sector_t::ceiling])->bAlways)
|
||||
{
|
||||
sector->SkyBoxes[sector_t::ceiling] = portal;
|
||||
if (sector->GetAlpha(sector_t::ceiling) == OPAQUE)
|
||||
|
@ -979,7 +980,7 @@ static void SetPortal(sector_t *sector, int plane, ASkyViewpoint *portal, fixed_
|
|||
}
|
||||
if (plane == 2 || plane == 0)
|
||||
{
|
||||
if (sector->SkyBoxes[sector_t::floor] == NULL || !sector->SkyBoxes[sector_t::floor]->bAlways)
|
||||
if (sector->SkyBoxes[sector_t::floor] == NULL || !barrier_cast<ASkyViewpoint*>(sector->SkyBoxes[sector_t::floor])->bAlways)
|
||||
{
|
||||
sector->SkyBoxes[sector_t::floor] = portal;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include "r_data/colormaps.h"
|
||||
#include "w_wad.h"
|
||||
#include "p_tags.h"
|
||||
#include "portal.h"
|
||||
#include "p_terrain.h"
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "portal.h"
|
||||
#include "p_local.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "r_bsp.h"
|
||||
|
@ -925,7 +924,7 @@ void P_CreateLinkedPortals()
|
|||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
ASkyViewpoint *box = sectors[i].SkyBoxes[j];
|
||||
AActor *box = sectors[i].SkyBoxes[j];
|
||||
if (box != NULL && box->special1 == SKYBOX_LINKEDPORTAL)
|
||||
{
|
||||
secplane_t &plane = j == 0 ? sectors[i].floorplane : sectors[i].ceilingplane;
|
||||
|
@ -961,7 +960,7 @@ void P_CreateLinkedPortals()
|
|||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
ASkyViewpoint *box = sectors[i].SkyBoxes[j];
|
||||
ASkyViewpoint *box = barrier_cast<ASkyViewpoint*>(sectors[i].SkyBoxes[j]);
|
||||
if (box != NULL)
|
||||
{
|
||||
if (box->special1 == SKYBOX_LINKEDPORTAL && sectors[i].PortalGroup == 0)
|
||||
|
@ -1061,10 +1060,10 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t
|
|||
static TArray<FLinePortal*> foundPortals;
|
||||
|
||||
bool retval = false;
|
||||
out.inited = true;
|
||||
if (linkedPortals.Size() == 0)
|
||||
{
|
||||
// If there are no portals, all sectors are in group 0.
|
||||
out.Add(0);
|
||||
return false;
|
||||
}
|
||||
processMask.setSize(linkedPortals.Size());
|
||||
|
|
90
src/portal.h
90
src/portal.h
|
@ -3,11 +3,7 @@
|
|||
|
||||
#include "basictypes.h"
|
||||
#include "v_video.h"
|
||||
#include "r_defs.h"
|
||||
#include "actor.h"
|
||||
#include "p_local.h"
|
||||
#include "m_bbox.h"
|
||||
#include "a_sharedglobal.h"
|
||||
|
||||
struct FPortalGroupArray;
|
||||
//============================================================================
|
||||
|
@ -180,90 +176,4 @@ public:
|
|||
/* new code */
|
||||
fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y);
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// some wrappers around the portal data.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
|
||||
// returns true if the portal is crossable by actors
|
||||
inline bool line_t::isLinePortal() const
|
||||
{
|
||||
return portalindex >= linePortals.Size() ? false : !!(linePortals[portalindex].mFlags & PORTF_PASSABLE);
|
||||
}
|
||||
|
||||
// returns true if the portal needs to be handled by the renderer
|
||||
inline bool line_t::isVisualPortal() const
|
||||
{
|
||||
return portalindex >= linePortals.Size() ? false : !!(linePortals[portalindex].mFlags & PORTF_VISIBLE);
|
||||
}
|
||||
|
||||
inline line_t *line_t::getPortalDestination() const
|
||||
{
|
||||
return portalindex >= linePortals.Size() ? (line_t*)NULL : linePortals[portalindex].mDestination;
|
||||
}
|
||||
|
||||
inline int line_t::getPortalAlignment() const
|
||||
{
|
||||
return portalindex >= linePortals.Size() ? 0 : linePortals[portalindex].mAlign;
|
||||
}
|
||||
|
||||
inline bool sector_t::PortalBlocksView(int plane)
|
||||
{
|
||||
if (SkyBoxes[plane] == NULL) return true;
|
||||
if (SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return false;
|
||||
return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
inline bool sector_t::PortalBlocksSight(int plane)
|
||||
{
|
||||
if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true;
|
||||
return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
inline bool sector_t::PortalBlocksMovement(int plane)
|
||||
{
|
||||
if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true;
|
||||
return !!(planes[plane].Flags & (PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
inline bool sector_t::PortalBlocksSound(int plane)
|
||||
{
|
||||
if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true;
|
||||
return !!(planes[plane].Flags & (PLANEF_BLOCKSOUND | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
// These may only be called if the portal has been validated
|
||||
inline FDisplacement §or_t::FloorDisplacement()
|
||||
{
|
||||
return Displacements(PortalGroup, SkyBoxes[sector_t::floor]->Sector->PortalGroup);
|
||||
}
|
||||
|
||||
inline FDisplacement §or_t::CeilingDisplacement()
|
||||
{
|
||||
return Displacements(PortalGroup, SkyBoxes[sector_t::ceiling]->Sector->PortalGroup);
|
||||
}
|
||||
|
||||
inline fixedvec3 AActor::PosRelative(AActor *other) const
|
||||
{
|
||||
FDisplacement &disp = Displacements(Sector->PortalGroup, other->Sector->PortalGroup);
|
||||
fixedvec3 ret = { X() + disp.pos.x, Y() + disp.pos.y, Z() };
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline fixedvec3 AActor::PosRelative(sector_t *sec) const
|
||||
{
|
||||
FDisplacement &disp = Displacements(Sector->PortalGroup, sec->PortalGroup);
|
||||
fixedvec3 ret = { X() + disp.pos.x, Y() + disp.pos.y, Z() };
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline fixedvec3 AActor::PosRelative(line_t *line) const
|
||||
{
|
||||
FDisplacement &disp = Displacements(Sector->PortalGroup, line->frontsector->PortalGroup);
|
||||
fixedvec3 ret = { X() + disp.pos.x, Y() + disp.pos.y, Z() };
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -56,7 +56,6 @@
|
|||
#include "r_sky.h"
|
||||
#include "po_man.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "portal.h"
|
||||
|
||||
seg_t* curline;
|
||||
side_t* sidedef;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include "tarray.h"
|
||||
#include <stddef.h>
|
||||
#include "portal.h"
|
||||
#include "r_defs.h"
|
||||
|
||||
// The 3072 below is just an arbitrary value picked to avoid
|
||||
// drawing lines the player is too close to that would overflow
|
||||
|
|
87
src/r_defs.h
87
src/r_defs.h
|
@ -739,10 +739,41 @@ struct sector_t
|
|||
Flags &= ~SECF_SPECIALFLAGS;
|
||||
}
|
||||
|
||||
bool PortalBlocksView(int plane);
|
||||
bool PortalBlocksSight(int plane);
|
||||
bool PortalBlocksMovement(int plane);
|
||||
bool PortalBlocksSound(int plane);
|
||||
bool PortalBlocksView(int plane)
|
||||
{
|
||||
if (SkyBoxes[plane] == NULL) return true;
|
||||
if (SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return false;
|
||||
return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
bool PortalBlocksSight(int plane)
|
||||
{
|
||||
if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true;
|
||||
return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
bool PortalBlocksMovement(int plane)
|
||||
{
|
||||
if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true;
|
||||
return !!(planes[plane].Flags & (PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
bool PortalBlocksSound(int plane)
|
||||
{
|
||||
if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true;
|
||||
return !!(planes[plane].Flags & (PLANEF_BLOCKSOUND | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
// These may only be called if the portal has been validated
|
||||
FDisplacement &FloorDisplacement()
|
||||
{
|
||||
return Displacements(PortalGroup, SkyBoxes[sector_t::floor]->Sector->PortalGroup);
|
||||
}
|
||||
|
||||
FDisplacement &CeilingDisplacement()
|
||||
{
|
||||
return Displacements(PortalGroup, SkyBoxes[sector_t::ceiling]->Sector->PortalGroup);
|
||||
}
|
||||
|
||||
int GetTerrain(int pos) const;
|
||||
|
||||
|
@ -778,9 +809,6 @@ struct sector_t
|
|||
return NextLowestFloorAt(a->X(), a->Y(), z, resultsec, resultffloor);
|
||||
}
|
||||
|
||||
FDisplacement &FloorDisplacement();
|
||||
FDisplacement &CeilingDisplacement();
|
||||
|
||||
// Member variables
|
||||
fixed_t CenterFloor () const { return floorplane.ZatPoint (soundorg[0], soundorg[1]); }
|
||||
fixed_t CenterCeiling () const { return ceilingplane.ZatPoint (soundorg[0], soundorg[1]); }
|
||||
|
@ -864,7 +892,7 @@ struct sector_t
|
|||
|
||||
// [RH] The sky box to render for this sector. NULL means use a
|
||||
// regular sky.
|
||||
TObjPtr<ASkyViewpoint> SkyBoxes[2];
|
||||
TObjPtr<AActor> SkyBoxes[2];
|
||||
int PortalGroup;
|
||||
|
||||
int sectornum; // for comparing sector copies
|
||||
|
@ -1045,11 +1073,26 @@ struct line_t
|
|||
unsigned portalindex;
|
||||
|
||||
// returns true if the portal is crossable by actors
|
||||
bool isLinePortal() const;
|
||||
bool isLinePortal() const
|
||||
{
|
||||
return portalindex >= linePortals.Size() ? false : !!(linePortals[portalindex].mFlags & PORTF_PASSABLE);
|
||||
}
|
||||
|
||||
// returns true if the portal needs to be handled by the renderer
|
||||
bool isVisualPortal() const;
|
||||
line_t *getPortalDestination() const;
|
||||
int getPortalAlignment() const;
|
||||
bool isVisualPortal() const
|
||||
{
|
||||
return portalindex >= linePortals.Size() ? false : !!(linePortals[portalindex].mFlags & PORTF_VISIBLE);
|
||||
}
|
||||
|
||||
line_t *getPortalDestination() const
|
||||
{
|
||||
return portalindex >= linePortals.Size() ? (line_t*)NULL : linePortals[portalindex].mDestination;
|
||||
}
|
||||
|
||||
int getPortalAlignment() const
|
||||
{
|
||||
return portalindex >= linePortals.Size() ? 0 : linePortals[portalindex].mAlign;
|
||||
}
|
||||
};
|
||||
|
||||
// phares 3/14/98
|
||||
|
@ -1195,6 +1238,24 @@ inline sector_t *P_PointInSector(fixed_t x, fixed_t y)
|
|||
return P_PointInSubsector(x, y)->sector;
|
||||
}
|
||||
|
||||
#define _ZatPoint ZatPoint // so that it still compiles during the transition
|
||||
inline fixedvec3 AActor::PosRelative(AActor *other) const
|
||||
{
|
||||
return __pos + Displacements(Sector->PortalGroup, other->Sector->PortalGroup);
|
||||
}
|
||||
|
||||
inline fixedvec3 AActor::PosRelative(sector_t *sec) const
|
||||
{
|
||||
return __pos + Displacements(Sector->PortalGroup, sec->PortalGroup);
|
||||
}
|
||||
|
||||
inline fixedvec3 AActor::PosRelative(line_t *line) const
|
||||
{
|
||||
return __pos + Displacements(Sector->PortalGroup, line->frontsector->PortalGroup);
|
||||
}
|
||||
|
||||
inline fixedvec3 PosRelative(const fixedvec3 &pos, line_t *line, sector_t *refsec = NULL)
|
||||
{
|
||||
return pos + Displacements(refsec->PortalGroup, line->frontsector->PortalGroup);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
#include "v_font.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "farchive.h"
|
||||
#include "portal.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
#include "r_3dfloors.h"
|
||||
#include "v_palette.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "portal.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4244)
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
#include "r_3dfloors.h"
|
||||
#include "v_palette.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "portal.h"
|
||||
|
||||
#define WALLYREPEAT 8
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "doomstat.h"
|
||||
#include "m_random.h"
|
||||
#include "m_bbox.h"
|
||||
#include "portal.h"
|
||||
#include "r_sky.h"
|
||||
#include "st_stuff.h"
|
||||
#include "c_cvars.h"
|
||||
|
@ -57,7 +56,7 @@
|
|||
#include "farchive.h"
|
||||
#include "r_utility.h"
|
||||
#include "d_player.h"
|
||||
#include "portal.h"
|
||||
#include "p_local.h"
|
||||
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue