mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-01-30 12:31:07 +00:00
Merge branch 'master' of c:\programming\doom-dev\zdoom
# Conflicts: # .gitignore
This commit is contained in:
commit
56202c49f1
84 changed files with 1246 additions and 588 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -43,4 +43,5 @@
|
||||||
/zlib/x64/
|
/zlib/x64/
|
||||||
/build_vc2013_64bit
|
/build_vc2013_64bit
|
||||||
/build_vc2015
|
/build_vc2015
|
||||||
build_cmake
|
/build_vc2015-32
|
||||||
|
/build_vc2015-64
|
||||||
|
|
|
@ -899,11 +899,13 @@ set( NOT_COMPILED_SOURCE_FILES
|
||||||
g_strife/a_crusader.cpp
|
g_strife/a_crusader.cpp
|
||||||
g_strife/a_entityboss.cpp
|
g_strife/a_entityboss.cpp
|
||||||
g_strife/a_inquisitor.cpp
|
g_strife/a_inquisitor.cpp
|
||||||
|
g_strife/a_loremaster.cpp
|
||||||
g_strife/a_oracle.cpp
|
g_strife/a_oracle.cpp
|
||||||
g_strife/a_programmer.cpp
|
g_strife/a_programmer.cpp
|
||||||
g_strife/a_reaver.cpp
|
g_strife/a_reaver.cpp
|
||||||
g_strife/a_rebels.cpp
|
g_strife/a_rebels.cpp
|
||||||
g_strife/a_sentinel.cpp
|
g_strife/a_sentinel.cpp
|
||||||
|
g_strife/a_spectral.cpp
|
||||||
g_strife/a_stalker.cpp
|
g_strife/a_stalker.cpp
|
||||||
g_strife/a_strifeitems.cpp
|
g_strife/a_strifeitems.cpp
|
||||||
g_strife/a_strifeweapons.cpp
|
g_strife/a_strifeweapons.cpp
|
||||||
|
|
33
src/actor.h
33
src/actor.h
|
@ -43,6 +43,8 @@
|
||||||
|
|
||||||
struct subsector_t;
|
struct subsector_t;
|
||||||
class PClassAmmo;
|
class PClassAmmo;
|
||||||
|
struct FBlockNode;
|
||||||
|
struct FPortalGroupArray;
|
||||||
|
|
||||||
//
|
//
|
||||||
// NOTES: AActor
|
// NOTES: AActor
|
||||||
|
@ -530,21 +532,6 @@ enum EThingSpecialActivationType
|
||||||
THINGSPEC_Switch = 1<<10, // The thing is alternatively activated and deactivated when triggered
|
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 FDecalBase;
|
||||||
class AInventory;
|
class AInventory;
|
||||||
|
@ -569,16 +556,6 @@ struct line_t;
|
||||||
struct secplane_t;
|
struct secplane_t;
|
||||||
struct FStrifeDialogueNode;
|
struct FStrifeDialogueNode;
|
||||||
|
|
||||||
struct fixedvec3
|
|
||||||
{
|
|
||||||
fixed_t x, y, z;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fixedvec2
|
|
||||||
{
|
|
||||||
fixed_t x, y;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DDropItem : public DObject
|
class DDropItem : public DObject
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(DDropItem, DObject)
|
DECLARE_CLASS(DDropItem, DObject)
|
||||||
|
@ -1155,11 +1132,10 @@ private:
|
||||||
friend class FActorIterator;
|
friend class FActorIterator;
|
||||||
friend bool P_IsTIDUsed(int tid);
|
friend bool P_IsTIDUsed(int tid);
|
||||||
|
|
||||||
sector_t *LinkToWorldForMapThing ();
|
bool FixMapthingPos();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void LinkToWorld (bool buggy=false);
|
void LinkToWorld (bool spawningmapthing=false, FPortalGroupArray *groups = NULL, sector_t *sector = NULL);
|
||||||
void LinkToWorld (sector_t *sector);
|
|
||||||
void UnlinkFromWorld ();
|
void UnlinkFromWorld ();
|
||||||
void AdjustFloorClip ();
|
void AdjustFloorClip ();
|
||||||
virtual void SetOrigin (fixed_t x, fixed_t y, fixed_t z, bool moving = false);
|
virtual void SetOrigin (fixed_t x, fixed_t y, fixed_t z, bool moving = false);
|
||||||
|
@ -1415,6 +1391,7 @@ inline fixedvec3 PosRelative(const fixedvec3 &pos, line_t *line, sector_t *refse
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintMiscActorInfo(AActor * query);
|
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
|
#define S_FREETARGMOBJ 1
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
#include "r_renderer.h"
|
#include "r_renderer.h"
|
||||||
#include "r_sky.h"
|
#include "r_sky.h"
|
||||||
#include "sbar.h"
|
#include "sbar.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "p_blockmap.h"
|
||||||
|
|
||||||
#include "m_cheat.h"
|
#include "m_cheat.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
@ -58,6 +60,7 @@
|
||||||
// State.
|
// State.
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
|
||||||
// Data.
|
// Data.
|
||||||
#include "gstrings.h"
|
#include "gstrings.h"
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "teaminfo.h"
|
#include "teaminfo.h"
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
|
||||||
IMPLEMENT_POINTY_CLASS(DBot)
|
IMPLEMENT_POINTY_CLASS(DBot)
|
||||||
DECLARE_POINTER(dest)
|
DECLARE_POINTER(dest)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
#include "b_bot.h"
|
#include "b_bot.h"
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
|
@ -20,6 +21,9 @@
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "d_event.h"
|
#include "d_event.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
#include "p_checkposition.h"
|
||||||
|
|
||||||
static FRandom pr_botdofire ("BotDoFire");
|
static FRandom pr_botdofire ("BotDoFire");
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ Everything that is changed is marked (maybe commented) with "Added by MC"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
#include "d_netinf.h"
|
#include "d_netinf.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
|
||||||
static FRandom pr_botspawn ("BotSpawn");
|
static FRandom pr_botspawn ("BotSpawn");
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
#include "a_keys.h"
|
#include "a_keys.h"
|
||||||
#include "d_event.h"
|
#include "d_event.h"
|
||||||
#include "p_enemy.h"
|
#include "p_enemy.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
#include "p_checkposition.h"
|
||||||
|
|
||||||
static FRandom pr_botopendoor ("BotOpenDoor");
|
static FRandom pr_botopendoor ("BotOpenDoor");
|
||||||
static FRandom pr_bottrywalk ("BotTryWalk");
|
static FRandom pr_bottrywalk ("BotTryWalk");
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "statnums.h"
|
#include "statnums.h"
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
#include "d_event.h"
|
#include "d_event.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
|
||||||
static FRandom pr_botmove ("BotMove");
|
static FRandom pr_botmove ("BotMove");
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,17 @@ union QWORD_UNION
|
||||||
typedef SDWORD fixed_t;
|
typedef SDWORD fixed_t;
|
||||||
typedef DWORD dsfixed_t; // fixedpt used by span drawer
|
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_MAX (signed)(0x7fffffff)
|
||||||
#define FIXED_MIN (signed)(0x80000000)
|
#define FIXED_MIN (signed)(0x80000000)
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,8 @@
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "r_data/r_interpolate.h"
|
||||||
|
|
||||||
extern FILE *Logfile;
|
extern FILE *Logfile;
|
||||||
extern bool insave;
|
extern bool insave;
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "p_spec.h"
|
#include "p_spec.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
|
#include "r_utility.h"
|
||||||
#include "intermission/intermission.h"
|
#include "intermission/intermission.h"
|
||||||
|
|
||||||
EXTERN_CVAR (Int, disableautosave)
|
EXTERN_CVAR (Int, disableautosave)
|
||||||
|
|
|
@ -73,6 +73,8 @@
|
||||||
#include "po_man.h"
|
#include "po_man.h"
|
||||||
#include "autosegs.h"
|
#include "autosegs.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
#include "textures.h"
|
||||||
|
#include "r_utility.h"
|
||||||
#include "menu/menu.h"
|
#include "menu/menu.h"
|
||||||
#include "intermission/intermission.h"
|
#include "intermission/intermission.h"
|
||||||
|
|
||||||
|
|
|
@ -197,6 +197,41 @@ struct PalEntry
|
||||||
#endif
|
#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
|
// Screenshot buffer image data types
|
||||||
enum ESSType
|
enum ESSType
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "r_data/r_interpolate.h"
|
#include "r_data/r_interpolate.h"
|
||||||
#include "statnums.h"
|
#include "statnums.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "doomstat.h"
|
||||||
|
|
||||||
IMPLEMENT_CLASS (DSectorEffect)
|
IMPLEMENT_CLASS (DSectorEffect)
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "doomerrors.h"
|
#include "doomerrors.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
|
||||||
|
|
||||||
static cycle_t ThinkCycles;
|
static cycle_t ThinkCycles;
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "sc_man.h"
|
#include "sc_man.h"
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "r_renderer.h"
|
#include "r_renderer.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
static FRandom pr_script("FScript");
|
static FRandom pr_script("FScript");
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "actor.h"
|
#include "actor.h"
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "p_spec.h"
|
||||||
#include "a_sharedglobal.h"
|
#include "a_sharedglobal.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
|
@ -15,6 +16,9 @@
|
||||||
#include "m_bbox.h"
|
#include "m_bbox.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
#include "portal.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 all the other Doom stuff here to reduce compile time
|
||||||
#include "a_arachnotron.cpp"
|
#include "a_arachnotron.cpp"
|
||||||
|
|
|
@ -80,6 +80,9 @@
|
||||||
#include "m_joy.h"
|
#include "m_joy.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
#include "r_renderer.h"
|
#include "r_renderer.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "a_morph.h"
|
||||||
|
#include "p_spec.h"
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#include "r_data/r_translate.h"
|
#include "r_data/r_translate.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "a_morph.h"
|
||||||
|
|
||||||
// Include all the other Heretic stuff here to reduce compile time
|
// Include all the other Heretic stuff here to reduce compile time
|
||||||
#include "a_chicken.cpp"
|
#include "a_chicken.cpp"
|
||||||
|
|
|
@ -1077,12 +1077,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm)
|
||||||
mo = Spawn<ARainPillar> (pos.x, pos.y, ONCEILINGZ, ALLOW_REPLACE);
|
mo = Spawn<ARainPillar> (pos.x, pos.y, ONCEILINGZ, ALLOW_REPLACE);
|
||||||
// We used bouncecount to store the 3D floor index in A_HideInCeiling
|
// We used bouncecount to store the 3D floor index in A_HideInCeiling
|
||||||
if (!mo) return 0;
|
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;
|
fixed_t newz;
|
||||||
if (self->bouncecount >= 0
|
if (self->bouncecount >= 0 && (unsigned)self->bouncecount < self->Sector->e->XFloor.ffloors.Size())
|
||||||
&& (unsigned)self->bouncecount < self->Sector->e->XFloor.ffloors.Size())
|
newz = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPoint(mo);// - 40 * FRACUNIT;
|
||||||
newz = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPoint(pos.x, pos.y);// - 40 * FRACUNIT;
|
|
||||||
else
|
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);
|
int moceiling = P_Find3DFloor(NULL, pos.x, pos.y, newz, false, false, newz);
|
||||||
if (moceiling >= 0)
|
if (moceiling >= 0)
|
||||||
mo->SetZ(newz - mo->height, false);
|
mo->SetZ(newz - mo->height, false);
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
#include "v_palette.h"
|
#include "v_palette.h"
|
||||||
#include "g_game.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 all the Hexen stuff here to reduce compile time
|
||||||
#include "a_bats.cpp"
|
#include "a_bats.cpp"
|
||||||
|
|
|
@ -83,6 +83,8 @@
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
#include "r_renderer.h"
|
#include "r_renderer.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,14 @@
|
||||||
#include "a_artifacts.h"
|
#include "a_artifacts.h"
|
||||||
#include "gstrings.h"
|
#include "gstrings.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "p_spec.h"
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "a_morph.h"
|
||||||
|
|
||||||
static FRandom pr_tele ("TeleportSelf");
|
static FRandom pr_tele ("TeleportSelf");
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "a_pickups.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
|
||||||
#define MAULATORTICS (25*35)
|
#define MAULATORTICS (25*35)
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "v_palette.h"
|
#include "v_palette.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
|
|
||||||
static FRandom pr_torch ("Torch");
|
static FRandom pr_torch ("Torch");
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "colormatcher.h"
|
#include "colormatcher.h"
|
||||||
#include "v_palette.h"
|
#include "v_palette.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "doomdata.h"
|
||||||
|
|
||||||
static fixed_t DecalWidth, DecalLeft, DecalRight;
|
static fixed_t DecalWidth, DecalLeft, DecalRight;
|
||||||
static fixed_t SpreadZ;
|
static fixed_t SpreadZ;
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "r_sky.h"
|
#include "r_sky.h"
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
|
#include "b_bot.h"
|
||||||
|
#include "p_checkposition.h"
|
||||||
|
|
||||||
|
|
||||||
IMPLEMENT_CLASS(AFastProjectile)
|
IMPLEMENT_CLASS(AFastProjectile)
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
#include "p_enemy.h"
|
#include "p_enemy.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
|
||||||
static FRandom pr_morphmonst ("MorphMonster");
|
static FRandom pr_morphmonst ("MorphMonster");
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
static FRandom pr_restore ("RestorePos");
|
static FRandom pr_restore ("RestorePos");
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "a_sharedglobal.h"
|
#include "a_sharedglobal.h"
|
||||||
#include "statnums.h"
|
#include "statnums.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
|
||||||
static FRandom pr_quake ("Quake");
|
static FRandom pr_quake ("Quake");
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#include "a_action.h"
|
#include "a_action.h"
|
||||||
#include "thingdef/thingdef.h"
|
#include "thingdef/thingdef.h"
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
|
#include "doomstat.h"
|
||||||
|
#include "doomdata.h"
|
||||||
|
|
||||||
#define MAX_RANDOMSPAWNERS_RECURSION 32 // Should be largely more than enough, honestly.
|
#define MAX_RANDOMSPAWNERS_RECURSION 32 // Should be largely more than enough, honestly.
|
||||||
static FRandom pr_randomspawn("RandomSpawn");
|
static FRandom pr_randomspawn("RandomSpawn");
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "thingdef/thingdef.h"
|
#include "thingdef/thingdef.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "a_pickups.h"
|
||||||
|
|
||||||
static FRandom pr_spot ("SpecialSpot");
|
static FRandom pr_spot ("SpecialSpot");
|
||||||
static FRandom pr_spawnmace ("SpawnMace");
|
static FRandom pr_spawnmace ("SpawnMace");
|
||||||
|
|
|
@ -50,6 +50,8 @@
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "d_event.h"
|
#include "d_event.h"
|
||||||
#include "v_font.h"
|
#include "v_font.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
// Include all the other Strife stuff here to reduce compile time
|
// Include all the other Strife stuff here to reduce compile time
|
||||||
#include "a_acolyte.cpp"
|
#include "a_acolyte.cpp"
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "doomstat.h"
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
#include "m_fixed.h"
|
#include "m_fixed.h"
|
||||||
#include "c_dispatch.h"
|
#include "c_dispatch.h"
|
||||||
|
@ -51,6 +52,8 @@
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
|
#include "thingdef.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
|
||||||
extern void LoadActors ();
|
extern void LoadActors ();
|
||||||
extern void InitBotStuff();
|
extern void InitBotStuff();
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include "m_bbox.h"
|
#include "m_bbox.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
#include "d_dehacked.h"
|
#include "d_dehacked.h"
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
#include "farchive.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
|
// [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
|
// writes some bytes to the network data stream, and the network code
|
||||||
|
|
|
@ -38,10 +38,14 @@
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
#include "sc_man.h"
|
#include "sc_man.h"
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "p_terrain.h"
|
#include "p_terrain.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "p_spec.h"
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Int, vid_renderer)
|
EXTERN_CVAR(Int, vid_renderer)
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
#include "p_terrain.h"
|
#include "p_terrain.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "d_player.h"
|
||||||
#include "p_spec.h"
|
#include "p_spec.h"
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
|
@ -79,6 +80,8 @@
|
||||||
#include "p_terrain.h"
|
#include "p_terrain.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "p_effect.h"
|
#include "p_effect.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "a_morph.h"
|
||||||
|
|
||||||
#include "g_shared/a_pickups.h"
|
#include "g_shared/a_pickups.h"
|
||||||
|
|
||||||
|
|
34
src/p_blockmap.h
Normal file
34
src/p_blockmap.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#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
|
||||||
|
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, int group = -1);
|
||||||
|
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
|
|
@ -18,6 +18,7 @@
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
#include "portal.h"
|
#include "portal.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
|
|
110
src/p_checkposition.h
Normal file
110
src/p_checkposition.h
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
#ifndef P_CHECKPOS_H
|
||||||
|
#define P_CHECKPOS_H
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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 FPortalGroupArray
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MAX_STATIC = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
FPortalGroupArray()
|
||||||
|
{
|
||||||
|
varused = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
data.Clear();
|
||||||
|
varused = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add(DWORD num)
|
||||||
|
{
|
||||||
|
if (varused < MAX_STATIC) entry[varused++] = num;
|
||||||
|
else data.Push(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned Size()
|
||||||
|
{
|
||||||
|
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<DWORD> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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<AActor*, bool> LastRipped;
|
||||||
|
|
||||||
|
FPortalGroupArray Groups;
|
||||||
|
int PushTime;
|
||||||
|
|
||||||
|
FCheckPosition(bool rip=false)
|
||||||
|
{
|
||||||
|
DoRipping = rip;
|
||||||
|
PushTime = 0;
|
||||||
|
FromPMove = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -36,6 +36,8 @@
|
||||||
#include "sc_man.h"
|
#include "sc_man.h"
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
|
|
|
@ -51,6 +51,8 @@
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
#include "v_palette.h"
|
#include "v_palette.h"
|
||||||
#include "colormatcher.h"
|
#include "colormatcher.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
|
||||||
CVAR (Int, cl_rockettrails, 1, CVAR_ARCHIVE);
|
CVAR (Int, cl_rockettrails, 1, CVAR_ARCHIVE);
|
||||||
CVAR (Bool, r_rail_smartspiral, 0, CVAR_ARCHIVE);
|
CVAR (Bool, r_rail_smartspiral, 0, CVAR_ARCHIVE);
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
|
#include "d_player.h"
|
||||||
#include "m_bbox.h"
|
#include "m_bbox.h"
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
|
@ -44,8 +46,12 @@
|
||||||
#include "thingdef/thingdef.h"
|
#include "thingdef/thingdef.h"
|
||||||
#include "d_dehacked.h"
|
#include "d_dehacked.h"
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "p_blockmap.h"
|
||||||
#include "r_data/r_translate.h"
|
#include "r_data/r_translate.h"
|
||||||
#include "teaminfo.h"
|
#include "teaminfo.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
#include "p_checkposition.h"
|
||||||
|
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "tables.h"
|
#include "tables.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
#include "p_3dmidtex.h"
|
#include "p_3dmidtex.h"
|
||||||
|
#include "p_spec.h"
|
||||||
#include "r_data/r_interpolate.h"
|
#include "r_data/r_interpolate.h"
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -411,8 +412,8 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
|
||||||
|
|
||||||
case DFloor::floorLowerByTexture:
|
case DFloor::floorLowerByTexture:
|
||||||
floor->m_Direction = -1;
|
floor->m_Direction = -1;
|
||||||
newheight = sec->floorplane.ZatPoint (0, 0) - sec->FindShortestTextureAround ();
|
newheight = sec->floorplane.ZatPoint (sec->soundorg[0], sec->soundorg[1]) - sec->FindShortestTextureAround ();
|
||||||
floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, newheight);
|
floor->m_FloorDestDist = sec->floorplane.PointToDist (sec->soundorg[0], sec->soundorg[1], newheight);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DFloor::floorLowerToCeiling:
|
case DFloor::floorLowerToCeiling:
|
||||||
|
@ -428,14 +429,14 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
|
||||||
// since the code is identical to what was here. (Oddly
|
// since the code is identical to what was here. (Oddly
|
||||||
// enough, BOOM preserved the code here even though it
|
// enough, BOOM preserved the code here even though it
|
||||||
// also had this function.)
|
// also had this function.)
|
||||||
newheight = sec->floorplane.ZatPoint (0, 0) + sec->FindShortestTextureAround ();
|
newheight = sec->floorplane.ZatPoint (sec->soundorg[0], sec->soundorg[1]) + sec->FindShortestTextureAround ();
|
||||||
floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, newheight);
|
floor->m_FloorDestDist = sec->floorplane.PointToDist (sec->soundorg[0], sec->soundorg[1], newheight);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DFloor::floorRaiseAndChange:
|
case DFloor::floorRaiseAndChange:
|
||||||
floor->m_Direction = 1;
|
floor->m_Direction = 1;
|
||||||
newheight = sec->floorplane.ZatPoint (0, 0) + height;
|
newheight = sec->floorplane.ZatPoint (sec->soundorg[0], sec->soundorg[1]) + height;
|
||||||
floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, newheight);
|
floor->m_FloorDestDist = sec->floorplane.PointToDist (sec->soundorg[0], sec->soundorg[1], newheight);
|
||||||
if (line != NULL)
|
if (line != NULL)
|
||||||
{
|
{
|
||||||
FTextureID oldpic = sec->GetTexture(sector_t::floor);
|
FTextureID oldpic = sec->GetTexture(sector_t::floor);
|
||||||
|
@ -618,8 +619,8 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
|
||||||
floor->m_Hexencrush = false;
|
floor->m_Hexencrush = false;
|
||||||
|
|
||||||
floor->m_Speed = speed;
|
floor->m_Speed = speed;
|
||||||
height = sec->floorplane.ZatPoint (0, 0) + stairstep;
|
height = sec->floorplane.ZatPoint (sec->soundorg[0], sec->soundorg[1]) + stairstep;
|
||||||
floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, height);
|
floor->m_FloorDestDist = sec->floorplane.PointToDist (sec->soundorg[0], sec->soundorg[1], height);
|
||||||
|
|
||||||
texture = sec->GetTexture(sector_t::floor);
|
texture = sec->GetTexture(sector_t::floor);
|
||||||
osecnum = secnum; //jff 3/4/98 preserve loop index
|
osecnum = secnum; //jff 3/4/98 preserve loop index
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
#include "m_misc.h"
|
#include "m_misc.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "cmdlib.h"
|
||||||
|
|
||||||
void P_GetPolySpots (MapData * lump, TArray<FNodeBuilder::FPolyStart> &spots, TArray<FNodeBuilder::FPolyStart> &anchors);
|
void P_GetPolySpots (MapData * lump, TArray<FNodeBuilder::FPolyStart> &spots, TArray<FNodeBuilder::FPolyStart> &anchors);
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
#include "d_netinf.h"
|
#include "d_netinf.h"
|
||||||
|
#include "a_morph.h"
|
||||||
|
|
||||||
static FRandom pr_obituary ("Obituary");
|
static FRandom pr_obituary ("Obituary");
|
||||||
static FRandom pr_botrespawn ("BotRespawn");
|
static FRandom pr_botrespawn ("BotRespawn");
|
||||||
|
|
|
@ -27,8 +27,10 @@
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
|
#include "doomstat.h"
|
||||||
|
|
||||||
// State.
|
// State.
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,8 +58,12 @@
|
||||||
#include "d_event.h"
|
#include "d_event.h"
|
||||||
#include "gstrings.h"
|
#include "gstrings.h"
|
||||||
#include "portal.h"
|
#include "portal.h"
|
||||||
|
#include "po_man.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "r_utility.h"
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
#include "fragglescript/t_fs.h"
|
#include "fragglescript/t_fs.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
// Remaps EE sector change types to Generic_Floor values. According to the Eternity Wiki:
|
// Remaps EE sector change types to Generic_Floor values. According to the Eternity Wiki:
|
||||||
/*
|
/*
|
||||||
|
|
310
src/p_local.h
310
src/p_local.h
|
@ -24,13 +24,19 @@
|
||||||
#define __P_LOCAL__
|
#define __P_LOCAL__
|
||||||
|
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
#include "doomdef.h"
|
|
||||||
#include "tables.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;
|
||||||
|
struct FCheckPosition;
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@ -119,7 +125,7 @@ void P_PredictionLerpReset();
|
||||||
#define SPF_TEMPPLAYER 1 // spawning a short-lived dummy player
|
#define SPF_TEMPPLAYER 1 // spawning a short-lived dummy player
|
||||||
#define SPF_WEAPONFULLYUP 2 // spawn with weapon already raised
|
#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);
|
void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move);
|
||||||
int P_FaceMobj (AActor *source, AActor *target, angle_t *delta);
|
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<HashEntry> 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<intercept_t> 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_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, int, void *), void *params = NULL);
|
||||||
AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false);
|
AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false);
|
||||||
|
@ -423,45 +235,6 @@ AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false)
|
||||||
// P_MAP
|
// 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<AActor*, bool> LastRipped;
|
|
||||||
int PushTime;
|
|
||||||
|
|
||||||
FCheckPosition(bool rip=false)
|
|
||||||
{
|
|
||||||
DoRipping = rip;
|
|
||||||
PushTime = 0;
|
|
||||||
FromPMove = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// If "floatok" true, move would be ok
|
// If "floatok" true, move would be ok
|
||||||
// if within "tmfloorz - tmceilingz".
|
// if within "tmfloorz - tmceilingz".
|
||||||
|
@ -539,7 +312,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, 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_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, 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, angle_t angle, int pitch);
|
||||||
void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version
|
void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version
|
||||||
|
@ -587,31 +359,10 @@ bool Check_Sides(AActor *, int, int); // phares
|
||||||
// [RH]
|
// [RH]
|
||||||
const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymove);
|
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
|
// P_SETUP
|
||||||
//
|
//
|
||||||
extern BYTE* rejectmatrix; // for fast sight rejection
|
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 +390,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
|
// P_SPEC
|
||||||
//
|
//
|
||||||
#include "p_spec.h"
|
|
||||||
|
|
||||||
bool P_AlignFlat (int linenum, int side, int fc);
|
bool P_AlignFlat (int linenum, int side, int fc);
|
||||||
|
|
||||||
#endif // __P_LOCAL__
|
#endif // __P_LOCAL__
|
||||||
|
|
|
@ -34,10 +34,15 @@
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
#include "p_effect.h"
|
#include "p_effect.h"
|
||||||
#include "p_terrain.h"
|
#include "p_terrain.h"
|
||||||
#include "p_trace.h"
|
#include "p_trace.h"
|
||||||
|
#include "p_checkposition.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "decallib.h"
|
#include "decallib.h"
|
||||||
|
|
375
src/p_maputl.cpp
375
src/p_maputl.cpp
|
@ -32,9 +32,13 @@
|
||||||
#include "m_bbox.h"
|
#include "m_bbox.h"
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
|
#include "doomdata.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
#include "p_3dmidtex.h"
|
#include "p_3dmidtex.h"
|
||||||
|
#include "p_blockmap.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
|
||||||
// State.
|
// State.
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
|
@ -42,6 +46,8 @@
|
||||||
#include "po_man.h"
|
#include "po_man.h"
|
||||||
|
|
||||||
static AActor *RoughBlockCheck (AActor *mo, int index, void *);
|
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);
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -311,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
|
// 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
|
// Sets thing->sector properly
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void AActor::LinkToWorld (bool buggy)
|
void AActor::LinkToWorld (bool spawningmapthing, FPortalGroupArray *groups, sector_t *sector)
|
||||||
{
|
{
|
||||||
// link into subsector
|
if (spawningmapthing && (flags4 & MF4_FIXMAPTHINGPOS) && sector == NULL)
|
||||||
sector_t *sec;
|
|
||||||
|
|
||||||
if (!buggy || numgamenodes == 0)
|
|
||||||
{
|
{
|
||||||
sec = P_PointInSector (X(), Y());
|
if (FixMapthingPos()) spawningmapthing = false;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sec = LinkToWorldForMapThing ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkToWorld (sec);
|
if (sector == NULL)
|
||||||
}
|
|
||||||
|
|
||||||
void AActor::LinkToWorld (sector_t *sec)
|
|
||||||
{
|
|
||||||
if (sec == NULL)
|
|
||||||
{
|
{
|
||||||
LinkToWorld ();
|
if (!spawningmapthing || numgamenodes == 0)
|
||||||
return;
|
{
|
||||||
|
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!
|
subsector = R_PointInSubsector(X(), Y()); // this is from the rendering nodes, not the gameplay nodes!
|
||||||
|
|
||||||
if ( !(flags & MF_NOSECTOR) )
|
if ( !(flags & MF_NOSECTOR) )
|
||||||
|
@ -352,7 +437,7 @@ void AActor::LinkToWorld (sector_t *sec)
|
||||||
// killough 8/11/98: simpler scheme using pointer-to-pointer prev
|
// killough 8/11/98: simpler scheme using pointer-to-pointer prev
|
||||||
// pointers, allows head nodes to be treated like everything else
|
// pointers, allows head nodes to be treated like everything else
|
||||||
|
|
||||||
AActor **link = &sec->thinglist;
|
AActor **link = §or->thinglist;
|
||||||
AActor *next = *link;
|
AActor *next = *link;
|
||||||
if ((snext = next))
|
if ((snext = next))
|
||||||
next->sprev = &snext;
|
next->sprev = &snext;
|
||||||
|
@ -401,7 +486,7 @@ void AActor::LinkToWorld (sector_t *sec)
|
||||||
for (int x = x1; x <= x2; ++x)
|
for (int x = x1; x <= x2; ++x)
|
||||||
{
|
{
|
||||||
FBlockNode **link = &blocklinks[y*bmapwidth + 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
|
// Link in to block
|
||||||
if ((node->NextActor = *link) != NULL)
|
if ((node->NextActor = *link) != NULL)
|
||||||
|
@ -422,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)
|
void AActor::SetOrigin (fixed_t ix, fixed_t iy, fixed_t iz, bool moving)
|
||||||
{
|
{
|
||||||
UnlinkFromWorld ();
|
UnlinkFromWorld ();
|
||||||
|
@ -597,7 +520,7 @@ void AActor::SetOrigin (fixed_t ix, fixed_t iy, fixed_t iz, bool moving)
|
||||||
|
|
||||||
FBlockNode *FBlockNode::FreeBlocks = NULL;
|
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;
|
FBlockNode *block;
|
||||||
|
|
||||||
|
@ -1524,6 +1447,67 @@ static AActor *RoughBlockCheck (AActor *mo, int index, void *param)
|
||||||
return NULL;
|
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
|
// P_VanillaPointOnLineSide
|
||||||
|
@ -1612,3 +1596,24 @@ int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line)
|
||||||
return 1; // back side
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
208
src/p_maputl.h
Normal file
208
src/p_maputl.h
Normal file
|
@ -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<HashEntry> 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<intercept_t> 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
|
|
@ -29,6 +29,7 @@
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
#include "p_effect.h"
|
#include "p_effect.h"
|
||||||
#include "p_terrain.h"
|
#include "p_terrain.h"
|
||||||
|
@ -66,6 +67,9 @@
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
#include "r_renderer.h"
|
#include "r_renderer.h"
|
||||||
|
#include "po_man.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
#include "p_checkposition.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -452,7 +456,7 @@ void AActor::Serialize (FArchive &arc)
|
||||||
if (arc.IsLoading ())
|
if (arc.IsLoading ())
|
||||||
{
|
{
|
||||||
touching_sectorlist = NULL;
|
touching_sectorlist = NULL;
|
||||||
LinkToWorld (Sector);
|
LinkToWorld (false, NULL, Sector);
|
||||||
AddToHash ();
|
AddToHash ();
|
||||||
SetShade (fillcolor);
|
SetShade (fillcolor);
|
||||||
if (player)
|
if (player)
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
static FRandom pr_doplat ("DoPlat");
|
static FRandom pr_doplat ("DoPlat");
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,10 @@
|
||||||
|
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
// State.
|
// State.
|
||||||
|
#include "d_player.h"
|
||||||
#include "dobject.h"
|
#include "dobject.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
|
@ -532,6 +534,7 @@ void P_SerializeWorld (FArchive &arc)
|
||||||
{
|
{
|
||||||
linePortals.Clear();
|
linePortals.Clear();
|
||||||
}
|
}
|
||||||
|
P_CollectLinkedPortals();
|
||||||
}
|
}
|
||||||
|
|
||||||
void extsector_t::Serialize(FArchive &arc)
|
void extsector_t::Serialize(FArchive &arc)
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
|
#include "d_player.h"
|
||||||
#include "m_argv.h"
|
#include "m_argv.h"
|
||||||
#include "m_swap.h"
|
#include "m_swap.h"
|
||||||
#include "m_bbox.h"
|
#include "m_bbox.h"
|
||||||
|
@ -69,6 +70,9 @@
|
||||||
#include "r_renderer.h"
|
#include "r_renderer.h"
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
#include "portal.h"
|
#include "portal.h"
|
||||||
|
#include "p_blockmap.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "p_spec.h"
|
||||||
#ifndef NO_EDATA
|
#ifndef NO_EDATA
|
||||||
#include "edata.h"
|
#include "edata.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -14,11 +14,16 @@
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
|
#include "p_blockmap.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "m_bbox.h"
|
#include "m_bbox.h"
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "po_man.h"
|
#include "po_man.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "b_bot.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
// State.
|
// State.
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
|
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
#include "p_blockmap.h"
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
#include "p_terrain.h"
|
#include "p_terrain.h"
|
||||||
#include "p_acs.h"
|
#include "p_acs.h"
|
||||||
|
@ -64,7 +66,10 @@
|
||||||
#include "a_keys.h"
|
#include "a_keys.h"
|
||||||
#include "c_dispatch.h"
|
#include "c_dispatch.h"
|
||||||
#include "r_sky.h"
|
#include "r_sky.h"
|
||||||
|
#include "d_player.h"
|
||||||
#include "portal.h"
|
#include "portal.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
|
#include "p_blockmap.h"
|
||||||
#ifndef NO_EDATA
|
#ifndef NO_EDATA
|
||||||
#include "edata.h"
|
#include "edata.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -47,6 +47,8 @@
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,10 @@
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
#define FUDGEFACTOR 10
|
#define FUDGEFACTOR 10
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,9 @@
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
#include "i_system.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.
|
// Set of spawnable things for the Thing_Spawn and Thing_Projectile specials.
|
||||||
FClassMap SpawnableThings;
|
FClassMap SpawnableThings;
|
||||||
|
|
|
@ -31,7 +31,10 @@
|
||||||
#include "sbar.h"
|
#include "sbar.h"
|
||||||
#include "r_data/r_interpolate.h"
|
#include "r_data/r_interpolate.h"
|
||||||
#include "i_sound.h"
|
#include "i_sound.h"
|
||||||
|
#include "d_player.h"
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
extern gamestate_t wipegamestate;
|
extern gamestate_t wipegamestate;
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,9 @@
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "r_sky.h"
|
#include "r_sky.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
|
#include "r_defs.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
struct FTraceInfo
|
struct FTraceInfo
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,6 +54,11 @@
|
||||||
#include "gstrings.h"
|
#include "gstrings.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
#include "r_renderer.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");
|
static FRandom pr_skullpop ("SkullPop");
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include "r_defs.h"
|
#include "r_defs.h"
|
||||||
#include "m_swap.h"
|
#include "m_swap.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
static int WriteTHINGS (FILE *file);
|
static int WriteTHINGS (FILE *file);
|
||||||
static int WriteLINEDEFS (FILE *file);
|
static int WriteLINEDEFS (FILE *file);
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "p_blockmap.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
36
src/po_man.h
36
src/po_man.h
|
@ -107,4 +107,40 @@ FArchive &operator<< (FArchive &arc, FPolyObj *&poly);
|
||||||
FArchive &operator<< (FArchive &arc, const 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
|
#endif
|
332
src/portal.cpp
332
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 "portal.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
|
@ -11,6 +50,9 @@
|
||||||
#include "a_sharedglobal.h"
|
#include "a_sharedglobal.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "c_dispatch.h"
|
#include "c_dispatch.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
#include "p_checkposition.h"
|
||||||
|
|
||||||
// simulation recurions maximum
|
// simulation recurions maximum
|
||||||
CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
||||||
|
@ -18,7 +60,47 @@ CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
||||||
FDisplacementTable Displacements;
|
FDisplacementTable Displacements;
|
||||||
|
|
||||||
TArray<FLinePortal> linePortals;
|
TArray<FLinePortal> linePortals;
|
||||||
|
TArray<FLinePortal*> 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<DWORD> 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));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// Save a line portal for savegames.
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
FArchive &operator<< (FArchive &arc, FLinePortal &port)
|
FArchive &operator<< (FArchive &arc, FLinePortal &port)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +116,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)
|
static line_t *FindDestination(line_t *src, int tag)
|
||||||
{
|
{
|
||||||
if (tag)
|
if (tag)
|
||||||
|
@ -52,6 +140,12 @@ static line_t *FindDestination(line_t *src, int tag)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// Spawns a single line portal
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
void P_SpawnLinePortal(line_t* line)
|
void P_SpawnLinePortal(line_t* line)
|
||||||
{
|
{
|
||||||
// portal destination is special argument #0
|
// portal destination is special argument #0
|
||||||
|
@ -132,6 +226,12 @@ void P_SpawnLinePortal(line_t* line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// Update a line portal's state after all have been spawned
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
void P_UpdatePortal(FLinePortal *port)
|
void P_UpdatePortal(FLinePortal *port)
|
||||||
{
|
{
|
||||||
if (port->mDestination == NULL)
|
if (port->mDestination == NULL)
|
||||||
|
@ -168,6 +268,32 @@ 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();
|
||||||
|
for (unsigned i = 0; i < linePortals.Size(); i++)
|
||||||
|
{
|
||||||
|
FLinePortal * port = &linePortals[i];
|
||||||
|
if (port->mType == PORTT_LINKED)
|
||||||
|
{
|
||||||
|
linkedPortals.Push(port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// Post-process all line portals
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
void P_FinalizePortals()
|
void P_FinalizePortals()
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < linePortals.Size(); i++)
|
for (unsigned i = 0; i < linePortals.Size(); i++)
|
||||||
|
@ -175,8 +301,15 @@ void P_FinalizePortals()
|
||||||
FLinePortal * port = &linePortals[i];
|
FLinePortal * port = &linePortals[i];
|
||||||
P_UpdatePortal(port);
|
P_UpdatePortal(port);
|
||||||
}
|
}
|
||||||
|
P_CollectLinkedPortals();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// Change the destination of a portal
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
static bool ChangePortalLine(line_t *line, int destid)
|
static bool ChangePortalLine(line_t *line, int destid)
|
||||||
{
|
{
|
||||||
if (line->portalindex >= linePortals.Size()) return false;
|
if (line->portalindex >= linePortals.Size()) return false;
|
||||||
|
@ -207,6 +340,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)
|
bool P_ChangePortal(line_t *ln, int thisid, int destid)
|
||||||
{
|
{
|
||||||
int lineno;
|
int lineno;
|
||||||
|
@ -221,7 +360,13 @@ bool P_ChangePortal(line_t *ln, int thisid, int destid)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// Calculate the intersection between two lines.
|
||||||
// [ZZ] lots of floats here to avoid overflowing a lot
|
// [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,
|
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 o2x, fixed_t o2y, fixed_t p2x, fixed_t p2y,
|
||||||
fixed_t& rx, fixed_t& ry)
|
fixed_t& rx, fixed_t& ry)
|
||||||
|
@ -261,9 +406,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;
|
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)
|
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 behind1 = !!P_PointOnLineSidePrecise(line->v1->x, line->v1->y, portal);
|
||||||
bool behind2 = !!P_PointOnLineSidePrecise(line->v2->x, line->v2->y, portal);
|
bool behind2 = !!P_PointOnLineSidePrecise(line->v2->x, line->v2->y, portal);
|
||||||
|
|
||||||
|
@ -289,6 +440,12 @@ bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t vie
|
||||||
return false;
|
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)
|
void P_TranslatePortalXY(line_t* src, line_t* dst, fixed_t& x, fixed_t& y)
|
||||||
{
|
{
|
||||||
if (!src || !dst)
|
if (!src || !dst)
|
||||||
|
@ -325,6 +482,12 @@ void P_TranslatePortalXY(line_t* src, line_t* dst, fixed_t& x, fixed_t& y)
|
||||||
y = ty;
|
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)
|
void P_TranslatePortalVXVY(line_t* src, line_t* dst, fixed_t& vx, fixed_t& vy)
|
||||||
{
|
{
|
||||||
angle_t angle =
|
angle_t angle =
|
||||||
|
@ -343,6 +506,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);
|
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)
|
void P_TranslatePortalAngle(line_t* src, line_t* dst, angle_t& angle)
|
||||||
{
|
{
|
||||||
if (!src || !dst)
|
if (!src || !dst)
|
||||||
|
@ -359,6 +528,12 @@ void P_TranslatePortalAngle(line_t* src, line_t* dst, angle_t& angle)
|
||||||
angle += xangle;
|
angle += xangle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// Translates a z-coordinate by a portal's displacement
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
void P_TranslatePortalZ(line_t* src, line_t* dst, fixed_t& z)
|
void P_TranslatePortalZ(line_t* src, line_t* dst, fixed_t& z)
|
||||||
{
|
{
|
||||||
// args[2] = 0 - no adjustment
|
// args[2] = 0 - no adjustment
|
||||||
|
@ -380,7 +555,12 @@ void P_TranslatePortalZ(line_t* src, line_t* dst, fixed_t& z)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
// calculate shortest distance from a point (x,y) to a linedef
|
// calculate shortest distance from a point (x,y) to a linedef
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y)
|
fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y)
|
||||||
{
|
{
|
||||||
angle_t angle = R_PointToAngle2(0, 0, line->dx, line->dy);
|
angle_t angle = R_PointToAngle2(0, 0, line->dx, line->dy);
|
||||||
|
@ -406,7 +586,12 @@ void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy)
|
||||||
vy = FLOAT2FIXED(_vy/len);
|
vy = FLOAT2FIXED(_vy/len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
// portal tracer code
|
// portal tracer code
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
PortalTracer::PortalTracer(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy)
|
PortalTracer::PortalTracer(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy)
|
||||||
{
|
{
|
||||||
this->startx = startx;
|
this->startx = startx;
|
||||||
|
@ -521,8 +706,6 @@ bool PortalTracer::TraceStep()
|
||||||
return (oDepth != depth); // if a portal has been found, return false
|
return (oDepth != depth); // if a portal has been found, return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// CollectSectors
|
// CollectSectors
|
||||||
|
@ -566,6 +749,9 @@ static bool CollectSectors(int groupid, sector_t *origin)
|
||||||
// Adds the displacement for one portal to the displacement array
|
// Adds the displacement for one portal to the displacement array
|
||||||
// (one version for sector to sector plane, one for line to line portals)
|
// (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)
|
static void AddDisplacementForPortal(AStackPoint *portal)
|
||||||
|
@ -779,14 +965,13 @@ void P_CreateLinkedPortals()
|
||||||
ASkyViewpoint *box = sectors[i].SkyBoxes[j];
|
ASkyViewpoint *box = sectors[i].SkyBoxes[j];
|
||||||
if (box != NULL)
|
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);
|
// Note: the linked actor will be on the other side of the portal.
|
||||||
box = box->Mate;
|
// To get this side's group we will have to look at the mate object.
|
||||||
if (box->special1 == SKYBOX_LINKEDPORTAL && box->Sector->PortalGroup == 0)
|
CollectSectors(box->Mate->Sector->PortalGroup, §ors[i]);
|
||||||
{
|
// We cannot process the backlink here because all we can access is the anchor object
|
||||||
CollectSectors(box->Sector->PortalGroup, box->Sector);
|
// If necessary that will have to be done for the other side's portal.
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -812,10 +997,32 @@ void P_CreateLinkedPortals()
|
||||||
if (dispxy.isSet && dispyx.isSet &&
|
if (dispxy.isSet && dispyx.isSet &&
|
||||||
(dispxy.x != -dispyx.x || dispxy.y != -dispyx.y))
|
(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;
|
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();
|
bogus |= ConnectGroups();
|
||||||
|
@ -839,6 +1046,106 @@ void P_CreateLinkedPortals()
|
||||||
//BuildBlockmap();
|
//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, FPortalGroupArray &out)
|
||||||
|
{
|
||||||
|
// 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<FLinePortal*> foundPortals;
|
||||||
|
|
||||||
|
bool retval = false;
|
||||||
|
if (linkedPortals.Size() == 0)
|
||||||
|
{
|
||||||
|
// If there are no portals, all sectors are in group 0.
|
||||||
|
out.Add(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
processMask.setSize(linkedPortals.Size());
|
||||||
|
processMask.clear();
|
||||||
|
foundPortals.Clear();
|
||||||
|
|
||||||
|
int thisgroup = actor->Sector->PortalGroup;
|
||||||
|
processMask.setBit(thisgroup);
|
||||||
|
out.Add(thisgroup);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < linkedPortals.Size(); i++)
|
||||||
|
{
|
||||||
|
line_t *ld = linkedPortals[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(linkedPortals[i]->mOrigin) != -1) continue; // not touched
|
||||||
|
foundPortals.Push(linkedPortals[i]);
|
||||||
|
}
|
||||||
|
bool foundone = true;
|
||||||
|
while (foundone)
|
||||||
|
{
|
||||||
|
foundone = false;
|
||||||
|
for (int i = foundPortals.Size() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (processMask.getBit(foundPortals[i]->mOrigin->frontsector->PortalGroup) &&
|
||||||
|
!processMask.getBit(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// print the group link table to the console
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
CCMD(dumplinktable)
|
CCMD(dumplinktable)
|
||||||
{
|
{
|
||||||
for (int x = 1; x < Displacements.size; x++)
|
for (int x = 1; x < Displacements.size; x++)
|
||||||
|
@ -854,3 +1161,4 @@ CCMD(dumplinktable)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
77
src/portal.h
77
src/portal.h
|
@ -7,6 +7,26 @@
|
||||||
#include "actor.h"
|
#include "actor.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
#include "m_bbox.h"
|
#include "m_bbox.h"
|
||||||
|
#include "a_sharedglobal.h"
|
||||||
|
|
||||||
|
struct FPortalGroupArray;
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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
|
struct FDisplacement
|
||||||
{
|
{
|
||||||
|
@ -33,6 +53,14 @@ struct FDisplacementTable
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern FDisplacementTable Displacements;
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// Flags and types for linedef portals
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PORTF_VISIBLE = 1,
|
PORTF_VISIBLE = 1,
|
||||||
|
@ -60,6 +88,20 @@ enum
|
||||||
PORG_CEILING,
|
PORG_CEILING,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PCOLL_NOTLINKED = 1,
|
||||||
|
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
|
struct FLinePortal
|
||||||
{
|
{
|
||||||
line_t *mOrigin;
|
line_t *mOrigin;
|
||||||
|
@ -78,6 +120,12 @@ void P_SpawnLinePortal(line_t* line);
|
||||||
void P_FinalizePortals();
|
void P_FinalizePortals();
|
||||||
bool P_ChangePortal(line_t *ln, int thisid, int destid);
|
bool P_ChangePortal(line_t *ln, int thisid, int destid);
|
||||||
void P_CreateLinkedPortals();
|
void P_CreateLinkedPortals();
|
||||||
|
bool P_CollectConnectedGroups(AActor *actor, fixed_t newx, fixed_t newy, FPortalGroupArray &out);
|
||||||
|
void P_CollectLinkedPortals();
|
||||||
|
inline int P_NumPortalGroups()
|
||||||
|
{
|
||||||
|
return Displacements.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code ported from prototype */
|
/* code ported from prototype */
|
||||||
|
@ -88,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_TranslatePortalZ(line_t* src, line_t* dst, fixed_t& z);
|
||||||
void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy);
|
void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy);
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
// basically, this is a teleporting tracer function,
|
// basically, this is a teleporting tracer function,
|
||||||
// which can be used by itself (to calculate portal-aware offsets, say, for projectiles)
|
// which can be used by itself (to calculate portal-aware offsets, say, for projectiles)
|
||||||
// or to teleport normal tracers (like hitscan, railgun, autoaim tracers)
|
// or to teleport normal tracers (like hitscan, railgun, autoaim tracers)
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
class PortalTracer
|
class PortalTracer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -122,6 +175,12 @@ public:
|
||||||
/* new code */
|
/* new code */
|
||||||
fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y);
|
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
|
// returns true if the portal is crossable by actors
|
||||||
inline bool line_t::isLinePortal() const
|
inline bool line_t::isLinePortal() const
|
||||||
|
@ -145,4 +204,22 @@ inline int line_t::getPortalAlignment() const
|
||||||
return portalindex >= linePortals.Size() ? 0 : linePortals[portalindex].mAlign;
|
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
|
#endif
|
31
src/r_defs.h
31
src/r_defs.h
|
@ -792,21 +792,9 @@ struct sector_t
|
||||||
Flags &= ~SECF_SPECIALFLAGS;
|
Flags &= ~SECF_SPECIALFLAGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool PortalBlocksView(int plane)
|
bool PortalBlocksView(int plane);
|
||||||
{
|
bool PortalBlocksMovement(int plane);
|
||||||
return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
bool PortalBlocksSound(int plane);
|
||||||
}
|
|
||||||
|
|
||||||
inline bool PortalBlocksMovement(int plane)
|
|
||||||
{
|
|
||||||
return !!(planes[plane].Flags & (PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool PortalBlocksSound(int plane)
|
|
||||||
{
|
|
||||||
return !!(planes[plane].Flags & (PLANEF_BLOCKSOUND | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int GetTerrain(int pos) const;
|
int GetTerrain(int pos) const;
|
||||||
|
|
||||||
|
@ -1277,4 +1265,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
|
#endif
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
#include "r_data/voxels.h"
|
#include "r_data/voxels.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
|
|
||||||
// [RH] A c-buffer. Used for keeping track of offscreen voxel spans.
|
// [RH] A c-buffer. Used for keeping track of offscreen voxel spans.
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,8 @@
|
||||||
#include "r_renderer.h"
|
#include "r_renderer.h"
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
|
||||||
|
|
||||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||||
|
@ -878,16 +880,22 @@ void R_SetupFrame (AActor *actor)
|
||||||
interpolator.DoInterpolations (r_TicFrac);
|
interpolator.DoInterpolations (r_TicFrac);
|
||||||
|
|
||||||
// Keep the view within the sector's floor and ceiling
|
// Keep the view within the sector's floor and ceiling
|
||||||
fixed_t theZ = viewsector->ceilingplane.ZatPoint (viewx, viewy) - 4*FRACUNIT;
|
if (viewsector->PortalBlocksMovement(sector_t::ceiling))
|
||||||
if (viewz > theZ)
|
|
||||||
{
|
{
|
||||||
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 (viewsector->PortalBlocksMovement(sector_t::floor))
|
||||||
if (viewz < theZ)
|
|
||||||
{
|
{
|
||||||
viewz = theZ;
|
fixed_t theZ = viewsector->floorplane.ZatPoint(viewx, viewy) + 4 * FRACUNIT;
|
||||||
|
if (viewz < theZ)
|
||||||
|
{
|
||||||
|
viewz = theZ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!paused)
|
if (!paused)
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "c_dispatch.h"
|
#include "c_dispatch.h"
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "po_man.h"
|
#include "po_man.h"
|
||||||
#include "farchive.h"
|
#include "farchive.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -37,36 +37,6 @@ class FTerrainTypeArray;
|
||||||
class FGLTexture;
|
class FGLTexture;
|
||||||
class FMaterial;
|
class FMaterial;
|
||||||
|
|
||||||
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
|
class FNullTextureID : public FTextureID
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -73,6 +73,9 @@
|
||||||
#include "p_trace.h"
|
#include "p_trace.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "gstrings.h"
|
#include "gstrings.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
|
#include "p_spec.h"
|
||||||
|
|
||||||
AActor *SingleActorFromTID(int tid, AActor *defactor);
|
AActor *SingleActorFromTID(int tid, AActor *defactor);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue