mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 01:01:33 +00:00
Make linedef type 6 closer to ZDoom's Sector_SetPortal
This commit is contained in:
parent
03daf721ef
commit
5b387ec94a
11 changed files with 236 additions and 108 deletions
|
@ -4285,7 +4285,6 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
||||||
|
|
||||||
// Portal objects
|
// Portal objects
|
||||||
"MT_SKYBOX",
|
"MT_SKYBOX",
|
||||||
"MT_PORTALREFPOINT",
|
|
||||||
|
|
||||||
// Debris
|
// Debris
|
||||||
"MT_SPARK", //spark
|
"MT_SPARK", //spark
|
||||||
|
|
|
@ -2352,11 +2352,11 @@ static void HWR_AddLine(seg_t * line)
|
||||||
gl_backsector = R_FakeFlat(gl_backsector, &tempsec, NULL, NULL, true);
|
gl_backsector = R_FakeFlat(gl_backsector, &tempsec, NULL, NULL, true);
|
||||||
|
|
||||||
if (gl_backsector->ceilingpic == skyflatnum && gl_frontsector->ceilingpic == skyflatnum
|
if (gl_backsector->ceilingpic == skyflatnum && gl_frontsector->ceilingpic == skyflatnum
|
||||||
&& !(gl_backsector->portal_ceiling.exists || gl_frontsector->portal_ceiling.exists))
|
&& !(P_SectorHasCeilingPortal(gl_backsector) || P_SectorHasCeilingPortal(gl_frontsector)))
|
||||||
bothceilingssky = true;
|
bothceilingssky = true;
|
||||||
|
|
||||||
if (gl_backsector->floorpic == skyflatnum && gl_frontsector->floorpic == skyflatnum
|
if (gl_backsector->floorpic == skyflatnum && gl_frontsector->floorpic == skyflatnum
|
||||||
&& !(gl_backsector->portal_floor.exists || gl_frontsector->portal_floor.exists))
|
&& !(P_SectorHasFloorPortal(gl_backsector) || P_SectorHasFloorPortal(gl_frontsector)))
|
||||||
bothfloorssky = true;
|
bothfloorssky = true;
|
||||||
|
|
||||||
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
|
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
|
||||||
|
|
27
src/info.c
27
src/info.c
|
@ -20759,33 +20759,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_PORTALREFPOINT
|
|
||||||
781, // doomednum
|
|
||||||
S_INVISIBLE, // spawnstate
|
|
||||||
1000, // spawnhealth
|
|
||||||
S_NULL, // seestate
|
|
||||||
sfx_None, // seesound
|
|
||||||
8, // reactiontime
|
|
||||||
sfx_None, // attacksound
|
|
||||||
S_NULL, // painstate
|
|
||||||
0, // painchance
|
|
||||||
sfx_None, // painsound
|
|
||||||
S_NULL, // meleestate
|
|
||||||
S_NULL, // missilestate
|
|
||||||
S_NULL, // deathstate
|
|
||||||
S_NULL, // xdeathstate
|
|
||||||
sfx_None, // deathsound
|
|
||||||
0, // speed
|
|
||||||
12*FRACUNIT, // radius
|
|
||||||
24*FRACUNIT, // height
|
|
||||||
0, // display offset
|
|
||||||
10, // mass
|
|
||||||
0, // damage
|
|
||||||
sfx_None, // activesound
|
|
||||||
MF_SCENERY|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags
|
|
||||||
S_NULL // raisestate
|
|
||||||
},
|
|
||||||
|
|
||||||
{ // MT_SPARK
|
{ // MT_SPARK
|
||||||
-1, // doomednum
|
-1, // doomednum
|
||||||
S_SPRK1, // spawnstate
|
S_SPRK1, // spawnstate
|
||||||
|
|
|
@ -5116,7 +5116,6 @@ typedef enum mobj_type
|
||||||
|
|
||||||
// Portal objects
|
// Portal objects
|
||||||
MT_SKYBOX,
|
MT_SKYBOX,
|
||||||
MT_PORTALREFPOINT,
|
|
||||||
|
|
||||||
// Debris
|
// Debris
|
||||||
MT_SPARK, //spark
|
MT_SPARK, //spark
|
||||||
|
|
|
@ -980,9 +980,7 @@ static void P_LoadVertices(UINT8 *data)
|
||||||
|
|
||||||
static void InitializeSectorPortal(sectorportal_t *secportal)
|
static void InitializeSectorPortal(sectorportal_t *secportal)
|
||||||
{
|
{
|
||||||
secportal->exists = false;
|
memset(secportal, 0, sizeof(*secportal));
|
||||||
secportal->target.x = secportal->target.y = secportal->target.z = 0;
|
|
||||||
secportal->target.angle = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_InitializeSector(sector_t *ss)
|
static void P_InitializeSector(sector_t *ss)
|
||||||
|
|
165
src/p_spec.c
165
src/p_spec.c
|
@ -6186,22 +6186,54 @@ fixed_t P_GetSectorGravityFactor(sector_t *sec)
|
||||||
return sec->gravity;
|
return sec->gravity;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean P_CompareSectorPortals(sectorportal_t *a, sectorportal_t *b)
|
static boolean P_IsSectorPortalValid(sectorportal_t *secportal)
|
||||||
{
|
{
|
||||||
return !memcmp(a, b, sizeof(sectorportal_t));
|
switch (secportal->type)
|
||||||
|
{
|
||||||
|
case SECPORTAL_LINE:
|
||||||
|
case SECPORTAL_FLOOR:
|
||||||
|
case SECPORTAL_CEILING:
|
||||||
|
return true;
|
||||||
|
case SECPORTAL_OBJECT:
|
||||||
|
return secportal->mobj && !P_MobjWasRemoved(secportal->mobj);
|
||||||
|
case SECPORTAL_SKYBOX:
|
||||||
|
return skyboxmo[0] && !P_MobjWasRemoved(skyboxmo[0]);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetSectorPortal(sectorportal_t *secportal, sector_t *target_sector, fixed_t default_z, INT32 viewpoint_tag)
|
boolean P_SectorHasFloorPortal(sector_t *sector)
|
||||||
{
|
{
|
||||||
secportal->exists = target_sector;
|
return P_IsSectorPortalValid(§or->portal_floor);
|
||||||
secportal->target.x = target_sector->soundorg.x;
|
}
|
||||||
secportal->target.y = target_sector->soundorg.y;
|
|
||||||
secportal->target.z = default_z;
|
|
||||||
secportal->target.angle = 0;
|
|
||||||
|
|
||||||
if (viewpoint_tag <= 0)
|
boolean P_SectorHasCeilingPortal(sector_t *sector)
|
||||||
return;
|
{
|
||||||
|
return P_IsSectorPortalValid(§or->portal_ceiling);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean P_CompareSectorPortals(sectorportal_t *a, sectorportal_t *b)
|
||||||
|
{
|
||||||
|
if (a->type != b->type)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (a->type)
|
||||||
|
{
|
||||||
|
case SECPORTAL_LINE:
|
||||||
|
return a->line.start == b->line.start && a->line.dest == b->line.dest;
|
||||||
|
case SECPORTAL_FLOOR:
|
||||||
|
case SECPORTAL_CEILING:
|
||||||
|
return a->sector == b->sector;
|
||||||
|
case SECPORTAL_OBJECT:
|
||||||
|
return a->mobj == b->mobj;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static mobj_t *GetSectorPortalObject(INT32 tag)
|
||||||
|
{
|
||||||
for (thinker_t *th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
for (thinker_t *th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||||
{
|
{
|
||||||
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||||
|
@ -6209,18 +6241,14 @@ static void SetSectorPortal(sectorportal_t *secportal, sector_t *target_sector,
|
||||||
|
|
||||||
mobj_t *mo = (mobj_t *)th;
|
mobj_t *mo = (mobj_t *)th;
|
||||||
|
|
||||||
if (mo->type != MT_PORTALREFPOINT || mo->spawnpoint == NULL)
|
if (mo->spawnpoint == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!Tag_Find(&mo->spawnpoint->tags, viewpoint_tag))
|
if (Tag_Find(&mo->spawnpoint->tags, tag))
|
||||||
continue;
|
return mo;
|
||||||
|
|
||||||
secportal->target.x = mo->x;
|
|
||||||
secportal->target.y = mo->y;
|
|
||||||
secportal->target.z = mo->z;
|
|
||||||
secportal->target.angle = mo->angle;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** After the map has loaded, scans for specials that spawn 3Dfloors and
|
/** After the map has loaded, scans for specials that spawn 3Dfloors and
|
||||||
|
@ -6390,26 +6418,97 @@ void P_SpawnSpecials(boolean fromnetsave)
|
||||||
|
|
||||||
case 6: // Sector portal
|
case 6: // Sector portal
|
||||||
{
|
{
|
||||||
INT32 s1, s2;
|
int target_sector_tag = lines[i].args[0];
|
||||||
TAG_ITER_SECTORS(lines[i].args[0], s1) // Target sector tag
|
int portal_type = lines[i].args[1];
|
||||||
|
int plane_type = lines[i].args[2];
|
||||||
|
int misc = lines[i].args[3];
|
||||||
|
|
||||||
|
boolean floor, ceiling;
|
||||||
|
if (plane_type == TMP_BOTH)
|
||||||
|
floor = ceiling = true;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
TAG_ITER_SECTORS(lines[i].args[1], s2) // Sector tag to make a portal to
|
floor = plane_type == TMP_FLOOR;
|
||||||
|
ceiling = plane_type == TMP_CEILING;
|
||||||
|
}
|
||||||
|
|
||||||
|
INT32 s1 = -1;
|
||||||
|
|
||||||
|
TAG_ITER_SECTORS(target_sector_tag, s1) // Target sector tag
|
||||||
|
{
|
||||||
|
sectorportal_t *floorportal = §ors[s1].portal_floor;
|
||||||
|
sectorportal_t *ceilportal = §ors[s1].portal_ceiling;
|
||||||
|
|
||||||
|
// Line portal
|
||||||
|
if (portal_type == 0)
|
||||||
{
|
{
|
||||||
sector_t *target_sector = §ors[s2];
|
INT32 linenum = -1;
|
||||||
boolean floor, ceiling;
|
TAG_ITER_LINES(misc, linenum)
|
||||||
|
|
||||||
if (lines[i].args[2] == TMP_BOTH)
|
|
||||||
floor = ceiling = true;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
floor = lines[i].args[2] == TMP_FLOOR;
|
if (lines[linenum].special == 6
|
||||||
ceiling = lines[i].args[2] == TMP_CEILING;
|
&& lines[linenum].args[0] == target_sector_tag
|
||||||
|
&& lines[linenum].args[1] == portal_type
|
||||||
|
&& lines[linenum].args[2] == plane_type
|
||||||
|
&& lines[linenum].args[3] == 1)
|
||||||
|
{
|
||||||
|
if (floor)
|
||||||
|
{
|
||||||
|
floorportal->type = SECPORTAL_LINE;
|
||||||
|
floorportal->line.start = &lines[i];
|
||||||
|
floorportal->line.dest = &lines[linenum];
|
||||||
|
}
|
||||||
|
if (ceiling)
|
||||||
|
{
|
||||||
|
ceilportal->type = SECPORTAL_LINE;
|
||||||
|
ceilportal->line.start = &lines[i];
|
||||||
|
ceilportal->line.dest = &lines[linenum];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// Skybox portal
|
||||||
|
else if (portal_type == 2)
|
||||||
|
{
|
||||||
if (floor)
|
if (floor)
|
||||||
SetSectorPortal(§ors[s1].portal_floor, target_sector, target_sector->ceilingheight, lines[i].args[3]);
|
floorportal->type = SECPORTAL_SKYBOX;
|
||||||
if (ceiling)
|
if (ceiling)
|
||||||
SetSectorPortal(§ors[s1].portal_ceiling, target_sector, target_sector->floorheight, lines[i].args[3]);
|
ceilportal->type = SECPORTAL_SKYBOX;
|
||||||
|
}
|
||||||
|
// Plane portal
|
||||||
|
else if (portal_type == 7)
|
||||||
|
{
|
||||||
|
INT32 s2 = -1;
|
||||||
|
TAG_ITER_SECTORS(misc, s2) // Sector tag to make a portal to
|
||||||
|
{
|
||||||
|
sector_t *target_sector = §ors[s2];
|
||||||
|
if (floor)
|
||||||
|
{
|
||||||
|
floorportal->type = SECPORTAL_CEILING;
|
||||||
|
floorportal->sector = target_sector;
|
||||||
|
}
|
||||||
|
if (ceiling)
|
||||||
|
{
|
||||||
|
ceilportal->type = SECPORTAL_FLOOR;
|
||||||
|
ceilportal->sector = target_sector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Use mobj as viewpoint
|
||||||
|
else if (portal_type == 8)
|
||||||
|
{
|
||||||
|
mobj_t *mobj = GetSectorPortalObject(misc);
|
||||||
|
if (!mobj)
|
||||||
|
break;
|
||||||
|
if (floor)
|
||||||
|
{
|
||||||
|
floorportal->type = SECPORTAL_OBJECT;
|
||||||
|
floorportal->mobj = mobj;
|
||||||
|
}
|
||||||
|
if (ceiling)
|
||||||
|
{
|
||||||
|
ceilportal->type = SECPORTAL_OBJECT;
|
||||||
|
ceilportal->mobj = mobj;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -521,6 +521,8 @@ INT32 P_FindMinSurroundingLight(sector_t *sector, INT32 max);
|
||||||
void P_SetupSignExit(player_t *player);
|
void P_SetupSignExit(player_t *player);
|
||||||
boolean P_IsFlagAtBase(mobjtype_t flag);
|
boolean P_IsFlagAtBase(mobjtype_t flag);
|
||||||
|
|
||||||
|
boolean P_SectorHasFloorPortal(sector_t *sector);
|
||||||
|
boolean P_SectorHasCeilingPortal(sector_t *sector);
|
||||||
boolean P_CompareSectorPortals(sectorportal_t *a, sectorportal_t *b);
|
boolean P_CompareSectorPortals(sectorportal_t *a, sectorportal_t *b);
|
||||||
|
|
||||||
boolean P_IsMobjTouchingSectorPlane(mobj_t *mo, sector_t *sec);
|
boolean P_IsMobjTouchingSectorPlane(mobj_t *mo, sector_t *sec);
|
||||||
|
|
|
@ -488,12 +488,12 @@ static void R_AddLine(seg_t *line)
|
||||||
// hack to allow height changes in outdoor areas
|
// hack to allow height changes in outdoor areas
|
||||||
// This is what gets rid of the upper textures if there should be sky
|
// This is what gets rid of the upper textures if there should be sky
|
||||||
if (backsector->ceilingpic == skyflatnum && frontsector->ceilingpic == skyflatnum
|
if (backsector->ceilingpic == skyflatnum && frontsector->ceilingpic == skyflatnum
|
||||||
&& !(backsector->portal_ceiling.exists || frontsector->portal_ceiling.exists))
|
&& !(P_SectorHasCeilingPortal(backsector) || P_SectorHasCeilingPortal(frontsector)))
|
||||||
bothceilingssky = true;
|
bothceilingssky = true;
|
||||||
|
|
||||||
// likewise, but for floors and upper textures
|
// likewise, but for floors and upper textures
|
||||||
if (backsector->floorpic == skyflatnum && frontsector->floorpic == skyflatnum
|
if (backsector->floorpic == skyflatnum && frontsector->floorpic == skyflatnum
|
||||||
&& !(backsector->portal_floor.exists || frontsector->portal_floor.exists))
|
&& !(P_SectorHasFloorPortal(backsector) || P_SectorHasFloorPortal(frontsector)))
|
||||||
bothfloorssky = true;
|
bothfloorssky = true;
|
||||||
|
|
||||||
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
|
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
|
||||||
|
@ -918,7 +918,7 @@ static void R_Subsector(size_t num)
|
||||||
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))
|
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))
|
||||||
{
|
{
|
||||||
floorplane = R_FindPlane(frontsector, frontsector->floorheight, frontsector->floorpic, floorlightlevel,
|
floorplane = R_FindPlane(frontsector, frontsector->floorheight, frontsector->floorpic, floorlightlevel,
|
||||||
frontsector->floorxoffset, frontsector->flooryoffset, frontsector->floorangle, floorcolormap, NULL, NULL, frontsector->f_slope, frontsector->portal_floor.exists ? &frontsector->portal_floor : NULL);
|
frontsector->floorxoffset, frontsector->flooryoffset, frontsector->floorangle, floorcolormap, NULL, NULL, frontsector->f_slope, P_SectorHasFloorPortal(frontsector) ? &frontsector->portal_floor : NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
floorplane = NULL;
|
floorplane = NULL;
|
||||||
|
@ -929,7 +929,7 @@ static void R_Subsector(size_t num)
|
||||||
{
|
{
|
||||||
ceilingplane = R_FindPlane(frontsector, frontsector->ceilingheight, frontsector->ceilingpic,
|
ceilingplane = R_FindPlane(frontsector, frontsector->ceilingheight, frontsector->ceilingpic,
|
||||||
ceilinglightlevel, frontsector->ceilingxoffset, frontsector->ceilingyoffset, frontsector->ceilingangle,
|
ceilinglightlevel, frontsector->ceilingxoffset, frontsector->ceilingyoffset, frontsector->ceilingangle,
|
||||||
ceilingcolormap, NULL, NULL, frontsector->c_slope, frontsector->portal_ceiling.exists ? &frontsector->portal_ceiling : NULL);
|
ceilingcolormap, NULL, NULL, frontsector->c_slope, P_SectorHasCeilingPortal(frontsector) ? &frontsector->portal_ceiling : NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ceilingplane = NULL;
|
ceilingplane = NULL;
|
||||||
|
|
24
src/r_defs.h
24
src/r_defs.h
|
@ -208,13 +208,27 @@ typedef enum
|
||||||
BT_STRONG,
|
BT_STRONG,
|
||||||
} busttype_e;
|
} busttype_e;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
SECPORTAL_NONE,
|
||||||
|
SECPORTAL_LINE,
|
||||||
|
SECPORTAL_OBJECT,
|
||||||
|
SECPORTAL_SKYBOX,
|
||||||
|
SECPORTAL_FLOOR,
|
||||||
|
SECPORTAL_CEILING,
|
||||||
|
} secportaltype_e;
|
||||||
|
|
||||||
typedef struct sectorportal_s
|
typedef struct sectorportal_s
|
||||||
{
|
{
|
||||||
boolean exists;
|
secportaltype_e type;
|
||||||
struct {
|
union {
|
||||||
fixed_t x, y, z;
|
struct {
|
||||||
angle_t angle;
|
struct line_s *start;
|
||||||
} target;
|
struct line_s *dest;
|
||||||
|
} line;
|
||||||
|
struct sector_s *sector;
|
||||||
|
struct mobj_s *mobj;
|
||||||
|
};
|
||||||
} sectorportal_t;
|
} sectorportal_t;
|
||||||
|
|
||||||
typedef struct ffloor_s
|
typedef struct ffloor_s
|
||||||
|
|
106
src/r_portal.c
106
src/r_portal.c
|
@ -141,30 +141,17 @@ void Portal_Remove (portal_t* portal)
|
||||||
Z_Free(portal);
|
Z_Free(portal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a portal out of two lines and a determined screen range.
|
static void Portal_GetViewpointForLine(portal_t *portal, line_t *start, line_t *dest)
|
||||||
*
|
|
||||||
* line1 determines the entrance, and line2 the exit.
|
|
||||||
* x1 and x2 determine the screen's column bounds.
|
|
||||||
|
|
||||||
* The view's offset from the entry line center is obtained,
|
|
||||||
* and then rotated&translated to the exit line's center.
|
|
||||||
* When the portal renders, it will create the illusion of
|
|
||||||
* the two lines being seamed together.
|
|
||||||
*/
|
|
||||||
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2)
|
|
||||||
{
|
{
|
||||||
portal_t* portal = Portal_Add(x1, x2);
|
|
||||||
|
|
||||||
// Offset the portal view by the linedef centers
|
// Offset the portal view by the linedef centers
|
||||||
line_t* start = &lines[line1];
|
|
||||||
line_t* dest = &lines[line2];
|
|
||||||
|
|
||||||
angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0);
|
angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0);
|
||||||
|
|
||||||
fixed_t disttopoint;
|
fixed_t disttopoint;
|
||||||
angle_t angtopoint;
|
angle_t angtopoint;
|
||||||
|
|
||||||
vertex_t dest_c, start_c;
|
struct {
|
||||||
|
fixed_t x, y;
|
||||||
|
} dest_c, start_c;
|
||||||
|
|
||||||
// looking glass center
|
// looking glass center
|
||||||
start_c.x = (start->v1->x + start->v2->x) / 2;
|
start_c.x = (start->v1->x + start->v2->x) / 2;
|
||||||
|
@ -182,6 +169,26 @@ void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, con
|
||||||
portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||||
portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight;
|
portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight;
|
||||||
portal->viewangle = viewangle + dangle;
|
portal->viewangle = viewangle + dangle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a portal out of two lines and a determined screen range.
|
||||||
|
*
|
||||||
|
* line1 determines the entrance, and line2 the exit.
|
||||||
|
* x1 and x2 determine the screen's column bounds.
|
||||||
|
|
||||||
|
* The view's offset from the entry line center is obtained,
|
||||||
|
* and then rotated&translated to the exit line's center.
|
||||||
|
* When the portal renders, it will create the illusion of
|
||||||
|
* the two lines being seamed together.
|
||||||
|
*/
|
||||||
|
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2)
|
||||||
|
{
|
||||||
|
portal_t* portal = Portal_Add(x1, x2);
|
||||||
|
|
||||||
|
line_t* start = &lines[line1];
|
||||||
|
line_t* dest = &lines[line2];
|
||||||
|
|
||||||
|
Portal_GetViewpointForLine(portal, start, dest);
|
||||||
|
|
||||||
portal->clipline = line2;
|
portal->clipline = line2;
|
||||||
|
|
||||||
|
@ -314,9 +321,17 @@ void Portal_AddSkybox (const visplane_t* plane)
|
||||||
void Portal_AddSectorPortal (const visplane_t* plane)
|
void Portal_AddSectorPortal (const visplane_t* plane)
|
||||||
{
|
{
|
||||||
INT16 start, end;
|
INT16 start, end;
|
||||||
sector_t *source = plane->sector;
|
fixed_t x, y, z, angle;
|
||||||
sectorportal_t *secportal = plane->portalsector;
|
sectorportal_t *secportal = plane->portalsector;
|
||||||
|
|
||||||
|
if (secportal->type == SECPORTAL_NONE)
|
||||||
|
return;
|
||||||
|
else if (secportal->type == SECPORTAL_SKYBOX)
|
||||||
|
{
|
||||||
|
Portal_AddSkybox(plane);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (TrimVisplaneBounds(plane, &start, &end))
|
if (TrimVisplaneBounds(plane, &start, &end))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -324,24 +339,53 @@ void Portal_AddSectorPortal (const visplane_t* plane)
|
||||||
|
|
||||||
Portal_ClipVisplane(plane, portal);
|
Portal_ClipVisplane(plane, portal);
|
||||||
|
|
||||||
fixed_t refx = source->soundorg.x - viewx;
|
portal->clipline = -1;
|
||||||
fixed_t refy = source->soundorg.y - viewy;
|
|
||||||
|
|
||||||
// Rotate the X/Y to match the target angle
|
switch (secportal->type)
|
||||||
if (secportal->target.angle)
|
|
||||||
{
|
{
|
||||||
fixed_t x = refx, y = refy;
|
case SECPORTAL_LINE:
|
||||||
angle_t ang = secportal->target.angle >> ANGLETOFINESHIFT;
|
Portal_GetViewpointForLine(portal, secportal->line.start, secportal->line.dest);
|
||||||
refx = FixedMul(x, FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
return;
|
||||||
refy = FixedMul(x, FINESINE(ang)) + FixedMul(y, FINECOSINE(ang));
|
case SECPORTAL_OBJECT:
|
||||||
|
if (!secportal->mobj || P_MobjWasRemoved(secportal->mobj))
|
||||||
|
return;
|
||||||
|
x = secportal->mobj->x;
|
||||||
|
y = secportal->mobj->y;
|
||||||
|
z = secportal->mobj->z;
|
||||||
|
angle = secportal->mobj->angle;
|
||||||
|
break;
|
||||||
|
case SECPORTAL_FLOOR:
|
||||||
|
x = secportal->sector->soundorg.x;
|
||||||
|
y = secportal->sector->soundorg.y;
|
||||||
|
z = secportal->sector->floorheight;
|
||||||
|
angle = 0;
|
||||||
|
break;
|
||||||
|
case SECPORTAL_CEILING:
|
||||||
|
x = secportal->sector->soundorg.x;
|
||||||
|
y = secportal->sector->soundorg.y;
|
||||||
|
z = secportal->sector->ceilingheight;
|
||||||
|
angle = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
portal->viewx = secportal->target.x - refx;
|
fixed_t refx = plane->sector->soundorg.x - viewx;
|
||||||
portal->viewy = secportal->target.y - refy;
|
fixed_t refy = plane->sector->soundorg.y - viewy;
|
||||||
portal->viewz = secportal->target.z + viewz;
|
|
||||||
portal->viewangle = secportal->target.angle + viewangle;
|
|
||||||
|
|
||||||
portal->clipline = -1;
|
// Rotate the X/Y to match the target angle
|
||||||
|
if (angle != 0)
|
||||||
|
{
|
||||||
|
fixed_t tr_x = refx, tr_y = refy;
|
||||||
|
angle_t ang = angle >> ANGLETOFINESHIFT;
|
||||||
|
refx = FixedMul(tr_x, FINECOSINE(ang)) - FixedMul(tr_y, FINESINE(ang));
|
||||||
|
refy = FixedMul(tr_x, FINESINE(ang)) + FixedMul(tr_y, FINECOSINE(ang));
|
||||||
|
}
|
||||||
|
|
||||||
|
portal->viewx = x - refx;
|
||||||
|
portal->viewy = y - refy;
|
||||||
|
portal->viewz = z + viewz;
|
||||||
|
portal->viewangle = angle + viewangle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates portals for the currently existing sky visplanes.
|
/** Creates portals for the currently existing sky visplanes.
|
||||||
|
|
|
@ -1930,7 +1930,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||||
|| !P_CompareSectorPortals(&frontsector->portal_ceiling, &backsector->portal_ceiling)
|
|| !P_CompareSectorPortals(&frontsector->portal_ceiling, &backsector->portal_ceiling)
|
||||||
|| (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags)))
|
|| (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags)))
|
||||||
{
|
{
|
||||||
markceiling = true;
|
markceiling = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue