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