diff --git a/src/actor.h b/src/actor.h index 60e1521322..5445c92be7 100644 --- a/src/actor.h +++ b/src/actor.h @@ -568,6 +568,7 @@ struct FStrifeDialogueNode; struct FLinkContext { msecnode_t *sector_list = nullptr; + msecnode_t *render_list = nullptr; }; class DDropItem : public DObject @@ -1149,7 +1150,7 @@ public: struct msecnode_t *touching_sectorlist; // phares 3/14/98 struct msecnode_t *render_sectorlist; // same for cross-sectorportal rendering struct portnode_t *render_portallist; // and for cross-lineportal - std::forward_list* touching_render_sectors; // this is the list of sectors that this thing interesects with it's max(radius, renderradius). + struct msecnode_t *touching_rendersectors; // this is the list of sectors that this thing interesects with it's max(radius, renderradius). int validcount; diff --git a/src/p_local.h b/src/p_local.h index 25b465d26a..93bbbbf114 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -391,12 +391,10 @@ enum int P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance, FName damageType, int flags, int fulldamagedistance=0); -void P_DelSeclist(msecnode_t *); // phares 3/16/98 +void P_DelSeclist(msecnode_t *, msecnode_t *sector_t::*seclisthead); 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); -msecnode_t *P_CreateSecNodeList(AActor *thing, msecnode_t *sector_list); -void P_LinkRenderSectors(AActor*); -void P_UnlinkRenderSectors(AActor*); +msecnode_t *P_CreateSecNodeList(AActor *thing, double radius, msecnode_t *sector_list, msecnode_t *sector_t::*seclisthead); 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 9dcd165c2f..20796ed23d 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -6541,10 +6541,10 @@ msecnode_t *P_DelSecnode(msecnode_t *node, msecnode_t *sector_t::*listhead) // //============================================================================= -void P_DelSeclist(msecnode_t *node) +void P_DelSeclist(msecnode_t *node, msecnode_t *sector_t::*sechead) { while (node) - node = P_DelSecnode(node, §or_t::touching_thinglist); + node = P_DelSecnode(node, sechead); } //============================================================================= @@ -6556,7 +6556,7 @@ void P_DelSeclist(msecnode_t *node) // //============================================================================= -msecnode_t *P_CreateSecNodeList(AActor *thing, msecnode_t *sector_list) +msecnode_t *P_CreateSecNodeList(AActor *thing, double radius, msecnode_t *sector_list, msecnode_t *sector_t::*seclisthead) { msecnode_t *node; @@ -6572,7 +6572,7 @@ msecnode_t *P_CreateSecNodeList(AActor *thing, msecnode_t *sector_list) node = node->m_tnext; } - FBoundingBox box(thing->X(), thing->Y(), thing->radius); + FBoundingBox box(thing->X(), thing->Y(), radius); FBlockLinesIterator it(box); line_t *ld; @@ -6588,7 +6588,7 @@ msecnode_t *P_CreateSecNodeList(AActor *thing, msecnode_t *sector_list) // 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->touching_thinglist); + 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 @@ -6598,12 +6598,12 @@ msecnode_t *P_CreateSecNodeList(AActor *thing, msecnode_t *sector_list) // Use sidedefs instead of 2s flag to determine two-sidedness. if (ld->backsector) - sector_list = P_AddSecnode(ld->backsector, thing, sector_list, ld->backsector->touching_thinglist); + 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->touching_thinglist); + 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. @@ -6615,7 +6615,7 @@ msecnode_t *P_CreateSecNodeList(AActor *thing, msecnode_t *sector_list) { if (node == sector_list) sector_list = node->m_tnext; - node = P_DelSecnode(node, §or_t::touching_thinglist); + node = P_DelSecnode(node, seclisthead); } else { @@ -6625,103 +6625,6 @@ msecnode_t *P_CreateSecNodeList(AActor *thing, msecnode_t *sector_list) return sector_list; } - -//============================================================================= -// -// P_LinkRenderSectors -// -// Alters/creates the list of touched sectors for thing's render radius. -// -//============================================================================= - -void P_LinkRenderSectors(AActor* thing) -{ - // if this thing has RenderStyle None, don't link it anywhere. - if (thing->renderradius >= 0) - { - FBoundingBox box(thing->X(), thing->Y(), std::max(thing->radius, thing->renderradius)); - FBlockLinesIterator it(box); - line_t *ld; - - // add to surrounding sectors - while ((ld = it.Next())) - { - if (!box.inRange(ld) || box.BoxOnLineSide(ld) != -1) - continue; - - // - // create necessary lists. - if (!thing->touching_render_sectors) thing->touching_render_sectors = new std::forward_list(); - - // - if (ld->frontsector != thing->Sector) - { - if (std::find(thing->touching_render_sectors->begin(), thing->touching_render_sectors->end(), ld->frontsector) == thing->touching_render_sectors->end()) - thing->touching_render_sectors->push_front(ld->frontsector); - if (!ld->frontsector->touching_render_things) ld->frontsector->touching_render_things = new std::forward_list(); - ld->frontsector->touching_render_things->push_front(thing); - } - - if (ld->backsector && ld->backsector != thing->Sector) - { - if (std::find(thing->touching_render_sectors->begin(), thing->touching_render_sectors->end(), ld->backsector) == thing->touching_render_sectors->end()) - thing->touching_render_sectors->push_front(ld->backsector); - if (!ld->backsector->touching_render_things) ld->backsector->touching_render_things = new std::forward_list(); - ld->backsector->touching_render_things->push_front(thing); - } - } - } - - // add to own sector - if (!thing->Sector->touching_render_things) thing->Sector->touching_render_things = new std::forward_list(); - thing->Sector->touching_render_things->push_front(thing); -} - - -//============================================================================= -// -// P_UnlinkRenderSectors -// -// Reverses P_LinkRenderSectors. -// -//============================================================================= - -void P_UnlinkRenderSectors(AActor* thing) -{ - if (thing->renderradius >= 0) - { - if (thing->touching_render_sectors) - { - for (auto sec : *thing->touching_render_sectors) - { - if (sec->touching_render_things) - { - sec->touching_render_things->remove(thing); - if (sec->touching_render_things->empty()) - { - delete sec->touching_render_things; - sec->touching_render_things = NULL; - } - } - } - - delete thing->touching_render_sectors; - thing->touching_render_sectors = NULL; - } - } - - if (thing->Sector->touching_render_things) - { - thing->Sector->touching_render_things->remove(thing); - if (thing->Sector->touching_render_things->empty()) - { - delete thing->Sector->touching_render_things; - thing->Sector->touching_render_things = NULL; - } - } -} - - //============================================================================= // // P_DelPortalnode diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index d7d5fd6588..d4ac79ce7c 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -271,15 +271,19 @@ void AActor::UnlinkFromWorld (FLinkContext *ctx) // put it back into touching_sectorlist. It's done this way to // avoid a lot of deleting/creating for nodes, when most of the // time you just get back what you deleted anyway. - // - // If this Thing is being removed entirely, then the calling - // routine will clear out the nodes in sector_list. - if (ctx != nullptr) ctx->sector_list = touching_sectorlist; - else P_DelSeclist(touching_sectorlist); - touching_sectorlist = NULL; //to be restored by P_SetThingPosition - - P_UnlinkRenderSectors(this); + if (ctx != nullptr) + { + ctx->sector_list = touching_sectorlist; + ctx->render_list = touching_rendersectors; + } + else + { + P_DelSeclist(touching_sectorlist, §or_t::touching_thinglist); + P_DelSeclist(touching_rendersectors, §or_t::touching_renderthings); + } + touching_sectorlist = nullptr; //to be restored by P_SetThingPosition + touching_rendersectors = nullptr; } } @@ -456,9 +460,13 @@ void AActor::LinkToWorld(FLinkContext *ctx, bool spawningmapthing, sector_t *sec // When a node is deleted, its sector links (the links starting // at sector_t->touching_thinglist) are broken. When a node is // added, new sector links are created. - touching_sectorlist = P_CreateSecNodeList(this, ctx != nullptr? ctx->sector_list : nullptr); // Attach to thing - - P_LinkRenderSectors(this); + touching_sectorlist = P_CreateSecNodeList(this, radius, ctx != nullptr? ctx->sector_list : nullptr, §or_t::touching_thinglist); // Attach to thing + if (renderradius >= 0) touching_rendersectors = P_CreateSecNodeList(this, MAX(radius, renderradius), ctx != nullptr ? ctx->render_list : nullptr, §or_t::touching_renderthings); + else + { + touching_rendersectors = nullptr; + if (ctx != nullptr) P_DelSeclist(ctx->render_list, §or_t::touching_renderthings); + } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 1955f6b4ef..7e5dbc88e7 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -511,9 +511,8 @@ void AActor::Serialize(FSerializer &arc) void AActor::PostSerialize() { - touching_sectorlist = NULL; - if (touching_render_sectors) delete touching_render_sectors; - touching_render_sectors = NULL; + touching_sectorlist = nullptr; + touching_rendersectors = nullptr; LinkToWorld(nullptr, false, Sector); AddToHash(); @@ -4549,8 +4548,8 @@ AActor *AActor::StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t a actor->sprite = st->sprite; actor->frame = st->GetFrame(); actor->renderflags = (actor->renderflags & ~RF_FULLBRIGHT) | ActorRenderFlags::FromInt (st->GetFullbright()); - actor->touching_sectorlist = NULL; // NULL head of sector list // phares 3/13/98 - actor->touching_render_sectors = NULL; + actor->touching_sectorlist = nullptr; // NULL head of sector list // phares 3/13/98 + actor->touching_rendersectors = nullptr; if (G_SkillProperty(SKILLP_FastMonsters) && actor->GetClass()->FastSpeed >= 0) actor->Speed = actor->GetClass()->FastSpeed; diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 7c663508b1..d3bcc742d7 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1509,10 +1509,10 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) else // [RH] Translate to new sector special ss->special = P_TranslateSectorSpecial (LittleShort(ms->special)); tagManager.AddSectorTag(i, LittleShort(ms->tag)); - ss->thinglist = NULL; - ss->touching_thinglist = NULL; // phares 3/14/98 - ss->render_thinglist = NULL; - ss->touching_render_things = NULL; + ss->thinglist = nullptr; + ss->touching_thinglist = nullptr; // phares 3/14/98 + ss->render_thinglist = nullptr; + ss->touching_renderthings = nullptr; 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 2e335f4f07..2ef8a9ced0 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1294,10 +1294,10 @@ public: sec->SetYScale(sector_t::ceiling, 1.); sec->SetAlpha(sector_t::floor, 1.); sec->SetAlpha(sector_t::ceiling, 1.); - sec->thinglist = NULL; - sec->touching_thinglist = NULL; // phares 3/14/98 - sec->render_thinglist = NULL; - sec->touching_render_things = NULL; + sec->thinglist = nullptr; + sec->touching_thinglist = nullptr; // phares 3/14/98 + sec->render_thinglist = nullptr; + sec->touching_renderthings = nullptr; 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 40a3cb2f6d..6db4a57f5b 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2977,7 +2977,7 @@ void P_UnPredictPlayer () } // Make the sector_list match the player's touching_sectorlist before it got predicted. - P_DelSeclist(ctx.sector_list); + P_DelSeclist(ctx.sector_list, §or_t::touching_thinglist); ctx.sector_list = NULL; for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) { diff --git a/src/r_defs.h b/src/r_defs.h index 3b064c7607..edb478a067 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -1049,7 +1049,7 @@ public: // 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. - std::forward_list* touching_render_things; // this is used to allow wide things to be rendered not only from their main sector. + struct msecnode_t *touching_renderthings; // this is used to allow wide things to be rendered not only from their main sector. double gravity; // [RH] Sector gravity (1.0 is normal) FNameNoInit damagetype; // [RH] Means-of-death for applied damage diff --git a/src/r_things.cpp b/src/r_things.cpp index 8d326b319a..ce356808ed 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -714,7 +714,7 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop // R_ProjectSprite // Generates a vissprite for a thing if it might be visible. // -void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling) +void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector) { double tr_x; double tr_y; @@ -1086,6 +1086,10 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor } FDynamicColormap *mybasecolormap = basecolormap; + if (current_sector->sectornum != thing->Sector->sectornum) // compare sectornums to account for R_FakeFlat copies. + { + // Todo: The actor is from a different sector so we have to retrieve the proper basecolormap for that sector. + } // Sprites that are added to the scene must fade to black. if (vis->Style.RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0) @@ -1224,7 +1228,7 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside) // A sector might have been split into several // subsectors during BSP building. // Thus we check whether it was already added. - if (sec->touching_render_things == NULL || sec->validcount == validcount) + if (sec->touching_renderthings == nullptr || sec->validcount == validcount) return; // Well, now it will be done. @@ -1233,8 +1237,9 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside) spriteshade = LIGHT2SHADE(lightlevel + r_actualextralight); // Handle all things in sector. - for (auto thing : *sec->touching_render_things) + for(auto p = sec->touching_renderthings; p != nullptr; p = p->m_snext) { + auto thing = p->m_thing; if (thing->validcount == validcount) continue; thing->validcount = validcount; @@ -1250,7 +1255,7 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside) } // find fake level - for(auto rover : frontsector->e->XFloor.ffloors) + for(auto rover : thing->Sector->e->XFloor.ffloors) { if(!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) continue; if(!(rover->flags & FF_SOLID) || rover->alpha != 255) continue; @@ -1266,7 +1271,7 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside) if(rover->bottom.plane->ZatPoint(0., 0.) >= thing->Top()) fakeceiling = rover; } } - R_ProjectSprite (thing, fakeside, fakefloor, fakeceiling); + R_ProjectSprite (thing, fakeside, fakefloor, fakeceiling, sec); fakeceiling = NULL; fakefloor = NULL; }