From 5af53c0e623804c56c7a39cda9a22980b3c416a8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 14 Feb 2016 18:53:00 +0100 Subject: [PATCH 01/10] - fixed a few more sector movers which calculated their movement at (0,0) instead of inside the sector. --- src/p_floor.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/p_floor.cpp b/src/p_floor.cpp index c632e8ba2..2a2926460 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -411,8 +411,8 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, case DFloor::floorLowerByTexture: floor->m_Direction = -1; - newheight = sec->floorplane.ZatPoint (0, 0) - sec->FindShortestTextureAround (); - floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, newheight); + newheight = sec->floorplane.ZatPoint (sec->soundorg[0], sec->soundorg[1]) - sec->FindShortestTextureAround (); + floor->m_FloorDestDist = sec->floorplane.PointToDist (sec->soundorg[0], sec->soundorg[1], newheight); break; case DFloor::floorLowerToCeiling: @@ -428,14 +428,14 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, // since the code is identical to what was here. (Oddly // enough, BOOM preserved the code here even though it // also had this function.) - newheight = sec->floorplane.ZatPoint (0, 0) + sec->FindShortestTextureAround (); - floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, newheight); + newheight = sec->floorplane.ZatPoint (sec->soundorg[0], sec->soundorg[1]) + sec->FindShortestTextureAround (); + floor->m_FloorDestDist = sec->floorplane.PointToDist (sec->soundorg[0], sec->soundorg[1], newheight); break; case DFloor::floorRaiseAndChange: floor->m_Direction = 1; - newheight = sec->floorplane.ZatPoint (0, 0) + height; - floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, newheight); + newheight = sec->floorplane.ZatPoint (sec->soundorg[0], sec->soundorg[1]) + height; + floor->m_FloorDestDist = sec->floorplane.PointToDist (sec->soundorg[0], sec->soundorg[1], newheight); if (line != NULL) { FTextureID oldpic = sec->GetTexture(sector_t::floor); @@ -618,8 +618,8 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, floor->m_Hexencrush = false; floor->m_Speed = speed; - height = sec->floorplane.ZatPoint (0, 0) + stairstep; - floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, height); + height = sec->floorplane.ZatPoint (sec->soundorg[0], sec->soundorg[1]) + stairstep; + floor->m_FloorDestDist = sec->floorplane.PointToDist (sec->soundorg[0], sec->soundorg[1], height); texture = sec->GetTexture(sector_t::floor); osecnum = secnum; //jff 3/4/98 preserve loop index From 0dce22ce85adb244aecf3c0de777e108b257730b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 14 Feb 2016 21:02:18 +0100 Subject: [PATCH 02/10] - some portal considerations. --- src/g_heretic/a_hereticweaps.cpp | 13 +++++++++---- src/r_defs.h | 3 +++ src/r_utility.cpp | 18 ++++++++++++------ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 619fe7b5a..f51de13e1 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -1077,12 +1077,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm) mo = Spawn (pos.x, pos.y, ONCEILINGZ, ALLOW_REPLACE); // We used bouncecount to store the 3D floor index in A_HideInCeiling if (!mo) return 0; + if (mo->Sector->PortalGroup != self->Sector->PortalGroup) + { + // spawning this through a portal will never work right so abort right away. + mo->Destroy(); + return 0; + } fixed_t newz; - if (self->bouncecount >= 0 - && (unsigned)self->bouncecount < self->Sector->e->XFloor.ffloors.Size()) - newz = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPoint(pos.x, pos.y);// - 40 * FRACUNIT; + if (self->bouncecount >= 0 && (unsigned)self->bouncecount < self->Sector->e->XFloor.ffloors.Size()) + newz = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPoint(mo);// - 40 * FRACUNIT; else - newz = self->Sector->ceilingplane.ZatPoint(pos.x, pos.y); + newz = self->Sector->ceilingplane.ZatPoint(mo); int moceiling = P_Find3DFloor(NULL, pos.x, pos.y, newz, false, false, newz); if (moceiling >= 0) mo->SetZ(newz - mo->height, false); diff --git a/src/r_defs.h b/src/r_defs.h index da122e14a..d65b654c2 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -741,16 +741,19 @@ struct sector_t inline bool PortalBlocksView(int plane) { + if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); } inline bool PortalBlocksMovement(int plane) { + if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; return !!(planes[plane].Flags & (PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); } inline bool PortalBlocksSound(int plane) { + if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; return !!(planes[plane].Flags & (PLANEF_BLOCKSOUND | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); } diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 540ab740a..794c30d4c 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -878,16 +878,22 @@ void R_SetupFrame (AActor *actor) interpolator.DoInterpolations (r_TicFrac); // Keep the view within the sector's floor and ceiling - fixed_t theZ = viewsector->ceilingplane.ZatPoint (viewx, viewy) - 4*FRACUNIT; - if (viewz > theZ) + if (viewsector->PortalBlocksMovement(sector_t::ceiling)) { - viewz = theZ; + fixed_t theZ = viewsector->ceilingplane.ZatPoint(viewx, viewy) - 4 * FRACUNIT; + if (viewz > theZ) + { + viewz = theZ; + } } - theZ = viewsector->floorplane.ZatPoint (viewx, viewy) + 4*FRACUNIT; - if (viewz < theZ) + if (viewsector->PortalBlocksMovement(sector_t::floor)) { - viewz = theZ; + fixed_t theZ = viewsector->floorplane.ZatPoint(viewx, viewy) + 4 * FRACUNIT; + if (viewz < theZ) + { + viewz = theZ; + } } if (!paused) From 405db83393c80544abbd9743b10fb4bae90b53fa Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 15 Feb 2016 00:53:59 +0100 Subject: [PATCH 03/10] - added a function which collects all portal group an actor would touch if standing in a given position. --- src/p_saveg.cpp | 1 + src/portal.cpp | 98 +++++++++++++++++++++++++++++++++++++++++++++++++ src/portal.h | 65 ++++++++++++++++++++++++++++++++ src/r_defs.h | 21 ++--------- 4 files changed, 167 insertions(+), 18 deletions(-) diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index f0aedd5c6..e7b32bb23 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -524,6 +524,7 @@ void P_SerializeWorld (FArchive &arc) { linePortals.Clear(); } + P_CollectLinkedPortals(); } void extsector_t::Serialize(FArchive &arc) diff --git a/src/portal.cpp b/src/portal.cpp index d9156514d..1ce6a630d 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -18,6 +18,7 @@ CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO) FDisplacementTable Displacements; TArray linePortals; +TArray linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups. FArchive &operator<< (FArchive &arc, FLinePortal &port) @@ -168,6 +169,19 @@ void P_UpdatePortal(FLinePortal *port) } } +void P_CollectLinkedPortals() +{ + linkedPortals.Clear(); + for (unsigned i = 0; i < linePortals.Size(); i++) + { + FLinePortal * port = &linePortals[i]; + if (port->mType == PORTT_LINKED) + { + linkedPortals.Push(port); + } + } +} + void P_FinalizePortals() { for (unsigned i = 0; i < linePortals.Size(); i++) @@ -175,6 +189,7 @@ void P_FinalizePortals() FLinePortal * port = &linePortals[i]; P_UpdatePortal(port); } + P_CollectLinkedPortals(); } static bool ChangePortalLine(line_t *line, int destid) @@ -839,6 +854,88 @@ void P_CreateLinkedPortals() //BuildBlockmap(); } + +//============================================================================ +// +// Collect all portal groups this actor would occupy at the given position +// This is used to determine which parts of the map need to be checked. +// +//============================================================================ + +bool P_CollectConnectedGroups(AActor *actor, fixed_t newx, fixed_t newy, FPortalGroupTable &out) +{ + TArray foundPortals; + bool retval = false; + if (linePortals.Size() == 0) + { + return false; + } + out.setSize(Displacements.size); + out.setBit(actor->Sector->PortalGroup); + //FBoundingBox box(newx, newy, actor->radius); + int thisgroup = actor->Sector->PortalGroup; + for (unsigned i = 0; i < linePortals.Size(); i++) + { + if (linePortals[i].mType != PORTT_LINKED) continue; // not a linked portal + line_t *ld = linePortals[i].mOrigin; + int othergroup = ld->frontsector->PortalGroup; + FDisplacement &disp = Displacements(thisgroup, othergroup); + if (!disp.isSet) continue; // no connection. + + FBoundingBox box(newx + disp.x, newy + disp.y, actor->radius); + + if (box.Right() <= ld->bbox[BOXLEFT] + || box.Left() >= ld->bbox[BOXRIGHT] + || box.Top() <= ld->bbox[BOXBOTTOM] + || box.Bottom() >= ld->bbox[BOXTOP]) + continue; // not touched + + if (box.BoxOnLineSide(linePortals[i].mOrigin) != -1) continue; // not touched + foundPortals.Push(&linePortals[i]); + } + bool foundone = true; + while (foundone) + { + foundone = false; + for (int i = foundPortals.Size() - 1; i >= 0; i--) + { + if (out.getBit(foundPortals[i]->mOrigin->frontsector->PortalGroup) && + !out.getBit(foundPortals[i]->mDestination->frontsector->PortalGroup)) + { + out.setBit(foundPortals[i]->mDestination->frontsector->PortalGroup); + foundone = true; + retval = true; + foundPortals.Delete(i); + } + } + } + sector_t *sec = P_PointInSector(newx, newy); + sector_t *wsec = sec; + while (!wsec->PortalBlocksMovement(sector_t::ceiling) && actor->Top() > wsec->SkyBoxes[sector_t::ceiling]->threshold) + { + sector_t *othersec = wsec->SkyBoxes[sector_t::ceiling]->Sector; + FDisplacement &disp = Displacements(actor->Sector->PortalGroup, othersec->PortalGroup); + fixed_t dx = newx + disp.x; + fixed_t dy = newx + disp.y; + out.setBit(othersec->PortalGroup); + wsec = P_PointInSector(dx, dy); // get upper sector at the exact spot we want to check and repeat, + retval = true; + } + wsec = sec; + while (!wsec->PortalBlocksMovement(sector_t::floor) && actor->Z() < wsec->SkyBoxes[sector_t::floor]->threshold) + { + sector_t *othersec = wsec->SkyBoxes[sector_t::ceiling]->Sector; + FDisplacement &disp = Displacements(actor->Sector->PortalGroup, othersec->PortalGroup); + fixed_t dx = newx + disp.x; + fixed_t dy = newx + disp.y; + out.setBit(othersec->PortalGroup); + wsec = P_PointInSector(dx, dy); // get lower sector at the exact spot we want to check and repeat, + retval = true; + } + return retval; +} + + CCMD(dumplinktable) { for (int x = 1; x < Displacements.size; x++) @@ -854,3 +951,4 @@ CCMD(dumplinktable) + diff --git a/src/portal.h b/src/portal.h index 893f3ae69..faee141e5 100644 --- a/src/portal.h +++ b/src/portal.h @@ -7,6 +7,7 @@ #include "actor.h" #include "p_local.h" #include "m_bbox.h" +#include "a_sharedglobal.h" struct FDisplacement { @@ -33,6 +34,40 @@ struct FDisplacementTable } }; +extern FDisplacementTable Displacements; + +struct FPortalGroupTable +{ + TArray data; + TArray touchingGroups; + + void setSize(int num) + { + data.Resize((num + 31) / 32); + memset(&data[0], 0, data.Size()*sizeof(DWORD)); + } + + void clear() + { + data.Clear(); + touchingGroups.Clear(); + } + + void setBit(int group) + { + if (!getBit(group)) + { + data[group >> 5] |= (1 << (group & 31)); + touchingGroups.Push(group); + } + } + + int getBit(int group) + { + return data[group >> 5] & (1 << (group & 31)); + } +}; + enum { PORTF_VISIBLE = 1, @@ -60,6 +95,12 @@ enum PORG_CEILING, }; +enum +{ + PCOLL_NOTLINKED = 1, + PCOLL_LINKED = 2 +}; + struct FLinePortal { line_t *mOrigin; @@ -78,6 +119,12 @@ void P_SpawnLinePortal(line_t* line); void P_FinalizePortals(); bool P_ChangePortal(line_t *ln, int thisid, int destid); void P_CreateLinkedPortals(); +bool P_CollectConnectedGroups(AActor *actor, fixed_t newx, fixed_t newy, FPortalGroupTable &out); +void P_CollectLinkedPortals(); +inline int P_NumPortalGroups() +{ + return Displacements.size; +} /* code ported from prototype */ @@ -145,4 +192,22 @@ inline int line_t::getPortalAlignment() const return portalindex >= linePortals.Size() ? 0 : linePortals[portalindex].mAlign; } +inline bool sector_t::PortalBlocksView(int plane) +{ + if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; + return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); +} + +inline bool sector_t::PortalBlocksMovement(int plane) +{ + if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; + return !!(planes[plane].Flags & (PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); +} + +inline bool sector_t::PortalBlocksSound(int plane) +{ + if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; + return !!(planes[plane].Flags & (PLANEF_BLOCKSOUND | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); +} + #endif \ No newline at end of file diff --git a/src/r_defs.h b/src/r_defs.h index d65b654c2..7339b26ae 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -739,24 +739,9 @@ struct sector_t Flags &= ~SECF_SPECIALFLAGS; } - inline bool PortalBlocksView(int plane) - { - if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; - return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); - } - - inline bool PortalBlocksMovement(int plane) - { - if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; - return !!(planes[plane].Flags & (PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); - } - - inline bool PortalBlocksSound(int plane) - { - if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true; - return !!(planes[plane].Flags & (PLANEF_BLOCKSOUND | PLANEF_DISABLED | PLANEF_OBSTRUCTED)); - } - + bool PortalBlocksView(int plane); + bool PortalBlocksMovement(int plane); + bool PortalBlocksSound(int plane); int GetTerrain(int pos) const; From 6adb06950603a2c00bdd38febd35c5900b0ec4b8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 15 Feb 2016 02:14:34 +0100 Subject: [PATCH 04/10] - rewrote p_local.h so that it doesn't pull in the entire bunch of headers. This was to resolve some circular dependencies with the portal code. The most notable changees: * FTextureID was moved from textures.h to doomtype.h because it is frequently needed in files that don't want to do anything with actual textures. * split off the parts from p_maputl into a separate header. * consolidated all blockmap related data into p_blockmap.h * split off the polyobject parts into po_man.h --- .gitignore | 2 + src/actor.h | 27 +-- src/am_map.cpp | 3 + src/b_bot.cpp | 1 + src/b_func.cpp | 3 + src/b_game.cpp | 1 + src/b_move.cpp | 2 + src/b_think.cpp | 1 + src/basictypes.h | 11 ++ src/c_cmds.cpp | 2 + src/d_net.cpp | 1 + src/dobjgc.cpp | 2 + src/doomtype.h | 35 ++++ src/dsectoreffect.cpp | 1 + src/dthinker.cpp | 1 + src/fragglescript/t_cmd.cpp | 1 + src/g_doom/a_doommisc.cpp | 4 + src/g_game.cpp | 3 + src/g_heretic/a_hereticmisc.cpp | 2 + src/g_hexen/a_hexenmisc.cpp | 4 + src/g_level.cpp | 2 + src/g_raven/a_artitele.cpp | 3 + src/g_raven/a_minotaur.cpp | 2 + src/g_shared/a_artifacts.cpp | 2 + src/g_shared/a_fastprojectile.cpp | 1 + src/g_shared/a_morph.cpp | 1 + src/g_shared/a_pickups.cpp | 2 + src/g_shared/a_quake.cpp | 2 + src/g_shared/a_randomspawner.cpp | 2 + src/g_shared/a_specialspot.cpp | 1 + src/g_shared/shared_hud.cpp | 2 + src/info.cpp | 3 + src/m_bbox.cpp | 1 + src/m_cheat.cpp | 2 + src/p_3dfloors.cpp | 4 + src/p_3dmidtex.cpp | 2 + src/p_acs.cpp | 3 + src/p_blockmap.h | 33 ++++ src/p_doors.cpp | 2 + src/p_effect.cpp | 2 + src/p_enemy.cpp | 5 + src/p_glnodes.cpp | 2 + src/p_interaction.cpp | 1 + src/p_lights.cpp | 2 + src/p_lnspec.cpp | 4 + src/p_local.h | 273 ++---------------------------- src/p_map.cpp | 4 + src/p_maputl.cpp | 4 + src/p_maputl.h | 208 +++++++++++++++++++++++ src/p_mobj.cpp | 3 + src/p_saveg.cpp | 2 + src/p_setup.cpp | 4 + src/p_sight.cpp | 5 + src/p_slopes.cpp | 2 + src/p_spec.cpp | 5 + src/p_switch.cpp | 2 + src/p_teleport.cpp | 4 + src/p_things.cpp | 3 + src/p_tick.cpp | 3 + src/p_trace.cpp | 3 + src/p_user.cpp | 5 + src/p_writemap.cpp | 2 + src/po_man.cpp | 3 + src/po_man.h | 36 ++++ src/portal.cpp | 2 + src/r_defs.h | 13 ++ src/r_things.cpp | 1 + src/r_utility.cpp | 2 + src/s_sndseq.cpp | 1 + src/s_sound.cpp | 1 + src/textures/textures.h | 30 ---- src/thingdef/thingdef_codeptr.cpp | 3 + 72 files changed, 503 insertions(+), 314 deletions(-) create mode 100644 src/p_blockmap.h create mode 100644 src/p_maputl.h diff --git a/.gitignore b/.gitignore index f38b57ee9..422957e23 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,5 @@ /lzma/x64/ /zlib/x64/ /build_vc2015 +/build_vc2015-32 +/build_vc2015-64 diff --git a/src/actor.h b/src/actor.h index 579656ae0..1dcd35b90 100644 --- a/src/actor.h +++ b/src/actor.h @@ -43,6 +43,7 @@ struct subsector_t; class PClassAmmo; +struct FBlockNode; // // NOTES: AActor @@ -530,21 +531,6 @@ enum EThingSpecialActivationType THINGSPEC_Switch = 1<<10, // The thing is alternatively activated and deactivated when triggered }; -// [RH] Like msecnode_t, but for the blockmap -struct FBlockNode -{ - AActor *Me; // actor this node references - int BlockIndex; // index into blocklinks for the block this node is in - FBlockNode **PrevActor; // previous actor in this block - FBlockNode *NextActor; // next actor in this block - FBlockNode **PrevBlock; // previous block this actor is in - FBlockNode *NextBlock; // next block this actor is in - - static FBlockNode *Create (AActor *who, int x, int y); - void Release (); - - static FBlockNode *FreeBlocks; -}; class FDecalBase; class AInventory; @@ -569,16 +555,6 @@ struct line_t; struct secplane_t; struct FStrifeDialogueNode; -struct fixedvec3 -{ - fixed_t x, y, z; -}; - -struct fixedvec2 -{ - fixed_t x, y; -}; - class DDropItem : public DObject { DECLARE_CLASS(DDropItem, DObject) @@ -1407,6 +1383,7 @@ inline fixedvec3 PosRelative(const fixedvec3 &pos, line_t *line, sector_t *refse } void PrintMiscActorInfo(AActor * query); +AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, ActorFlags actorMask, DWORD wallMask); #define S_FREETARGMOBJ 1 diff --git a/src/am_map.cpp b/src/am_map.cpp index df464e59d..b0ae28a13 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -42,6 +42,8 @@ #include "r_renderer.h" #include "r_sky.h" #include "sbar.h" +#include "d_player.h" +#include "p_blockmap.h" #include "m_cheat.h" #include "i_system.h" @@ -58,6 +60,7 @@ // State. #include "doomstat.h" #include "r_state.h" +#include "r_utility.h" // Data. #include "gstrings.h" diff --git a/src/b_bot.cpp b/src/b_bot.cpp index aa5262929..ee954a206 100644 --- a/src/b_bot.cpp +++ b/src/b_bot.cpp @@ -13,6 +13,7 @@ #include "teaminfo.h" #include "d_net.h" #include "farchive.h" +#include "d_player.h" IMPLEMENT_POINTY_CLASS(DBot) DECLARE_POINTER(dest) diff --git a/src/b_func.cpp b/src/b_func.cpp index 3edc560b0..3b8ada882 100644 --- a/src/b_func.cpp +++ b/src/b_func.cpp @@ -11,6 +11,7 @@ #include "doomdef.h" #include "doomstat.h" #include "p_local.h" +#include "p_maputl.h" #include "b_bot.h" #include "g_game.h" #include "m_random.h" @@ -20,6 +21,8 @@ #include "i_system.h" #include "s_sound.h" #include "d_event.h" +#include "d_player.h" +#include "p_spec.h" static FRandom pr_botdofire ("BotDoFire"); diff --git a/src/b_game.cpp b/src/b_game.cpp index 44545f73d..b896878e7 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -59,6 +59,7 @@ Everything that is changed is marked (maybe commented) with "Added by MC" #include "i_system.h" #include "d_net.h" #include "d_netinf.h" +#include "d_player.h" static FRandom pr_botspawn ("BotSpawn"); diff --git a/src/b_move.cpp b/src/b_move.cpp index cee409265..7bd31a201 100644 --- a/src/b_move.cpp +++ b/src/b_move.cpp @@ -18,6 +18,8 @@ #include "a_keys.h" #include "d_event.h" #include "p_enemy.h" +#include "d_player.h" +#include "p_spec.h" static FRandom pr_botopendoor ("BotOpenDoor"); static FRandom pr_bottrywalk ("BotTryWalk"); diff --git a/src/b_think.cpp b/src/b_think.cpp index a2b169f56..94d8e7ea2 100644 --- a/src/b_think.cpp +++ b/src/b_think.cpp @@ -19,6 +19,7 @@ #include "statnums.h" #include "d_net.h" #include "d_event.h" +#include "d_player.h" static FRandom pr_botmove ("BotMove"); diff --git a/src/basictypes.h b/src/basictypes.h index 3aa4f4635..0ae68f39b 100644 --- a/src/basictypes.h +++ b/src/basictypes.h @@ -81,6 +81,17 @@ union QWORD_UNION typedef SDWORD fixed_t; typedef DWORD dsfixed_t; // fixedpt used by span drawer +struct fixedvec3 +{ + fixed_t x, y, z; +}; + +struct fixedvec2 +{ + fixed_t x, y; +}; + + #define FIXED_MAX (signed)(0x7fffffff) #define FIXED_MIN (signed)(0x80000000) diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 1d16af31f..ca9ddaf6e 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -69,6 +69,8 @@ #include "v_text.h" #include "p_lnspec.h" #include "v_video.h" +#include "r_utility.h" +#include "r_data/r_interpolate.h" extern FILE *Logfile; extern bool insave; diff --git a/src/d_net.cpp b/src/d_net.cpp index 00361053a..88b4372fb 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -60,6 +60,7 @@ #include "v_video.h" #include "p_spec.h" #include "hardware.h" +#include "r_utility.h" #include "intermission/intermission.h" EXTERN_CVAR (Int, disableautosave) diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index efc6d310e..d9c977670 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -73,6 +73,8 @@ #include "po_man.h" #include "autosegs.h" #include "v_video.h" +#include "textures.h" +#include "r_utility.h" #include "menu/menu.h" #include "intermission/intermission.h" diff --git a/src/doomtype.h b/src/doomtype.h index 92717e4c8..30fc1b65a 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -197,6 +197,41 @@ struct PalEntry #endif }; +class FArchive; +class PClassInventory; + +class FTextureID +{ + friend class FTextureManager; + friend FArchive &operator<< (FArchive &arc, FTextureID &tex); + friend FTextureID GetHUDIcon(PClassInventory *cls); + friend void R_InitSpriteDefs(); + +public: + FTextureID() throw() {} + bool isNull() const { return texnum == 0; } + bool isValid() const { return texnum > 0; } + bool Exists() const { return texnum >= 0; } + void SetInvalid() { texnum = -1; } + void SetNull() { texnum = 0; } + bool operator ==(const FTextureID &other) const { return texnum == other.texnum; } + bool operator !=(const FTextureID &other) const { return texnum != other.texnum; } + FTextureID operator +(int offset) throw(); + int GetIndex() const { return texnum; } // Use this only if you absolutely need the index! + + // The switch list needs these to sort the switches by texture index + int operator -(FTextureID other) const { return texnum - other.texnum; } + bool operator < (FTextureID other) const { return texnum < other.texnum; } + bool operator > (FTextureID other) const { return texnum > other.texnum; } + +protected: + FTextureID(int num) { texnum = num; } +private: + int texnum; +}; + + + // Screenshot buffer image data types enum ESSType { diff --git a/src/dsectoreffect.cpp b/src/dsectoreffect.cpp index 7bc9fc400..5a2760813 100644 --- a/src/dsectoreffect.cpp +++ b/src/dsectoreffect.cpp @@ -29,6 +29,7 @@ #include "r_data/r_interpolate.h" #include "statnums.h" #include "farchive.h" +#include "doomstat.h" IMPLEMENT_CLASS (DSectorEffect) diff --git a/src/dthinker.cpp b/src/dthinker.cpp index c186bb7cc..03f103ca6 100644 --- a/src/dthinker.cpp +++ b/src/dthinker.cpp @@ -39,6 +39,7 @@ #include "i_system.h" #include "doomerrors.h" #include "farchive.h" +#include "d_player.h" static cycle_t ThinkCycles; diff --git a/src/fragglescript/t_cmd.cpp b/src/fragglescript/t_cmd.cpp index 74f366357..0e621119c 100644 --- a/src/fragglescript/t_cmd.cpp +++ b/src/fragglescript/t_cmd.cpp @@ -47,6 +47,7 @@ #include "sc_man.h" #include "g_level.h" #include "r_renderer.h" +#include "d_player.h" //========================================================================== // diff --git a/src/g_doom/a_doommisc.cpp b/src/g_doom/a_doommisc.cpp index 6d64bc6b6..8819270b0 100644 --- a/src/g_doom/a_doommisc.cpp +++ b/src/g_doom/a_doommisc.cpp @@ -1,6 +1,7 @@ #include "actor.h" #include "info.h" #include "p_local.h" +#include "p_spec.h" #include "a_sharedglobal.h" #include "m_random.h" #include "gi.h" @@ -15,6 +16,9 @@ #include "m_bbox.h" #include "farchive.h" #include "portal.h" +#include "d_player.h" +#include "p_maputl.h" +#include "g_shared/a_pickups.h" // Include all the other Doom stuff here to reduce compile time #include "a_arachnotron.cpp" diff --git a/src/g_game.cpp b/src/g_game.cpp index 865e50c23..5f30af97b 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -80,6 +80,9 @@ #include "m_joy.h" #include "farchive.h" #include "r_renderer.h" +#include "r_utility.h" +#include "a_morph.h" +#include "p_spec.h" #include "r_data/colormaps.h" #include diff --git a/src/g_heretic/a_hereticmisc.cpp b/src/g_heretic/a_hereticmisc.cpp index 91499bd68..ebcb957e5 100644 --- a/src/g_heretic/a_hereticmisc.cpp +++ b/src/g_heretic/a_hereticmisc.cpp @@ -15,6 +15,8 @@ #include "r_data/r_translate.h" #include "doomstat.h" #include "farchive.h" +#include "d_player.h" +#include "a_morph.h" // Include all the other Heretic stuff here to reduce compile time #include "a_chicken.cpp" diff --git a/src/g_hexen/a_hexenmisc.cpp b/src/g_hexen/a_hexenmisc.cpp index 1141f381f..70bc3fb1e 100644 --- a/src/g_hexen/a_hexenmisc.cpp +++ b/src/g_hexen/a_hexenmisc.cpp @@ -20,6 +20,10 @@ #include "farchive.h" #include "v_palette.h" #include "g_game.h" +#include "p_blockmap.h" +#include "r_utility.h" +#include "p_maputl.h" +#include "p_spec.h" // Include all the Hexen stuff here to reduce compile time #include "a_bats.cpp" diff --git a/src/g_level.cpp b/src/g_level.cpp index e8bf16004..5f305e5df 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -83,6 +83,8 @@ #include "r_data/colormaps.h" #include "farchive.h" #include "r_renderer.h" +#include "r_utility.h" +#include "p_spec.h" #include "gi.h" diff --git a/src/g_raven/a_artitele.cpp b/src/g_raven/a_artitele.cpp index da71c31c8..7ae32b573 100644 --- a/src/g_raven/a_artitele.cpp +++ b/src/g_raven/a_artitele.cpp @@ -3,11 +3,14 @@ #include "a_artifacts.h" #include "gstrings.h" #include "p_local.h" +#include "p_spec.h" #include "gi.h" #include "s_sound.h" #include "m_random.h" #include "doomstat.h" #include "g_game.h" +#include "d_player.h" +#include "a_morph.h" static FRandom pr_tele ("TeleportSelf"); diff --git a/src/g_raven/a_minotaur.cpp b/src/g_raven/a_minotaur.cpp index 14757c43b..038878204 100644 --- a/src/g_raven/a_minotaur.cpp +++ b/src/g_raven/a_minotaur.cpp @@ -12,6 +12,8 @@ #include "g_level.h" #include "doomstat.h" #include "farchive.h" +#include "a_pickups.h" +#include "d_player.h" #define MAULATORTICS (25*35) diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 992e97cef..997f68579 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -20,6 +20,8 @@ #include "doomstat.h" #include "v_palette.h" #include "farchive.h" +#include "r_utility.h" + #include "r_data/colormaps.h" static FRandom pr_torch ("Torch"); diff --git a/src/g_shared/a_fastprojectile.cpp b/src/g_shared/a_fastprojectile.cpp index 4f103be57..5ecec1827 100644 --- a/src/g_shared/a_fastprojectile.cpp +++ b/src/g_shared/a_fastprojectile.cpp @@ -4,6 +4,7 @@ #include "g_level.h" #include "r_sky.h" #include "p_lnspec.h" +#include "b_bot.h" IMPLEMENT_CLASS(AFastProjectile) diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 2aa52ae4f..eb9f2e300 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -13,6 +13,7 @@ #include "g_level.h" #include "farchive.h" #include "p_enemy.h" +#include "d_player.h" static FRandom pr_morphmonst ("MorphMonster"); diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 4a73212aa..32a4167bb 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -19,6 +19,8 @@ #include "g_game.h" #include "doomstat.h" #include "farchive.h" +#include "d_player.h" +#include "p_spec.h" static FRandom pr_restore ("RestorePos"); diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index 94a375d3e..eac736f8b 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -9,6 +9,8 @@ #include "a_sharedglobal.h" #include "statnums.h" #include "farchive.h" +#include "d_player.h" +#include "r_utility.h" static FRandom pr_quake ("Quake"); diff --git a/src/g_shared/a_randomspawner.cpp b/src/g_shared/a_randomspawner.cpp index acadbe6da..42eccacca 100644 --- a/src/g_shared/a_randomspawner.cpp +++ b/src/g_shared/a_randomspawner.cpp @@ -16,6 +16,8 @@ #include "a_action.h" #include "thingdef/thingdef.h" #include "v_text.h" +#include "doomstat.h" +#include "doomdata.h" #define MAX_RANDOMSPAWNERS_RECURSION 32 // Should be largely more than enough, honestly. static FRandom pr_randomspawn("RandomSpawn"); diff --git a/src/g_shared/a_specialspot.cpp b/src/g_shared/a_specialspot.cpp index 2a97949f3..de72787a3 100644 --- a/src/g_shared/a_specialspot.cpp +++ b/src/g_shared/a_specialspot.cpp @@ -40,6 +40,7 @@ #include "thingdef/thingdef.h" #include "doomstat.h" #include "farchive.h" +#include "a_pickups.h" static FRandom pr_spot ("SpecialSpot"); static FRandom pr_spawnmace ("SpawnMace"); diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 349c1e9c5..97204cc63 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -50,6 +50,8 @@ #include "doomstat.h" #include "g_level.h" #include "d_net.h" +#include "d_player.h" +#include "r_utility.h" #include diff --git a/src/info.cpp b/src/info.cpp index d827cd7a0..0f3da5d78 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -35,6 +35,7 @@ */ +#include "doomstat.h" #include "info.h" #include "m_fixed.h" #include "c_dispatch.h" @@ -51,6 +52,8 @@ #include "cmdlib.h" #include "g_level.h" #include "stats.h" +#include "thingdef.h" +#include "d_player.h" extern void LoadActors (); extern void InitBotStuff(); diff --git a/src/m_bbox.cpp b/src/m_bbox.cpp index c73f47bc4..f7827ef72 100644 --- a/src/m_bbox.cpp +++ b/src/m_bbox.cpp @@ -26,6 +26,7 @@ #include "m_bbox.h" #include "p_local.h" +#include "p_maputl.h" //========================================================================== // diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index c6bb677b5..aa539f96b 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -46,6 +46,8 @@ #include "d_dehacked.h" #include "gi.h" #include "farchive.h" +#include "r_utility.h" +#include "a_morph.h" // [RH] Actually handle the cheat. The cheat code in st_stuff.c now just // writes some bytes to the network data stream, and the network code diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 0df3b2ebd..61c4564b9 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -38,10 +38,14 @@ #include "templates.h" #include "p_local.h" #include "p_lnspec.h" +#include "p_maputl.h" #include "w_wad.h" #include "sc_man.h" #include "g_level.h" #include "p_terrain.h" +#include "d_player.h" +#include "r_utility.h" +#include "p_spec.h" #include "r_data/colormaps.h" //========================================================================== diff --git a/src/p_3dmidtex.cpp b/src/p_3dmidtex.cpp index 5d5ba56d8..1c4ba7b7c 100644 --- a/src/p_3dmidtex.cpp +++ b/src/p_3dmidtex.cpp @@ -38,6 +38,8 @@ #include "templates.h" #include "p_local.h" #include "p_terrain.h" +#include "p_maputl.h" +#include "p_spec.h" //============================================================================ diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 070111d7b..7155c98e6 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -40,6 +40,7 @@ #include "templates.h" #include "doomdef.h" #include "p_local.h" +#include "d_player.h" #include "p_spec.h" #include "g_level.h" #include "s_sound.h" @@ -79,6 +80,8 @@ #include "p_terrain.h" #include "version.h" #include "p_effect.h" +#include "r_utility.h" +#include "a_morph.h" #include "g_shared/a_pickups.h" diff --git a/src/p_blockmap.h b/src/p_blockmap.h new file mode 100644 index 000000000..0380b9da7 --- /dev/null +++ b/src/p_blockmap.h @@ -0,0 +1,33 @@ +#ifndef __P_BLOCKMAP_H +#define __P_BLOCKMAP_H + +#include "doomtype.h" + +class AActor; + +// [RH] Like msecnode_t, but for the blockmap +struct FBlockNode +{ + AActor *Me; // actor this node references + int BlockIndex; // index into blocklinks for the block this node is in + FBlockNode **PrevActor; // previous actor in this block + FBlockNode *NextActor; // next actor in this block + FBlockNode **PrevBlock; // previous block this actor is in + FBlockNode *NextBlock; // next block this actor is in + + static FBlockNode *Create (AActor *who, int x, int y); + void Release (); + + static FBlockNode *FreeBlocks; +}; + +extern int* blockmaplump; // offsets in blockmap are from here + +extern int* blockmap; +extern int bmapwidth; +extern int bmapheight; // in mapblocks +extern fixed_t bmaporgx; +extern fixed_t bmaporgy; // origin of block map +extern FBlockNode** blocklinks; // for thing chains + +#endif diff --git a/src/p_doors.cpp b/src/p_doors.cpp index 7ed607e19..16d12be9d 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -36,6 +36,8 @@ #include "sc_man.h" #include "cmdlib.h" #include "farchive.h" +#include "d_player.h" +#include "p_spec.h" //============================================================================ // diff --git a/src/p_effect.cpp b/src/p_effect.cpp index c02e3a97b..ffd1f303c 100644 --- a/src/p_effect.cpp +++ b/src/p_effect.cpp @@ -51,6 +51,8 @@ #include "gi.h" #include "v_palette.h" #include "colormatcher.h" +#include "d_player.h" +#include "r_utility.h" CVAR (Int, cl_rockettrails, 1, CVAR_ARCHIVE); CVAR (Bool, r_rail_smartspiral, 0, CVAR_ARCHIVE); diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index eaf729771..16f632409 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -31,6 +31,8 @@ #include "i_system.h" #include "doomdef.h" #include "p_local.h" +#include "p_maputl.h" +#include "d_player.h" #include "m_bbox.h" #include "p_lnspec.h" #include "s_sound.h" @@ -44,8 +46,11 @@ #include "thingdef/thingdef.h" #include "d_dehacked.h" #include "g_level.h" +#include "r_utility.h" +#include "p_blockmap.h" #include "r_data/r_translate.h" #include "teaminfo.h" +#include "p_spec.h" #include "gi.h" diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index b8e3eb5c6..ea39844e0 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -65,6 +65,8 @@ #include "version.h" #include "md5.h" #include "m_misc.h" +#include "r_utility.h" +#include "cmdlib.h" void P_GetPolySpots (MapData * lump, TArray &spots, TArray &anchors); diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index dba66ca9b..98d08832e 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -58,6 +58,7 @@ #include "g_level.h" #include "d_net.h" #include "d_netinf.h" +#include "a_morph.h" static FRandom pr_obituary ("Obituary"); static FRandom pr_botrespawn ("BotRespawn"); diff --git a/src/p_lights.cpp b/src/p_lights.cpp index 656b86112..9c5202cdf 100644 --- a/src/p_lights.cpp +++ b/src/p_lights.cpp @@ -27,8 +27,10 @@ #include "doomdef.h" #include "p_local.h" +#include "p_spec.h" #include "p_lnspec.h" +#include "doomstat.h" // State. #include "r_state.h" diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 0061fd5dc..1e45c0fe5 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -58,8 +58,12 @@ #include "d_event.h" #include "gstrings.h" #include "portal.h" +#include "po_man.h" +#include "d_player.h" +#include "r_utility.h" #include "r_data/colormaps.h" #include "fragglescript/t_fs.h" +#include "p_spec.h" // Remaps EE sector change types to Generic_Floor values. According to the Eternity Wiki: /* diff --git a/src/p_local.h b/src/p_local.h index 9030a0736..5a173ea41 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -24,13 +24,19 @@ #define __P_LOCAL__ #include "doomtype.h" -#include "doomdef.h" #include "tables.h" -#include "r_state.h" -#include "r_utility.h" -#include "d_player.h" -#include "a_morph.h" +class player_t; +class AActor; +struct FPlayerStart; +class PClassActor; +struct fixedvec3; +class APlayerPawn; +struct line_t; +struct sector_t; +struct msecnode_t; +struct secplane_t; + #include @@ -119,7 +125,7 @@ void P_PredictionLerpReset(); #define SPF_TEMPPLAYER 1 // spawning a short-lived dummy player #define SPF_WEAPONFULLYUP 2 // spawn with weapon already raised -APlayerPawn *P_SpawnPlayer (struct FPlayerStart *mthing, int playernum, int flags=0); +APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags=0); void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move); int P_FaceMobj (AActor *source, AActor *target, angle_t *delta); @@ -221,200 +227,6 @@ enum WARPF -// -// P_MAPUTL -// -struct divline_t -{ - fixed_t x; - fixed_t y; - fixed_t dx; - fixed_t dy; - -}; - -struct intercept_t -{ - fixed_t frac; // along trace line - bool isaline; - bool done; - union { - AActor *thing; - line_t *line; - } d; -}; - -typedef bool (*traverser_t) (intercept_t *in); - -fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); - -//========================================================================== -// -// P_PointOnLineSide -// -// Returns 0 (front/on) or 1 (back) -// [RH] inlined, stripped down, and made more precise -// -//========================================================================== - -inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) -{ - extern int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line); - - return i_compatflags2 & COMPATF2_POINTONLINE - ? P_VanillaPointOnLineSide(x, y, line) - : DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; -} - -inline int P_PointOnLineSidePrecise (fixed_t x, fixed_t y, const line_t *line) -{ - return DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; -} - - -//========================================================================== -// -// P_PointOnDivlineSide -// -// Same as P_PointOnLineSide except it uses divlines -// [RH] inlined, stripped down, and made more precise -// -//========================================================================== - -inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line) -{ - extern int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line); - - return (i_compatflags2 & COMPATF2_POINTONLINE) - ? P_VanillaPointOnDivlineSide(x, y, line) - : (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0); -} - -inline int P_PointOnDivlineSidePrecise (fixed_t x, fixed_t y, const divline_t *line) -{ - return DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0; -} - - -//========================================================================== -// -// P_MakeDivline -// -//========================================================================== - -inline void P_MakeDivline (const line_t *li, divline_t *dl) -{ - dl->x = li->v1->x; - dl->y = li->v1->y; - dl->dx = li->dx; - dl->dy = li->dy; -} - -fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1); - -struct FLineOpening -{ - fixed_t top; - fixed_t bottom; - fixed_t range; - fixed_t lowfloor; - sector_t *bottomsec; - sector_t *topsec; - FTextureID ceilingpic; - FTextureID floorpic; - int floorterrain; - bool touchmidtex; - bool abovemidtex; -}; - -void P_LineOpening (FLineOpening &open, AActor *thing, const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx=FIXED_MIN, fixed_t refy=0, int flags=0); - -class FBoundingBox; -struct polyblock_t; - -class FBlockLinesIterator -{ - int minx, maxx; - int miny, maxy; - - int curx, cury; - polyblock_t *polyLink; - int polyIndex; - int *list; - - void StartBlock(int x, int y); - -public: - FBlockLinesIterator(int minx, int miny, int maxx, int maxy, bool keepvalidcount = false); - FBlockLinesIterator(const FBoundingBox &box); - line_t *Next(); - void Reset() { StartBlock(minx, miny); } -}; - -class FBlockThingsIterator -{ - int minx, maxx; - int miny, maxy; - - int curx, cury; - - FBlockNode *block; - - int Buckets[32]; - - struct HashEntry - { - AActor *Actor; - int Next; - }; - HashEntry FixedHash[10]; - int NumFixedHash; - TArray DynHash; - - HashEntry *GetHashEntry(int i) { return i < (int)countof(FixedHash) ? &FixedHash[i] : &DynHash[i - countof(FixedHash)]; } - - void StartBlock(int x, int y); - void SwitchBlock(int x, int y); - void ClearHash(); - - // The following is only for use in the path traverser - // and therefore declared private. - FBlockThingsIterator(); - - friend class FPathTraverse; - -public: - FBlockThingsIterator(int minx, int miny, int maxx, int maxy); - FBlockThingsIterator(const FBoundingBox &box); - AActor *Next(bool centeronly = false); - void Reset() { StartBlock(minx, miny); } -}; - -class FPathTraverse -{ - static TArray intercepts; - - divline_t trace; - unsigned int intercept_index; - unsigned int intercept_count; - unsigned int count; - - void AddLineIntercepts(int bx, int by); - void AddThingIntercepts(int bx, int by, FBlockThingsIterator &it, bool compatible); -public: - - intercept_t *Next(); - - FPathTraverse(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags); - ~FPathTraverse(); - const divline_t &Trace() const { return trace; } -}; - - -#define PT_ADDLINES 1 -#define PT_ADDTHINGS 2 -#define PT_COMPATIBLE 4 -#define PT_DELTA 8 // x2,y2 is passed as a delta, not as an endpoint AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, int, void *), void *params = NULL); AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false); @@ -451,6 +263,8 @@ struct FCheckPosition // ripping damage once per tic instead of once per move. bool DoRipping; TMap LastRipped; + + //FPortalGroupTable Groups; int PushTime; FCheckPosition(bool rip=false) @@ -539,7 +353,6 @@ enum // P_LineAttack flags AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL); AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL); -AActor *P_LinePickActor (AActor *t1, angle_t angle, fixed_t distance, int pitch, ActorFlags actorMask, DWORD wallMask); void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch); void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch); void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version @@ -587,31 +400,10 @@ bool Check_Sides(AActor *, int, int); // phares // [RH] const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymove); -//---------------------------------------------------------------------------------- -// -// Added so that in the source there's a clear distinction between -// game engine and renderer specific calls. -// (For ZDoom itself this doesn't make any difference here but for GZDoom it does.) -// -//---------------------------------------------------------------------------------- -subsector_t *P_PointInSubsector (fixed_t x, fixed_t y); -inline sector_t *P_PointInSector(fixed_t x, fixed_t y) -{ - return P_PointInSubsector(x,y)->sector; -} - // // P_SETUP // extern BYTE* rejectmatrix; // for fast sight rejection -extern int* blockmaplump; // offsets in blockmap are from here - -extern int* blockmap; -extern int bmapwidth; -extern int bmapheight; // in mapblocks -extern fixed_t bmaporgx; -extern fixed_t bmaporgy; // origin of block map -extern FBlockNode** blocklinks; // for thing chains @@ -639,46 +431,9 @@ enum EDmgFlags }; -// ===== PO_MAN ===== - -typedef enum -{ - PODOOR_NONE, - PODOOR_SLIDE, - PODOOR_SWING, -} podoortype_t; - -bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, int direction, bool overRide); -bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle, fixed_t dist, bool overRide); -bool EV_MovePolyTo (line_t *line, int polyNum, int speed, fixed_t x, fixed_t y, bool overRide); -bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle, int delay, int distance, podoortype_t type); -bool EV_StopPoly (int polyNum); - - -// [RH] Data structure for P_SpawnMapThing() to keep track -// of polyobject-related things. -struct polyspawns_t -{ - polyspawns_t *next; - fixed_t x; - fixed_t y; - short angle; - short type; -}; - -extern int po_NumPolyobjs; -extern polyspawns_t *polyspawns; // [RH] list of polyobject things to spawn - - -void PO_Init (); -bool PO_Busy (int polyobj); -FPolyObj *PO_GetPolyobj(int polyNum); - // // P_SPEC // -#include "p_spec.h" - bool P_AlignFlat (int linenum, int side, int fc); #endif // __P_LOCAL__ diff --git a/src/p_map.cpp b/src/p_map.cpp index 0e3cb6617..8e958cf8b 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -34,10 +34,14 @@ #include "doomdef.h" #include "p_local.h" +#include "p_spec.h" +#include "d_player.h" +#include "p_maputl.h" #include "p_lnspec.h" #include "p_effect.h" #include "p_terrain.h" #include "p_trace.h" +#include "r_utility.h" #include "s_sound.h" #include "decallib.h" diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index e5bb2bea2..7df43f1c8 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -32,9 +32,13 @@ #include "m_bbox.h" #include "doomdef.h" +#include "doomdata.h" #include "doomstat.h" #include "p_local.h" +#include "p_maputl.h" #include "p_3dmidtex.h" +#include "p_blockmap.h" +#include "r_utility.h" // State. #include "r_state.h" diff --git a/src/p_maputl.h b/src/p_maputl.h new file mode 100644 index 000000000..dbc4eaf9a --- /dev/null +++ b/src/p_maputl.h @@ -0,0 +1,208 @@ +#ifndef __P_MAPUTL_H +#define __P_MAPUTL_H + +#include "r_defs.h" +#include "doomstat.h" + +extern int validcount; + +struct divline_t +{ + fixed_t x; + fixed_t y; + fixed_t dx; + fixed_t dy; +}; + +struct intercept_t +{ + fixed_t frac; // along trace line + bool isaline; + bool done; + union { + AActor *thing; + line_t *line; + } d; +}; + + +//========================================================================== +// +// P_PointOnLineSide +// +// Returns 0 (front/on) or 1 (back) +// [RH] inlined, stripped down, and made more precise +// +//========================================================================== + +inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) +{ + extern int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line); + + return i_compatflags2 & COMPATF2_POINTONLINE + ? P_VanillaPointOnLineSide(x, y, line) + : DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; +} + +inline int P_PointOnLineSidePrecise (fixed_t x, fixed_t y, const line_t *line) +{ + return DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; +} + + +//========================================================================== +// +// P_PointOnDivlineSide +// +// Same as P_PointOnLineSide except it uses divlines +// [RH] inlined, stripped down, and made more precise +// +//========================================================================== + +inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line) +{ + extern int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line); + + return (i_compatflags2 & COMPATF2_POINTONLINE) + ? P_VanillaPointOnDivlineSide(x, y, line) + : (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0); +} + +inline int P_PointOnDivlineSidePrecise (fixed_t x, fixed_t y, const divline_t *line) +{ + return DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0; +} + + +//========================================================================== +// +// P_MakeDivline +// +//========================================================================== + +inline void P_MakeDivline (const line_t *li, divline_t *dl) +{ + dl->x = li->v1->x; + dl->y = li->v1->y; + dl->dx = li->dx; + dl->dy = li->dy; +} + +struct FLineOpening +{ + fixed_t top; + fixed_t bottom; + fixed_t range; + fixed_t lowfloor; + sector_t *bottomsec; + sector_t *topsec; + FTextureID ceilingpic; + FTextureID floorpic; + int floorterrain; + bool touchmidtex; + bool abovemidtex; +}; + +void P_LineOpening (FLineOpening &open, AActor *thing, const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx=FIXED_MIN, fixed_t refy=0, int flags=0); + +class FBoundingBox; +struct polyblock_t; + +class FBlockLinesIterator +{ + int minx, maxx; + int miny, maxy; + + int curx, cury; + polyblock_t *polyLink; + int polyIndex; + int *list; + + void StartBlock(int x, int y); + +public: + FBlockLinesIterator(int minx, int miny, int maxx, int maxy, bool keepvalidcount = false); + FBlockLinesIterator(const FBoundingBox &box); + line_t *Next(); + void Reset() { StartBlock(minx, miny); } +}; + +class FBlockThingsIterator +{ + int minx, maxx; + int miny, maxy; + + int curx, cury; + + FBlockNode *block; + + int Buckets[32]; + + struct HashEntry + { + AActor *Actor; + int Next; + }; + HashEntry FixedHash[10]; + int NumFixedHash; + TArray DynHash; + + HashEntry *GetHashEntry(int i) { return i < (int)countof(FixedHash) ? &FixedHash[i] : &DynHash[i - countof(FixedHash)]; } + + void StartBlock(int x, int y); + void SwitchBlock(int x, int y); + void ClearHash(); + + // The following is only for use in the path traverser + // and therefore declared private. + FBlockThingsIterator(); + + friend class FPathTraverse; + +public: + FBlockThingsIterator(int minx, int miny, int maxx, int maxy); + FBlockThingsIterator(const FBoundingBox &box); + AActor *Next(bool centeronly = false); + void Reset() { StartBlock(minx, miny); } +}; + +class FPathTraverse +{ + static TArray intercepts; + + divline_t trace; + unsigned int intercept_index; + unsigned int intercept_count; + unsigned int count; + + void AddLineIntercepts(int bx, int by); + void AddThingIntercepts(int bx, int by, FBlockThingsIterator &it, bool compatible); +public: + + intercept_t *Next(); + + FPathTraverse(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags); + ~FPathTraverse(); + const divline_t &Trace() const { return trace; } +}; + + + +// +// P_MAPUTL +// + +typedef bool(*traverser_t) (intercept_t *in); + +fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); + + +fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1); + +#define PT_ADDLINES 1 +#define PT_ADDTHINGS 2 +#define PT_COMPATIBLE 4 +#define PT_DELTA 8 // x2,y2 is passed as a delta, not as an endpoint + + +#endif \ No newline at end of file diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 658fcbc69..0910ac719 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -29,6 +29,7 @@ #include "m_random.h" #include "doomdef.h" #include "p_local.h" +#include "p_maputl.h" #include "p_lnspec.h" #include "p_effect.h" #include "p_terrain.h" @@ -66,6 +67,8 @@ #include "farchive.h" #include "r_data/colormaps.h" #include "r_renderer.h" +#include "po_man.h" +#include "p_spec.h" // MACROS ------------------------------------------------------------------ diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index e7b32bb23..a72c9d897 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -34,8 +34,10 @@ #include "i_system.h" #include "p_local.h" +#include "p_spec.h" // State. +#include "d_player.h" #include "dobject.h" #include "doomstat.h" #include "r_state.h" diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 746e50e40..c5780e912 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -29,6 +29,7 @@ #endif #include "templates.h" +#include "d_player.h" #include "m_argv.h" #include "m_swap.h" #include "m_bbox.h" @@ -69,6 +70,9 @@ #include "r_renderer.h" #include "r_data/colormaps.h" #include "portal.h" +#include "p_blockmap.h" +#include "r_utility.h" +#include "p_spec.h" #ifndef NO_EDATA #include "edata.h" #endif diff --git a/src/p_sight.cpp b/src/p_sight.cpp index b007410c8..e92380058 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -14,11 +14,16 @@ #include "doomdef.h" #include "i_system.h" #include "p_local.h" +#include "p_maputl.h" +#include "p_blockmap.h" #include "m_random.h" #include "m_bbox.h" #include "p_lnspec.h" #include "g_level.h" #include "po_man.h" +#include "r_utility.h" +#include "b_bot.h" +#include "p_spec.h" // State. #include "r_state.h" diff --git a/src/p_slopes.cpp b/src/p_slopes.cpp index 3e402f73a..bf6f1738c 100644 --- a/src/p_slopes.cpp +++ b/src/p_slopes.cpp @@ -36,6 +36,8 @@ #include "p_local.h" #include "cmdlib.h" #include "p_lnspec.h" +#include "p_maputl.h" +#include "p_spec.h" //=========================================================================== // diff --git a/src/p_spec.cpp b/src/p_spec.cpp index b010165b1..45ed51be2 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -46,6 +46,8 @@ #include "w_wad.h" #include "p_local.h" +#include "p_spec.h" +#include "p_blockmap.h" #include "p_lnspec.h" #include "p_terrain.h" #include "p_acs.h" @@ -64,7 +66,10 @@ #include "a_keys.h" #include "c_dispatch.h" #include "r_sky.h" +#include "d_player.h" #include "portal.h" +#include "p_maputl.h" +#include "p_blockmap.h" #ifndef NO_EDATA #include "edata.h" #endif diff --git a/src/p_switch.cpp b/src/p_switch.cpp index 1ae0c43ea..0c9d37ccc 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -47,6 +47,8 @@ #include "tarray.h" #include "cmdlib.h" #include "farchive.h" +#include "p_maputl.h" +#include "p_spec.h" #include "gi.h" diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index a6dcbf7f3..b7f9c4fd5 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -34,6 +34,10 @@ #include "m_random.h" #include "i_system.h" #include "doomstat.h" +#include "d_player.h" +#include "p_maputl.h" +#include "r_utility.h" +#include "p_spec.h" #define FUDGEFACTOR 10 diff --git a/src/p_things.cpp b/src/p_things.cpp index 14ca85aa3..1c8a4a46d 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -47,6 +47,9 @@ #include "g_level.h" #include "v_text.h" #include "i_system.h" +#include "d_player.h" +#include "r_utility.h" +#include "p_spec.h" // Set of spawnable things for the Thing_Spawn and Thing_Projectile specials. FClassMap SpawnableThings; diff --git a/src/p_tick.cpp b/src/p_tick.cpp index 44fe88110..29b2cd4ad 100644 --- a/src/p_tick.cpp +++ b/src/p_tick.cpp @@ -31,7 +31,10 @@ #include "sbar.h" #include "r_data/r_interpolate.h" #include "i_sound.h" +#include "d_player.h" #include "g_level.h" +#include "r_utility.h" +#include "p_spec.h" extern gamestate_t wipegamestate; diff --git a/src/p_trace.cpp b/src/p_trace.cpp index 619a61361..929f284b1 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -37,6 +37,9 @@ #include "i_system.h" #include "r_sky.h" #include "doomstat.h" +#include "p_maputl.h" +#include "r_defs.h" +#include "p_spec.h" struct FTraceInfo { diff --git a/src/p_user.cpp b/src/p_user.cpp index d5f89576b..529420347 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -54,6 +54,11 @@ #include "gstrings.h" #include "farchive.h" #include "r_renderer.h" +#include "d_player.h" +#include "r_utility.h" +#include "p_blockmap.h" +#include "a_morph.h" +#include "p_spec.h" static FRandom pr_skullpop ("SkullPop"); diff --git a/src/p_writemap.cpp b/src/p_writemap.cpp index 8f1a4edfa..c442fc0d9 100644 --- a/src/p_writemap.cpp +++ b/src/p_writemap.cpp @@ -5,6 +5,8 @@ #include "r_defs.h" #include "m_swap.h" #include "doomstat.h" +#include "d_player.h" +#include "p_spec.h" static int WriteTHINGS (FILE *file); static int WriteLINEDEFS (FILE *file); diff --git a/src/po_man.cpp b/src/po_man.cpp index a0cc4487b..7cfa3cf1b 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -29,6 +29,9 @@ #include "p_setup.h" #include "vectors.h" #include "farchive.h" +#include "p_blockmap.h" +#include "p_maputl.h" +#include "r_utility.h" // MACROS ------------------------------------------------------------------ diff --git a/src/po_man.h b/src/po_man.h index 9e81cc266..08ac465e3 100644 --- a/src/po_man.h +++ b/src/po_man.h @@ -107,4 +107,40 @@ FArchive &operator<< (FArchive &arc, FPolyObj *&poly); FArchive &operator<< (FArchive &arc, const FPolyObj *&poly); +// ===== PO_MAN ===== + +typedef enum +{ + PODOOR_NONE, + PODOOR_SLIDE, + PODOOR_SWING, +} podoortype_t; + +bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, int direction, bool overRide); +bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle, fixed_t dist, bool overRide); +bool EV_MovePolyTo (line_t *line, int polyNum, int speed, fixed_t x, fixed_t y, bool overRide); +bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle, int delay, int distance, podoortype_t type); +bool EV_StopPoly (int polyNum); + + +// [RH] Data structure for P_SpawnMapThing() to keep track +// of polyobject-related things. +struct polyspawns_t +{ + polyspawns_t *next; + fixed_t x; + fixed_t y; + short angle; + short type; +}; + +extern int po_NumPolyobjs; +extern polyspawns_t *polyspawns; // [RH] list of polyobject things to spawn + + +void PO_Init (); +bool PO_Busy (int polyobj); +FPolyObj *PO_GetPolyobj(int polyNum); + + #endif \ No newline at end of file diff --git a/src/portal.cpp b/src/portal.cpp index 1ce6a630d..e24e045eb 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -11,6 +11,8 @@ #include "a_sharedglobal.h" #include "i_system.h" #include "c_dispatch.h" +#include "p_maputl.h" +#include "p_spec.h" // simulation recurions maximum CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO) diff --git a/src/r_defs.h b/src/r_defs.h index 7339b26ae..6913d868b 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -1153,4 +1153,17 @@ struct visstyle_t }; +//---------------------------------------------------------------------------------- +// +// The playsim can use different nodes than the renderer so this is +// not the same as R_PointInSubsector +// +//---------------------------------------------------------------------------------- +subsector_t *P_PointInSubsector(fixed_t x, fixed_t y); +inline sector_t *P_PointInSector(fixed_t x, fixed_t y) +{ + return P_PointInSubsector(x, y)->sector; +} + + #endif diff --git a/src/r_things.cpp b/src/r_things.cpp index 1179c7291..1fb4c845b 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -63,6 +63,7 @@ #include "r_data/colormaps.h" #include "r_data/voxels.h" #include "p_local.h" +#include "p_maputl.h" // [RH] A c-buffer. Used for keeping track of offscreen voxel spans. diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 794c30d4c..bcba624e1 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -55,6 +55,8 @@ #include "r_renderer.h" #include "r_data/colormaps.h" #include "farchive.h" +#include "r_utility.h" +#include "d_player.h" // EXTERNAL DATA DECLARATIONS ---------------------------------------------- diff --git a/src/s_sndseq.cpp b/src/s_sndseq.cpp index cf2957885..4a5bfa25e 100644 --- a/src/s_sndseq.cpp +++ b/src/s_sndseq.cpp @@ -28,6 +28,7 @@ #include "c_dispatch.h" #include "g_level.h" #include "farchive.h" +#include "d_player.h" // MACROS ------------------------------------------------------------------ diff --git a/src/s_sound.cpp b/src/s_sound.cpp index dabed23f6..e61a0f701 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -51,6 +51,7 @@ #include "g_level.h" #include "po_man.h" #include "farchive.h" +#include "d_player.h" // MACROS ------------------------------------------------------------------ diff --git a/src/textures/textures.h b/src/textures/textures.h index 157f8555f..b5f3364cd 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -14,36 +14,6 @@ class FArchive; class FTextureManager; class FTerrainTypeArray; -class FTextureID -{ - friend class FTextureManager; - friend FArchive &operator<< (FArchive &arc, FTextureID &tex); - friend FTextureID GetHUDIcon(PClassInventory *cls); - friend void R_InitSpriteDefs (); - -public: - FTextureID() throw() {} - bool isNull() const { return texnum == 0; } - bool isValid() const { return texnum > 0; } - bool Exists() const { return texnum >= 0; } - void SetInvalid() { texnum = -1; } - void SetNull() { texnum = 0; } - bool operator ==(const FTextureID &other) const { return texnum == other.texnum; } - bool operator !=(const FTextureID &other) const { return texnum != other.texnum; } - FTextureID operator +(int offset) throw(); - int GetIndex() const { return texnum; } // Use this only if you absolutely need the index! - - // The switch list needs these to sort the switches by texture index - int operator -(FTextureID other) const { return texnum - other.texnum; } - bool operator < (FTextureID other) const { return texnum < other.texnum; } - bool operator > (FTextureID other) const { return texnum > other.texnum; } - -protected: - FTextureID(int num) { texnum = num; } -private: - int texnum; -}; - class FNullTextureID : public FTextureID { public: diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index e4744c8b4..4b9bb77de 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -73,6 +73,9 @@ #include "p_trace.h" #include "p_setup.h" #include "gstrings.h" +#include "d_player.h" +#include "p_maputl.h" +#include "p_spec.h" AActor *SingleActorFromTID(int tid, AActor *defactor); From afc631b537deff3593fa7b99190cb7b907be5c20 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 15 Feb 2016 09:25:48 +0100 Subject: [PATCH 05/10] - this wasn't saved for last night's commit. --- src/fragglescript/t_func.cpp | 1 + src/g_shared/a_decals.cpp | 1 + src/g_strife/a_strifestuff.cpp | 1 + src/p_buildmap.cpp | 1 + src/p_ceiling.cpp | 1 + src/p_floor.cpp | 1 + src/p_linkedsectors.cpp | 1 + src/p_plats.cpp | 1 + 8 files changed, 8 insertions(+) diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 8be7f798d..e30c76326 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -68,6 +68,7 @@ #include "r_data/colormaps.h" #include "farchive.h" #include "p_setup.h" +#include "p_spec.h" static FRandom pr_script("FScript"); diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index 64921d647..ebefcdff0 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -45,6 +45,7 @@ #include "colormatcher.h" #include "v_palette.h" #include "farchive.h" +#include "doomdata.h" static fixed_t DecalWidth, DecalLeft, DecalRight; static fixed_t SpreadZ; diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index fc11ba433..724deaee2 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -19,6 +19,7 @@ #include "d_event.h" #include "v_font.h" #include "farchive.h" +#include "p_spec.h" // Include all the other Strife stuff here to reduce compile time #include "a_acolyte.cpp" diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 6705addd6..116c9ff6d 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -18,6 +18,7 @@ #include "r_data/colormaps.h" #include "gi.h" #include "portal.h" +#include "p_spec.h" // MACROS ------------------------------------------------------------------ diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index 24ab121c4..bd75fbee2 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -30,6 +30,7 @@ #include "r_state.h" #include "gi.h" #include "farchive.h" +#include "p_spec.h" //============================================================================ // diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 2a2926460..d91c05170 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -31,6 +31,7 @@ #include "tables.h" #include "farchive.h" #include "p_3dmidtex.h" +#include "p_spec.h" #include "r_data/r_interpolate.h" //========================================================================== diff --git a/src/p_linkedsectors.cpp b/src/p_linkedsectors.cpp index b9ef8b100..f1e199b2f 100644 --- a/src/p_linkedsectors.cpp +++ b/src/p_linkedsectors.cpp @@ -36,6 +36,7 @@ #include "templates.h" #include "p_local.h" #include "p_lnspec.h" +#include "p_spec.h" enum { diff --git a/src/p_plats.cpp b/src/p_plats.cpp index b0697fc34..83d7e101d 100644 --- a/src/p_plats.cpp +++ b/src/p_plats.cpp @@ -31,6 +31,7 @@ #include "r_state.h" #include "gi.h" #include "farchive.h" +#include "p_spec.h" static FRandom pr_doplat ("DoPlat"); From 5664cee2e59bcf6940dc8cfc21ebea5acfb4d3c4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 15 Feb 2016 12:35:40 +0100 Subject: [PATCH 06/10] - fixed: The check for leftover portal sectors was not correct. It only checked the sectors the portal thing was in and those were already processed in the first phase. - improved: If there's an offset mismatch, do not print group numbers as they are utterly meaningless. Instead look for a sector in each group and report those. - added a copyright notice and some comments to portals.cpp. --- src/portal.cpp | 166 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 157 insertions(+), 9 deletions(-) diff --git a/src/portal.cpp b/src/portal.cpp index e24e045eb..9c7c7b512 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -1,3 +1,42 @@ +/* +** portals.cpp +** Everything that has to do with portals (both of the line and sector variety) +** +**--------------------------------------------------------------------------- +** Copyright 2016 ZZYZX +** Copyright 2016 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** There is no code here that is directly taken from Eternity +** although some similarities may be inevitable because it has to +** implement the same concepts. +*/ + + #include "portal.h" #include "p_local.h" #include "p_lnspec.h" @@ -23,6 +62,12 @@ TArray linePortals; TArray linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups. +//============================================================================ +// +// Save a line portal for savegames. +// +//============================================================================ + FArchive &operator<< (FArchive &arc, FLinePortal &port) { arc << port.mOrigin @@ -37,6 +82,12 @@ FArchive &operator<< (FArchive &arc, FLinePortal &port) } +//============================================================================ +// +// finds the destination for a line portal for spawning +// +//============================================================================ + static line_t *FindDestination(line_t *src, int tag) { if (tag) @@ -55,6 +106,12 @@ static line_t *FindDestination(line_t *src, int tag) return NULL; } +//============================================================================ +// +// Spawns a single line portal +// +//============================================================================ + void P_SpawnLinePortal(line_t* line) { // portal destination is special argument #0 @@ -135,6 +192,12 @@ void P_SpawnLinePortal(line_t* line) } } +//============================================================================ +// +// Update a line portal's state after all have been spawned +// +//============================================================================ + void P_UpdatePortal(FLinePortal *port) { if (port->mDestination == NULL) @@ -171,6 +234,13 @@ void P_UpdatePortal(FLinePortal *port) } } +//============================================================================ +// +// Collect a separate list of linked portals so that these can be +// processed faster without the simpler types interfering. +// +//============================================================================ + void P_CollectLinkedPortals() { linkedPortals.Clear(); @@ -184,6 +254,12 @@ void P_CollectLinkedPortals() } } +//============================================================================ +// +// Post-process all line portals +// +//============================================================================ + void P_FinalizePortals() { for (unsigned i = 0; i < linePortals.Size(); i++) @@ -194,6 +270,12 @@ void P_FinalizePortals() P_CollectLinkedPortals(); } +//============================================================================ +// +// Change the destination of a portal +// +//============================================================================ + static bool ChangePortalLine(line_t *line, int destid) { if (line->portalindex >= linePortals.Size()) return false; @@ -224,6 +306,12 @@ static bool ChangePortalLine(line_t *line, int destid) } +//============================================================================ +// +// Change the destination of a group of portals +// +//============================================================================ + bool P_ChangePortal(line_t *ln, int thisid, int destid) { int lineno; @@ -238,7 +326,13 @@ bool P_ChangePortal(line_t *ln, int thisid, int destid) return res; } +//============================================================================ +// +// Calculate the intersection between two lines. // [ZZ] lots of floats here to avoid overflowing a lot +// +//============================================================================ + bool P_IntersectLines(fixed_t o1x, fixed_t o1y, fixed_t p1x, fixed_t p1y, fixed_t o2x, fixed_t o2y, fixed_t p2x, fixed_t p2y, fixed_t& rx, fixed_t& ry) @@ -278,9 +372,15 @@ inline int P_PointOnLineSideExplicit (fixed_t x, fixed_t y, fixed_t x1, fixed_t return DMulScale32 (y-y1, x2-x1, x1-x, y2-y1) > 0; } +//============================================================================ +// +// check if this line is between portal and the viewer. clip away if it is. +// (this may need some fixing) +// +//============================================================================ + bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t viewy, bool partial, bool samebehind) { - // check if this line is between portal and the viewer. clip away if it is. bool behind1 = !!P_PointOnLineSidePrecise(line->v1->x, line->v1->y, portal); bool behind2 = !!P_PointOnLineSidePrecise(line->v2->x, line->v2->y, portal); @@ -306,6 +406,12 @@ bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t vie return false; } +//============================================================================ +// +// Translates a coordinate by a portal's displacement +// +//============================================================================ + void P_TranslatePortalXY(line_t* src, line_t* dst, fixed_t& x, fixed_t& y) { if (!src || !dst) @@ -342,6 +448,12 @@ void P_TranslatePortalXY(line_t* src, line_t* dst, fixed_t& x, fixed_t& y) y = ty; } +//============================================================================ +// +// Translates a velocity vector by a portal's displacement +// +//============================================================================ + void P_TranslatePortalVXVY(line_t* src, line_t* dst, fixed_t& vx, fixed_t& vy) { angle_t angle = @@ -360,6 +472,12 @@ void P_TranslatePortalVXVY(line_t* src, line_t* dst, fixed_t& vx, fixed_t& vy) vy = FixedMul(orig_vely, c) + FixedMul(orig_velx, s); } +//============================================================================ +// +// Translates an angle by a portal's displacement +// +//============================================================================ + void P_TranslatePortalAngle(line_t* src, line_t* dst, angle_t& angle) { if (!src || !dst) @@ -376,6 +494,12 @@ void P_TranslatePortalAngle(line_t* src, line_t* dst, angle_t& angle) angle += xangle; } +//============================================================================ +// +// Translates a z-coordinate by a portal's displacement +// +//============================================================================ + void P_TranslatePortalZ(line_t* src, line_t* dst, fixed_t& z) { // args[2] = 0 - no adjustment @@ -397,7 +521,12 @@ void P_TranslatePortalZ(line_t* src, line_t* dst, fixed_t& z) } } +//============================================================================ +// // calculate shortest distance from a point (x,y) to a linedef +// +//============================================================================ + fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y) { angle_t angle = R_PointToAngle2(0, 0, line->dx, line->dy); @@ -423,7 +552,12 @@ void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy) vy = FLOAT2FIXED(_vy/len); } +//============================================================================ +// // portal tracer code +// +//============================================================================ + PortalTracer::PortalTracer(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy) { this->startx = startx; @@ -583,6 +717,9 @@ static bool CollectSectors(int groupid, sector_t *origin) // Adds the displacement for one portal to the displacement array // (one version for sector to sector plane, one for line to line portals) // +// Note: Despite the similarities to Eternity's equivalent this is +// original code! +// //============================================================================ static void AddDisplacementForPortal(AStackPoint *portal) @@ -796,14 +933,13 @@ void P_CreateLinkedPortals() ASkyViewpoint *box = sectors[i].SkyBoxes[j]; if (box != NULL) { - if (box->special1 == SKYBOX_LINKEDPORTAL && box->Sector->PortalGroup == 0) + if (box->special1 == SKYBOX_LINKEDPORTAL && sectors[i].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); - } + // Note: the linked actor will be on the other side of the portal. + // To get this side's group we will have to look at the mate object. + CollectSectors(box->Mate->Sector->PortalGroup, §ors[i]); + // We cannot process the backlink here because all we can access is the anchor object + // If necessary that will have to be done for the other side's portal. } } } @@ -829,7 +965,13 @@ void P_CreateLinkedPortals() 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. + int sec1 = -1, sec2 = -1; + for (int i = 0; i < numsectors && (sec1 == -1 || sec2 == -1); i++) + { + if (sec1 == -1 && sectors[i].PortalGroup == x) sec1 = i; + if (sec2 == -1 && sectors[i].PortalGroup == y) sec2 = i; + } + Printf("Link offset mismatch between sectors %d and %d\n", sec1, sec2); bogus = true; } // todo: Find sectors that have no group but belong to a portal. @@ -938,6 +1080,12 @@ bool P_CollectConnectedGroups(AActor *actor, fixed_t newx, fixed_t newy, FPortal } +//============================================================================ +// +// print the group link table to the console +// +//============================================================================ + CCMD(dumplinktable) { for (int x = 1; x < Displacements.size; x++) From f24bf7e622da805236c535e3be74205440ec7468 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 15 Feb 2016 13:40:31 +0100 Subject: [PATCH 07/10] - separated FCheckPosition and its FPortalGroupTable substructure into its own header because this was creating too many dependencies on other headers with FCheckPosition in p_local.h and FPortalGroupTable in portals.h. --- src/b_func.cpp | 1 + src/b_move.cpp | 1 + src/g_shared/a_fastprojectile.cpp | 1 + src/p_checkposition.h | 93 +++++++++++++++++++++++++++++++ src/p_enemy.cpp | 1 + src/p_local.h | 43 +------------- src/p_map.cpp | 1 + src/p_mobj.cpp | 1 + src/portal.cpp | 3 +- src/portal.h | 74 +++++++++++++----------- 10 files changed, 144 insertions(+), 75 deletions(-) create mode 100644 src/p_checkposition.h diff --git a/src/b_func.cpp b/src/b_func.cpp index 3b8ada882..fe2e2393d 100644 --- a/src/b_func.cpp +++ b/src/b_func.cpp @@ -23,6 +23,7 @@ #include "d_event.h" #include "d_player.h" #include "p_spec.h" +#include "p_checkposition.h" static FRandom pr_botdofire ("BotDoFire"); diff --git a/src/b_move.cpp b/src/b_move.cpp index 7bd31a201..1fcf207ed 100644 --- a/src/b_move.cpp +++ b/src/b_move.cpp @@ -20,6 +20,7 @@ #include "p_enemy.h" #include "d_player.h" #include "p_spec.h" +#include "p_checkposition.h" static FRandom pr_botopendoor ("BotOpenDoor"); static FRandom pr_bottrywalk ("BotTryWalk"); diff --git a/src/g_shared/a_fastprojectile.cpp b/src/g_shared/a_fastprojectile.cpp index 5ecec1827..29a72c23c 100644 --- a/src/g_shared/a_fastprojectile.cpp +++ b/src/g_shared/a_fastprojectile.cpp @@ -5,6 +5,7 @@ #include "r_sky.h" #include "p_lnspec.h" #include "b_bot.h" +#include "p_checkposition.h" IMPLEMENT_CLASS(AFastProjectile) diff --git a/src/p_checkposition.h b/src/p_checkposition.h new file mode 100644 index 000000000..8898f291c --- /dev/null +++ b/src/p_checkposition.h @@ -0,0 +1,93 @@ +#ifndef P_CHECKPOS_H +#define P_CHECKPOS_H + + +//============================================================================ +// +// Data structure which collects all portals being touched by an actor +// when checking its position. +// +//============================================================================ + +struct FPortalGroupTable +{ + TArray data; + TArray touchingGroups; + + void setSize(int num) + { + data.Resize((num + 31) / 32); + memset(&data[0], 0, data.Size()*sizeof(DWORD)); + } + + void clear() + { + data.Clear(); + touchingGroups.Clear(); + } + + void setBit(int group) + { + if (!getBit(group)) + { + data[group >> 5] |= (1 << (group & 31)); + touchingGroups.Push(group); + } + } + + int getBit(int group) + { + return data[group >> 5] & (1 << (group & 31)); + } +}; + + +//============================================================================ +// +// Used by P_CheckPosition and P_TryMove in place of the original +// set of global variables. +// +//============================================================================ + +struct FCheckPosition +{ + // in + AActor *thing; + fixed_t x; + fixed_t y; + fixed_t z; + + // out + sector_t *sector; + fixed_t floorz; + fixed_t ceilingz; + fixed_t dropoffz; + FTextureID floorpic; + int floorterrain; + sector_t *floorsector; + FTextureID ceilingpic; + sector_t *ceilingsector; + bool touchmidtex; + bool abovemidtex; + bool floatok; + bool FromPMove; + line_t *ceilingline; + AActor *stepthing; + // [RH] These are used by PIT_CheckThing and P_XYMovement to apply + // ripping damage once per tic instead of once per move. + bool DoRipping; + TMap LastRipped; + + //FPortalGroupTable Groups; + int PushTime; + + FCheckPosition(bool rip=false) + { + DoRipping = rip; + PushTime = 0; + FromPMove = false; + } +}; + + +#endif diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 16f632409..fed155627 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -51,6 +51,7 @@ #include "r_data/r_translate.h" #include "teaminfo.h" #include "p_spec.h" +#include "p_checkposition.h" #include "gi.h" diff --git a/src/p_local.h b/src/p_local.h index 5a173ea41..44a430c27 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -36,7 +36,7 @@ struct line_t; struct sector_t; struct msecnode_t; struct secplane_t; - +struct FCheckPosition; #include @@ -235,47 +235,6 @@ AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false) // P_MAP // -struct FCheckPosition -{ - // in - AActor *thing; - fixed_t x; - fixed_t y; - fixed_t z; - - // out - sector_t *sector; - fixed_t floorz; - fixed_t ceilingz; - fixed_t dropoffz; - FTextureID floorpic; - int floorterrain; - sector_t *floorsector; - FTextureID ceilingpic; - sector_t *ceilingsector; - bool touchmidtex; - bool abovemidtex; - bool floatok; - bool FromPMove; - line_t *ceilingline; - AActor *stepthing; - // [RH] These are used by PIT_CheckThing and P_XYMovement to apply - // ripping damage once per tic instead of once per move. - bool DoRipping; - TMap LastRipped; - - //FPortalGroupTable Groups; - int PushTime; - - FCheckPosition(bool rip=false) - { - DoRipping = rip; - PushTime = 0; - FromPMove = false; - } -}; - - // If "floatok" true, move would be ok // if within "tmfloorz - tmceilingz". diff --git a/src/p_map.cpp b/src/p_map.cpp index 8e958cf8b..b77d6c55a 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -41,6 +41,7 @@ #include "p_effect.h" #include "p_terrain.h" #include "p_trace.h" +#include "p_checkposition.h" #include "r_utility.h" #include "s_sound.h" diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 0910ac719..edf8598c9 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -69,6 +69,7 @@ #include "r_renderer.h" #include "po_man.h" #include "p_spec.h" +#include "p_checkposition.h" // MACROS ------------------------------------------------------------------ diff --git a/src/portal.cpp b/src/portal.cpp index 9c7c7b512..aad4e6ad5 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -52,6 +52,7 @@ #include "c_dispatch.h" #include "p_maputl.h" #include "p_spec.h" +#include "p_checkposition.h" // simulation recurions maximum CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO) @@ -672,8 +673,6 @@ bool PortalTracer::TraceStep() return (oDepth != depth); // if a portal has been found, return false } - - //============================================================================ // // CollectSectors diff --git a/src/portal.h b/src/portal.h index faee141e5..6dd271696 100644 --- a/src/portal.h +++ b/src/portal.h @@ -9,6 +9,25 @@ #include "m_bbox.h" #include "a_sharedglobal.h" +struct FPortalGroupTable; +//============================================================================ +// +// This table holds the offsets for the different parts of a map +// that are connected by portals. +// The idea here is basically the same as implemented in Eternity Engine: +// +// - each portal creates two sector groups in the map +// which are offset by the displacement of the portal anchors +// +// - for two or multiple groups the displacement is calculated by +// adding the displacements between intermediate groups which +// have to be traversed to connect the two +// +// - any sector not connected to any portal is assigned to group 0 +// Group 0 has no displacement to any other group in the level. +// +//============================================================================ + struct FDisplacement { fixed_t x, y; @@ -36,37 +55,11 @@ struct FDisplacementTable extern FDisplacementTable Displacements; -struct FPortalGroupTable -{ - TArray data; - TArray touchingGroups; - - void setSize(int num) - { - data.Resize((num + 31) / 32); - memset(&data[0], 0, data.Size()*sizeof(DWORD)); - } - - void clear() - { - data.Clear(); - touchingGroups.Clear(); - } - - void setBit(int group) - { - if (!getBit(group)) - { - data[group >> 5] |= (1 << (group & 31)); - touchingGroups.Push(group); - } - } - - int getBit(int group) - { - return data[group >> 5] & (1 << (group & 31)); - } -}; +//============================================================================ +// +// Flags and types for linedef portals +// +//============================================================================ enum { @@ -101,6 +94,14 @@ enum PCOLL_LINKED = 2 }; +//============================================================================ +// +// All information about a line-to-line portal (all types) +// There is no structure for sector plane portals because for historic +// reasons those use actors to connect. +// +//============================================================================ + struct FLinePortal { line_t *mOrigin; @@ -135,9 +136,14 @@ void P_TranslatePortalAngle(line_t* src, line_t* dst, angle_t& angle); void P_TranslatePortalZ(line_t* src, line_t* dst, fixed_t& z); void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy); +//============================================================================ +// // basically, this is a teleporting tracer function, // which can be used by itself (to calculate portal-aware offsets, say, for projectiles) // or to teleport normal tracers (like hitscan, railgun, autoaim tracers) +// +//============================================================================ + class PortalTracer { public: @@ -169,6 +175,12 @@ public: /* new code */ fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y); +//============================================================================ +// +// some wrappers around the portal data. +// +//============================================================================ + // returns true if the portal is crossable by actors inline bool line_t::isLinePortal() const From b9037ef3eea271261af18e04795b2ff8227445b2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 15 Feb 2016 21:49:46 +0100 Subject: [PATCH 08/10] - added a check to detect self-referencing sectors in the portal setup code because those are problem cases. --- src/p_checkposition.h | 2 +- src/portal.cpp | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/p_checkposition.h b/src/p_checkposition.h index 8898f291c..7deccc562 100644 --- a/src/p_checkposition.h +++ b/src/p_checkposition.h @@ -78,7 +78,7 @@ struct FCheckPosition bool DoRipping; TMap LastRipped; - //FPortalGroupTable Groups; + FPortalGroupTable Groups; int PushTime; FCheckPosition(bool rip=false) diff --git a/src/portal.cpp b/src/portal.cpp index aad4e6ad5..8f7fda6e6 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -973,7 +973,23 @@ void P_CreateLinkedPortals() Printf("Link offset mismatch between sectors %d and %d\n", sec1, sec2); bogus = true; } - // todo: Find sectors that have no group but belong to a portal. + // mark everything that connects to a one-sided line + for (int i = 0; i < numlines; i++) + { + if (lines[i].backsector == NULL && lines[i].frontsector->PortalGroup == 0) + { + CollectSectors(-1, lines[i].frontsector); + } + } + // and now print a message for everything that still wasn't processed. + for (int i = 0; i < numsectors; i++) + { + if (sectors[i].PortalGroup == 0) + { + Printf("Unable to assign sector %d to any group. Possibly self-referencing\n", i); + } + else if (sectors[i].PortalGroup == -1) sectors[i].PortalGroup = 0; + } } } bogus |= ConnectGroups(); From 22e867890367c8d9d65446d4f4dbe9807bd10c42 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 16 Feb 2016 12:51:10 +0100 Subject: [PATCH 09/10] - refactored P_CollectConnectedGroups to avoid frequent heap allocations for the common cases * the temporary checking arrays are now static * the array that gets the returned values only starts allocating memory when the third touched sector group is found. The most common cases (no touched portal and one touched portal) can be handled without accessing the heap. - did some streamlining of AActor::LinkToSector: * there's only now version of this function that can handle everything * moved the FIXMAPTHINGPOS stuff into a separate function. * removed LinkToWorldForMapThing and put all special handling this function did into P_PointInSectorBuggy. --- src/actor.h | 6 +- src/p_blockmap.h | 3 +- src/p_checkposition.h | 57 ++++--- src/p_maputl.cpp | 371 +++++++++++++++++++++--------------------- src/p_mobj.cpp | 2 +- src/portal.cpp | 81 +++++++-- src/portal.h | 4 +- 7 files changed, 294 insertions(+), 230 deletions(-) diff --git a/src/actor.h b/src/actor.h index 1dcd35b90..42865543c 100644 --- a/src/actor.h +++ b/src/actor.h @@ -44,6 +44,7 @@ struct subsector_t; class PClassAmmo; struct FBlockNode; +struct FPortalGroupArray; // // NOTES: AActor @@ -1131,11 +1132,10 @@ private: friend class FActorIterator; friend bool P_IsTIDUsed(int tid); - sector_t *LinkToWorldForMapThing (); + bool FixMapthingPos(); public: - void LinkToWorld (bool buggy=false); - void LinkToWorld (sector_t *sector); + void LinkToWorld (bool spawningmapthing=false, FPortalGroupArray *groups = NULL, sector_t *sector = NULL); void UnlinkFromWorld (); void AdjustFloorClip (); void SetOrigin (fixed_t x, fixed_t y, fixed_t z, bool moving = false); diff --git a/src/p_blockmap.h b/src/p_blockmap.h index 0380b9da7..9cbe2e84b 100644 --- a/src/p_blockmap.h +++ b/src/p_blockmap.h @@ -10,12 +10,13 @@ struct FBlockNode { AActor *Me; // actor this node references int BlockIndex; // index into blocklinks for the block this node is in + int Group; // portal group this link belongs to (can be different than the actor's own group FBlockNode **PrevActor; // previous actor in this block FBlockNode *NextActor; // next actor in this block FBlockNode **PrevBlock; // previous block this actor is in FBlockNode *NextBlock; // next block this actor is in - static FBlockNode *Create (AActor *who, int x, int y); + static FBlockNode *Create (AActor *who, int x, int y, int group = -1); void Release (); static FBlockNode *FreeBlocks; diff --git a/src/p_checkposition.h b/src/p_checkposition.h index 7deccc562..6eee5374a 100644 --- a/src/p_checkposition.h +++ b/src/p_checkposition.h @@ -4,41 +4,58 @@ //============================================================================ // -// Data structure which collects all portals being touched by an actor -// when checking its position. +// This is a dynamic array which holds its first MAX_STATIC entries in normal +// variables to avoid constant allocations which this would otherwise +// require. +// +// When collecting touched portal groups the normal cases are either +// no portals == one group or +// two portals = two groups +// +// Anything with more can happen but far less infrequently, so this +// organization helps avoiding the overhead from heap allocations +// in the vast majority of situations. // //============================================================================ -struct FPortalGroupTable +struct FPortalGroupArray { - TArray data; - TArray touchingGroups; - - void setSize(int num) + enum { - data.Resize((num + 31) / 32); - memset(&data[0], 0, data.Size()*sizeof(DWORD)); + MAX_STATIC = 2 + }; + + FPortalGroupArray() + { + varused = 0; } - void clear() + void Clear() { data.Clear(); - touchingGroups.Clear(); + varused = 0; } - void setBit(int group) + void Add(DWORD num) { - if (!getBit(group)) - { - data[group >> 5] |= (1 << (group & 31)); - touchingGroups.Push(group); - } + if (varused < MAX_STATIC) entry[varused++] = num; + else data.Push(num); } - int getBit(int group) + unsigned Size() { - return data[group >> 5] & (1 << (group & 31)); + return varused + data.Size(); } + + DWORD operator[](unsigned index) + { + return index < MAX_STATIC ? entry[index] : data[index - MAX_STATIC]; + } + +private: + DWORD entry[MAX_STATIC]; + unsigned varused; + TArray data; }; @@ -78,7 +95,7 @@ struct FCheckPosition bool DoRipping; TMap LastRipped; - FPortalGroupTable Groups; + FPortalGroupArray Groups; int PushTime; FCheckPosition(bool rip=false) diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 7df43f1c8..e09c86eb4 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -46,6 +46,8 @@ #include "po_man.h" static AActor *RoughBlockCheck (AActor *mo, int index, void *); +static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node); +sector_t *P_PointInSectorBuggy(fixed_t x, fixed_t y); //========================================================================== @@ -315,39 +317,118 @@ void AActor::UnlinkFromWorld () } +//========================================================================== +// +// If the thing is exactly on a line, move it into the sector +// slightly in order to resolve clipping issues in the renderer. +// +//========================================================================== + +bool AActor::FixMapthingPos() +{ + sector_t *secstart = P_PointInSectorBuggy(X(), Y()); + + int blockx = GetSafeBlockX(X() - bmaporgx); + int blocky = GetSafeBlockY(Y() - bmaporgy); + bool success = false; + + if ((unsigned int)blockx < (unsigned int)bmapwidth && + (unsigned int)blocky < (unsigned int)bmapheight) + { + int *list; + + for (list = blockmaplump + blockmap[blocky*bmapwidth + blockx] + 1; *list != -1; ++list) + { + line_t *ldef = &lines[*list]; + + if (ldef->frontsector == ldef->backsector) + { // Skip two-sided lines inside a single sector + continue; + } + if (ldef->backsector != NULL) + { + if (ldef->frontsector->floorplane == ldef->backsector->floorplane && + ldef->frontsector->ceilingplane == ldef->backsector->ceilingplane) + { // Skip two-sided lines without any height difference on either side + continue; + } + } + + // Not inside the line's bounding box + if (X() + radius <= ldef->bbox[BOXLEFT] + || X() - radius >= ldef->bbox[BOXRIGHT] + || Y() + radius <= ldef->bbox[BOXBOTTOM] + || Y() - radius >= ldef->bbox[BOXTOP]) + continue; + + // Get the exact distance to the line + divline_t dll, dlv; + fixed_t linelen = (fixed_t)sqrt((double)ldef->dx*ldef->dx + (double)ldef->dy*ldef->dy); + + P_MakeDivline(ldef, &dll); + + dlv.x = X(); + dlv.y = Y(); + dlv.dx = FixedDiv(dll.dy, linelen); + dlv.dy = -FixedDiv(dll.dx, linelen); + + fixed_t distance = abs(P_InterceptVector(&dlv, &dll)); + + if (distance < radius) + { + DPrintf("%s at (%d,%d) lies on %s line %td, distance = %f\n", + this->GetClass()->TypeName.GetChars(), X() >> FRACBITS, Y() >> FRACBITS, + ldef->dx == 0 ? "vertical" : ldef->dy == 0 ? "horizontal" : "diagonal", + ldef - lines, FIXED2DBL(distance)); + angle_t finean = R_PointToAngle2(0, 0, ldef->dx, ldef->dy); + if (ldef->backsector != NULL && ldef->backsector == secstart) + { + finean += ANGLE_90; + } + else + { + finean -= ANGLE_90; + } + finean >>= ANGLETOFINESHIFT; + + // Get the distance we have to move the object away from the wall + distance = radius - distance; + SetXY(X() + FixedMul(distance, finecosine[finean]), Y() + FixedMul(distance, finesine[finean])); + success = true; + } + } + } + return success; +} + //========================================================================== // // P_SetThingPosition -// Links a thing into both a block and a subsector based on it's x y. +// Links a thing into both a block and a subsector based on its x y. // Sets thing->sector properly // //========================================================================== -void AActor::LinkToWorld (bool buggy) +void AActor::LinkToWorld (bool spawningmapthing, FPortalGroupArray *groups, sector_t *sector) { - // link into subsector - sector_t *sec; - - if (!buggy || numgamenodes == 0) + if (spawningmapthing && (flags4 & MF4_FIXMAPTHINGPOS) && sector == NULL) { - sec = P_PointInSector (X(), Y()); - } - else - { - sec = LinkToWorldForMapThing (); + if (FixMapthingPos()) spawningmapthing = false; } - LinkToWorld (sec); -} - -void AActor::LinkToWorld (sector_t *sec) -{ - if (sec == NULL) + if (sector == NULL) { - LinkToWorld (); - return; + if (!spawningmapthing || numgamenodes == 0) + { + sector = P_PointInSector(X(), Y()); + } + else + { + sector = P_PointInSectorBuggy(X(), Y()); + } } - Sector = sec; + + Sector = sector; subsector = R_PointInSubsector(X(), Y()); // this is from the rendering nodes, not the gameplay nodes! if ( !(flags & MF_NOSECTOR) ) @@ -356,7 +437,7 @@ void AActor::LinkToWorld (sector_t *sec) // killough 8/11/98: simpler scheme using pointer-to-pointer prev // pointers, allows head nodes to be treated like everything else - AActor **link = &sec->thinglist; + AActor **link = §or->thinglist; AActor *next = *link; if ((snext = next)) next->sprev = &snext; @@ -405,7 +486,7 @@ void AActor::LinkToWorld (sector_t *sec) for (int x = x1; x <= x2; ++x) { FBlockNode **link = &blocklinks[y*bmapwidth + x]; - FBlockNode *node = FBlockNode::Create (this, x, y); + FBlockNode *node = FBlockNode::Create (this, x, y, this->Sector->PortalGroup); // Link in to block if ((node->NextActor = *link) != NULL) @@ -426,168 +507,6 @@ void AActor::LinkToWorld (sector_t *sec) } } -//========================================================================== -// -// [RH] LinkToWorldForMapThing -// -// Emulate buggy PointOnLineSide and fix actors that lie on -// lines to compensate for some IWAD maps. -// -//========================================================================== - -static int R_PointOnSideSlow (fixed_t x, fixed_t y, node_t *node) -{ - // [RH] This might have been faster than two multiplies and an - // add on a 386/486, but it certainly isn't on anything newer than that. - fixed_t dx; - fixed_t dy; - double left; - double right; - - if (!node->dx) - { - if (x <= node->x) - return node->dy > 0; - - return node->dy < 0; - } - if (!node->dy) - { - if (y <= node->y) - return node->dx < 0; - - return node->dx > 0; - } - - dx = (x - node->x); - dy = (y - node->y); - - // Try to quickly decide by looking at sign bits. - if ( (node->dy ^ node->dx ^ dx ^ dy)&0x80000000 ) - { - if ( (node->dy ^ dx) & 0x80000000 ) - { - // (left is negative) - return 1; - } - return 0; - } - - // we must use doubles here because the fixed point code will produce errors due to loss of precision for extremely short linedefs. - left = (double)node->dy * (double)dx; - right = (double)dy * (double)node->dx; - - if (right < left) - { - // front side - return 0; - } - // back side - return 1; -} - -sector_t *AActor::LinkToWorldForMapThing () -{ - node_t *node = gamenodes + numgamenodes - 1; - - do - { - // Use original buggy point-on-side test when spawning - // things at level load so that the map spots in the - // emerald key room of Hexen MAP01 are spawned on the - // window ledge instead of the blocking floor in front - // of it. Why do I consider it buggy? Because a point - // that lies directly on a line should always be - // considered as "in front" of the line. The orientation - // of the line should be irrelevant. - node = (node_t *)node->children[R_PointOnSideSlow (X(), Y(), node)]; - } - while (!((size_t)node & 1)); - - subsector_t *ssec = (subsector_t *)((BYTE *)node - 1); - - if (flags4 & MF4_FIXMAPTHINGPOS) - { - // If the thing is exactly on a line, move it into the subsector - // slightly in order to resolve clipping issues in the renderer. - // This check needs to use the blockmap, because an actor on a - // one-sided line might go into a subsector behind the line, so - // the line would not be included as one of its subsector's segs. - - int blockx = GetSafeBlockX(X() - bmaporgx); - int blocky = GetSafeBlockY(Y() - bmaporgy); - - if ((unsigned int)blockx < (unsigned int)bmapwidth && - (unsigned int)blocky < (unsigned int)bmapheight) - { - int *list; - - for (list = blockmaplump + blockmap[blocky*bmapwidth + blockx] + 1; *list != -1; ++list) - { - line_t *ldef = &lines[*list]; - - if (ldef->frontsector == ldef->backsector) - { // Skip two-sided lines inside a single sector - continue; - } - if (ldef->backsector != NULL) - { - if (ldef->frontsector->floorplane == ldef->backsector->floorplane && - ldef->frontsector->ceilingplane == ldef->backsector->ceilingplane) - { // Skip two-sided lines without any height difference on either side - continue; - } - } - - // Not inside the line's bounding box - if (X() + radius <= ldef->bbox[BOXLEFT] - || X() - radius >= ldef->bbox[BOXRIGHT] - || Y() + radius <= ldef->bbox[BOXBOTTOM] - || Y() - radius >= ldef->bbox[BOXTOP] ) - continue; - - // Get the exact distance to the line - divline_t dll, dlv; - fixed_t linelen = (fixed_t)sqrt((double)ldef->dx*ldef->dx + (double)ldef->dy*ldef->dy); - - P_MakeDivline (ldef, &dll); - - dlv.x = X(); - dlv.y = Y(); - dlv.dx = FixedDiv(dll.dy, linelen); - dlv.dy = -FixedDiv(dll.dx, linelen); - - fixed_t distance = abs(P_InterceptVector(&dlv, &dll)); - - if (distance < radius) - { - DPrintf ("%s at (%d,%d) lies on %s line %td, distance = %f\n", - this->GetClass()->TypeName.GetChars(), X()>>FRACBITS, Y()>>FRACBITS, - ldef->dx == 0? "vertical" : ldef->dy == 0? "horizontal" : "diagonal", - ldef-lines, FIXED2DBL(distance)); - angle_t finean = R_PointToAngle2 (0, 0, ldef->dx, ldef->dy); - if (ldef->backsector != NULL && ldef->backsector == ssec->sector) - { - finean += ANGLE_90; - } - else - { - finean -= ANGLE_90; - } - finean >>= ANGLETOFINESHIFT; - - // Get the distance we have to move the object away from the wall - distance = radius - distance; - SetXY(X() + FixedMul(distance, finecosine[finean]), Y() + FixedMul(distance, finesine[finean])); - return P_PointInSector (X(), Y()); - } - } - } - } - - return ssec->sector; -} - void AActor::SetOrigin (fixed_t ix, fixed_t iy, fixed_t iz, bool moving) { UnlinkFromWorld (); @@ -601,7 +520,7 @@ void AActor::SetOrigin (fixed_t ix, fixed_t iy, fixed_t iz, bool moving) FBlockNode *FBlockNode::FreeBlocks = NULL; -FBlockNode *FBlockNode::Create (AActor *who, int x, int y) +FBlockNode *FBlockNode::Create (AActor *who, int x, int y, int group) { FBlockNode *block; @@ -1528,6 +1447,67 @@ static AActor *RoughBlockCheck (AActor *mo, int index, void *param) return NULL; } +//========================================================================== +// +// [RH] LinkToWorldForMapThing +// +// Emulate buggy PointOnLineSide and fix actors that lie on +// lines to compensate for some IWAD maps. +// +//========================================================================== + +static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node) +{ + // [RH] This might have been faster than two multiplies and an + // add on a 386/486, but it certainly isn't on anything newer than that. + fixed_t dx; + fixed_t dy; + double left; + double right; + + if (!node->dx) + { + if (x <= node->x) + return node->dy > 0; + + return node->dy < 0; + } + if (!node->dy) + { + if (y <= node->y) + return node->dx < 0; + + return node->dx > 0; + } + + dx = (x - node->x); + dy = (y - node->y); + + // Try to quickly decide by looking at sign bits. + if ((node->dy ^ node->dx ^ dx ^ dy) & 0x80000000) + { + if ((node->dy ^ dx) & 0x80000000) + { + // (left is negative) + return 1; + } + return 0; + } + + // we must use doubles here because the fixed point code will produce errors due to loss of precision for extremely short linedefs. + left = (double)node->dy * (double)dx; + right = (double)dy * (double)node->dx; + + if (right < left) + { + // front side + return 0; + } + // back side + return 1; +} + + //=========================================================================== // // P_VanillaPointOnLineSide @@ -1616,3 +1596,24 @@ int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line) return 1; // back side } +sector_t *P_PointInSectorBuggy(fixed_t x, fixed_t y) +{ + node_t *node = gamenodes + numgamenodes - 1; + + do + { + // Use original buggy point-on-side test when spawning + // things at level load so that the map spots in the + // emerald key room of Hexen MAP01 are spawned on the + // window ledge instead of the blocking floor in front + // of it. Why do I consider it buggy? Because a point + // that lies directly on a line should always be + // considered as "in front" of the line. The orientation + // of the line should be irrelevant. + node = (node_t *)node->children[R_PointOnSideSlow(x, y, node)]; + } while (!((size_t)node & 1)); + + subsector_t *ssec = (subsector_t *)((BYTE *)node - 1); + return ssec->sector; +} + diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index edf8598c9..82326c39b 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -456,7 +456,7 @@ void AActor::Serialize (FArchive &arc) if (arc.IsLoading ()) { touching_sectorlist = NULL; - LinkToWorld (Sector); + LinkToWorld (false, NULL, Sector); AddToHash (); SetShade (fillcolor); if (player) diff --git a/src/portal.cpp b/src/portal.cpp index 8f7fda6e6..a525b22f0 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -62,6 +62,39 @@ FDisplacementTable Displacements; TArray linePortals; TArray linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups. +//============================================================================ +// +// This is used to mark processed portals for some collection functions. +// +//============================================================================ + +struct FPortalBits +{ + TArray data; + + void setSize(int num) + { + data.Resize((num + 31) / 32); + clear(); + } + + void clear() + { + memset(&data[0], 0, data.Size()*sizeof(DWORD)); + } + + void setBit(int group) + { + data[group >> 5] |= (1 << (group & 31)); + } + + int getBit(int group) + { + return data[group >> 5] & (1 << (group & 31)); + } +}; + + //============================================================================ // @@ -1021,22 +1054,31 @@ void P_CreateLinkedPortals() // //============================================================================ -bool P_CollectConnectedGroups(AActor *actor, fixed_t newx, fixed_t newy, FPortalGroupTable &out) +bool P_CollectConnectedGroups(AActor *actor, fixed_t newx, fixed_t newy, FPortalGroupArray &out) { - TArray foundPortals; + // Keep this temporary work stuff static. This function can never be called recursively + // and this would have to be reallocated for each call otherwise. + static FPortalBits processMask; + static TArray foundPortals; + bool retval = false; - if (linePortals.Size() == 0) + if (linkedPortals.Size() == 0) { + // If there are no portals, all sectors are in group 0. + out.Add(0); return false; } - out.setSize(Displacements.size); - out.setBit(actor->Sector->PortalGroup); - //FBoundingBox box(newx, newy, actor->radius); + processMask.setSize(linkedPortals.Size()); + processMask.clear(); + foundPortals.Clear(); + int thisgroup = actor->Sector->PortalGroup; - for (unsigned i = 0; i < linePortals.Size(); i++) + processMask.setBit(thisgroup); + out.Add(thisgroup); + + for (unsigned i = 0; i < linkedPortals.Size(); i++) { - if (linePortals[i].mType != PORTT_LINKED) continue; // not a linked portal - line_t *ld = linePortals[i].mOrigin; + line_t *ld = linkedPortals[i]->mOrigin; int othergroup = ld->frontsector->PortalGroup; FDisplacement &disp = Displacements(thisgroup, othergroup); if (!disp.isSet) continue; // no connection. @@ -1049,8 +1091,8 @@ bool P_CollectConnectedGroups(AActor *actor, fixed_t newx, fixed_t newy, FPortal || box.Bottom() >= ld->bbox[BOXTOP]) continue; // not touched - if (box.BoxOnLineSide(linePortals[i].mOrigin) != -1) continue; // not touched - foundPortals.Push(&linePortals[i]); + if (box.BoxOnLineSide(linkedPortals[i]->mOrigin) != -1) continue; // not touched + foundPortals.Push(linkedPortals[i]); } bool foundone = true; while (foundone) @@ -1058,10 +1100,11 @@ bool P_CollectConnectedGroups(AActor *actor, fixed_t newx, fixed_t newy, FPortal foundone = false; for (int i = foundPortals.Size() - 1; i >= 0; i--) { - if (out.getBit(foundPortals[i]->mOrigin->frontsector->PortalGroup) && - !out.getBit(foundPortals[i]->mDestination->frontsector->PortalGroup)) + if (processMask.getBit(foundPortals[i]->mOrigin->frontsector->PortalGroup) && + !processMask.getBit(foundPortals[i]->mDestination->frontsector->PortalGroup)) { - out.setBit(foundPortals[i]->mDestination->frontsector->PortalGroup); + processMask.setBit(foundPortals[i]->mDestination->frontsector->PortalGroup); + out.Add(foundPortals[i]->mDestination->frontsector->PortalGroup); foundone = true; retval = true; foundPortals.Delete(i); @@ -1076,8 +1119,9 @@ bool P_CollectConnectedGroups(AActor *actor, fixed_t newx, fixed_t newy, FPortal FDisplacement &disp = Displacements(actor->Sector->PortalGroup, othersec->PortalGroup); fixed_t dx = newx + disp.x; fixed_t dy = newx + disp.y; - out.setBit(othersec->PortalGroup); - wsec = P_PointInSector(dx, dy); // get upper sector at the exact spot we want to check and repeat, + processMask.setBit(othersec->PortalGroup); + out.Add(othersec->PortalGroup); + wsec = P_PointInSector(dx, dy); // get upper sector at the exact spot we want to check and repeat retval = true; } wsec = sec; @@ -1087,8 +1131,9 @@ bool P_CollectConnectedGroups(AActor *actor, fixed_t newx, fixed_t newy, FPortal FDisplacement &disp = Displacements(actor->Sector->PortalGroup, othersec->PortalGroup); fixed_t dx = newx + disp.x; fixed_t dy = newx + disp.y; - out.setBit(othersec->PortalGroup); - wsec = P_PointInSector(dx, dy); // get lower sector at the exact spot we want to check and repeat, + processMask.setBit(othersec->PortalGroup); + out.Add(othersec->PortalGroup); + wsec = P_PointInSector(dx, dy); // get lower sector at the exact spot we want to check and repeat retval = true; } return retval; diff --git a/src/portal.h b/src/portal.h index 6dd271696..40c4a30fc 100644 --- a/src/portal.h +++ b/src/portal.h @@ -9,7 +9,7 @@ #include "m_bbox.h" #include "a_sharedglobal.h" -struct FPortalGroupTable; +struct FPortalGroupArray; //============================================================================ // // This table holds the offsets for the different parts of a map @@ -120,7 +120,7 @@ void P_SpawnLinePortal(line_t* line); void P_FinalizePortals(); bool P_ChangePortal(line_t *ln, int thisid, int destid); void P_CreateLinkedPortals(); -bool P_CollectConnectedGroups(AActor *actor, fixed_t newx, fixed_t newy, FPortalGroupTable &out); +bool P_CollectConnectedGroups(AActor *actor, fixed_t newx, fixed_t newy, FPortalGroupArray &out); void P_CollectLinkedPortals(); inline int P_NumPortalGroups() { From 45108e9bb8d9c662e2c6265db584a31f3f941fe4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 16 Feb 2016 12:52:45 +0100 Subject: [PATCH 10/10] - added two missing files to CMakeLists.txt. --- src/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6b5f66a3e..6e617c712 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -835,11 +835,13 @@ set( NOT_COMPILED_SOURCE_FILES g_strife/a_crusader.cpp g_strife/a_entityboss.cpp g_strife/a_inquisitor.cpp + g_strife/a_loremaster.cpp g_strife/a_oracle.cpp g_strife/a_programmer.cpp g_strife/a_reaver.cpp g_strife/a_rebels.cpp g_strife/a_sentinel.cpp + g_strife/a_spectral.cpp g_strife/a_stalker.cpp g_strife/a_strifeitems.cpp g_strife/a_strifeweapons.cpp