From ed25cf61c532eb08e685100704d55c17bdc32710 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 6 Jan 2017 12:54:01 +0100 Subject: [PATCH] - moved the msecnode code to its own file. Note that this originates from Boom so it needs to keep the Doom license. --- src/CMakeLists.txt | 1 + src/p_blockmap.h | 7 + src/p_local.h | 4 - src/p_map.cpp | 407 ------------------------------------------ src/p_secnodes.cpp | 434 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 442 insertions(+), 411 deletions(-) create mode 100644 src/p_secnodes.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 64e865a21..5d5d52c0f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1106,6 +1106,7 @@ set (PCH_SOURCES p_pusher.cpp p_saveg.cpp p_scroll.cpp + p_secnodes.cpp p_sectors.cpp p_setup.cpp p_sight.cpp diff --git a/src/p_blockmap.h b/src/p_blockmap.h index b2cee1bdd..e6474b4ea 100644 --- a/src/p_blockmap.h +++ b/src/p_blockmap.h @@ -31,6 +31,13 @@ extern double bmaporgx; extern double bmaporgy; // origin of block map extern FBlockNode** blocklinks; // for thing chains + // mapblocks are used to check movement + // against lines and things +enum +{ + MAPBLOCKUNITS = 128 +}; + inline int GetBlockX(double xpos) { return int((xpos - bmaporgx) / MAPBLOCKUNITS); diff --git a/src/p_local.h b/src/p_local.h index c66792549..93875df2f 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -48,10 +48,6 @@ struct FTranslatedLineTarget; #define BONUSADD 6 -// mapblocks are used to check movement -// against lines and things -#define MAPBLOCKUNITS 128 - // Inspired by Maes extern int bmapnegx; extern int bmapnegy; diff --git a/src/p_map.cpp b/src/p_map.cpp index bb3f63f4e..7f6a47b66 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -6448,413 +6448,6 @@ bool P_ChangeSector(sector_t *sector, int crunch, double amt, int floorOrCeil, b return cpos.nofit; } -//============================================================================= -// phares 3/21/98 -// -// Maintain a freelist of msecnode_t's to reduce memory allocs and frees. -//============================================================================= - -msecnode_t *headsecnode = NULL; - -//============================================================================= -// -// P_GetSecnode -// -// Retrieve a node from the freelist. The calling routine -// should make sure it sets all fields properly. -// -//============================================================================= - -msecnode_t *P_GetSecnode() -{ - msecnode_t *node; - - if (headsecnode) - { - node = headsecnode; - headsecnode = headsecnode->m_snext; - } - else - { - node = (msecnode_t *)M_Malloc(sizeof(*node)); - } - return node; -} - -//============================================================================= -// -// P_PutSecnode -// -// Returns a node to the freelist. -// -//============================================================================= - -void P_PutSecnode(msecnode_t *node) -{ - node->m_snext = headsecnode; - headsecnode = node; -} - -//============================================================================= -// phares 3/16/98 -// -// P_AddSecnode -// -// Searches the current list to see if this sector is -// already there. If not, it adds a sector node at the head of the list of -// sectors this object appears in. This is called when creating a list of -// nodes that will get linked in later. Returns a pointer to the new node. -// -//============================================================================= - -msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode, msecnode_t *&sec_thinglist) -{ - msecnode_t *node; - - if (s == 0) - { - I_FatalError("AddSecnode of 0 for %s\n", thing->GetClass()->TypeName.GetChars()); - } - - node = nextnode; - while (node) - { - if (node->m_sector == s) // Already have a node for this sector? - { - node->m_thing = thing; // Yes. Setting m_thing says 'keep it'. - return nextnode; - } - node = node->m_tnext; - } - - // Couldn't find an existing node for this sector. Add one at the head - // of the list. - - node = P_GetSecnode(); - - // killough 4/4/98, 4/7/98: mark new nodes unvisited. - node->visited = 0; - - node->m_sector = s; // sector - node->m_thing = thing; // mobj - node->m_tprev = NULL; // prev node on Thing thread - node->m_tnext = nextnode; // next node on Thing thread - if (nextnode) - nextnode->m_tprev = node; // set back link on Thing - - // 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 = sec_thinglist; // next node on sector thread - if (sec_thinglist) - node->m_snext->m_sprev = node; - sec_thinglist = node; - return node; -} - -//============================================================================= -// -// P_DelSecnode -// -// Deletes a sector node from the list of -// sectors this object appears in. Returns a pointer to the next node -// on the linked list, or NULL. -// -//============================================================================= - -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 - msecnode_t* sp; // prev node on sector thread - msecnode_t* sn; // next node on sector thread - - if (node) - { - // Unlink from the Thing thread. The Thing thread begins at - // sector_list and not from AActor->touching_sectorlist. - - tp = node->m_tprev; - tn = node->m_tnext; - if (tp) - tp->m_tnext = tn; - if (tn) - tn->m_tprev = tp; - - // Unlink from the sector thread. This thread begins at - // sector_t->touching_thinglist. - - sp = node->m_sprev; - sn = node->m_snext; - if (sp) - sp->m_snext = sn; - else - node->m_sector->*listhead = sn; - if (sn) - sn->m_sprev = sp; - - // Return this node to the freelist - - P_PutSecnode(node); - return tn; - } - return NULL; -} // phares 3/13/98 - -//============================================================================= -// -// P_DelSeclist -// -// Delete an entire sector list -// -//============================================================================= - -void P_DelSeclist(msecnode_t *node, msecnode_t *sector_t::*sechead) -{ - while (node) - node = P_DelSecnode(node, sechead); -} - -//============================================================================= -// phares 3/14/98 -// -// P_CreateSecNodeList -// -// Alters/creates the sector_list that shows what sectors the object resides in -// -//============================================================================= - -msecnode_t *P_CreateSecNodeList(AActor *thing, double radius, msecnode_t *sector_list, msecnode_t *sector_t::*seclisthead) -{ - msecnode_t *node; - - // First, clear out the existing m_thing fields. As each node is - // added or verified as needed, m_thing will be set properly. When - // finished, delete all nodes where m_thing is still NULL. These - // represent the sectors the Thing has vacated. - - node = sector_list; - while (node) - { - node->m_thing = NULL; - node = node->m_tnext; - } - - FBoundingBox box(thing->X(), thing->Y(), radius); - FBlockLinesIterator it(box); - line_t *ld; - - while ((ld = it.Next())) - { - if (!box.inRange(ld) || box.BoxOnLineSide(ld) != -1) - continue; - - // This line crosses through the object. - - // Collect the sector(s) from the line and add to the - // sector_list you're examining. If the Thing ends up being - // 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, ld->frontsector->*seclisthead); - - // Don't assume all lines are 2-sided, since some Things - // like MT_TFOG are allowed regardless of whether their radius takes - // them beyond an impassable linedef. - - // killough 3/27/98, 4/4/98: - // Use sidedefs instead of 2s flag to determine two-sidedness. - - if (ld->backsector) - sector_list = P_AddSecnode(ld->backsector, thing, sector_list, ld->backsector->*seclisthead); - } - - // Add the sector of the (x,y) point to sector_list. - - sector_list = P_AddSecnode(thing->Sector, thing, sector_list, thing->Sector->*seclisthead); - - // Now delete any nodes that won't be used. These are the ones where - // m_thing is still NULL. - - node = sector_list; - while (node) - { - if (node->m_thing == NULL) - { - if (node == sector_list) - sector_list = node->m_tnext; - node = P_DelSecnode(node, seclisthead); - } - else - { - node = node->m_tnext; - } - } - return sector_list; -} - -//============================================================================= -// -// P_DelPortalnode -// -// Same for line portal nodes -// -//============================================================================= - -portnode_t *P_DelPortalnode(portnode_t *node) -{ - portnode_t* tp; // prev node on thing thread - portnode_t* tn; // next node on thing thread - portnode_t* sp; // prev node on sector thread - portnode_t* sn; // next node on sector thread - - if (node) - { - // Unlink from the Thing thread. The Thing thread begins at - // sector_list and not from AActor->touching_sectorlist. - - tp = node->m_tprev; - tn = node->m_tnext; - if (tp) - tp->m_tnext = tn; - if (tn) - tn->m_tprev = tp; - - // Unlink from the sector thread. This thread begins at - // sector_t->touching_thinglist. - - sp = node->m_sprev; - sn = node->m_snext; - if (sp) - sp->m_snext = sn; - else - node->m_portal->lineportal_thinglist = sn; - if (sn) - sn->m_sprev = sp; - - // Return this node to the freelist (use the same one as for msecnodes, since both types are the same size.) - P_PutSecnode(reinterpret_cast(node)); - return tn; - } - return NULL; -} - - -//============================================================================= -// -// P_AddPortalnode -// -//============================================================================= - -portnode_t *P_AddPortalnode(FLinePortal *s, AActor *thing, portnode_t *nextnode) -{ - portnode_t *node; - - if (s == 0) - { - I_FatalError("AddSecnode of 0 for %s\n", thing->GetClass()->TypeName.GetChars()); - } - - node = reinterpret_cast(P_GetSecnode()); - - // killough 4/4/98, 4/7/98: mark new nodes unvisited. - node->visited = 0; - - node->m_portal = s; // portal - node->m_thing = thing; // mobj - node->m_tprev = NULL; // prev node on Thing thread - node->m_tnext = nextnode; // next node on Thing thread - if (nextnode) - nextnode->m_tprev = node; // set back link on Thing - - // Add new node at head of portal thread starting at s->touching_thinglist - - node->m_sprev = NULL; // prev node on portal thread - node->m_snext = s->lineportal_thinglist; // next node on portal thread - if (s->lineportal_thinglist) - node->m_snext->m_sprev = node; - s->lineportal_thinglist = node; - return node; -} - - -//========================================================================== -// -// Handle the lists used to render actors from other portal areas -// -//========================================================================== - -void AActor::UpdateRenderSectorList() -{ - static const double SPRITE_SPACE = 64.; - if (Pos() != OldRenderPos && !(flags & MF_NOSECTOR)) - { - // Only check if the map contains line portals - ClearRenderLineList(); - if (PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY()) - { - int bx = GetBlockX(X()); - int by = GetBlockY(Y()); - FBoundingBox bb(X(), Y(), MIN(radius*1.5, 128.)); // Don't go further than 128 map units, even for large actors - // Are there any portals near the actor's position? - if (bx >= 0 && by >= 0 && bx < bmapwidth && by < bmapheight && PortalBlockmap(bx, by).neighborContainsLines) - { - // Go through the entire list. In most cases this is faster than setting up a blockmap iterator - for (auto &p : linePortals) - { - if (p.mType == PORTT_VISUAL) continue; - if (bb.inRange(p.mOrigin) && bb.BoxOnLineSide(p.mOrigin)) - { - touching_lineportallist = P_AddPortalnode(&p, this, touching_lineportallist); - } - } - } - } - sector_t *sec = Sector; - double lasth = -FLT_MAX; - ClearRenderSectorList(); - while (!sec->PortalBlocksMovement(sector_t::ceiling)) - { - double planeh = sec->GetPortalPlaneZ(sector_t::ceiling); - if (planeh <= lasth) break; // broken setup. - if (Top() + SPRITE_SPACE < planeh) break; - lasth = planeh; - DVector2 newpos = Pos() + sec->GetPortalDisplacement(sector_t::ceiling); - sec = P_PointInSector(newpos); - touching_sectorportallist = P_AddSecnode(sec, this, touching_sectorportallist, sec->sectorportal_thinglist); - } - sec = Sector; - lasth = FLT_MAX; - while (!sec->PortalBlocksMovement(sector_t::floor)) - { - double planeh = sec->GetPortalPlaneZ(sector_t::floor); - if (planeh >= lasth) break; // broken setup. - if (Z() - SPRITE_SPACE > planeh) break; - lasth = planeh; - DVector2 newpos = Pos() + sec->GetPortalDisplacement(sector_t::floor); - sec = P_PointInSector(newpos); - touching_sectorportallist = P_AddSecnode(sec, this, touching_sectorportallist, sec->sectorportal_thinglist); - } - } -} - -void AActor::ClearRenderSectorList() -{ - msecnode_t *node = touching_sectorportallist; - while (node) - node = P_DelSecnode(node, §or_t::sectorportal_thinglist); - touching_sectorportallist = NULL; -} - -void AActor::ClearRenderLineList() -{ - portnode_t *node = touching_lineportallist; - while (node) - node = P_DelPortalnode(node); - touching_lineportallist = NULL; -} - - //========================================================================== // // diff --git a/src/p_secnodes.cpp b/src/p_secnodes.cpp new file mode 100644 index 000000000..14d354a7f --- /dev/null +++ b/src/p_secnodes.cpp @@ -0,0 +1,434 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id:$ +// +// Copyright (C) 1998-1996 by id Software, Inc. +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// $Log:$ +// +// DESCRIPTION: +// Boom secnodes +// +//----------------------------------------------------------------------------- + +#include "r_state.h" +#include "p_maputl.h" +#include "p_blockmap.h" + +//============================================================================= +// phares 3/21/98 +// +// Maintain a freelist of msecnode_t's to reduce memory allocs and frees. +//============================================================================= + +msecnode_t *headsecnode = NULL; + +//============================================================================= +// +// P_GetSecnode +// +// Retrieve a node from the freelist. The calling routine +// should make sure it sets all fields properly. +// +//============================================================================= + +msecnode_t *P_GetSecnode() +{ + msecnode_t *node; + + if (headsecnode) + { + node = headsecnode; + headsecnode = headsecnode->m_snext; + } + else + { + node = (msecnode_t *)M_Malloc(sizeof(*node)); + } + return node; +} + +//============================================================================= +// +// P_PutSecnode +// +// Returns a node to the freelist. +// +//============================================================================= + +void P_PutSecnode(msecnode_t *node) +{ + node->m_snext = headsecnode; + headsecnode = node; +} + +//============================================================================= +// phares 3/16/98 +// +// P_AddSecnode +// +// Searches the current list to see if this sector is +// already there. If not, it adds a sector node at the head of the list of +// sectors this object appears in. This is called when creating a list of +// nodes that will get linked in later. Returns a pointer to the new node. +// +//============================================================================= + +msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode, msecnode_t *&sec_thinglist) +{ + msecnode_t *node; + + if (s == 0) + { + I_FatalError("AddSecnode of 0 for %s\n", thing->GetClass()->TypeName.GetChars()); + } + + node = nextnode; + while (node) + { + if (node->m_sector == s) // Already have a node for this sector? + { + node->m_thing = thing; // Yes. Setting m_thing says 'keep it'. + return nextnode; + } + node = node->m_tnext; + } + + // Couldn't find an existing node for this sector. Add one at the head + // of the list. + + node = P_GetSecnode(); + + // killough 4/4/98, 4/7/98: mark new nodes unvisited. + node->visited = 0; + + node->m_sector = s; // sector + node->m_thing = thing; // mobj + node->m_tprev = NULL; // prev node on Thing thread + node->m_tnext = nextnode; // next node on Thing thread + if (nextnode) + nextnode->m_tprev = node; // set back link on Thing + + // 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 = sec_thinglist; // next node on sector thread + if (sec_thinglist) + node->m_snext->m_sprev = node; + sec_thinglist = node; + return node; +} + +//============================================================================= +// +// P_DelSecnode +// +// Deletes a sector node from the list of +// sectors this object appears in. Returns a pointer to the next node +// on the linked list, or NULL. +// +//============================================================================= + +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 + msecnode_t* sp; // prev node on sector thread + msecnode_t* sn; // next node on sector thread + + if (node) + { + // Unlink from the Thing thread. The Thing thread begins at + // sector_list and not from AActor->touching_sectorlist. + + tp = node->m_tprev; + tn = node->m_tnext; + if (tp) + tp->m_tnext = tn; + if (tn) + tn->m_tprev = tp; + + // Unlink from the sector thread. This thread begins at + // sector_t->touching_thinglist. + + sp = node->m_sprev; + sn = node->m_snext; + if (sp) + sp->m_snext = sn; + else + node->m_sector->*listhead = sn; + if (sn) + sn->m_sprev = sp; + + // Return this node to the freelist + + P_PutSecnode(node); + return tn; + } + return NULL; +} // phares 3/13/98 + +//============================================================================= +// +// P_DelSeclist +// +// Delete an entire sector list +// +//============================================================================= + +void P_DelSeclist(msecnode_t *node, msecnode_t *sector_t::*sechead) +{ + while (node) + node = P_DelSecnode(node, sechead); +} + +//============================================================================= +// phares 3/14/98 +// +// P_CreateSecNodeList +// +// Alters/creates the sector_list that shows what sectors the object resides in +// +//============================================================================= + +msecnode_t *P_CreateSecNodeList(AActor *thing, double radius, msecnode_t *sector_list, msecnode_t *sector_t::*seclisthead) +{ + msecnode_t *node; + + // First, clear out the existing m_thing fields. As each node is + // added or verified as needed, m_thing will be set properly. When + // finished, delete all nodes where m_thing is still NULL. These + // represent the sectors the Thing has vacated. + + node = sector_list; + while (node) + { + node->m_thing = NULL; + node = node->m_tnext; + } + + FBoundingBox box(thing->X(), thing->Y(), radius); + FBlockLinesIterator it(box); + line_t *ld; + + while ((ld = it.Next())) + { + if (!box.inRange(ld) || box.BoxOnLineSide(ld) != -1) + continue; + + // This line crosses through the object. + + // Collect the sector(s) from the line and add to the + // sector_list you're examining. If the Thing ends up being + // 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, ld->frontsector->*seclisthead); + + // Don't assume all lines are 2-sided, since some Things + // like MT_TFOG are allowed regardless of whether their radius takes + // them beyond an impassable linedef. + + // killough 3/27/98, 4/4/98: + // Use sidedefs instead of 2s flag to determine two-sidedness. + + if (ld->backsector) + sector_list = P_AddSecnode(ld->backsector, thing, sector_list, ld->backsector->*seclisthead); + } + + // Add the sector of the (x,y) point to sector_list. + + sector_list = P_AddSecnode(thing->Sector, thing, sector_list, thing->Sector->*seclisthead); + + // Now delete any nodes that won't be used. These are the ones where + // m_thing is still NULL. + + node = sector_list; + while (node) + { + if (node->m_thing == NULL) + { + if (node == sector_list) + sector_list = node->m_tnext; + node = P_DelSecnode(node, seclisthead); + } + else + { + node = node->m_tnext; + } + } + return sector_list; +} + +//============================================================================= +// +// P_DelPortalnode +// +// Same for line portal nodes +// +//============================================================================= + +portnode_t *P_DelPortalnode(portnode_t *node) +{ + portnode_t* tp; // prev node on thing thread + portnode_t* tn; // next node on thing thread + portnode_t* sp; // prev node on sector thread + portnode_t* sn; // next node on sector thread + + if (node) + { + // Unlink from the Thing thread. The Thing thread begins at + // sector_list and not from AActor->touching_sectorlist. + + tp = node->m_tprev; + tn = node->m_tnext; + if (tp) + tp->m_tnext = tn; + if (tn) + tn->m_tprev = tp; + + // Unlink from the sector thread. This thread begins at + // sector_t->touching_thinglist. + + sp = node->m_sprev; + sn = node->m_snext; + if (sp) + sp->m_snext = sn; + else + node->m_portal->lineportal_thinglist = sn; + if (sn) + sn->m_sprev = sp; + + // Return this node to the freelist (use the same one as for msecnodes, since both types are the same size.) + P_PutSecnode(reinterpret_cast(node)); + return tn; + } + return NULL; +} + + +//============================================================================= +// +// P_AddPortalnode +// +//============================================================================= + +portnode_t *P_AddPortalnode(FLinePortal *s, AActor *thing, portnode_t *nextnode) +{ + portnode_t *node; + + if (s == 0) + { + I_FatalError("AddSecnode of 0 for %s\n", thing->GetClass()->TypeName.GetChars()); + } + + node = reinterpret_cast(P_GetSecnode()); + + // killough 4/4/98, 4/7/98: mark new nodes unvisited. + node->visited = 0; + + node->m_portal = s; // portal + node->m_thing = thing; // mobj + node->m_tprev = NULL; // prev node on Thing thread + node->m_tnext = nextnode; // next node on Thing thread + if (nextnode) + nextnode->m_tprev = node; // set back link on Thing + + // Add new node at head of portal thread starting at s->touching_thinglist + + node->m_sprev = NULL; // prev node on portal thread + node->m_snext = s->lineportal_thinglist; // next node on portal thread + if (s->lineportal_thinglist) + node->m_snext->m_sprev = node; + s->lineportal_thinglist = node; + return node; +} + + +//========================================================================== +// +// Handle the lists used to render actors from other portal areas +// +//========================================================================== + +void AActor::UpdateRenderSectorList() +{ + static const double SPRITE_SPACE = 64.; + if (Pos() != OldRenderPos && !(flags & MF_NOSECTOR)) + { + // Only check if the map contains line portals + ClearRenderLineList(); + if (PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY()) + { + int bx = GetBlockX(X()); + int by = GetBlockY(Y()); + FBoundingBox bb(X(), Y(), MIN(radius*1.5, 128.)); // Don't go further than 128 map units, even for large actors + // Are there any portals near the actor's position? + if (bx >= 0 && by >= 0 && bx < bmapwidth && by < bmapheight && PortalBlockmap(bx, by).neighborContainsLines) + { + // Go through the entire list. In most cases this is faster than setting up a blockmap iterator + for (auto &p : linePortals) + { + if (p.mType == PORTT_VISUAL) continue; + if (bb.inRange(p.mOrigin) && bb.BoxOnLineSide(p.mOrigin)) + { + touching_lineportallist = P_AddPortalnode(&p, this, touching_lineportallist); + } + } + } + } + sector_t *sec = Sector; + double lasth = -FLT_MAX; + ClearRenderSectorList(); + while (!sec->PortalBlocksMovement(sector_t::ceiling)) + { + double planeh = sec->GetPortalPlaneZ(sector_t::ceiling); + if (planeh <= lasth) break; // broken setup. + if (Top() + SPRITE_SPACE < planeh) break; + lasth = planeh; + DVector2 newpos = Pos() + sec->GetPortalDisplacement(sector_t::ceiling); + sec = P_PointInSector(newpos); + touching_sectorportallist = P_AddSecnode(sec, this, touching_sectorportallist, sec->sectorportal_thinglist); + } + sec = Sector; + lasth = FLT_MAX; + while (!sec->PortalBlocksMovement(sector_t::floor)) + { + double planeh = sec->GetPortalPlaneZ(sector_t::floor); + if (planeh >= lasth) break; // broken setup. + if (Z() - SPRITE_SPACE > planeh) break; + lasth = planeh; + DVector2 newpos = Pos() + sec->GetPortalDisplacement(sector_t::floor); + sec = P_PointInSector(newpos); + touching_sectorportallist = P_AddSecnode(sec, this, touching_sectorportallist, sec->sectorportal_thinglist); + } + } +} + +void AActor::ClearRenderSectorList() +{ + msecnode_t *node = touching_sectorportallist; + while (node) + node = P_DelSecnode(node, §or_t::sectorportal_thinglist); + touching_sectorportallist = NULL; +} + +void AActor::ClearRenderLineList() +{ + portnode_t *node = touching_lineportallist; + while (node) + node = P_DelPortalnode(node); + touching_lineportallist = NULL; +} + +