From 3ed7a25d61e5c4594cb1134c5cccdd62c75de2d4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 17 Apr 2016 17:10:11 +0200 Subject: [PATCH 1/5] - added polyportal offset updates. - removed the nodebuilder message for splitting polyobject subsectors because it is no longer relevant. --- src/nodebuild.cpp | 9 ------- src/p_saveg.cpp | 10 +++++++- src/po_man.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++++++ src/po_man.h | 2 ++ src/portal.cpp | 3 +-- src/portal.h | 8 +++++++ src/version.h | 2 +- 7 files changed, 82 insertions(+), 13 deletions(-) diff --git a/src/nodebuild.cpp b/src/nodebuild.cpp index c56ee697e..d1a8737ec 100644 --- a/src/nodebuild.cpp +++ b/src/nodebuild.cpp @@ -811,15 +811,6 @@ void FNodeBuilder::SplitSegs (DWORD set, node_t &node, DWORD splitseg, DWORD &ou unsigned int vertnum; int seg2; - if (seg->loopnum) - { - Printf (" Split seg %u (%d,%d)-(%d,%d) of sector %td in loop %d\n", - set, - Vertices[seg->v1].x>>16, Vertices[seg->v1].y>>16, - Vertices[seg->v2].x>>16, Vertices[seg->v2].y>>16, - seg->frontsector - sectors, seg->loopnum); - } - frac = InterceptVector (node, *seg); newvert.x = Vertices[seg->v1].x; newvert.y = Vertices[seg->v1].y; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 8744ec740..81218640a 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -539,7 +539,7 @@ void P_SerializePolyobjs (FArchive &arc) arc << seg << po_NumPolyobjs; for(i = 0, po = polyobjs; i < po_NumPolyobjs; i++, po++) { - arc << po->tag << po->Angle << po->StartSpot.pos << po->interpolation << po->bBlocked; + arc << po->tag << po->Angle << po->StartSpot.pos << po->interpolation << po->bBlocked << po->bHasPortals; } } else @@ -573,6 +573,14 @@ void P_SerializePolyobjs (FArchive &arc) { po->bBlocked = false; } + if (SaveVersion >= 4538) + { + arc << po->bHasPortals; + } + else + { + po->bHasPortals = 0; + } po->RotatePolyobj (angle, true); delta -= po->StartSpot.pos; diff --git a/src/po_man.cpp b/src/po_man.cpp index f2029026d..d2faa6690 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -425,6 +425,11 @@ bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, { // poly is already in motion break; } + if (poly->bHasPortals == 2) + { + // cannot do rotations on linked polyportals. + break; + } pe = new DRotatePoly(poly->tag); poly->specialdata = pe; poly->bBlocked = false; @@ -476,6 +481,7 @@ void DMovePoly::Tick () m_Speed = m_Dist * (m_Speed < 0 ? -1 : 1); m_Speedv = m_Angle.ToVector(m_Speed); } + poly->UpdateLinks(); } } } @@ -555,6 +561,7 @@ void DMovePolyTo::Tick () m_Speed = m_Dist * (m_Speed < 0 ? -1 : 1); m_Speedv = m_Target - poly->StartSpot.pos; } + poly->UpdateLinks(); } } } @@ -649,6 +656,7 @@ void DPolyDoor::Tick () Destroy (); } } + poly->UpdateLinks(); } else { @@ -735,6 +743,12 @@ bool EV_OpenPolyDoor(line_t *line, int polyNum, double speed, DAngle angle, int { // poly is already moving break; } + if (poly->bHasPortals == 2 && type == PODOOR_SWING) + { + // cannot do rotations on linked polyportals. + break; + } + pd = new DPolyDoor(poly->tag, type); poly->specialdata = pd; if (type == PODOOR_SLIDE) @@ -899,6 +913,36 @@ void FPolyObj::ThrustMobj (AActor *actor, side_t *side) // //========================================================================== +void FPolyObj::UpdateLinks() +{ + if (bHasPortals == 2) + { + TMap processed; + for (unsigned i = 0; i < Linedefs.Size(); i++) + { + if (Linedefs[i]->isLinePortal()) + { + FLinePortal *port = Linedefs[i]->getPortal(); + if (port->mType == PORTT_LINKED) + { + DVector2 old = port->mDisplacement; + port->mDisplacement = port->mDestination->v2->fPos() - port->mOrigin->v1->fPos(); + FLinePortal *port2 = port->mDestination->getPortal(); + if (port2) port2->mDisplacement = -port->mDisplacement; + int destgroup = port->mDestination->frontsector->PortalGroup; + bool *done = processed.CheckKey(destgroup); + if (!done || !*done) + { + processed[destgroup] = true; + DVector2 delta = port->mDisplacement - old; + Displacements.MoveGroup(destgroup, delta); + } + } + } + } + } +} + void FPolyObj::UpdateBBox () { for(unsigned i=0;iisLinePortal()) + { + // Fixme: this still needs to figure out if the polyobject move made the player cross the portal line. + if (P_TryMove(mobj, mobj->Pos(), false)) + { + continue; + } + } // We have a two-sided linedef so we should only check one side // so that the thrust from both sides doesn't cancel each other out. // Best use the one facing the player and ignore the back side. @@ -1496,6 +1549,8 @@ static void SpawnPolyobj (int index, int tag, int type) { continue; } + po->bBlocked = false; + po->bHasPortals = 0; side_t *sd = &sides[i]; @@ -1563,6 +1618,12 @@ static void SpawnPolyobj (int index, int tag, int type) if (l->validcount != validcount) { + FLinePortal *port = l->getPortal(); + if (port && (port->mDefFlags & PORTF_PASSABLE)) + { + int type = port->mType == PORTT_LINKED ? 2 : 1; + if (po->bHasPortals < type) po->bHasPortals = (BYTE)type; + } l->validcount = validcount; po->Linedefs.Push(l); diff --git a/src/po_man.h b/src/po_man.h index 2b9c8afef..9bc853255 100644 --- a/src/po_man.h +++ b/src/po_man.h @@ -63,6 +63,7 @@ struct FPolyObj int crush; // should the polyobj attempt to crush mobjs? bool bHurtOnTouch; // should the polyobj hurt anything it touches? bool bBlocked; + BYTE bHasPortals; // 1 for any portal, 2 for a linked portal (2 must block rotations.) int seqType; double Size; // polyobj size (area of POLY_AREAUNIT == size of FRACUNIT) FPolyNode *subsectorlinks; @@ -82,6 +83,7 @@ struct FPolyObj void CreateSubsectorLinks(); void ClearSubsectorLinks(); void CalcCenter(); + void UpdateLinks(); static void ClearAllSubsectorLinks(); private: diff --git a/src/portal.cpp b/src/portal.cpp index 3ce45c636..1be08fc85 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -384,8 +384,7 @@ void P_UpdatePortal(FLinePortal *port) } else { - port->mDisplacement.X = port->mDestination->v2->fX() - port->mOrigin->v1->fX(); - port->mDisplacement.Y = port->mDestination->v2->fY() - port->mOrigin->v1->fY(); + port->mDisplacement = port->mDestination->v2->fPos() - port->mOrigin->v1->fPos(); } } } diff --git a/src/portal.h b/src/portal.h index 2868521bc..0aa9a2ef2 100644 --- a/src/portal.h +++ b/src/portal.h @@ -64,6 +64,14 @@ struct FDisplacementTable return data[x + size*y].pos; } + void MoveGroup(int grp, DVector2 delta) + { + for (int i = 1; i < size; i++) + { + data[grp + size*i].pos -= delta; + data[i + grp*size].pos += delta; + } + } }; extern FDisplacementTable Displacements; diff --git a/src/version.h b/src/version.h index a824525c9..14da98c1a 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4537 +#define SAVEVER 4538 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) From 08514de768e048657ad39d9b6134e564f203057e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 17 Apr 2016 18:19:46 +0200 Subject: [PATCH 2/5] - fixed A_WraithFX2 which had an incomplete floating point conversion. --- src/g_hexen/a_wraith.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_hexen/a_wraith.cpp b/src/g_hexen/a_wraith.cpp index 24ae22afd..460fa6503 100644 --- a/src/g_hexen/a_wraith.cpp +++ b/src/g_hexen/a_wraith.cpp @@ -127,8 +127,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2) angle = -angle; } angle += self->Angles.Yaw; - mo->Vel.X = ((pr_wraithfx2() << 7) + 1) * angle.Cos(); - mo->Vel.Y = ((pr_wraithfx2() << 7) + 1) * angle.Sin(); + mo->Vel.X = ((pr_wraithfx2() / 512.) + 1) * angle.Cos(); + mo->Vel.Y = ((pr_wraithfx2() / 512.) + 1) * angle.Sin(); mo->Vel.Z = 0; mo->target = self; mo->Floorclip = 10; From f66202aef1e90d91c55e50cff6b59729414b15a2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 17 Apr 2016 18:42:54 +0200 Subject: [PATCH 3/5] - fixed: If due to portal transitions, the chasecam cannot be interpolated, the entire view interpolation must be disabled for the current frame. --- src/r_utility.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 0977505fd..929d4073d 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -949,6 +949,7 @@ void R_SetupFrame (AActor *actor) { iview->otic = nowtic; iview->Old = iview->New; + r_NoInterpolate = true; } } else From 54d78df2678633b257ac39e414ced9348f1ca724 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 17 Apr 2016 23:48:04 +0200 Subject: [PATCH 4/5] - added a new sector list to AActor that collects all portal-linked sectors the actor's center is in. (Inspired by Eternity's solution to the same problem.) This is for rendering the sprite properly in all areas the actor touches. The original thinglist is not sufficient for this and Boom's touching thinglist has other purposes and collects too much data. This new list will only get filled in when the actor is actually crossing a portal plane, for the normal sector thinglist will still be used. This piggybacks on the msecnode_t code which has been extended to be able to handle more than one list by passing the sector's membert pointers as parameters. --- src/actor.h | 5 +++ src/p_local.h | 3 +- src/p_map.cpp | 93 ++++++++++++++++++++++++++++++++++++++++--------- src/p_mobj.cpp | 7 ++++ src/p_setup.cpp | 1 + src/p_udmf.cpp | 1 + src/p_user.cpp | 6 ++-- src/r_defs.h | 1 + 8 files changed, 96 insertions(+), 21 deletions(-) diff --git a/src/actor.h b/src/actor.h index e7fe048ef..d369e5fa9 100644 --- a/src/actor.h +++ b/src/actor.h @@ -959,11 +959,14 @@ public: // Triggers SECSPAC_Exit/SECSPAC_Enter and related events if oldsec != current sector void CheckSectorTransition(sector_t *oldsec); + void UpdateRenderSectorList(); + void ClearRenderSectorList(); // info for drawing // NOTE: The first member variable *must* be snext. AActor *snext, **sprev; // links in sector (if needed) DVector3 __Pos; // double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions. + DVector3 OldRenderPos; DRotator Angles; DVector3 Vel; @@ -1094,6 +1097,8 @@ public: // a linked list of sectors where this object appears struct msecnode_t *touching_sectorlist; // phares 3/14/98 + struct msecnode_t *render_sectorlist; // same for cross-portal rendering + TObjPtr Inventory; // [RH] This actor's inventory DWORD InventoryID; // A unique ID to keep track of inventory items diff --git a/src/p_local.h b/src/p_local.h index a5336a9ee..1a8915495 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -350,7 +350,8 @@ void P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance, void P_DelSector_List(); void P_DelSeclist(msecnode_t *); // phares 3/16/98 -msecnode_t* P_DelSecnode(msecnode_t *); +msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode, msecnode_t *&sec_thinglist); +msecnode_t* P_DelSecnode(msecnode_t *, msecnode_t *sector_t::*head); void P_CreateSecNodeList(AActor*); // phares 3/14/98 double P_GetMoveFactor(const AActor *mo, double *frictionp); // phares 3/6/98 double P_GetFriction(const AActor *mo, double *frictionfactor); diff --git a/src/p_map.cpp b/src/p_map.cpp index 8254ac5bb..d1cd91816 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -5555,6 +5555,7 @@ int P_PushUp(AActor *thing, FChangePosition *cpos) intersect->SetZ(oldz); return 2; } + intersect->UpdateRenderSectorList(); } thing->CheckPortalTransition(true); return 0; @@ -5602,6 +5603,7 @@ int P_PushDown(AActor *thing, FChangePosition *cpos) intersect->SetZ(oldz); return 2; } + intersect->UpdateRenderSectorList(); } } thing->CheckPortalTransition(true); @@ -5634,6 +5636,7 @@ void PIT_FloorDrop(AActor *thing, FChangePosition *cpos) { thing->SetZ(thing->floorz); P_CheckFakeFloorTriggers(thing, oldz); + thing->UpdateRenderSectorList(); } } else if ((thing->Z() != oldfloorz && !(thing->flags & MF_NOLIFTDROP))) @@ -5642,6 +5645,7 @@ void PIT_FloorDrop(AActor *thing, FChangePosition *cpos) { thing->AddZ(-oldfloorz + thing->floorz); P_CheckFakeFloorTriggers(thing, oldz); + thing->UpdateRenderSectorList(); } } if (thing->player && thing->player->mo == thing) @@ -5689,10 +5693,12 @@ void PIT_FloorRaise(AActor *thing, FChangePosition *cpos) { default: P_CheckFakeFloorTriggers(thing, oldz); + thing->UpdateRenderSectorList(); break; case 1: P_DoCrunch(thing, cpos); P_CheckFakeFloorTriggers(thing, oldz); + thing->UpdateRenderSectorList(); break; case 2: P_DoCrunch(thing, cpos); @@ -5735,6 +5741,7 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos) { thing->SetZ(thing->floorz); } + thing->UpdateRenderSectorList(); switch (P_PushDown(thing, cpos)) { case 2: @@ -5744,9 +5751,11 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos) thing->SetZ(thing->floorz); P_DoCrunch(thing, cpos); P_CheckFakeFloorTriggers(thing, oldz); + thing->UpdateRenderSectorList(); break; default: P_CheckFakeFloorTriggers(thing, oldz); + thing->UpdateRenderSectorList(); break; } } @@ -5782,6 +5791,7 @@ void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos) thing->SetZ(thing->ceilingz - thing->Height); } P_CheckFakeFloorTriggers(thing, oldz); + thing->UpdateRenderSectorList(); } else if ((thing->flags2 & MF2_PASSMOBJ) && !isgood && thing->Top() < thing->ceilingz) { @@ -5789,6 +5799,7 @@ void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos) if (!P_TestMobjZ(thing, true, &onmobj) && onmobj->Z() <= thing->Z()) { thing->SetZ(MIN(thing->ceilingz - thing->Height, onmobj->Top())); + thing->UpdateRenderSectorList(); } } if (thing->player && thing->player->mo == thing) @@ -6023,7 +6034,7 @@ void P_PutSecnode(msecnode_t *node) // //============================================================================= -msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode) +msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode, msecnode_t *&sec_thinglist) { msecnode_t *node; @@ -6061,10 +6072,10 @@ msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode) // Add new node at head of sector thread starting at s->touching_thinglist node->m_sprev = NULL; // prev node on sector thread - node->m_snext = s->touching_thinglist; // next node on sector thread - if (s->touching_thinglist) + node->m_snext = sec_thinglist; // next node on sector thread + if (sec_thinglist) node->m_snext->m_sprev = node; - s->touching_thinglist = node; + sec_thinglist = node; return node; } @@ -6078,7 +6089,7 @@ msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode) // //============================================================================= -msecnode_t *P_DelSecnode(msecnode_t *node) +msecnode_t *P_DelSecnode(msecnode_t *node, msecnode_t *sector_t::*listhead) { msecnode_t* tp; // prev node on thing thread msecnode_t* tn; // next node on thing thread @@ -6105,7 +6116,7 @@ msecnode_t *P_DelSecnode(msecnode_t *node) if (sp) sp->m_snext = sn; else - node->m_sector->touching_thinglist = sn; + node->m_sector->*listhead = sn; if (sn) sn->m_sprev = sp; @@ -6145,7 +6156,7 @@ void P_DelSector_List() void P_DelSeclist(msecnode_t *node) { while (node) - node = P_DelSecnode(node); + node = P_DelSecnode(node, §or_t::touching_thinglist); } //============================================================================= @@ -6173,13 +6184,15 @@ void P_CreateSecNodeList(AActor *thing) node = node->m_tnext; } - FBoundingBox box(thing->X(), thing->Y(), thing->radius); - FBlockLinesIterator it(box); - line_t *ld; + FPortalGroupArray grouplist; + FMultiBlockLinesIterator mit(grouplist, thing); + FMultiBlockLinesIterator::CheckResult cres; - while ((ld = it.Next())) + while (mit.Next(&cres)) { - if (!box.inRange(ld) || box.BoxOnLineSide(ld) != -1) + line_t *ld = cres.line; + + if (!mit.Box().inRange(ld) || mit.Box().BoxOnLineSide(ld) != -1) continue; // This line crosses through the object. @@ -6189,7 +6202,7 @@ void P_CreateSecNodeList(AActor *thing) // allowed to move to this position, then the sector_list // will be attached to the Thing's AActor at touching_sectorlist. - sector_list = P_AddSecnode(ld->frontsector, thing, sector_list); + sector_list = P_AddSecnode(ld->frontsector, thing, sector_list, ld->frontsector->touching_thinglist); // Don't assume all lines are 2-sided, since some Things // like MT_TFOG are allowed regardless of whether their radius takes @@ -6199,12 +6212,12 @@ void P_CreateSecNodeList(AActor *thing) // Use sidedefs instead of 2s flag to determine two-sidedness. if (ld->backsector) - sector_list = P_AddSecnode(ld->backsector, thing, sector_list); + sector_list = P_AddSecnode(ld->backsector, thing, sector_list, ld->backsector->touching_thinglist); } // Add the sector of the (x,y) point to sector_list. - sector_list = P_AddSecnode(thing->Sector, thing, sector_list); + sector_list = P_AddSecnode(thing->Sector, thing, sector_list, thing->Sector->touching_thinglist); // Now delete any nodes that won't be used. These are the ones where // m_thing is still NULL. @@ -6216,7 +6229,7 @@ void P_CreateSecNodeList(AActor *thing) { if (node == sector_list) sector_list = node->m_tnext; - node = P_DelSecnode(node); + node = P_DelSecnode(node, §or_t::touching_thinglist); } else { @@ -6225,6 +6238,54 @@ void P_CreateSecNodeList(AActor *thing) } } + +//========================================================================== +// +// Handle the lists used to render actors from other portal areas +// +//========================================================================== + +void AActor::UpdateRenderSectorList() +{ + static const double SPRITE_SPACE = 64.; + if (Pos() != OldRenderPos) + { + sector_t *sec = Sector; + double lasth = -FLT_MAX; + ClearRenderSectorList(); + while (!sec->PortalBlocksMovement(sector_t::ceiling)) + { + double planeh = sec->SkyBoxes[sector_t::ceiling]->specialf1; + if (planeh < lasth) break; // broken setup. + if (Top() + SPRITE_SPACE < planeh) break; + lasth = planeh; + DVector2 newpos = Pos() + sec->SkyBoxes[sector_t::ceiling]->Scale; + sec = P_PointInSector(newpos); + render_sectorlist = P_AddSecnode(sec, this, render_sectorlist, sec->render_thinglist); + } + lasth = FLT_MAX; + while (!sec->PortalBlocksMovement(sector_t::floor)) + { + double planeh = sec->SkyBoxes[sector_t::floor]->specialf1; + if (planeh > lasth) break; // broken setup. + if (Z() - SPRITE_SPACE > planeh) break; + lasth = planeh; + DVector2 newpos = Pos() + sec->SkyBoxes[sector_t::floor]->Scale; + sec = P_PointInSector(newpos); + render_sectorlist = P_AddSecnode(sec, this, render_sectorlist, sec->render_thinglist); + } + } +} + +void AActor::ClearRenderSectorList() +{ + msecnode_t *node = render_sectorlist; + while (node) + node = P_DelSecnode(node, §or_t::render_thinglist); + render_sectorlist = NULL; +} + + //========================================================================== // // diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index f018be55b..18caa2f3c 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3752,6 +3752,9 @@ void AActor::Tick () if (!CheckNoDelay()) return; // freed itself // cycle through states, calling action functions at transitions + + UpdateRenderSectorList(); + if (tics != -1) { // [RH] Use tics <= 0 instead of == 0 so that spawnstates @@ -4011,6 +4014,7 @@ AActor *AActor::StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t a } actor->SetXYZ(pos); + actor->OldRenderPos = { FLT_MAX, FLT_MAX, FLT_MAX }; actor->picnum.SetInvalid(); actor->health = actor->SpawnHealth(); @@ -4322,12 +4326,15 @@ void AActor::Deactivate (AActor *activator) } } + // // P_RemoveMobj // void AActor::Destroy () { + ClearRenderSectorList(); + // [RH] Destroy any inventory this actor is carrying DestroyAllInventory (); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 148dcbea8..718e54e9b 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1510,6 +1510,7 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) tagManager.AddSectorTag(i, LittleShort(ms->tag)); ss->thinglist = NULL; ss->touching_thinglist = NULL; // phares 3/14/98 + ss->render_thinglist = NULL; ss->seqType = defSeqType; ss->SeqName = NAME_None; ss->nextsec = -1; //jff 2/26/98 add fields to support locking out diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 017f73cf1..20852a585 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1291,6 +1291,7 @@ public: sec->SetAlpha(sector_t::ceiling, 1.); sec->thinglist = NULL; sec->touching_thinglist = NULL; // phares 3/14/98 + sec->render_thinglist = NULL; sec->seqType = (level.flags & LEVEL_SNDSEQTOTALCTRL) ? 0 : -1; sec->nextsec = -1; //jff 2/26/98 add fields to support locking out sec->prevsec = -1; // stair retriggering until build completes diff --git a/src/p_user.cpp b/src/p_user.cpp index 30a849b84..486044070 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2860,8 +2860,6 @@ void P_PredictPlayer (player_t *player) } } -extern msecnode_t *P_AddSecnode (sector_t *s, AActor *thing, msecnode_t *nextnode); - void P_UnPredictPlayer () { player_t *player = &players[consoleplayer]; @@ -2922,7 +2920,7 @@ void P_UnPredictPlayer () sector_list = NULL; for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) { - sector_list = P_AddSecnode(PredictionTouchingSectorsBackup[i], act, sector_list); + sector_list = P_AddSecnode(PredictionTouchingSectorsBackup[i], act, sector_list, PredictionTouchingSectorsBackup[i]->touching_thinglist); } act->touching_sectorlist = sector_list; // Attach to thing sector_list = NULL; // clear for next time @@ -2934,7 +2932,7 @@ void P_UnPredictPlayer () { if (node == sector_list) sector_list = node->m_tnext; - node = P_DelSecnode(node); + node = P_DelSecnode(node, §or_t::touching_thinglist); } else { diff --git a/src/r_defs.h b/src/r_defs.h index 2b7b4a218..79af0929f 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -1057,6 +1057,7 @@ public: // list of mobjs that are at least partially in the sector // thinglist is a subset of touching_thinglist struct msecnode_t *touching_thinglist; // phares 3/14/98 + struct msecnode_t *render_thinglist; // for cross-portal rendering. double gravity; // [RH] Sector gravity (1.0 is normal) FNameNoInit damagetype; // [RH] Means-of-death for applied damage From 89b2cc45a214eec959cb64dee5d07227b659b386 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 18 Apr 2016 00:02:07 +0200 Subject: [PATCH 5/5] - reverted P_CreateSecNodes to the regular FBlockLinesIterator. This got accidentally committed. Even if this gets extended to reach through portals it needs to be done differently. FMultiBlockLinesIterator can't guarantee to get every sector that's being touched. --- src/p_map.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index d1cd91816..33f69f201 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -6184,15 +6184,13 @@ void P_CreateSecNodeList(AActor *thing) node = node->m_tnext; } - FPortalGroupArray grouplist; - FMultiBlockLinesIterator mit(grouplist, thing); - FMultiBlockLinesIterator::CheckResult cres; + FBoundingBox box(thing->X(), thing->Y(), thing->radius); + FBlockLinesIterator it(box); + line_t *ld; - while (mit.Next(&cres)) + while ((ld = it.Next())) { - line_t *ld = cres.line; - - if (!mit.Box().inRange(ld) || mit.Box().BoxOnLineSide(ld) != -1) + if (!box.inRange(ld) || box.BoxOnLineSide(ld) != -1) continue; // This line crosses through the object.