mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 06:42:08 +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/
|
||||
/build_vc2013_64bit
|
||||
/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_entityboss.cpp
|
||||
g_strife/a_inquisitor.cpp
|
||||
g_strife/a_loremaster.cpp
|
||||
g_strife/a_oracle.cpp
|
||||
g_strife/a_programmer.cpp
|
||||
g_strife/a_reaver.cpp
|
||||
g_strife/a_rebels.cpp
|
||||
g_strife/a_sentinel.cpp
|
||||
g_strife/a_spectral.cpp
|
||||
g_strife/a_stalker.cpp
|
||||
g_strife/a_strifeitems.cpp
|
||||
g_strife/a_strifeweapons.cpp
|
||||
|
|
33
src/actor.h
33
src/actor.h
|
@ -43,6 +43,8 @@
|
|||
|
||||
struct subsector_t;
|
||||
class PClassAmmo;
|
||||
struct FBlockNode;
|
||||
struct FPortalGroupArray;
|
||||
|
||||
//
|
||||
// NOTES: AActor
|
||||
|
@ -530,21 +532,6 @@ enum EThingSpecialActivationType
|
|||
THINGSPEC_Switch = 1<<10, // The thing is alternatively activated and deactivated when triggered
|
||||
};
|
||||
|
||||
// [RH] Like msecnode_t, but for the blockmap
|
||||
struct FBlockNode
|
||||
{
|
||||
AActor *Me; // actor this node references
|
||||
int BlockIndex; // index into blocklinks for the block this node is in
|
||||
FBlockNode **PrevActor; // previous actor in this block
|
||||
FBlockNode *NextActor; // next actor in this block
|
||||
FBlockNode **PrevBlock; // previous block this actor is in
|
||||
FBlockNode *NextBlock; // next block this actor is in
|
||||
|
||||
static FBlockNode *Create (AActor *who, int x, int y);
|
||||
void Release ();
|
||||
|
||||
static FBlockNode *FreeBlocks;
|
||||
};
|
||||
|
||||
class FDecalBase;
|
||||
class AInventory;
|
||||
|
@ -569,16 +556,6 @@ struct line_t;
|
|||
struct secplane_t;
|
||||
struct FStrifeDialogueNode;
|
||||
|
||||
struct fixedvec3
|
||||
{
|
||||
fixed_t x, y, z;
|
||||
};
|
||||
|
||||
struct fixedvec2
|
||||
{
|
||||
fixed_t x, y;
|
||||
};
|
||||
|
||||
class DDropItem : public DObject
|
||||
{
|
||||
DECLARE_CLASS(DDropItem, DObject)
|
||||
|
@ -1155,11 +1132,10 @@ private:
|
|||
friend class FActorIterator;
|
||||
friend bool P_IsTIDUsed(int tid);
|
||||
|
||||
sector_t *LinkToWorldForMapThing ();
|
||||
bool FixMapthingPos();
|
||||
|
||||
public:
|
||||
void LinkToWorld (bool buggy=false);
|
||||
void LinkToWorld (sector_t *sector);
|
||||
void LinkToWorld (bool spawningmapthing=false, FPortalGroupArray *groups = NULL, sector_t *sector = NULL);
|
||||
void UnlinkFromWorld ();
|
||||
void AdjustFloorClip ();
|
||||
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);
|
||||
AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, ActorFlags actorMask, DWORD wallMask);
|
||||
|
||||
#define S_FREETARGMOBJ 1
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include "r_renderer.h"
|
||||
#include "r_sky.h"
|
||||
#include "sbar.h"
|
||||
#include "d_player.h"
|
||||
#include "p_blockmap.h"
|
||||
|
||||
#include "m_cheat.h"
|
||||
#include "i_system.h"
|
||||
|
@ -58,6 +60,7 @@
|
|||
// State.
|
||||
#include "doomstat.h"
|
||||
#include "r_state.h"
|
||||
#include "r_utility.h"
|
||||
|
||||
// Data.
|
||||
#include "gstrings.h"
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "teaminfo.h"
|
||||
#include "d_net.h"
|
||||
#include "farchive.h"
|
||||
#include "d_player.h"
|
||||
|
||||
IMPLEMENT_POINTY_CLASS(DBot)
|
||||
DECLARE_POINTER(dest)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "p_local.h"
|
||||
#include "p_maputl.h"
|
||||
#include "b_bot.h"
|
||||
#include "g_game.h"
|
||||
#include "m_random.h"
|
||||
|
@ -20,6 +21,9 @@
|
|||
#include "i_system.h"
|
||||
#include "s_sound.h"
|
||||
#include "d_event.h"
|
||||
#include "d_player.h"
|
||||
#include "p_spec.h"
|
||||
#include "p_checkposition.h"
|
||||
|
||||
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 "d_net.h"
|
||||
#include "d_netinf.h"
|
||||
#include "d_player.h"
|
||||
|
||||
static FRandom pr_botspawn ("BotSpawn");
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
#include "a_keys.h"
|
||||
#include "d_event.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_bottrywalk ("BotTryWalk");
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "statnums.h"
|
||||
#include "d_net.h"
|
||||
#include "d_event.h"
|
||||
#include "d_player.h"
|
||||
|
||||
static FRandom pr_botmove ("BotMove");
|
||||
|
||||
|
|
|
@ -81,6 +81,17 @@ union QWORD_UNION
|
|||
typedef SDWORD fixed_t;
|
||||
typedef DWORD dsfixed_t; // fixedpt used by span drawer
|
||||
|
||||
struct fixedvec3
|
||||
{
|
||||
fixed_t x, y, z;
|
||||
};
|
||||
|
||||
struct fixedvec2
|
||||
{
|
||||
fixed_t x, y;
|
||||
};
|
||||
|
||||
|
||||
#define FIXED_MAX (signed)(0x7fffffff)
|
||||
#define FIXED_MIN (signed)(0x80000000)
|
||||
|
||||
|
|
|
@ -69,6 +69,8 @@
|
|||
#include "v_text.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "v_video.h"
|
||||
#include "r_utility.h"
|
||||
#include "r_data/r_interpolate.h"
|
||||
|
||||
extern FILE *Logfile;
|
||||
extern bool insave;
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "v_video.h"
|
||||
#include "p_spec.h"
|
||||
#include "hardware.h"
|
||||
#include "r_utility.h"
|
||||
#include "intermission/intermission.h"
|
||||
|
||||
EXTERN_CVAR (Int, disableautosave)
|
||||
|
|
|
@ -73,6 +73,8 @@
|
|||
#include "po_man.h"
|
||||
#include "autosegs.h"
|
||||
#include "v_video.h"
|
||||
#include "textures.h"
|
||||
#include "r_utility.h"
|
||||
#include "menu/menu.h"
|
||||
#include "intermission/intermission.h"
|
||||
|
||||
|
|
|
@ -197,6 +197,41 @@ struct PalEntry
|
|||
#endif
|
||||
};
|
||||
|
||||
class FArchive;
|
||||
class PClassInventory;
|
||||
|
||||
class FTextureID
|
||||
{
|
||||
friend class FTextureManager;
|
||||
friend FArchive &operator<< (FArchive &arc, FTextureID &tex);
|
||||
friend FTextureID GetHUDIcon(PClassInventory *cls);
|
||||
friend void R_InitSpriteDefs();
|
||||
|
||||
public:
|
||||
FTextureID() throw() {}
|
||||
bool isNull() const { return texnum == 0; }
|
||||
bool isValid() const { return texnum > 0; }
|
||||
bool Exists() const { return texnum >= 0; }
|
||||
void SetInvalid() { texnum = -1; }
|
||||
void SetNull() { texnum = 0; }
|
||||
bool operator ==(const FTextureID &other) const { return texnum == other.texnum; }
|
||||
bool operator !=(const FTextureID &other) const { return texnum != other.texnum; }
|
||||
FTextureID operator +(int offset) throw();
|
||||
int GetIndex() const { return texnum; } // Use this only if you absolutely need the index!
|
||||
|
||||
// The switch list needs these to sort the switches by texture index
|
||||
int operator -(FTextureID other) const { return texnum - other.texnum; }
|
||||
bool operator < (FTextureID other) const { return texnum < other.texnum; }
|
||||
bool operator > (FTextureID other) const { return texnum > other.texnum; }
|
||||
|
||||
protected:
|
||||
FTextureID(int num) { texnum = num; }
|
||||
private:
|
||||
int texnum;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Screenshot buffer image data types
|
||||
enum ESSType
|
||||
{
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "r_data/r_interpolate.h"
|
||||
#include "statnums.h"
|
||||
#include "farchive.h"
|
||||
#include "doomstat.h"
|
||||
|
||||
IMPLEMENT_CLASS (DSectorEffect)
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "i_system.h"
|
||||
#include "doomerrors.h"
|
||||
#include "farchive.h"
|
||||
#include "d_player.h"
|
||||
|
||||
|
||||
static cycle_t ThinkCycles;
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "sc_man.h"
|
||||
#include "g_level.h"
|
||||
#include "r_renderer.h"
|
||||
#include "d_player.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include "r_data/colormaps.h"
|
||||
#include "farchive.h"
|
||||
#include "p_setup.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
static FRandom pr_script("FScript");
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "actor.h"
|
||||
#include "info.h"
|
||||
#include "p_local.h"
|
||||
#include "p_spec.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "m_random.h"
|
||||
#include "gi.h"
|
||||
|
@ -15,6 +16,9 @@
|
|||
#include "m_bbox.h"
|
||||
#include "farchive.h"
|
||||
#include "portal.h"
|
||||
#include "d_player.h"
|
||||
#include "p_maputl.h"
|
||||
#include "g_shared/a_pickups.h"
|
||||
|
||||
// Include all the other Doom stuff here to reduce compile time
|
||||
#include "a_arachnotron.cpp"
|
||||
|
|
|
@ -80,6 +80,9 @@
|
|||
#include "m_joy.h"
|
||||
#include "farchive.h"
|
||||
#include "r_renderer.h"
|
||||
#include "r_utility.h"
|
||||
#include "a_morph.h"
|
||||
#include "p_spec.h"
|
||||
#include "r_data/colormaps.h"
|
||||
|
||||
#include <zlib.h>
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "r_data/r_translate.h"
|
||||
#include "doomstat.h"
|
||||
#include "farchive.h"
|
||||
#include "d_player.h"
|
||||
#include "a_morph.h"
|
||||
|
||||
// Include all the other Heretic stuff here to reduce compile time
|
||||
#include "a_chicken.cpp"
|
||||
|
|
|
@ -1077,12 +1077,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm)
|
|||
mo = Spawn<ARainPillar> (pos.x, pos.y, ONCEILINGZ, ALLOW_REPLACE);
|
||||
// We used bouncecount to store the 3D floor index in A_HideInCeiling
|
||||
if (!mo) return 0;
|
||||
if (mo->Sector->PortalGroup != self->Sector->PortalGroup)
|
||||
{
|
||||
// spawning this through a portal will never work right so abort right away.
|
||||
mo->Destroy();
|
||||
return 0;
|
||||
}
|
||||
fixed_t newz;
|
||||
if (self->bouncecount >= 0
|
||||
&& (unsigned)self->bouncecount < self->Sector->e->XFloor.ffloors.Size())
|
||||
newz = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPoint(pos.x, pos.y);// - 40 * FRACUNIT;
|
||||
if (self->bouncecount >= 0 && (unsigned)self->bouncecount < self->Sector->e->XFloor.ffloors.Size())
|
||||
newz = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPoint(mo);// - 40 * FRACUNIT;
|
||||
else
|
||||
newz = self->Sector->ceilingplane.ZatPoint(pos.x, pos.y);
|
||||
newz = self->Sector->ceilingplane.ZatPoint(mo);
|
||||
int moceiling = P_Find3DFloor(NULL, pos.x, pos.y, newz, false, false, newz);
|
||||
if (moceiling >= 0)
|
||||
mo->SetZ(newz - mo->height, false);
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include "farchive.h"
|
||||
#include "v_palette.h"
|
||||
#include "g_game.h"
|
||||
#include "p_blockmap.h"
|
||||
#include "r_utility.h"
|
||||
#include "p_maputl.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
// Include all the Hexen stuff here to reduce compile time
|
||||
#include "a_bats.cpp"
|
||||
|
|
|
@ -83,6 +83,8 @@
|
|||
#include "r_data/colormaps.h"
|
||||
#include "farchive.h"
|
||||
#include "r_renderer.h"
|
||||
#include "r_utility.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
#include "gi.h"
|
||||
|
||||
|
|
|
@ -3,11 +3,14 @@
|
|||
#include "a_artifacts.h"
|
||||
#include "gstrings.h"
|
||||
#include "p_local.h"
|
||||
#include "p_spec.h"
|
||||
#include "gi.h"
|
||||
#include "s_sound.h"
|
||||
#include "m_random.h"
|
||||
#include "doomstat.h"
|
||||
#include "g_game.h"
|
||||
#include "d_player.h"
|
||||
#include "a_morph.h"
|
||||
|
||||
static FRandom pr_tele ("TeleportSelf");
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "g_level.h"
|
||||
#include "doomstat.h"
|
||||
#include "farchive.h"
|
||||
#include "a_pickups.h"
|
||||
#include "d_player.h"
|
||||
|
||||
#define MAULATORTICS (25*35)
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "doomstat.h"
|
||||
#include "v_palette.h"
|
||||
#include "farchive.h"
|
||||
#include "r_utility.h"
|
||||
|
||||
#include "r_data/colormaps.h"
|
||||
|
||||
static FRandom pr_torch ("Torch");
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "colormatcher.h"
|
||||
#include "v_palette.h"
|
||||
#include "farchive.h"
|
||||
#include "doomdata.h"
|
||||
|
||||
static fixed_t DecalWidth, DecalLeft, DecalRight;
|
||||
static fixed_t SpreadZ;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "g_level.h"
|
||||
#include "r_sky.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "b_bot.h"
|
||||
#include "p_checkposition.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLASS(AFastProjectile)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "g_level.h"
|
||||
#include "farchive.h"
|
||||
#include "p_enemy.h"
|
||||
#include "d_player.h"
|
||||
|
||||
static FRandom pr_morphmonst ("MorphMonster");
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "g_game.h"
|
||||
#include "doomstat.h"
|
||||
#include "farchive.h"
|
||||
#include "d_player.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
static FRandom pr_restore ("RestorePos");
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include "a_sharedglobal.h"
|
||||
#include "statnums.h"
|
||||
#include "farchive.h"
|
||||
#include "d_player.h"
|
||||
#include "r_utility.h"
|
||||
|
||||
static FRandom pr_quake ("Quake");
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#include "a_action.h"
|
||||
#include "thingdef/thingdef.h"
|
||||
#include "v_text.h"
|
||||
#include "doomstat.h"
|
||||
#include "doomdata.h"
|
||||
|
||||
#define MAX_RANDOMSPAWNERS_RECURSION 32 // Should be largely more than enough, honestly.
|
||||
static FRandom pr_randomspawn("RandomSpawn");
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "thingdef/thingdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "farchive.h"
|
||||
#include "a_pickups.h"
|
||||
|
||||
static FRandom pr_spot ("SpecialSpot");
|
||||
static FRandom pr_spawnmace ("SpawnMace");
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
#include "doomstat.h"
|
||||
#include "g_level.h"
|
||||
#include "d_net.h"
|
||||
#include "d_player.h"
|
||||
#include "r_utility.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "d_event.h"
|
||||
#include "v_font.h"
|
||||
#include "farchive.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
// Include all the other Strife stuff here to reduce compile time
|
||||
#include "a_acolyte.cpp"
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "doomstat.h"
|
||||
#include "info.h"
|
||||
#include "m_fixed.h"
|
||||
#include "c_dispatch.h"
|
||||
|
@ -51,6 +52,8 @@
|
|||
#include "cmdlib.h"
|
||||
#include "g_level.h"
|
||||
#include "stats.h"
|
||||
#include "thingdef.h"
|
||||
#include "d_player.h"
|
||||
|
||||
extern void LoadActors ();
|
||||
extern void InitBotStuff();
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "m_bbox.h"
|
||||
#include "p_local.h"
|
||||
#include "p_maputl.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#include "d_dehacked.h"
|
||||
#include "gi.h"
|
||||
#include "farchive.h"
|
||||
#include "r_utility.h"
|
||||
#include "a_morph.h"
|
||||
|
||||
// [RH] Actually handle the cheat. The cheat code in st_stuff.c now just
|
||||
// writes some bytes to the network data stream, and the network code
|
||||
|
|
|
@ -38,10 +38,14 @@
|
|||
#include "templates.h"
|
||||
#include "p_local.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "p_maputl.h"
|
||||
#include "w_wad.h"
|
||||
#include "sc_man.h"
|
||||
#include "g_level.h"
|
||||
#include "p_terrain.h"
|
||||
#include "d_player.h"
|
||||
#include "r_utility.h"
|
||||
#include "p_spec.h"
|
||||
#include "r_data/colormaps.h"
|
||||
|
||||
EXTERN_CVAR(Int, vid_renderer)
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#include "templates.h"
|
||||
#include "p_local.h"
|
||||
#include "p_terrain.h"
|
||||
#include "p_maputl.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
|
||||
//============================================================================
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "templates.h"
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
#include "d_player.h"
|
||||
#include "p_spec.h"
|
||||
#include "g_level.h"
|
||||
#include "s_sound.h"
|
||||
|
@ -79,6 +80,8 @@
|
|||
#include "p_terrain.h"
|
||||
#include "version.h"
|
||||
#include "p_effect.h"
|
||||
#include "r_utility.h"
|
||||
#include "a_morph.h"
|
||||
|
||||
#include "g_shared/a_pickups.h"
|
||||
|
||||
|
|
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 "gi.h"
|
||||
#include "portal.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "r_state.h"
|
||||
#include "gi.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 "cmdlib.h"
|
||||
#include "farchive.h"
|
||||
#include "d_player.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
#include "gi.h"
|
||||
#include "v_palette.h"
|
||||
#include "colormatcher.h"
|
||||
#include "d_player.h"
|
||||
#include "r_utility.h"
|
||||
|
||||
CVAR (Int, cl_rockettrails, 1, CVAR_ARCHIVE);
|
||||
CVAR (Bool, r_rail_smartspiral, 0, CVAR_ARCHIVE);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "i_system.h"
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
#include "p_maputl.h"
|
||||
#include "d_player.h"
|
||||
#include "m_bbox.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "s_sound.h"
|
||||
|
@ -44,8 +46,12 @@
|
|||
#include "thingdef/thingdef.h"
|
||||
#include "d_dehacked.h"
|
||||
#include "g_level.h"
|
||||
#include "r_utility.h"
|
||||
#include "p_blockmap.h"
|
||||
#include "r_data/r_translate.h"
|
||||
#include "teaminfo.h"
|
||||
#include "p_spec.h"
|
||||
#include "p_checkposition.h"
|
||||
|
||||
#include "gi.h"
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "tables.h"
|
||||
#include "farchive.h"
|
||||
#include "p_3dmidtex.h"
|
||||
#include "p_spec.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:
|
||||
floor->m_Direction = -1;
|
||||
newheight = sec->floorplane.ZatPoint (0, 0) - sec->FindShortestTextureAround ();
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, newheight);
|
||||
newheight = sec->floorplane.ZatPoint (sec->soundorg[0], sec->soundorg[1]) - sec->FindShortestTextureAround ();
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist (sec->soundorg[0], sec->soundorg[1], newheight);
|
||||
break;
|
||||
|
||||
case DFloor::floorLowerToCeiling:
|
||||
|
@ -428,14 +429,14 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
|
|||
// since the code is identical to what was here. (Oddly
|
||||
// enough, BOOM preserved the code here even though it
|
||||
// also had this function.)
|
||||
newheight = sec->floorplane.ZatPoint (0, 0) + sec->FindShortestTextureAround ();
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, newheight);
|
||||
newheight = sec->floorplane.ZatPoint (sec->soundorg[0], sec->soundorg[1]) + sec->FindShortestTextureAround ();
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist (sec->soundorg[0], sec->soundorg[1], newheight);
|
||||
break;
|
||||
|
||||
case DFloor::floorRaiseAndChange:
|
||||
floor->m_Direction = 1;
|
||||
newheight = sec->floorplane.ZatPoint (0, 0) + height;
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, newheight);
|
||||
newheight = sec->floorplane.ZatPoint (sec->soundorg[0], sec->soundorg[1]) + height;
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist (sec->soundorg[0], sec->soundorg[1], newheight);
|
||||
if (line != NULL)
|
||||
{
|
||||
FTextureID oldpic = sec->GetTexture(sector_t::floor);
|
||||
|
@ -618,8 +619,8 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
|
|||
floor->m_Hexencrush = false;
|
||||
|
||||
floor->m_Speed = speed;
|
||||
height = sec->floorplane.ZatPoint (0, 0) + stairstep;
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, height);
|
||||
height = sec->floorplane.ZatPoint (sec->soundorg[0], sec->soundorg[1]) + stairstep;
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist (sec->soundorg[0], sec->soundorg[1], height);
|
||||
|
||||
texture = sec->GetTexture(sector_t::floor);
|
||||
osecnum = secnum; //jff 3/4/98 preserve loop index
|
||||
|
|
|
@ -65,6 +65,8 @@
|
|||
#include "version.h"
|
||||
#include "md5.h"
|
||||
#include "m_misc.h"
|
||||
#include "r_utility.h"
|
||||
#include "cmdlib.h"
|
||||
|
||||
void P_GetPolySpots (MapData * lump, TArray<FNodeBuilder::FPolyStart> &spots, TArray<FNodeBuilder::FPolyStart> &anchors);
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "g_level.h"
|
||||
#include "d_net.h"
|
||||
#include "d_netinf.h"
|
||||
#include "a_morph.h"
|
||||
|
||||
static FRandom pr_obituary ("Obituary");
|
||||
static FRandom pr_botrespawn ("BotRespawn");
|
||||
|
|
|
@ -27,8 +27,10 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
#include "p_lnspec.h"
|
||||
#include "doomstat.h"
|
||||
|
||||
// State.
|
||||
#include "r_state.h"
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "templates.h"
|
||||
#include "p_local.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -58,8 +58,12 @@
|
|||
#include "d_event.h"
|
||||
#include "gstrings.h"
|
||||
#include "portal.h"
|
||||
#include "po_man.h"
|
||||
#include "d_player.h"
|
||||
#include "r_utility.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "fragglescript/t_fs.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
// Remaps EE sector change types to Generic_Floor values. According to the Eternity Wiki:
|
||||
/*
|
||||
|
|
310
src/p_local.h
310
src/p_local.h
|
@ -24,13 +24,19 @@
|
|||
#define __P_LOCAL__
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "doomdef.h"
|
||||
#include "tables.h"
|
||||
#include "r_state.h"
|
||||
#include "r_utility.h"
|
||||
#include "d_player.h"
|
||||
|
||||
#include "a_morph.h"
|
||||
class player_t;
|
||||
class AActor;
|
||||
struct FPlayerStart;
|
||||
class PClassActor;
|
||||
struct fixedvec3;
|
||||
class APlayerPawn;
|
||||
struct line_t;
|
||||
struct sector_t;
|
||||
struct msecnode_t;
|
||||
struct secplane_t;
|
||||
struct FCheckPosition;
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -119,7 +125,7 @@ void P_PredictionLerpReset();
|
|||
#define SPF_TEMPPLAYER 1 // spawning a short-lived dummy player
|
||||
#define SPF_WEAPONFULLYUP 2 // spawn with weapon already raised
|
||||
|
||||
APlayerPawn *P_SpawnPlayer (struct FPlayerStart *mthing, int playernum, int flags=0);
|
||||
APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags=0);
|
||||
|
||||
void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move);
|
||||
int P_FaceMobj (AActor *source, AActor *target, angle_t *delta);
|
||||
|
@ -221,200 +227,6 @@ enum WARPF
|
|||
|
||||
|
||||
|
||||
//
|
||||
// P_MAPUTL
|
||||
//
|
||||
struct divline_t
|
||||
{
|
||||
fixed_t x;
|
||||
fixed_t y;
|
||||
fixed_t dx;
|
||||
fixed_t dy;
|
||||
|
||||
};
|
||||
|
||||
struct intercept_t
|
||||
{
|
||||
fixed_t frac; // along trace line
|
||||
bool isaline;
|
||||
bool done;
|
||||
union {
|
||||
AActor *thing;
|
||||
line_t *line;
|
||||
} d;
|
||||
};
|
||||
|
||||
typedef bool (*traverser_t) (intercept_t *in);
|
||||
|
||||
fixed_t P_AproxDistance (fixed_t dx, fixed_t dy);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_PointOnLineSide
|
||||
//
|
||||
// Returns 0 (front/on) or 1 (back)
|
||||
// [RH] inlined, stripped down, and made more precise
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line)
|
||||
{
|
||||
extern int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line);
|
||||
|
||||
return i_compatflags2 & COMPATF2_POINTONLINE
|
||||
? P_VanillaPointOnLineSide(x, y, line)
|
||||
: DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0;
|
||||
}
|
||||
|
||||
inline int P_PointOnLineSidePrecise (fixed_t x, fixed_t y, const line_t *line)
|
||||
{
|
||||
return DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_PointOnDivlineSide
|
||||
//
|
||||
// Same as P_PointOnLineSide except it uses divlines
|
||||
// [RH] inlined, stripped down, and made more precise
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line)
|
||||
{
|
||||
extern int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line);
|
||||
|
||||
return (i_compatflags2 & COMPATF2_POINTONLINE)
|
||||
? P_VanillaPointOnDivlineSide(x, y, line)
|
||||
: (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0);
|
||||
}
|
||||
|
||||
inline int P_PointOnDivlineSidePrecise (fixed_t x, fixed_t y, const divline_t *line)
|
||||
{
|
||||
return DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_MakeDivline
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
inline void P_MakeDivline (const line_t *li, divline_t *dl)
|
||||
{
|
||||
dl->x = li->v1->x;
|
||||
dl->y = li->v1->y;
|
||||
dl->dx = li->dx;
|
||||
dl->dy = li->dy;
|
||||
}
|
||||
|
||||
fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1);
|
||||
|
||||
struct FLineOpening
|
||||
{
|
||||
fixed_t top;
|
||||
fixed_t bottom;
|
||||
fixed_t range;
|
||||
fixed_t lowfloor;
|
||||
sector_t *bottomsec;
|
||||
sector_t *topsec;
|
||||
FTextureID ceilingpic;
|
||||
FTextureID floorpic;
|
||||
int floorterrain;
|
||||
bool touchmidtex;
|
||||
bool abovemidtex;
|
||||
};
|
||||
|
||||
void P_LineOpening (FLineOpening &open, AActor *thing, const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx=FIXED_MIN, fixed_t refy=0, int flags=0);
|
||||
|
||||
class FBoundingBox;
|
||||
struct polyblock_t;
|
||||
|
||||
class FBlockLinesIterator
|
||||
{
|
||||
int minx, maxx;
|
||||
int miny, maxy;
|
||||
|
||||
int curx, cury;
|
||||
polyblock_t *polyLink;
|
||||
int polyIndex;
|
||||
int *list;
|
||||
|
||||
void StartBlock(int x, int y);
|
||||
|
||||
public:
|
||||
FBlockLinesIterator(int minx, int miny, int maxx, int maxy, bool keepvalidcount = false);
|
||||
FBlockLinesIterator(const FBoundingBox &box);
|
||||
line_t *Next();
|
||||
void Reset() { StartBlock(minx, miny); }
|
||||
};
|
||||
|
||||
class FBlockThingsIterator
|
||||
{
|
||||
int minx, maxx;
|
||||
int miny, maxy;
|
||||
|
||||
int curx, cury;
|
||||
|
||||
FBlockNode *block;
|
||||
|
||||
int Buckets[32];
|
||||
|
||||
struct HashEntry
|
||||
{
|
||||
AActor *Actor;
|
||||
int Next;
|
||||
};
|
||||
HashEntry FixedHash[10];
|
||||
int NumFixedHash;
|
||||
TArray<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_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false);
|
||||
|
@ -423,45 +235,6 @@ AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false)
|
|||
// P_MAP
|
||||
//
|
||||
|
||||
struct FCheckPosition
|
||||
{
|
||||
// in
|
||||
AActor *thing;
|
||||
fixed_t x;
|
||||
fixed_t y;
|
||||
fixed_t z;
|
||||
|
||||
// out
|
||||
sector_t *sector;
|
||||
fixed_t floorz;
|
||||
fixed_t ceilingz;
|
||||
fixed_t dropoffz;
|
||||
FTextureID floorpic;
|
||||
int floorterrain;
|
||||
sector_t *floorsector;
|
||||
FTextureID ceilingpic;
|
||||
sector_t *ceilingsector;
|
||||
bool touchmidtex;
|
||||
bool abovemidtex;
|
||||
bool floatok;
|
||||
bool FromPMove;
|
||||
line_t *ceilingline;
|
||||
AActor *stepthing;
|
||||
// [RH] These are used by PIT_CheckThing and P_XYMovement to apply
|
||||
// ripping damage once per tic instead of once per move.
|
||||
bool DoRipping;
|
||||
TMap<AActor*, bool> LastRipped;
|
||||
int PushTime;
|
||||
|
||||
FCheckPosition(bool rip=false)
|
||||
{
|
||||
DoRipping = rip;
|
||||
PushTime = 0;
|
||||
FromPMove = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// If "floatok" true, move would be ok
|
||||
// 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, FName pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL);
|
||||
AActor *P_LinePickActor (AActor *t1, angle_t angle, fixed_t distance, int pitch, ActorFlags actorMask, DWORD wallMask);
|
||||
void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch);
|
||||
void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch);
|
||||
void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version
|
||||
|
@ -587,31 +359,10 @@ bool Check_Sides(AActor *, int, int); // phares
|
|||
// [RH]
|
||||
const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymove);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
//
|
||||
// Added so that in the source there's a clear distinction between
|
||||
// game engine and renderer specific calls.
|
||||
// (For ZDoom itself this doesn't make any difference here but for GZDoom it does.)
|
||||
//
|
||||
//----------------------------------------------------------------------------------
|
||||
subsector_t *P_PointInSubsector (fixed_t x, fixed_t y);
|
||||
inline sector_t *P_PointInSector(fixed_t x, fixed_t y)
|
||||
{
|
||||
return P_PointInSubsector(x,y)->sector;
|
||||
}
|
||||
|
||||
//
|
||||
// P_SETUP
|
||||
//
|
||||
extern BYTE* rejectmatrix; // for fast sight rejection
|
||||
extern int* blockmaplump; // offsets in blockmap are from here
|
||||
|
||||
extern int* blockmap;
|
||||
extern int bmapwidth;
|
||||
extern int bmapheight; // in mapblocks
|
||||
extern fixed_t bmaporgx;
|
||||
extern fixed_t bmaporgy; // origin of block map
|
||||
extern FBlockNode** blocklinks; // for thing chains
|
||||
|
||||
|
||||
|
||||
|
@ -639,46 +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
|
||||
//
|
||||
#include "p_spec.h"
|
||||
|
||||
bool P_AlignFlat (int linenum, int side, int fc);
|
||||
|
||||
#endif // __P_LOCAL__
|
||||
|
|
|
@ -34,10 +34,15 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
#include "p_spec.h"
|
||||
#include "d_player.h"
|
||||
#include "p_maputl.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "p_effect.h"
|
||||
#include "p_terrain.h"
|
||||
#include "p_trace.h"
|
||||
#include "p_checkposition.h"
|
||||
#include "r_utility.h"
|
||||
|
||||
#include "s_sound.h"
|
||||
#include "decallib.h"
|
||||
|
|
375
src/p_maputl.cpp
375
src/p_maputl.cpp
|
@ -32,9 +32,13 @@
|
|||
#include "m_bbox.h"
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "doomdata.h"
|
||||
#include "doomstat.h"
|
||||
#include "p_local.h"
|
||||
#include "p_maputl.h"
|
||||
#include "p_3dmidtex.h"
|
||||
#include "p_blockmap.h"
|
||||
#include "r_utility.h"
|
||||
|
||||
// State.
|
||||
#include "r_state.h"
|
||||
|
@ -42,6 +46,8 @@
|
|||
#include "po_man.h"
|
||||
|
||||
static AActor *RoughBlockCheck (AActor *mo, int index, void *);
|
||||
static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node);
|
||||
sector_t *P_PointInSectorBuggy(fixed_t x, fixed_t y);
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
@ -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
|
||||
// Links a thing into both a block and a subsector based on it's x y.
|
||||
// Links a thing into both a block and a subsector based on its x y.
|
||||
// Sets thing->sector properly
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void AActor::LinkToWorld (bool buggy)
|
||||
void AActor::LinkToWorld (bool spawningmapthing, FPortalGroupArray *groups, sector_t *sector)
|
||||
{
|
||||
// link into subsector
|
||||
sector_t *sec;
|
||||
|
||||
if (!buggy || numgamenodes == 0)
|
||||
if (spawningmapthing && (flags4 & MF4_FIXMAPTHINGPOS) && sector == NULL)
|
||||
{
|
||||
sec = P_PointInSector (X(), Y());
|
||||
}
|
||||
else
|
||||
{
|
||||
sec = LinkToWorldForMapThing ();
|
||||
if (FixMapthingPos()) spawningmapthing = false;
|
||||
}
|
||||
|
||||
LinkToWorld (sec);
|
||||
}
|
||||
|
||||
void AActor::LinkToWorld (sector_t *sec)
|
||||
{
|
||||
if (sec == NULL)
|
||||
if (sector == NULL)
|
||||
{
|
||||
LinkToWorld ();
|
||||
return;
|
||||
if (!spawningmapthing || numgamenodes == 0)
|
||||
{
|
||||
sector = P_PointInSector(X(), Y());
|
||||
}
|
||||
else
|
||||
{
|
||||
sector = P_PointInSectorBuggy(X(), Y());
|
||||
}
|
||||
}
|
||||
Sector = sec;
|
||||
|
||||
Sector = sector;
|
||||
subsector = R_PointInSubsector(X(), Y()); // this is from the rendering nodes, not the gameplay nodes!
|
||||
|
||||
if ( !(flags & MF_NOSECTOR) )
|
||||
|
@ -352,7 +437,7 @@ void AActor::LinkToWorld (sector_t *sec)
|
|||
// killough 8/11/98: simpler scheme using pointer-to-pointer prev
|
||||
// pointers, allows head nodes to be treated like everything else
|
||||
|
||||
AActor **link = &sec->thinglist;
|
||||
AActor **link = §or->thinglist;
|
||||
AActor *next = *link;
|
||||
if ((snext = next))
|
||||
next->sprev = &snext;
|
||||
|
@ -401,7 +486,7 @@ void AActor::LinkToWorld (sector_t *sec)
|
|||
for (int x = x1; x <= x2; ++x)
|
||||
{
|
||||
FBlockNode **link = &blocklinks[y*bmapwidth + x];
|
||||
FBlockNode *node = FBlockNode::Create (this, x, y);
|
||||
FBlockNode *node = FBlockNode::Create (this, x, y, this->Sector->PortalGroup);
|
||||
|
||||
// Link in to block
|
||||
if ((node->NextActor = *link) != NULL)
|
||||
|
@ -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)
|
||||
{
|
||||
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::Create (AActor *who, int x, int y)
|
||||
FBlockNode *FBlockNode::Create (AActor *who, int x, int y, int group)
|
||||
{
|
||||
FBlockNode *block;
|
||||
|
||||
|
@ -1524,6 +1447,67 @@ static AActor *RoughBlockCheck (AActor *mo, int index, void *param)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// [RH] LinkToWorldForMapThing
|
||||
//
|
||||
// Emulate buggy PointOnLineSide and fix actors that lie on
|
||||
// lines to compensate for some IWAD maps.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node)
|
||||
{
|
||||
// [RH] This might have been faster than two multiplies and an
|
||||
// add on a 386/486, but it certainly isn't on anything newer than that.
|
||||
fixed_t dx;
|
||||
fixed_t dy;
|
||||
double left;
|
||||
double right;
|
||||
|
||||
if (!node->dx)
|
||||
{
|
||||
if (x <= node->x)
|
||||
return node->dy > 0;
|
||||
|
||||
return node->dy < 0;
|
||||
}
|
||||
if (!node->dy)
|
||||
{
|
||||
if (y <= node->y)
|
||||
return node->dx < 0;
|
||||
|
||||
return node->dx > 0;
|
||||
}
|
||||
|
||||
dx = (x - node->x);
|
||||
dy = (y - node->y);
|
||||
|
||||
// Try to quickly decide by looking at sign bits.
|
||||
if ((node->dy ^ node->dx ^ dx ^ dy) & 0x80000000)
|
||||
{
|
||||
if ((node->dy ^ dx) & 0x80000000)
|
||||
{
|
||||
// (left is negative)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// we must use doubles here because the fixed point code will produce errors due to loss of precision for extremely short linedefs.
|
||||
left = (double)node->dy * (double)dx;
|
||||
right = (double)dy * (double)node->dx;
|
||||
|
||||
if (right < left)
|
||||
{
|
||||
// front side
|
||||
return 0;
|
||||
}
|
||||
// back side
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// P_VanillaPointOnLineSide
|
||||
|
@ -1612,3 +1596,24 @@ int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line)
|
|||
return 1; // back side
|
||||
}
|
||||
|
||||
sector_t *P_PointInSectorBuggy(fixed_t x, fixed_t y)
|
||||
{
|
||||
node_t *node = gamenodes + numgamenodes - 1;
|
||||
|
||||
do
|
||||
{
|
||||
// Use original buggy point-on-side test when spawning
|
||||
// things at level load so that the map spots in the
|
||||
// emerald key room of Hexen MAP01 are spawned on the
|
||||
// window ledge instead of the blocking floor in front
|
||||
// of it. Why do I consider it buggy? Because a point
|
||||
// that lies directly on a line should always be
|
||||
// considered as "in front" of the line. The orientation
|
||||
// of the line should be irrelevant.
|
||||
node = (node_t *)node->children[R_PointOnSideSlow(x, y, node)];
|
||||
} while (!((size_t)node & 1));
|
||||
|
||||
subsector_t *ssec = (subsector_t *)((BYTE *)node - 1);
|
||||
return ssec->sector;
|
||||
}
|
||||
|
||||
|
|
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 "doomdef.h"
|
||||
#include "p_local.h"
|
||||
#include "p_maputl.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "p_effect.h"
|
||||
#include "p_terrain.h"
|
||||
|
@ -66,6 +67,9 @@
|
|||
#include "farchive.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "r_renderer.h"
|
||||
#include "po_man.h"
|
||||
#include "p_spec.h"
|
||||
#include "p_checkposition.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -452,7 +456,7 @@ void AActor::Serialize (FArchive &arc)
|
|||
if (arc.IsLoading ())
|
||||
{
|
||||
touching_sectorlist = NULL;
|
||||
LinkToWorld (Sector);
|
||||
LinkToWorld (false, NULL, Sector);
|
||||
AddToHash ();
|
||||
SetShade (fillcolor);
|
||||
if (player)
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "r_state.h"
|
||||
#include "gi.h"
|
||||
#include "farchive.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
static FRandom pr_doplat ("DoPlat");
|
||||
|
||||
|
|
|
@ -34,8 +34,10 @@
|
|||
|
||||
#include "i_system.h"
|
||||
#include "p_local.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
// State.
|
||||
#include "d_player.h"
|
||||
#include "dobject.h"
|
||||
#include "doomstat.h"
|
||||
#include "r_state.h"
|
||||
|
@ -532,6 +534,7 @@ void P_SerializeWorld (FArchive &arc)
|
|||
{
|
||||
linePortals.Clear();
|
||||
}
|
||||
P_CollectLinkedPortals();
|
||||
}
|
||||
|
||||
void extsector_t::Serialize(FArchive &arc)
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#endif
|
||||
|
||||
#include "templates.h"
|
||||
#include "d_player.h"
|
||||
#include "m_argv.h"
|
||||
#include "m_swap.h"
|
||||
#include "m_bbox.h"
|
||||
|
@ -69,6 +70,9 @@
|
|||
#include "r_renderer.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "portal.h"
|
||||
#include "p_blockmap.h"
|
||||
#include "r_utility.h"
|
||||
#include "p_spec.h"
|
||||
#ifndef NO_EDATA
|
||||
#include "edata.h"
|
||||
#endif
|
||||
|
|
|
@ -14,11 +14,16 @@
|
|||
#include "doomdef.h"
|
||||
#include "i_system.h"
|
||||
#include "p_local.h"
|
||||
#include "p_maputl.h"
|
||||
#include "p_blockmap.h"
|
||||
#include "m_random.h"
|
||||
#include "m_bbox.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "g_level.h"
|
||||
#include "po_man.h"
|
||||
#include "r_utility.h"
|
||||
#include "b_bot.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
// State.
|
||||
#include "r_state.h"
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include "p_local.h"
|
||||
#include "cmdlib.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "p_maputl.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#include "w_wad.h"
|
||||
|
||||
#include "p_local.h"
|
||||
#include "p_spec.h"
|
||||
#include "p_blockmap.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "p_terrain.h"
|
||||
#include "p_acs.h"
|
||||
|
@ -64,7 +66,10 @@
|
|||
#include "a_keys.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "r_sky.h"
|
||||
#include "d_player.h"
|
||||
#include "portal.h"
|
||||
#include "p_maputl.h"
|
||||
#include "p_blockmap.h"
|
||||
#ifndef NO_EDATA
|
||||
#include "edata.h"
|
||||
#endif
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
#include "tarray.h"
|
||||
#include "cmdlib.h"
|
||||
#include "farchive.h"
|
||||
#include "p_maputl.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
#include "gi.h"
|
||||
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
#include "m_random.h"
|
||||
#include "i_system.h"
|
||||
#include "doomstat.h"
|
||||
#include "d_player.h"
|
||||
#include "p_maputl.h"
|
||||
#include "r_utility.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
#define FUDGEFACTOR 10
|
||||
|
||||
|
|
|
@ -47,6 +47,9 @@
|
|||
#include "g_level.h"
|
||||
#include "v_text.h"
|
||||
#include "i_system.h"
|
||||
#include "d_player.h"
|
||||
#include "r_utility.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
// Set of spawnable things for the Thing_Spawn and Thing_Projectile specials.
|
||||
FClassMap SpawnableThings;
|
||||
|
|
|
@ -31,7 +31,10 @@
|
|||
#include "sbar.h"
|
||||
#include "r_data/r_interpolate.h"
|
||||
#include "i_sound.h"
|
||||
#include "d_player.h"
|
||||
#include "g_level.h"
|
||||
#include "r_utility.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
extern gamestate_t wipegamestate;
|
||||
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
#include "i_system.h"
|
||||
#include "r_sky.h"
|
||||
#include "doomstat.h"
|
||||
#include "p_maputl.h"
|
||||
#include "r_defs.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
struct FTraceInfo
|
||||
{
|
||||
|
|
|
@ -54,6 +54,11 @@
|
|||
#include "gstrings.h"
|
||||
#include "farchive.h"
|
||||
#include "r_renderer.h"
|
||||
#include "d_player.h"
|
||||
#include "r_utility.h"
|
||||
#include "p_blockmap.h"
|
||||
#include "a_morph.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
static FRandom pr_skullpop ("SkullPop");
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "r_defs.h"
|
||||
#include "m_swap.h"
|
||||
#include "doomstat.h"
|
||||
#include "d_player.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
static int WriteTHINGS (FILE *file);
|
||||
static int WriteLINEDEFS (FILE *file);
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
#include "p_setup.h"
|
||||
#include "vectors.h"
|
||||
#include "farchive.h"
|
||||
#include "p_blockmap.h"
|
||||
#include "p_maputl.h"
|
||||
#include "r_utility.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
|
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);
|
||||
|
||||
|
||||
// ===== 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
|
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 "p_local.h"
|
||||
#include "p_lnspec.h"
|
||||
|
@ -11,6 +50,9 @@
|
|||
#include "a_sharedglobal.h"
|
||||
#include "i_system.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "p_maputl.h"
|
||||
#include "p_spec.h"
|
||||
#include "p_checkposition.h"
|
||||
|
||||
// simulation recurions maximum
|
||||
CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
||||
|
@ -18,7 +60,47 @@ CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
|||
FDisplacementTable Displacements;
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
if (tag)
|
||||
|
@ -52,6 +140,12 @@ static line_t *FindDestination(line_t *src, int tag)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Spawns a single line portal
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void P_SpawnLinePortal(line_t* line)
|
||||
{
|
||||
// portal destination is special argument #0
|
||||
|
@ -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)
|
||||
{
|
||||
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()
|
||||
{
|
||||
for (unsigned i = 0; i < linePortals.Size(); i++)
|
||||
|
@ -175,8 +301,15 @@ void P_FinalizePortals()
|
|||
FLinePortal * port = &linePortals[i];
|
||||
P_UpdatePortal(port);
|
||||
}
|
||||
P_CollectLinkedPortals();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Change the destination of a portal
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
static bool ChangePortalLine(line_t *line, int destid)
|
||||
{
|
||||
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)
|
||||
{
|
||||
int lineno;
|
||||
|
@ -221,7 +360,13 @@ bool P_ChangePortal(line_t *ln, int thisid, int destid)
|
|||
return res;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Calculate the intersection between two lines.
|
||||
// [ZZ] lots of floats here to avoid overflowing a lot
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
bool P_IntersectLines(fixed_t o1x, fixed_t o1y, fixed_t p1x, fixed_t p1y,
|
||||
fixed_t o2x, fixed_t o2y, fixed_t p2x, fixed_t p2y,
|
||||
fixed_t& rx, fixed_t& ry)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// check if this line is between portal and the viewer. clip away if it is.
|
||||
// (this may need some fixing)
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t viewy, bool partial, bool samebehind)
|
||||
{
|
||||
// check if this line is between portal and the viewer. clip away if it is.
|
||||
bool behind1 = !!P_PointOnLineSidePrecise(line->v1->x, line->v1->y, portal);
|
||||
bool behind2 = !!P_PointOnLineSidePrecise(line->v2->x, line->v2->y, portal);
|
||||
|
||||
|
@ -289,6 +440,12 @@ bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t vie
|
|||
return false;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Translates a coordinate by a portal's displacement
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void P_TranslatePortalXY(line_t* src, line_t* dst, fixed_t& x, fixed_t& y)
|
||||
{
|
||||
if (!src || !dst)
|
||||
|
@ -325,6 +482,12 @@ void P_TranslatePortalXY(line_t* src, line_t* dst, fixed_t& x, fixed_t& y)
|
|||
y = ty;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Translates a velocity vector by a portal's displacement
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void P_TranslatePortalVXVY(line_t* src, line_t* dst, fixed_t& vx, fixed_t& vy)
|
||||
{
|
||||
angle_t angle =
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Translates an angle by a portal's displacement
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void P_TranslatePortalAngle(line_t* src, line_t* dst, angle_t& angle)
|
||||
{
|
||||
if (!src || !dst)
|
||||
|
@ -359,6 +528,12 @@ void P_TranslatePortalAngle(line_t* src, line_t* dst, angle_t& angle)
|
|||
angle += xangle;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Translates a z-coordinate by a portal's displacement
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void P_TranslatePortalZ(line_t* src, line_t* dst, fixed_t& z)
|
||||
{
|
||||
// args[2] = 0 - no adjustment
|
||||
|
@ -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
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// portal tracer code
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
PortalTracer::PortalTracer(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy)
|
||||
{
|
||||
this->startx = startx;
|
||||
|
@ -521,8 +706,6 @@ bool PortalTracer::TraceStep()
|
|||
return (oDepth != depth); // if a portal has been found, return false
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// CollectSectors
|
||||
|
@ -566,6 +749,9 @@ static bool CollectSectors(int groupid, sector_t *origin)
|
|||
// Adds the displacement for one portal to the displacement array
|
||||
// (one version for sector to sector plane, one for line to line portals)
|
||||
//
|
||||
// Note: Despite the similarities to Eternity's equivalent this is
|
||||
// original code!
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
static void AddDisplacementForPortal(AStackPoint *portal)
|
||||
|
@ -779,14 +965,13 @@ void P_CreateLinkedPortals()
|
|||
ASkyViewpoint *box = sectors[i].SkyBoxes[j];
|
||||
if (box != NULL)
|
||||
{
|
||||
if (box->special1 == SKYBOX_LINKEDPORTAL && box->Sector->PortalGroup == 0)
|
||||
if (box->special1 == SKYBOX_LINKEDPORTAL && sectors[i].PortalGroup == 0)
|
||||
{
|
||||
CollectSectors(box->Sector->PortalGroup, box->Sector);
|
||||
box = box->Mate;
|
||||
if (box->special1 == SKYBOX_LINKEDPORTAL && box->Sector->PortalGroup == 0)
|
||||
{
|
||||
CollectSectors(box->Sector->PortalGroup, box->Sector);
|
||||
}
|
||||
// Note: the linked actor will be on the other side of the portal.
|
||||
// To get this side's group we will have to look at the mate object.
|
||||
CollectSectors(box->Mate->Sector->PortalGroup, §ors[i]);
|
||||
// We cannot process the backlink here because all we can access is the anchor object
|
||||
// If necessary that will have to be done for the other side's portal.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -812,10 +997,32 @@ void P_CreateLinkedPortals()
|
|||
if (dispxy.isSet && dispyx.isSet &&
|
||||
(dispxy.x != -dispyx.x || dispxy.y != -dispyx.y))
|
||||
{
|
||||
Printf("Link offset mismatch between groups %d and %d\n", x, y); // need to find some sectors to report.
|
||||
int sec1 = -1, sec2 = -1;
|
||||
for (int i = 0; i < numsectors && (sec1 == -1 || sec2 == -1); i++)
|
||||
{
|
||||
if (sec1 == -1 && sectors[i].PortalGroup == x) sec1 = i;
|
||||
if (sec2 == -1 && sectors[i].PortalGroup == y) sec2 = i;
|
||||
}
|
||||
Printf("Link offset mismatch between sectors %d and %d\n", sec1, sec2);
|
||||
bogus = true;
|
||||
}
|
||||
// todo: Find sectors that have no group but belong to a portal.
|
||||
// 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();
|
||||
|
@ -839,6 +1046,106 @@ void P_CreateLinkedPortals()
|
|||
//BuildBlockmap();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Collect all portal groups this actor would occupy at the given position
|
||||
// This is used to determine which parts of the map need to be checked.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
bool P_CollectConnectedGroups(AActor *actor, fixed_t newx, fixed_t newy, 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)
|
||||
{
|
||||
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 "p_local.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
|
||||
{
|
||||
|
@ -33,6 +53,14 @@ struct FDisplacementTable
|
|||
}
|
||||
};
|
||||
|
||||
extern FDisplacementTable Displacements;
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Flags and types for linedef portals
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
enum
|
||||
{
|
||||
PORTF_VISIBLE = 1,
|
||||
|
@ -60,6 +88,20 @@ enum
|
|||
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
|
||||
{
|
||||
line_t *mOrigin;
|
||||
|
@ -78,6 +120,12 @@ void P_SpawnLinePortal(line_t* line);
|
|||
void P_FinalizePortals();
|
||||
bool P_ChangePortal(line_t *ln, int thisid, int destid);
|
||||
void P_CreateLinkedPortals();
|
||||
bool P_CollectConnectedGroups(AActor *actor, fixed_t newx, fixed_t newy, FPortalGroupArray &out);
|
||||
void P_CollectLinkedPortals();
|
||||
inline int P_NumPortalGroups()
|
||||
{
|
||||
return Displacements.size;
|
||||
}
|
||||
|
||||
|
||||
/* 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_NormalizeVXVY(fixed_t& vx, fixed_t& vy);
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// basically, this is a teleporting tracer function,
|
||||
// which can be used by itself (to calculate portal-aware offsets, say, for projectiles)
|
||||
// or to teleport normal tracers (like hitscan, railgun, autoaim tracers)
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
class PortalTracer
|
||||
{
|
||||
public:
|
||||
|
@ -122,6 +175,12 @@ public:
|
|||
/* new code */
|
||||
fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y);
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// some wrappers around the portal data.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
|
||||
// returns true if the portal is crossable by actors
|
||||
inline bool line_t::isLinePortal() const
|
||||
|
@ -145,4 +204,22 @@ inline int line_t::getPortalAlignment() const
|
|||
return portalindex >= linePortals.Size() ? 0 : linePortals[portalindex].mAlign;
|
||||
}
|
||||
|
||||
inline bool sector_t::PortalBlocksView(int plane)
|
||||
{
|
||||
if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true;
|
||||
return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
inline bool sector_t::PortalBlocksMovement(int plane)
|
||||
{
|
||||
if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true;
|
||||
return !!(planes[plane].Flags & (PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
inline bool sector_t::PortalBlocksSound(int plane)
|
||||
{
|
||||
if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true;
|
||||
return !!(planes[plane].Flags & (PLANEF_BLOCKSOUND | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
#endif
|
31
src/r_defs.h
31
src/r_defs.h
|
@ -792,21 +792,9 @@ struct sector_t
|
|||
Flags &= ~SECF_SPECIALFLAGS;
|
||||
}
|
||||
|
||||
inline bool PortalBlocksView(int plane)
|
||||
{
|
||||
return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
bool PortalBlocksView(int plane);
|
||||
bool PortalBlocksMovement(int plane);
|
||||
bool PortalBlocksSound(int plane);
|
||||
|
||||
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
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "r_data/colormaps.h"
|
||||
#include "r_data/voxels.h"
|
||||
#include "p_local.h"
|
||||
#include "p_maputl.h"
|
||||
|
||||
// [RH] A c-buffer. Used for keeping track of offscreen voxel spans.
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
#include "r_renderer.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "farchive.h"
|
||||
#include "r_utility.h"
|
||||
#include "d_player.h"
|
||||
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
@ -878,16 +880,22 @@ void R_SetupFrame (AActor *actor)
|
|||
interpolator.DoInterpolations (r_TicFrac);
|
||||
|
||||
// Keep the view within the sector's floor and ceiling
|
||||
fixed_t theZ = viewsector->ceilingplane.ZatPoint (viewx, viewy) - 4*FRACUNIT;
|
||||
if (viewz > theZ)
|
||||
if (viewsector->PortalBlocksMovement(sector_t::ceiling))
|
||||
{
|
||||
viewz = theZ;
|
||||
fixed_t theZ = viewsector->ceilingplane.ZatPoint(viewx, viewy) - 4 * FRACUNIT;
|
||||
if (viewz > theZ)
|
||||
{
|
||||
viewz = theZ;
|
||||
}
|
||||
}
|
||||
|
||||
theZ = viewsector->floorplane.ZatPoint (viewx, viewy) + 4*FRACUNIT;
|
||||
if (viewz < theZ)
|
||||
if (viewsector->PortalBlocksMovement(sector_t::floor))
|
||||
{
|
||||
viewz = theZ;
|
||||
fixed_t theZ = viewsector->floorplane.ZatPoint(viewx, viewy) + 4 * FRACUNIT;
|
||||
if (viewz < theZ)
|
||||
{
|
||||
viewz = theZ;
|
||||
}
|
||||
}
|
||||
|
||||
if (!paused)
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "c_dispatch.h"
|
||||
#include "g_level.h"
|
||||
#include "farchive.h"
|
||||
#include "d_player.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "g_level.h"
|
||||
#include "po_man.h"
|
||||
#include "farchive.h"
|
||||
#include "d_player.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -37,36 +37,6 @@ class FTerrainTypeArray;
|
|||
class FGLTexture;
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -73,6 +73,9 @@
|
|||
#include "p_trace.h"
|
||||
#include "p_setup.h"
|
||||
#include "gstrings.h"
|
||||
#include "d_player.h"
|
||||
#include "p_maputl.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
AActor *SingleActorFromTID(int tid, AActor *defactor);
|
||||
|
||||
|
|
Loading…
Reference in a new issue