From a5f6c6c7477b9404abf7260dc250c9f300c755bb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 14 Feb 2016 09:27:20 +0100 Subject: [PATCH 1/5] Updated console font by GFD. --- wadsrc/static/confont.lmp | Bin 10239 -> 10302 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/wadsrc/static/confont.lmp b/wadsrc/static/confont.lmp index 3d46a3ca4cd3acd1046a9e82360df64403285e36..6b68df2e3e3004a2752dc9b53f65d3a06d0a7ec0 100644 GIT binary patch delta 1774 zcmezGzb|0J6IRB)$xm6e75cat`}!Ce80ODsoIjuOAH#n}CI&{vhYUX${`avk^z}_P zVAEyl`!l&vRCsa`n-G8BKL)`*uyT+VhRKuJbb0&!Gcxr3W%xIrnSqgE@)!+*vX41XE^H~eAv-#1y1U6ZkIvNiiG#=gnd z*q^cgW%$SV|NQ^S=lMk^-{jz7{5SaphdKX0hQIs&GqN$9KhMZ`{`|kmhMeMz|0a8L zN;CFNPUn)mnakKW`7@`oRNsGw|MUMbvd(8@Sihd}-+F#VhW+~)_wQ$9oNT}) z!q_+2mCKN^Z*n=8He=u9URl}62e?3iag0lkv2XHME(ONE$zt3pAV+cQvG)A~IWmvi zfT{2INa_x>M-zl=W^82bJ(F!fCi zb#g^U^dCfoBGF!oI@;1v;MWMuer|3Bk@ z28g=feUqo~Y6^io2Ey~@7{Ot`e*NT+3i4t<8UBM^$-wY$J_z%J{XLn5PXTJJCZ8dc z70;(USx1;h80KzJNU=c-n;a)Dt@EGZ2gC0^P|P9X>mS4a{r^D;<2;D`eg7ZBZ^rKo zfBPoC;8SJno6N^A&EEHifthjs{K@+KY8rii8UD}bXPiHu0TlWmr!X)ug0wTfWVp!i z>;8X+UyR=v{`YOJ;pb%00;~SV$iVP#{eQ;43`~ss_y1=2f1ZKyH^aaCzZw34G&cNZ z_}|AcIZ#fOzn*jQVyh6QVNvq&85s4`zGg0 z`7?o&h_DbSygxAfWBAwbm*IaOSi@7PaMnI%Muxu0j?&gpR--h?c!s{o`=m`7`zC*p zR%Y&F{4?24Mw<;3Q%rr6y=9D<`xyErH_Di?f*jH}d5=sEh{f19SyvX6kz>JRudEhh z-{b?zDolNhlMg7%a{XmsX!y;*1k!s@S#Gkn3dqNSaypEClk4QPSwK-Wd97SHW8Y*} zd1H`)eSMQ{=|82?UwAg?)jt|~iAA0w1=R+Sy>iu>{=P^A(I8PKq7RRCqc)e4{x zc&uQ;*f&{1(G;vYKrx50Z}MJ6ke#m-LGBY(vSjR=?5_kW hNVrI<>$3DQF!W9KQU?|4HR_;*wM<)#v43(Ln;L)rKL){mMvzJnW}G~kO_!(tKO;l`Uxt74|1V?hJ0c8-~XH8|9l3Hp^$C-VtNOuo&*#mvOWF!>pWxd#&?1H<3_+>8ti=g%`To<9%b-v7_|kKr#P z1H*fUzw`frP5-|hr0~yv2CygopJ!xb_;de1<9~)fj0_ClKo%x&$};v(PT&-oJc%=s zv48R#PG!da$pTywVql{g7(r&<{{uGn8^gc;$#z_ZjQx`fxU?DjC(q$hV(g#1pG%Li ze=+(KllGK{9*jg@CPKI!q`9Agj0-2W~@%67k7aJlr6CO#PF+cyvIl|NWDzdGs0kC$Hu)VC!ct8A43j6wsj~b4 z#pxAcZPxyN#(({jSwzA(7#SHDzJi34L_$C*LQX~aA2@yf?f=8@e?B;st^YH5A)h!m zMErk0BPh*?%CPh^Gxkq55VcU~X9Oj=KlA@H{9g}_k^SHpInT(z_~-sVMuy4lq6&=t zlUImpIUZyHL0As>56Tzw85n;v{Aaw+05bnK!~cG;&*npN%RL4;hK2?P5bg(A+&|e~ zOjZVzU;Fz(*%gc#K%QV^e8BJ>y{(ex_JufDyC;-yVz`)4B(BIF%2%`VZ z|Ife-iv53#%nXbSlmClFOFv{_V0^^zih*JNO$KI=jz1tJAb+t;o++-#`dLDWf=P>^GT_2FfjgMU}Eg=pKKu|2T~m& z1mS^#$#M!NP}SiI8PHHXqM*vyKlzn{ zIdebbzsYq%+LQei*%|vMhbx+b-QKU5!`MIhk0Qu&O(l>!LzFBT`zQA)fr_fVO8Q_` z@0E<8CaWpOF!oPwR<0)CBldpAUksoeq@XIz0ZE)p{gV%>XhOXAP6d=crT;i*?6rv?YT@BC^oT^^yX b%hC@@Y@O<$(s;KzC@DQv*MkU(Yp4SNH}sfX From 993a840630851aba9de60dcf76874e1fef20b5fa Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 14 Feb 2016 12:33:47 +0100 Subject: [PATCH 2/5] - bring formatting in line with GZDoom's version of this function. --- src/p_3dfloors.cpp | 97 +++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index b60c69e11..0df3b2ebd 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -214,97 +214,98 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag //========================================================================== static int P_Set3DFloor(line_t * line, int param, int param2, int alpha) { - int s,i; + int s, i; int flags; - int tag=line->args[0]; - sector_t * sec = line->frontsector, * ss; + int tag = line->args[0]; + sector_t * sec = line->frontsector, *ss; - FSectorTagIterator it(tag); - while ((s = it.Next()) >= 0) + FSectorTagIterator itr(tag); + while ((s = itr.Next()) >= 0) { - ss=§ors[s]; + ss = §ors[s]; - if (param==0) + if (param == 0) { - flags=FF_EXISTS|FF_RENDERALL|FF_SOLID|FF_INVERTSECTOR; + flags = FF_EXISTS | FF_RENDERALL | FF_SOLID | FF_INVERTSECTOR; alpha = 255; - for (i=0;ilinecount;i++) + for (i = 0; i < sec->linecount; i++) { - line_t * l=sec->lines[i]; + line_t * l = sec->lines[i]; - if (l->special==Sector_SetContents && l->frontsector==sec) + if (l->special == Sector_SetContents && l->frontsector == sec) { - alpha=clamp(l->args[1], 0, 100); + alpha = clamp(l->args[1], 0, 100); if (l->args[2] & 1) flags &= ~FF_SOLID; if (l->args[2] & 2) flags |= FF_SEETHROUGH; if (l->args[2] & 4) flags |= FF_SHOOTTHROUGH; if (l->args[2] & 8) flags |= FF_ADDITIVETRANS; - if (alpha!=100) flags|=FF_TRANSLUCENT;//|FF_BOTHPLANES|FF_ALLSIDES; - if (l->args[0]) + if (alpha != 100) flags |= FF_TRANSLUCENT;//|FF_BOTHPLANES|FF_ALLSIDES; + if (l->args[0]) { // Yes, Vavoom's 3D-floor definitions suck! // The content list changed in r1783 of Vavoom to be unified // among all its supported games, so it has now ten different // values instead of just five. - static DWORD vavoomcolors[]={VC_EMPTY, + static DWORD vavoomcolors[] = { VC_EMPTY, VC_WATER, VC_LAVA, VC_NUKAGE, VC_SLIME, VC_HELLSLIME, - VC_BLOOD, VC_SLUDGE, VC_HAZARD, VC_BOOMWATER}; - flags|=FF_SWIMMABLE|FF_BOTHPLANES|FF_ALLSIDES|FF_FLOOD; + VC_BLOOD, VC_SLUDGE, VC_HAZARD, VC_BOOMWATER }; + flags |= FF_SWIMMABLE | FF_BOTHPLANES | FF_ALLSIDES | FF_FLOOD; - l->frontsector->ColorMap = - GetSpecialLights (l->frontsector->ColorMap->Color, - vavoomcolors[l->args[0]], - l->frontsector->ColorMap->Desaturate); + l->frontsector->ColorMap = + GetSpecialLights(l->frontsector->ColorMap->Color, + vavoomcolors[l->args[0]], + l->frontsector->ColorMap->Desaturate); } - alpha=(alpha*255)/100; + alpha = (alpha * 255) / 100; break; } } } - else if (param==4) + else if (param == 4) { - flags=FF_EXISTS|FF_RENDERPLANES|FF_INVERTPLANES|FF_NOSHADE|FF_FIX; - alpha=255; + flags = FF_EXISTS | FF_RENDERPLANES | FF_INVERTPLANES | FF_NOSHADE | FF_FIX; + if (param2 & 1) flags |= FF_SEETHROUGH; // marker for allowing missing texture checks + alpha = 255; } - else + else { - static const int defflags[]= {0, - FF_SOLID, - FF_SWIMMABLE|FF_BOTHPLANES|FF_ALLSIDES|FF_SHOOTTHROUGH|FF_SEETHROUGH, - FF_SHOOTTHROUGH|FF_SEETHROUGH, + static const int defflags[] = { 0, + FF_SOLID, + FF_SWIMMABLE | FF_BOTHPLANES | FF_ALLSIDES | FF_SHOOTTHROUGH | FF_SEETHROUGH, + FF_SHOOTTHROUGH | FF_SEETHROUGH, }; - flags = defflags[param&3] | FF_EXISTS|FF_RENDERALL; + flags = defflags[param & 3] | FF_EXISTS | FF_RENDERALL; - if (param&4) flags |= FF_ALLSIDES|FF_BOTHPLANES; - if (param&16) flags ^= FF_SEETHROUGH; - if (param&32) flags ^= FF_SHOOTTHROUGH; + if (param & 4) flags |= FF_ALLSIDES | FF_BOTHPLANES; + if (param & 16) flags ^= FF_SEETHROUGH; + if (param & 32) flags ^= FF_SHOOTTHROUGH; - if (param2&1) flags |= FF_NOSHADE; - if (param2&2) flags |= FF_DOUBLESHADOW; - if (param2&4) flags |= FF_FOG; - if (param2&8) flags |= FF_THINFLOOR; - if (param2&16) flags |= FF_UPPERTEXTURE; - if (param2&32) flags |= FF_LOWERTEXTURE; - if (param2&64) flags |= FF_ADDITIVETRANS|FF_TRANSLUCENT; + if (param2 & 1) flags |= FF_NOSHADE; + if (param2 & 2) flags |= FF_DOUBLESHADOW; + if (param2 & 4) flags |= FF_FOG; + if (param2 & 8) flags |= FF_THINFLOOR; + if (param2 & 16) flags |= FF_UPPERTEXTURE; + if (param2 & 32) flags |= FF_LOWERTEXTURE; + if (param2 & 64) flags |= FF_ADDITIVETRANS | FF_TRANSLUCENT; // if flooding is used the floor must be non-solid and is automatically made shootthrough and seethrough - if ((param2&128) && !(flags & FF_SOLID)) flags |= FF_FLOOD|FF_SEETHROUGH|FF_SHOOTTHROUGH; - if (param2&512) flags |= FF_FADEWALLS; + if ((param2 & 128) && !(flags & FF_SOLID)) flags |= FF_FLOOD | FF_SEETHROUGH | FF_SHOOTTHROUGH; + if (param2 & 512) flags |= FF_FADEWALLS; if (param2&1024) flags |= FF_RESET; FTextureID tex = line->sidedef[0]->GetTexture(side_t::top); - if (!tex.Exists() && alpha<255) + if (!tex.Exists() && alpha < 255) { alpha = -tex.GetIndex(); } alpha = clamp(alpha, 0, 255); - if (alpha==0) flags&=~(FF_RENDERALL|FF_BOTHPLANES|FF_ALLSIDES); - else if (alpha!=255) flags|=FF_TRANSLUCENT; - + if (alpha == 0) flags &= ~(FF_RENDERALL | FF_BOTHPLANES | FF_ALLSIDES); + else if (alpha != 255) flags |= FF_TRANSLUCENT; + } P_Add3DFloor(ss, sec, line, flags, alpha); } // To be 100% safe this should be done even if the alpha by texture value isn't used. - if (!line->sidedef[0]->GetTexture(side_t::top).isValid()) + if (!line->sidedef[0]->GetTexture(side_t::top).isValid()) line->sidedef[0]->SetTexture(side_t::top, FNullTextureID()); return 1; } From d5a1004c41ec69be450859c377030296a02221e5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 14 Feb 2016 13:12:03 +0100 Subject: [PATCH 3/5] - some preparations for portal stuff: * set up linked sector portals so that everything that will eventually have to be considered is present, even though the software renderer currently can't handle those adequately. * tag all skybox things with a type so that they can easily be distinguished at run time. * fill in the linked portal types in xlat/eternity.txt. --- src/g_shared/a_sharedglobal.h | 6 +----- src/g_shared/a_skies.cpp | 9 +++++++++ src/p_spec.cpp | 22 ++++++++++++++++++---- src/portal.cpp | 5 +++++ src/portal.h | 1 + src/r_bsp.cpp | 3 +++ src/r_defs.h | 12 ++++++++++++ wadsrc/static/xlat/eternity.txt | 8 ++++---- 8 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index acb4faf0f..0c9e723b6 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -106,11 +106,7 @@ class ASkyCamCompat : public ASkyViewpoint DECLARE_CLASS (ASkyCamCompat, ASkyViewpoint) public: - void BeginPlay () - { - // Do not call the SkyViewpoint's super method because it would trash our setup - AActor::BeginPlay(); - } + void BeginPlay(); }; diff --git a/src/g_shared/a_skies.cpp b/src/g_shared/a_skies.cpp index a8c8ebd55..a34a30956 100644 --- a/src/g_shared/a_skies.cpp +++ b/src/g_shared/a_skies.cpp @@ -54,6 +54,7 @@ void ASkyViewpoint::BeginPlay () { level.DefaultSkybox = this; } + special1 = SKYBOX_SKYVIEWPOINT; } void ASkyViewpoint::Serialize (FArchive &arc) @@ -85,6 +86,13 @@ void ASkyViewpoint::Destroy () IMPLEMENT_CLASS (ASkyCamCompat) +void ASkyCamCompat::BeginPlay() +{ + // Do not call the SkyViewpoint's super method because it would trash our setup + AActor::BeginPlay(); + special1 = SKYBOX_SKYVIEWPOINT; +} + //--------------------------------------------------------------------------- @@ -154,6 +162,7 @@ void AStackPoint::BeginPlay () AActor::BeginPlay (); bAlways = true; + special1 = SKYBOX_STACKEDSECTORTHING; } //--------------------------------------------------------------------------- diff --git a/src/p_spec.cpp b/src/p_spec.cpp index a8c13c5ac..9ea1ecb9b 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1019,15 +1019,16 @@ static void CopyPortal(int sectortag, int plane, ASkyViewpoint *origin, fixed_t } } -void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha) +void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha, int linked) { + if (plane < 0 || plane > 2 || (linked && plane == 2)) return; for (int i=0;iv1->y) + SQWORD(line->v2->y)) >> 1); fixed_t x2 = fixed_t((SQWORD(lines[i].v1->x) + SQWORD(lines[i].v2->x)) >> 1); fixed_t y2 = fixed_t((SQWORD(lines[i].v1->y) + SQWORD(lines[i].v2->y)) >> 1); + fixed_t z = linked ? line->frontsector->planes[plane].TexZ : 0; // the map's sector height defines the portal plane for linked portals + fixed_t alpha = Scale (lines[i].args[4], OPAQUE, 255); AStackPoint *anchor = Spawn(x1, y1, 0, NO_REPLACE); AStackPoint *reference = Spawn(x2, y2, 0, NO_REPLACE); + reference->special1 = linked ? SKYBOX_LINKEDPORTAL : SKYBOX_PORTAL; + anchor->special1 = SKYBOX_ANCHOR; + // store the portal displacement in the unused scaleX/Y members of the portal reference actor. + anchor->scaleX = -(reference->scaleX = x2 - x1); + anchor->scaleY = -(reference->scaleY = y2 - y1); + anchor->threshold = reference->threshold = z; reference->Mate = anchor; anchor->Mate = reference; @@ -1427,13 +1436,17 @@ void P_SpawnSpecials (void) // - 0: normal (handled here) // - 1: copy (handled by the portal they copy) // - 2: EE-style skybox (handled by the camera object) + // - 3: EE-style flat portal (GZDoom HW renderer only for now) + // - 4: EE-style horizon portal (GZDoom HW renderer only for now) + // - 5: copy portal to line (GZDoom HW renderer only for now) + // - 6: linked portal // other values reserved for later use // arg 2 = 0:floor, 1:ceiling, 2:both // arg 3 = 0: anchor, 1: reference line // arg 4 = for the anchor only: alpha - if (lines[i].args[1] == 0 && lines[i].args[3] == 0) + if ((lines[i].args[1] == 0 || lines[i].args[1] == 6) && lines[i].args[3] == 0) { - P_SpawnPortal(&lines[i], lines[i].args[0], lines[i].args[2], lines[i].args[4]); + P_SpawnPortal(&lines[i], lines[i].args[0], lines[i].args[2], lines[i].args[4], lines[i].args[1]); } break; @@ -1510,6 +1523,7 @@ void P_SpawnSpecials (void) break; } } + P_CreateLinkedPortals(); // [RH] Start running any open scripts on this map FBehavior::StaticStartTypedScripts (SCRIPT_Open, NULL, false); P_FinalizePortals(); diff --git a/src/portal.cpp b/src/portal.cpp index 7f08e6d6e..a8e66db70 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -504,3 +504,8 @@ bool PortalTracer::TraceStep() return (oDepth != depth); // if a portal has been found, return false } +void P_CreateLinkedPortals() +{ +} + + diff --git a/src/portal.h b/src/portal.h index 53fb1c16e..5e3d5bb8d 100644 --- a/src/portal.h +++ b/src/portal.h @@ -53,6 +53,7 @@ extern TArray linePortals; void P_SpawnLinePortal(line_t* line); void P_FinalizePortals(); bool P_ChangePortal(line_t *ln, int thisid, int destid); +void P_CreateLinkedPortals(); /* code ported from prototype */ diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 819bd9532..8fba4a8e3 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -1094,6 +1094,7 @@ void R_Subsector (subsector_t *sub) } skybox = frontsector->GetSkyBox(sector_t::ceiling); + if (skybox != NULL && skybox->special1 >= SKYBOX_PLANE) skybox = NULL; // skip unsupported portal types ceilingplane = frontsector->ceilingplane.PointOnSide(viewx, viewy, viewz) > 0 || frontsector->GetTexture(sector_t::ceiling) == skyflatnum || @@ -1135,6 +1136,8 @@ void R_Subsector (subsector_t *sub) // killough 3/16/98: add floorlightlevel // killough 10/98: add support for skies transferred from sidedefs skybox = frontsector->GetSkyBox(sector_t::floor); + if (skybox != NULL && skybox->special1 >= SKYBOX_PLANE) skybox = NULL; // skip unsupported portal types + floorplane = frontsector->floorplane.PointOnSide(viewx, viewy, viewz) > 0 || // killough 3/7/98 frontsector->GetTexture(sector_t::floor) == skyflatnum || (skybox != NULL && skybox->bAlways) || diff --git a/src/r_defs.h b/src/r_defs.h index a9b09c9e6..7b86e00de 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -57,6 +57,18 @@ enum extern size_t MaxDrawSegs; +enum +{ + SKYBOX_ANCHOR = -1, + SKYBOX_SKYVIEWPOINT = 0, // a regular skybox + SKYBOX_STACKEDSECTORTHING, // stacked sectors with the thing method + SKYBOX_PORTAL, // stacked sectors with Sector_SetPortal + SKYBOX_LINKEDPORTAL, // linked portal (interactive) + SKYBOX_PLANE, // EE-style plane portal (not implemented in SW renderer) + SKYBOX_HORIZON, // EE-style horizon portal (not implemented in SW renderer) +}; + + // // INTERNAL MAP TYPES // used by play and refresh diff --git a/wadsrc/static/xlat/eternity.txt b/wadsrc/static/xlat/eternity.txt index f76466c29..04d5febff 100644 --- a/wadsrc/static/xlat/eternity.txt +++ b/wadsrc/static/xlat/eternity.txt @@ -132,10 +132,10 @@ enum 357 = 0, Polyobj_OR_RotateLeft(0) // Eternity's linked portals, vertical link version (floor-to-ceiling) -358 = 0, Unsupported() // "Portal_LinkedCeiling" -359 = 0, Unsupported() // "Portal_LinkedFloor" -360 = 0, Unsupported() // "Portal_LinkedAnchorLine" -361 = 0, Unsupported() // "Portal_LinkedAnchorLineFloor" +358 = 0, Sector_SetPortal(tag, 6, 1, 1, 0) // "Portal_AnchoredCeiling" +359 = 0, Sector_SetPortal(tag, 6, 0, 1, 0) // "Portal_AnchoredFloor" +360 = 0, Sector_SetPortal(tag, 6, 1, 0, 0) // "Portal_AnchorLine" +361 = 0, Sector_SetPortal(tag, 6, 0, 0, 0) // "Portal_AnchorLineFloor" // Even more parameterized linedefs 362 = 0, Pillar_Build(0) From c338b9cde312e1c70e347bfdd90cd362624342a1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 14 Feb 2016 16:26:27 +0100 Subject: [PATCH 4/5] - some more portal preparation . --- src/g_strife/a_thingstoblowup.cpp | 1 + src/p_enemy.cpp | 5 +++++ src/p_map.cpp | 3 +++ src/p_sectors.cpp | 13 +++++++++++++ src/portal.h | 24 ++++++++++++++++++++++++ src/r_data/r_interpolate.cpp | 2 ++ src/r_defs.h | 18 ++++++++++++++++++ 7 files changed, 66 insertions(+) diff --git a/src/g_strife/a_thingstoblowup.cpp b/src/g_strife/a_thingstoblowup.cpp index a1899e60b..4cf4f6861 100644 --- a/src/g_strife/a_thingstoblowup.cpp +++ b/src/g_strife/a_thingstoblowup.cpp @@ -104,6 +104,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightGoesOut) sec->floorplane.d = sec->floorplane.PointToDist (spot, newheight); fixed_t newtheight = sec->floorplane.Zat0(); sec->ChangePlaneTexZ(sector_t::floor, newtheight - oldtheight); + sec->CheckPortalPlane(sector_t::floor); for (int i = 0; i < 8; ++i) { diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index ad286fdd4..eaf729771 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2582,6 +2582,11 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) abs(corpsehit->Y() - viletry.y) > maxdist) continue; // not actually touching // Let's check if there are floors in between the archvile and its target + + // if in a different section of the map, only consider possible if a line of sight exists. + if (corpsehit->Sector->PortalGroup != self->Sector->PortalGroup && !P_CheckSight(self, corpsehit)) + continue; + sector_t *vilesec = self->Sector; sector_t *corpsec = corpsehit->Sector; // We only need to test if at least one of the sectors has a 3D floor. diff --git a/src/p_map.cpp b/src/p_map.cpp index 6416e0a6e..0e3cb6617 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -5532,6 +5532,7 @@ bool P_ChangeSector(sector_t *sector, int crunch, int amt, int floorOrCeil, bool } } } while (n); + sec->CheckPortalPlane(!floorOrCeil); } } P_Recalculate3DFloors(sector); // Must recalculate the 3d floor and light lists @@ -5595,6 +5596,8 @@ bool P_ChangeSector(sector_t *sector, int crunch, int amt, int floorOrCeil, bool } } while (n); // repeat from scratch until all things left are marked valid + sector->CheckPortalPlane(floorOrCeil); // check for portal obstructions after everything is done. + if (!cpos.nofit && !isreset /* && sector->MoreFlags & (SECF_UNDERWATERMASK)*/) { // If this is a control sector for a deep water transfer, all actors in affected diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index a1cf2077f..a10568388 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -871,6 +871,19 @@ int sector_t::GetTerrain(int pos) const return terrainnum[pos] >= 0 ? terrainnum[pos] : TerrainTypes[GetTexture(pos)]; } +void sector_t::CheckPortalPlane(int plane) +{ + ASkyViewpoint *portal = SkyBoxes[plane]; + if (!portal || portal->special1 != SKYBOX_LINKEDPORTAL) return; + + fixed_t planeh = planes[plane].TexZ; + int obstructed = PLANEF_OBSTRUCTED * (plane == sector_t::floor ? + planeh > portal->threshold : planeh < portal->threshold); + planes[plane].Flags = (planes[plane].Flags & ~PLANEF_OBSTRUCTED) | obstructed; +} + + + FArchive &operator<< (FArchive &arc, secspecial_t &p) { if (SaveVersion < 4529) diff --git a/src/portal.h b/src/portal.h index 5e3d5bb8d..893f3ae69 100644 --- a/src/portal.h +++ b/src/portal.h @@ -8,6 +8,30 @@ #include "p_local.h" #include "m_bbox.h" +struct FDisplacement +{ + fixed_t x, y; + bool isSet; + BYTE indirect; // just for illustration. +}; + +struct FDisplacementTable +{ + TArray data; + int size; + + void Create(int numgroups) + { + data.Resize(numgroups*numgroups); + memset(&data[0], 0, numgroups*numgroups*sizeof(data[0])); + size = numgroups; + } + + FDisplacement &operator()(int x, int y) + { + return data[x + size*y]; + } +}; enum { diff --git a/src/r_data/r_interpolate.cpp b/src/r_data/r_interpolate.cpp index ed12cbf4e..760850bb4 100644 --- a/src/r_data/r_interpolate.cpp +++ b/src/r_data/r_interpolate.cpp @@ -469,6 +469,7 @@ void DSectorPlaneInterpolation::Restore() sector->SetPlaneTexZ(sector_t::ceiling, baktexz); } P_RecalculateAttached3DFloors(sector); + sector->CheckPortalPlane(ceiling? sector_t::ceiling : sector_t::floor); } //========================================================================== @@ -505,6 +506,7 @@ void DSectorPlaneInterpolation::Interpolate(fixed_t smoothratio) *pheight = oldheight + FixedMul(bakheight - oldheight, smoothratio); sector->SetPlaneTexZ(pos, oldtexz + FixedMul(baktexz - oldtexz, smoothratio)); P_RecalculateAttached3DFloors(sector); + sector->CheckPortalPlane(pos); } } diff --git a/src/r_defs.h b/src/r_defs.h index 7b86e00de..da122e14a 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -518,6 +518,7 @@ struct sector_t DInterpolation *SetInterpolation(int position, bool attach); ASkyViewpoint *GetSkyBox(int which); + void CheckPortalPlane(int plane); enum { @@ -738,6 +739,22 @@ struct sector_t Flags &= ~SECF_SPECIALFLAGS; } + inline bool PortalBlocksView(int plane) + { + return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); + } + + inline bool PortalBlocksMovement(int plane) + { + return !!(planes[plane].Flags & (PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); + } + + inline bool PortalBlocksSound(int plane) + { + return !!(planes[plane].Flags & (PLANEF_BLOCKSOUND | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); + } + + int GetTerrain(int pos) const; void TransferSpecial(sector_t *model); @@ -830,6 +847,7 @@ struct sector_t // [RH] The sky box to render for this sector. NULL means use a // regular sky. TObjPtr SkyBoxes[2]; + int PortalGroup; int sectornum; // for comparing sector copies From 126c80d597f340f5fc70fdfa74810d029baa51ef Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 14 Feb 2016 18:16:59 +0100 Subject: [PATCH 5/5] - create the portal group table. --- src/p_spec.cpp | 2 +- src/portal.cpp | 349 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 348 insertions(+), 3 deletions(-) diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 9ea1ecb9b..b010165b1 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1523,10 +1523,10 @@ void P_SpawnSpecials (void) break; } } - P_CreateLinkedPortals(); // [RH] Start running any open scripts on this map FBehavior::StaticStartTypedScripts (SCRIPT_Open, NULL, false); P_FinalizePortals(); + P_CreateLinkedPortals(); } // killough 2/28/98: diff --git a/src/portal.cpp b/src/portal.cpp index a8e66db70..d9156514d 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -8,10 +8,15 @@ #include "p_tags.h" #include "farchive.h" #include "v_text.h" +#include "a_sharedglobal.h" +#include "i_system.h" +#include "c_dispatch.h" // simulation recurions maximum CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO) +FDisplacementTable Displacements; + TArray linePortals; @@ -148,7 +153,19 @@ void P_UpdatePortal(FLinePortal *port) else { port->mFlags = port->mDefFlags; - } + if (port->mType == PORTT_LINKED) + { + if (linePortals[port->mDestination->portalindex].mType != PORTT_LINKED) + { + port->mType = PORTT_INTERACTIVE; // linked portals must be two-way. + } + else + { + port->mXDisplacement = port->mDestination->v2->x - port->mOrigin->v1->x; + port->mYDisplacement = port->mDestination->v2->y - port->mOrigin->v1->y; + } + } + } } void P_FinalizePortals() @@ -504,8 +521,336 @@ bool PortalTracer::TraceStep() return (oDepth != depth); // if a portal has been found, return false } -void P_CreateLinkedPortals() + + +//============================================================================ +// +// CollectSectors +// +// Collects all sectors that are connected to any sector belonging to a portal +// because they all will need the same displacement values +// +//============================================================================ + +static bool CollectSectors(int groupid, sector_t *origin) { + if (origin->PortalGroup != 0) return false; // already processed + origin->PortalGroup = groupid; + + TArray list(16); + list.Push(origin); + + for (unsigned i = 0; i < list.Size(); i++) + { + sector_t *sec = list[i]; + + for (int j = 0; j < sec->linecount; j++) + { + line_t *line = sec->lines[j]; + sector_t *other = line->frontsector == sec ? line->backsector : line->frontsector; + if (other != NULL && other != sec && other->PortalGroup != groupid) + { + other->PortalGroup = groupid; + list.Push(other); + } + } + } + return true; } +//============================================================================ +// +// AddDisplacementForPortal +// +// Adds the displacement for one portal to the displacement array +// (one version for sector to sector plane, one for line to line portals) +// +//============================================================================ + +static void AddDisplacementForPortal(AStackPoint *portal) +{ + int thisgroup = portal->Mate->Sector->PortalGroup; + int othergroup = portal->Sector->PortalGroup; + if (thisgroup == othergroup) + { + Printf("Portal between sectors %d and %d has both sides in same group and will be disabled\n", portal->Sector->sectornum, portal->Mate->Sector->sectornum); + portal->special1 = portal->Mate->special1 = SKYBOX_PORTAL; + return; + } + if (thisgroup <= 0 || thisgroup >= Displacements.size || othergroup <= 0 || othergroup >= Displacements.size) + { + Printf("Portal between sectors %d and %d has invalid group and will be disabled\n", portal->Sector->sectornum, portal->Mate->Sector->sectornum); + portal->special1 = portal->Mate->special1 = SKYBOX_PORTAL; + return; + } + + FDisplacement & disp = Displacements(thisgroup, othergroup); + if (!disp.isSet) + { + disp.x = portal->scaleX; + disp.y = portal->scaleY; + disp.isSet = true; + } + else + { + if (disp.x != portal->scaleX || disp.y != portal->scaleY) + { + Printf("Portal between sectors %d and %d has displacement mismatch and will be disabled\n", portal->Sector->sectornum, portal->Mate->Sector->sectornum); + portal->special1 = portal->Mate->special1 = SKYBOX_PORTAL; + return; + } + } +} + + +static void AddDisplacementForPortal(FLinePortal *portal) +{ + int thisgroup = portal->mOrigin->frontsector->PortalGroup; + int othergroup = portal->mDestination->frontsector->PortalGroup; + if (thisgroup == othergroup) + { + Printf("Portal between lines %d and %d has both sides in same group\n", int(portal->mOrigin-lines), int(portal->mDestination-lines)); + portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT; + return; + } + if (thisgroup <= 0 || thisgroup >= Displacements.size || othergroup <= 0 || othergroup >= Displacements.size) + { + Printf("Portal between lines %d and %d has invalid group\n", int(portal->mOrigin - lines), int(portal->mDestination - lines)); + portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT; + return; + } + + FDisplacement & disp = Displacements(thisgroup, othergroup); + if (!disp.isSet) + { + disp.x = portal->mXDisplacement; + disp.y = portal->mYDisplacement; + disp.isSet = true; + } + else + { + if (disp.x != portal->mXDisplacement || disp.y != portal->mYDisplacement) + { + Printf("Portal between lines %d and %d has displacement mismatch\n", int(portal->mOrigin - lines), int(portal->mDestination - lines)); + portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT; + return; + } + } +} + +//============================================================================ +// +// ConnectGroups +// +// Do the indirect connections. This loop will run until it cannot find any new connections +// +//============================================================================ + +static bool ConnectGroups() +{ + // Now + BYTE indirect = 1; + bool bogus = false; + bool changed; + do + { + changed = false; + for (int x = 1; x < Displacements.size; x++) + { + for (int y = 1; y < Displacements.size; y++) + { + FDisplacement &dispxy = Displacements(x, y); + if (dispxy.isSet) + { + for (int z = 1; z < Displacements.size; z++) + { + FDisplacement &dispyz = Displacements(y, z); + if (dispyz.isSet) + { + FDisplacement &dispxz = Displacements(x, z); + if (dispxz.isSet) + { + if (dispxy.x + dispyz.x != dispxz.x || dispxy.y + dispyz.y != dispxz.y) + { + bogus = true; + } + } + else + { + dispxz.x = dispxy.x + dispyz.x; + dispxz.y = dispxy.y + dispyz.y; + dispxz.isSet = true; + dispxz.indirect = indirect; + changed = true; + } + } + } + } + } + } + indirect++; + } while (changed); + return bogus; +} + + +//============================================================================ +// +// P_CreateLinkedPortals +// +// Creates the data structures needed for linked portals +// Removes portals from sloped sectors (as they cannot work on them) +// Group all sectors connected to one side of the portal +// Caclculate displacements between all created groups. +// +// Portals with the same offset but different anchors will not be merged. +// +//============================================================================ + +void P_CreateLinkedPortals() +{ + TThinkerIterator it; + AStackPoint *mo; + TArray orgs; + int id = 0; + bool bogus = false; + + while ((mo = it.Next())) + { + if (mo->special1 == SKYBOX_LINKEDPORTAL) + { + if (mo->Mate != NULL) + { + orgs.Push(mo); + mo->reactiontime = ++id; + } + else + { + // this should never happen, but if it does, the portal needs to be removed + mo->Destroy(); + } + } + } + if (orgs.Size() == 0) + { + return; + } + for (int i = 0; i < numsectors; i++) + { + for (int j = 0; j < 2; j++) + { + ASkyViewpoint *box = sectors[i].SkyBoxes[j]; + if (box != NULL && box->special1 == SKYBOX_LINKEDPORTAL) + { + secplane_t &plane = j == 0 ? sectors[i].floorplane : sectors[i].ceilingplane; + if (plane.a || plane.b) + { + // The engine cannot deal with portals on a sloped plane. + sectors[i].SkyBoxes[j] = NULL; + Printf("Portal on %s of sector %d is sloped and will be disabled\n", j==0? "floor":"ceiling", i); + } + } + } + } + + // Group all sectors, starting at each portal origin. + id = 1; + for (unsigned i = 0; i < orgs.Size(); i++) + { + if (CollectSectors(id, orgs[i]->Sector)) id++; + if (CollectSectors(id, orgs[i]->Mate->Sector)) id++; + } + for (unsigned i = 0; i < linePortals.Size(); i++) + { + if (linePortals[i].mType == PORTT_LINKED) + { + if (CollectSectors(id, linePortals[i].mOrigin->frontsector)) id++; + if (CollectSectors(id, linePortals[i].mDestination->frontsector)) id++; + } + } + + Displacements.Create(id); + // Check for leftover sectors that connect to a portal + for (int i = 0; ispecial1 == SKYBOX_LINKEDPORTAL && box->Sector->PortalGroup == 0) + { + CollectSectors(box->Sector->PortalGroup, box->Sector); + box = box->Mate; + if (box->special1 == SKYBOX_LINKEDPORTAL && box->Sector->PortalGroup == 0) + { + CollectSectors(box->Sector->PortalGroup, box->Sector); + } + } + } + } + } + for (unsigned i = 0; i < orgs.Size(); i++) + { + AddDisplacementForPortal(orgs[i]); + } + for (unsigned i = 0; i < linePortals.Size(); i++) + { + if (linePortals[i].mType == PORTT_LINKED) + { + AddDisplacementForPortal(&linePortals[i]); + } + } + + for (int x = 1; x < Displacements.size; x++) + { + for (int y = x + 1; y < Displacements.size; y++) + { + FDisplacement &dispxy = Displacements(x, y); + FDisplacement &dispyx = Displacements(y, x); + if (dispxy.isSet && dispyx.isSet && + (dispxy.x != -dispyx.x || dispxy.y != -dispyx.y)) + { + Printf("Link offset mismatch between groups %d and %d\n", x, y); // need to find some sectors to report. + bogus = true; + } + // todo: Find sectors that have no group but belong to a portal. + } + } + bogus |= ConnectGroups(); + if (bogus) + { + // todo: disable all portals whose offsets do not match the associated groups + } + + // reject would just get in the way when checking sight through portals. + if (rejectmatrix != NULL) + { + delete[] rejectmatrix; + rejectmatrix = NULL; + } + // finally we must flag all planes which are obstructed by the sector's own ceiling or floor. + for (int i = 0; i < numsectors; i++) + { + sectors[i].CheckPortalPlane(sector_t::floor); + sectors[i].CheckPortalPlane(sector_t::ceiling); + } + //BuildBlockmap(); +} + +CCMD(dumplinktable) +{ + for (int x = 1; x < Displacements.size; x++) + { + for (int y = 1; y < Displacements.size; y++) + { + FDisplacement &disp = Displacements(x, y); + Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, disp.x >> FRACBITS, disp.y >> FRACBITS); + } + Printf("\n"); + } +} + + +