- VC++ doesn't seem to like the TArray serializer so I added a workaround

to be able to save the 3dMidtex attachment info.
- Fixed: The TArray serializer needs to be declared as a friend of TArray
  in order to be able to access its fields.
- Since there are no backwards compatibility issues due to savegame version
  bumping I closed all gaps in the level flag set.
- Bumped min. Savegame version and Netgame version for 3dMidtex related
  changes.
- Changed Jump and Crouch DMFlags into 3-way switches:
  0: map default, 1: off, 2: on. Since I needed new bits the rest of
  the DMFlag bit values had to be changed as a result.
- fixed: PTR_SlideTraverse didn't check ML_BLOCKMONSTERS for sliding
  actors without MF3_NOBLOCKMONST.
- Added MAPINFO commands 'checkswitchrange' and 'nocheckswitchrange'
  that can enable or disable switch range checking globally per map.
- Changed ML_3DMIDTEX to force ML_CHECKSWITCHRANGE.
- Added a ML_CHECKSWITCHRANGE flag which allows checking whether the 
  player can actually reach the switch he wants to use.
- Made DActiveButton::EWhere global so that I can use it outside thr
  DActiveButton class.

March 17, 2008 (Changes by Graf Zahl)
- Changed P_LineOpening to pass its result in a struct instead of global
  variables.
- Added Eternity's 3DMIDTEX feature (no Eternity code used though.)
  It should be feature complete with the exception of the ML_BLOCKMONSTERS
  flag handling. That particular part of Eternity's implementation is
  sub-optimal because it hijacks an existing flag and doesn't seem to make
  much sense to me. Maybe I'll implement it as a separate flag later.


SVN r810 (trunk)
This commit is contained in:
Christoph Oelckers 2008-03-18 18:18:18 +00:00
parent 3720f7fa7d
commit 7c87465d35
30 changed files with 1140 additions and 4022 deletions

View file

@ -1,3 +1,34 @@
March 18, 2008 (Changes by Graf Zahl)
- VC++ doesn't seem to like the TArray serializer so I added a workaround
to be able to save the 3dMidtex attachment info.
- Fixed: The TArray serializer needs to be declared as a friend of TArray
in order to be able to access its fields.
- Since there are no backwards compatibility issues due to savegame version
bumping I closed all gaps in the level flag set.
- Bumped min. Savegame version and Netgame version for 3dMidtex related
changes.
- Changed Jump and Crouch DMFlags into 3-way switches:
0: map default, 1: off, 2: on. Since I needed new bits the rest of
the DMFlag bit values had to be changed as a result.
- fixed: PTR_SlideTraverse didn't check ML_BLOCKMONSTERS for sliding
actors without MF3_NOBLOCKMONST.
- Added MAPINFO commands 'checkswitchrange' and 'nocheckswitchrange'
that can enable or disable switch range checking globally per map.
- Changed ML_3DMIDTEX to force ML_CHECKSWITCHRANGE.
- Added a ML_CHECKSWITCHRANGE flag which allows checking whether the
player can actually reach the switch he wants to use.
- Made DActiveButton::EWhere global so that I can use it outside thr
DActiveButton class.
March 17, 2008 (Changes by Graf Zahl)
- Changed P_LineOpening to pass its result in a struct instead of global
variables.
- Added Eternity's 3DMIDTEX feature (no Eternity code used though.)
It should be feature complete with the exception of the ML_BLOCKMONSTERS
flag handling. That particular part of Eternity's implementation is
sub-optimal because it hijacks an existing flag and doesn't seem to make
much sense to me. Maybe I'll implement it as a separate flag later.
March 17, 2008 March 17, 2008
- Fixed: The botinfo field of DCajunMaster was improperly listed as an object - Fixed: The botinfo field of DCajunMaster was improperly listed as an object
pointer. pointer.

View file

@ -376,11 +376,13 @@ CVAR (Flag, sv_monsterrespawn, dmflags, DF_MONSTERS_RESPAWN);
CVAR (Flag, sv_itemrespawn, dmflags, DF_ITEMS_RESPAWN); CVAR (Flag, sv_itemrespawn, dmflags, DF_ITEMS_RESPAWN);
CVAR (Flag, sv_fastmonsters, dmflags, DF_FAST_MONSTERS); CVAR (Flag, sv_fastmonsters, dmflags, DF_FAST_MONSTERS);
CVAR (Flag, sv_nojump, dmflags, DF_NO_JUMP); CVAR (Flag, sv_nojump, dmflags, DF_NO_JUMP);
CVAR (Flag, sv_allowjump, dmflags, DF_YES_JUMP);
CVAR (Flag, sv_nofreelook, dmflags, DF_NO_FREELOOK); CVAR (Flag, sv_nofreelook, dmflags, DF_NO_FREELOOK);
CVAR (Flag, sv_respawnsuper, dmflags, DF_RESPAWN_SUPER); CVAR (Flag, sv_respawnsuper, dmflags, DF_RESPAWN_SUPER);
CVAR (Flag, sv_nofov, dmflags, DF_NO_FOV); CVAR (Flag, sv_nofov, dmflags, DF_NO_FOV);
CVAR (Flag, sv_noweaponspawn, dmflags, DF_NO_COOP_WEAPON_SPAWN); CVAR (Flag, sv_noweaponspawn, dmflags, DF_NO_COOP_WEAPON_SPAWN);
CVAR (Flag, sv_nocrouch, dmflags, DF_NO_CROUCH); CVAR (Flag, sv_nocrouch, dmflags, DF_NO_CROUCH);
CVAR (Flag, sv_allowcrouch, dmflags, DF_YES_CROUCH);
//========================================================================== //==========================================================================
// //

View file

@ -149,9 +149,6 @@ static inline int GET_SPAC (int flags)
#define SPAC_OTHERCROSS 8 // [RH] Not a real activation type. Here for compatibility. #define SPAC_OTHERCROSS 8 // [RH] Not a real activation type. Here for compatibility.
// [RH] Monsters (as well as players) can active the line
#define ML_MONSTERSCANACTIVATE 0x2000
#define ML_BLOCK_PLAYERS 0x4000
// [RH] BOOM's ML_PASSUSE flag (conflicts with ML_REPEATSPECIAL) // [RH] BOOM's ML_PASSUSE flag (conflicts with ML_REPEATSPECIAL)
#define ML_PASSUSE_BOOM 0x0200 #define ML_PASSUSE_BOOM 0x0200
@ -169,13 +166,17 @@ static inline int GET_SPAC (int flags)
#define ML_RAILING_STRIFE 0x0200 #define ML_RAILING_STRIFE 0x0200
#define ML_BLOCK_FLOATERS_STRIFE 0x0400 #define ML_BLOCK_FLOATERS_STRIFE 0x0400
// Extended flags
#define ML_MONSTERSCANACTIVATE 0x00002000 // [RH] Monsters (as well as players) can active the line
#define ML_BLOCK_PLAYERS 0x00004000
#define ML_BLOCKEVERYTHING 0x00008000 // [RH] Line blocks everything #define ML_BLOCKEVERYTHING 0x00008000 // [RH] Line blocks everything
#define ML_ZONEBOUNDARY 0x00010000 #define ML_ZONEBOUNDARY 0x00010000
#define ML_RAILING 0x00020000 #define ML_RAILING 0x00020000
#define ML_BLOCK_FLOATERS 0x00040000 #define ML_BLOCK_FLOATERS 0x00040000
#define ML_CLIP_MIDTEX 0x00080000 // Automatic for every Strife line #define ML_CLIP_MIDTEX 0x00080000 // Automatic for every Strife line
#define ML_WRAP_MIDTEX 0x00100000 #define ML_WRAP_MIDTEX 0x00100000
#define ML_3DMIDTEX 0x00200000
#define ML_CHECKSWITCHRANGE 0x00400000
// Sector definition, from editing // Sector definition, from editing
typedef struct typedef struct

View file

@ -218,18 +218,20 @@ enum
DF_ITEMS_RESPAWN = 1 << 14, // Items other than invuln. and invis. respawn DF_ITEMS_RESPAWN = 1 << 14, // Items other than invuln. and invis. respawn
DF_FAST_MONSTERS = 1 << 15, // Monsters are fast (replaces -fast parm) DF_FAST_MONSTERS = 1 << 15, // Monsters are fast (replaces -fast parm)
DF_NO_JUMP = 1 << 16, // Don't allow jumping DF_NO_JUMP = 1 << 16, // Don't allow jumping
DF_NO_FREELOOK = 1 << 17, // Don't allow freelook DF_YES_JUMP = 2 << 16,
DF_RESPAWN_SUPER = 1 << 18, // Respawn invulnerability and invisibility DF_NO_FREELOOK = 1 << 18, // Don't allow freelook
DF_NO_FOV = 1 << 19, // Only let the arbitrator set FOV (for all players) DF_RESPAWN_SUPER = 1 << 19, // Respawn invulnerability and invisibility
DF_NO_COOP_WEAPON_SPAWN = 1 << 20, // Don't spawn multiplayer weapons in coop games DF_NO_FOV = 1 << 20, // Only let the arbitrator set FOV (for all players)
DF_NO_CROUCH = 1 << 21, // Don't allow crouching DF_NO_COOP_WEAPON_SPAWN = 1 << 21, // Don't spawn multiplayer weapons in coop games
DF_COOP_LOSE_INVENTORY = 1 << 22, // Lose all your old inventory when respawning in coop DF_NO_CROUCH = 1 << 22, // Don't allow crouching
DF_COOP_LOSE_KEYS = 1 << 23, // Lose keys when respawning in coop DF_YES_CROUCH = 2 << 22, //
DF_COOP_LOSE_WEAPONS = 1 << 24, // Lose weapons when respawning in coop DF_COOP_LOSE_INVENTORY = 1 << 24, // Lose all your old inventory when respawning in coop
DF_COOP_LOSE_ARMOR = 1 << 25, // Lose armor when respawning in coop DF_COOP_LOSE_KEYS = 1 << 25, // Lose keys when respawning in coop
DF_COOP_LOSE_POWERUPS = 1 << 26, // Lose powerups when respawning in coop DF_COOP_LOSE_WEAPONS = 1 << 26, // Lose weapons when respawning in coop
DF_COOP_LOSE_AMMO = 1 << 27, // Lose ammo when respawning in coop DF_COOP_LOSE_ARMOR = 1 << 27, // Lose armor when respawning in coop
DF_COOP_HALVE_AMMO = 1 << 28, // Lose half your ammo when respawning in coop (but not less than the normal starting amount) DF_COOP_LOSE_POWERUPS = 1 << 28, // Lose powerups when respawning in coop
DF_COOP_LOSE_AMMO = 1 << 29, // Lose ammo when respawning in coop
DF_COOP_HALVE_AMMO = 1 << 30, // Lose half your ammo when respawning in coop (but not less than the normal starting amount)
}; };
// [BC] More dmflags. w00p! // [BC] More dmflags. w00p!

View file

@ -25,6 +25,7 @@
#include "dsectoreffect.h" #include "dsectoreffect.h"
#include "gi.h" #include "gi.h"
#include "p_local.h" #include "p_local.h"
#include "p_3dmidtex.h"
IMPLEMENT_CLASS (DSectorEffect) IMPLEMENT_CLASS (DSectorEffect)
@ -103,6 +104,16 @@ DMovingCeiling::DMovingCeiling (sector_t *sector)
setinterpolation (INTERP_SectorCeiling, sector); setinterpolation (INTERP_SectorCeiling, sector);
} }
bool DMover::MoveAttached(int crush, fixed_t move, int floorOrCeiling, bool resetfailed)
{
if (!P_Scroll3dMidtex(m_Sector, crush, move, !!floorOrCeiling) && resetfailed)
{
P_Scroll3dMidtex(m_Sector, crush, -move, !!floorOrCeiling);
return false;
}
return true;
}
// //
// Move a plane (floor or ceiling) and check for crushing // Move a plane (floor or ceiling) and check for crushing
// [RH] Crush specifies the actual amount of crushing damage inflictable. // [RH] Crush specifies the actual amount of crushing damage inflictable.
@ -114,6 +125,8 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
{ {
bool flag; bool flag;
fixed_t lastpos; fixed_t lastpos;
fixed_t movedest;
fixed_t move;
//fixed_t destheight; //jff 02/04/98 used to keep floors/ceilings //fixed_t destheight; //jff 02/04/98 used to keep floors/ceilings
// from moving thru each other // from moving thru each other
switch (floorOrCeiling) switch (floorOrCeiling)
@ -125,32 +138,40 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
{ {
case -1: case -1:
// DOWN // DOWN
m_Sector->floorplane.ChangeHeight (-speed); movedest = m_Sector->floorplane.GetChangedHeight (-speed);
if (m_Sector->floorplane.d >= dest) if (movedest >= dest)
{ {
move = m_Sector->floorplane.HeightDiff (lastpos, dest);
if (!MoveAttached(crush, move, 0, true)) return crushed;
m_Sector->floorplane.d = dest; m_Sector->floorplane.d = dest;
flag = P_ChangeSector (m_Sector, crush, flag = P_ChangeSector (m_Sector, crush, move, 0);
m_Sector->floorplane.HeightDiff (lastpos), 0);
if (flag) if (flag)
{ {
m_Sector->floorplane.d = lastpos; m_Sector->floorplane.d = lastpos;
P_ChangeSector (m_Sector, crush, P_ChangeSector (m_Sector, crush, -move, 0);
m_Sector->floorplane.HeightDiff (dest), 0); MoveAttached(crush, -move, 0, false);
} }
else else
{ {
m_Sector->floortexz += m_Sector->floorplane.HeightDiff (lastpos); m_Sector->floortexz += move;
m_Sector->AdjustFloorClip (); m_Sector->AdjustFloorClip ();
} }
return pastdest; return pastdest;
} }
else else
{ {
if (!MoveAttached(crush, -speed, 0, true)) return crushed;
m_Sector->floorplane.d = movedest;
flag = P_ChangeSector (m_Sector, crush, -speed, 0); flag = P_ChangeSector (m_Sector, crush, -speed, 0);
if (flag) if (flag)
{ {
m_Sector->floorplane.d = lastpos; m_Sector->floorplane.d = lastpos;
P_ChangeSector (m_Sector, crush, speed, 0); P_ChangeSector (m_Sector, crush, speed, 0);
MoveAttached(crush, speed, 0, false);
return crushed; return crushed;
} }
else else
@ -172,27 +193,37 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
{ {
dest = -m_Sector->ceilingplane.d; dest = -m_Sector->ceilingplane.d;
} }
m_Sector->floorplane.ChangeHeight (speed);
if (m_Sector->floorplane.d <= dest) movedest = m_Sector->floorplane.GetChangedHeight (speed);
if (movedest <= dest)
{ {
move = m_Sector->floorplane.HeightDiff (lastpos, dest);
if (!MoveAttached(crush, move, 0, true)) return crushed;
m_Sector->floorplane.d = dest; m_Sector->floorplane.d = dest;
flag = P_ChangeSector (m_Sector, crush,
m_Sector->floorplane.HeightDiff (lastpos), 0); flag = P_ChangeSector (m_Sector, crush, move, 0);
if (flag) if (flag)
{ {
m_Sector->floorplane.d = lastpos; m_Sector->floorplane.d = lastpos;
P_ChangeSector (m_Sector, crush, P_ChangeSector (m_Sector, crush, -move, 0);
m_Sector->floorplane.HeightDiff (dest), 0); MoveAttached(crush, -move, 0, false);
} }
else else
{ {
m_Sector->floortexz += m_Sector->floorplane.HeightDiff (lastpos); m_Sector->floortexz += move;
m_Sector->AdjustFloorClip (); m_Sector->AdjustFloorClip ();
} }
return pastdest; return pastdest;
} }
else else
{ {
if (!MoveAttached(crush, speed, 0, true)) return crushed;
m_Sector->floorplane.d = movedest;
// COULD GET CRUSHED // COULD GET CRUSHED
flag = P_ChangeSector (m_Sector, crush, speed, 0); flag = P_ChangeSector (m_Sector, crush, speed, 0);
if (flag) if (flag)
@ -205,6 +236,7 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
} }
m_Sector->floorplane.d = lastpos; m_Sector->floorplane.d = lastpos;
P_ChangeSector (m_Sector, crush, -speed, 0); P_ChangeSector (m_Sector, crush, -speed, 0);
MoveAttached(crush, -speed, 0, false);
return crushed; return crushed;
} }
m_Sector->floortexz += m_Sector->floorplane.HeightDiff (lastpos); m_Sector->floortexz += m_Sector->floorplane.HeightDiff (lastpos);
@ -230,27 +262,34 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
{ {
dest = -m_Sector->floorplane.d; dest = -m_Sector->floorplane.d;
} }
m_Sector->ceilingplane.ChangeHeight (-speed); movedest = m_Sector->ceilingplane.GetChangedHeight (-speed);
if (m_Sector->ceilingplane.d <= dest) if (movedest <= dest)
{ {
move = m_Sector->ceilingplane.HeightDiff (lastpos, dest);
if (!MoveAttached(crush, move, 1, true)) return crushed;
m_Sector->ceilingplane.d = dest; m_Sector->ceilingplane.d = dest;
flag = P_ChangeSector (m_Sector, crush, flag = P_ChangeSector (m_Sector, crush, move, 1);
m_Sector->ceilingplane.HeightDiff (lastpos), 1);
if (flag) if (flag)
{ {
m_Sector->ceilingplane.d = lastpos; m_Sector->ceilingplane.d = lastpos;
P_ChangeSector (m_Sector, crush, P_ChangeSector (m_Sector, crush, -move, 1);
m_Sector->ceilingplane.HeightDiff (dest), 1); MoveAttached(crush, -move, 1, false);
} }
else else
{ {
m_Sector->ceilingtexz += m_Sector->ceilingplane.HeightDiff (lastpos); m_Sector->ceilingtexz += move;
} }
return pastdest; return pastdest;
} }
else else
{ {
if (!MoveAttached(crush, -speed, 1, true)) return crushed;
m_Sector->ceilingplane.d = movedest;
// COULD GET CRUSHED // COULD GET CRUSHED
flag = P_ChangeSector (m_Sector, crush, -speed, 1); flag = P_ChangeSector (m_Sector, crush, -speed, 1);
if (flag) if (flag)
@ -262,6 +301,7 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
} }
m_Sector->ceilingplane.d = lastpos; m_Sector->ceilingplane.d = lastpos;
P_ChangeSector (m_Sector, crush, speed, 1); P_ChangeSector (m_Sector, crush, speed, 1);
MoveAttached(crush, speed, 1, false);
return crushed; return crushed;
} }
m_Sector->ceilingtexz += m_Sector->ceilingplane.HeightDiff (lastpos); m_Sector->ceilingtexz += m_Sector->ceilingplane.HeightDiff (lastpos);
@ -270,36 +310,42 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush,
case 1: case 1:
// UP // UP
m_Sector->ceilingplane.ChangeHeight (speed); movedest = m_Sector->ceilingplane.GetChangedHeight (speed);
if (m_Sector->ceilingplane.d >= dest) if (movedest >= dest)
{ {
move = m_Sector->ceilingplane.HeightDiff (lastpos, dest);
if (!MoveAttached(crush, move, 1, true)) return crushed;
m_Sector->ceilingplane.d = dest; m_Sector->ceilingplane.d = dest;
flag = P_ChangeSector (m_Sector, crush,
m_Sector->ceilingplane.HeightDiff (lastpos), 1); flag = P_ChangeSector (m_Sector, crush, move, 1);
if (flag) if (flag)
{ {
m_Sector->ceilingplane.d = lastpos; m_Sector->ceilingplane.d = lastpos;
P_ChangeSector (m_Sector, crush, P_ChangeSector (m_Sector, crush, move, 1);
m_Sector->ceilingplane.HeightDiff (dest), 1); MoveAttached(crush, move, 1, false);
} }
else else
{ {
m_Sector->ceilingtexz += m_Sector->ceilingplane.HeightDiff (lastpos); m_Sector->ceilingtexz += move;
} }
return pastdest; return pastdest;
} }
else else
{ {
if (!MoveAttached(crush, speed, 1, true)) return crushed;
m_Sector->ceilingplane.d = movedest;
flag = P_ChangeSector (m_Sector, crush, speed, 1); flag = P_ChangeSector (m_Sector, crush, speed, 1);
// UNUSED
#if 0
if (flag) if (flag)
{ {
m_Sector->ceilingplane.d = lastpos; m_Sector->ceilingplane.d = lastpos;
P_ChangeSector (m_Sector, crush, -speed, 1); P_ChangeSector (m_Sector, crush, -speed, 1);
MoveAttached(crush, -speed, 1, false);
return crushed; return crushed;
} }
#endif
m_Sector->ceilingtexz += m_Sector->ceilingplane.HeightDiff (lastpos); m_Sector->ceilingtexz += m_Sector->ceilingplane.HeightDiff (lastpos);
} }
break; break;

View file

@ -29,6 +29,7 @@ public:
protected: protected:
enum EResult { ok, crushed, pastdest }; enum EResult { ok, crushed, pastdest };
private: private:
bool MoveAttached(int crush, fixed_t move, int floorOrCeiling, bool resetfailed);
EResult MovePlane (fixed_t speed, fixed_t dest, int crush, int floorOrCeiling, int direction); EResult MovePlane (fixed_t speed, fixed_t dest, int crush, int floorOrCeiling, int direction);
protected: protected:
DMover (); DMover ();

View file

@ -307,6 +307,8 @@ static const char *MapInfoMapLevel[] =
"skyfog", "skyfog",
"teamplayon", "teamplayon",
"teamplayoff", "teamplayoff",
"checkswitchrange",
"nocheckswitchrange",
NULL NULL
}; };
@ -377,8 +379,8 @@ MapHandlers[] =
{ MITYPE_SETFLAG, LEVEL_FORCENOSKYSTRETCH, 0 }, { MITYPE_SETFLAG, LEVEL_FORCENOSKYSTRETCH, 0 },
{ MITYPE_SCFLAGS, LEVEL_FREELOOK_YES, ~LEVEL_FREELOOK_NO }, { MITYPE_SCFLAGS, LEVEL_FREELOOK_YES, ~LEVEL_FREELOOK_NO },
{ MITYPE_SCFLAGS, LEVEL_FREELOOK_NO, ~LEVEL_FREELOOK_YES }, { MITYPE_SCFLAGS, LEVEL_FREELOOK_NO, ~LEVEL_FREELOOK_YES },
{ MITYPE_SCFLAGS, LEVEL_JUMP_YES, ~LEVEL_JUMP_NO }, { MITYPE_CLRFLAG, LEVEL_JUMP_NO, 0 },
{ MITYPE_SCFLAGS, LEVEL_JUMP_NO, ~LEVEL_JUMP_YES }, { MITYPE_SETFLAG, LEVEL_JUMP_NO, 0 },
{ MITYPE_SCFLAGS, LEVEL_FALLDMG_HX, ~LEVEL_FALLDMG_ZD }, { MITYPE_SCFLAGS, LEVEL_FALLDMG_HX, ~LEVEL_FALLDMG_ZD },
{ MITYPE_SCFLAGS, LEVEL_FALLDMG_ZD, ~LEVEL_FALLDMG_HX }, { MITYPE_SCFLAGS, LEVEL_FALLDMG_ZD, ~LEVEL_FALLDMG_HX },
{ MITYPE_SCFLAGS, LEVEL_FALLDMG_ZD, ~LEVEL_FALLDMG_HX }, { MITYPE_SCFLAGS, LEVEL_FALLDMG_ZD, ~LEVEL_FALLDMG_HX },
@ -423,8 +425,8 @@ MapHandlers[] =
{ MITYPE_LUMPNAME, lioffset(soundinfo), 0 }, { MITYPE_LUMPNAME, lioffset(soundinfo), 0 },
{ MITYPE_SETFLAG, LEVEL_CLIPMIDTEX, 0 }, { MITYPE_SETFLAG, LEVEL_CLIPMIDTEX, 0 },
{ MITYPE_SETFLAG, LEVEL_WRAPMIDTEX, 0 }, { MITYPE_SETFLAG, LEVEL_WRAPMIDTEX, 0 },
{ MITYPE_SCFLAGS, LEVEL_CROUCH_YES, ~LEVEL_CROUCH_NO }, { MITYPE_CLRFLAG, LEVEL_CROUCH_NO, 0 },
{ MITYPE_SCFLAGS, LEVEL_CROUCH_NO, ~LEVEL_CROUCH_YES }, { MITYPE_SETFLAG, LEVEL_CROUCH_NO, 0 },
{ MITYPE_SCFLAGS, LEVEL_PAUSE_MUSIC_IN_MENUS, 0 }, { MITYPE_SCFLAGS, LEVEL_PAUSE_MUSIC_IN_MENUS, 0 },
{ MITYPE_COMPATFLAG, COMPATF_SHORTTEX}, { MITYPE_COMPATFLAG, COMPATF_SHORTTEX},
{ MITYPE_COMPATFLAG, COMPATF_STAIRINDEX}, { MITYPE_COMPATFLAG, COMPATF_STAIRINDEX},
@ -454,6 +456,8 @@ MapHandlers[] =
{ MITYPE_INT, lioffset(skyfog), 0 }, { MITYPE_INT, lioffset(skyfog), 0 },
{ MITYPE_SCFLAGS, LEVEL_FORCETEAMPLAYON, ~LEVEL_FORCETEAMPLAYOFF }, { MITYPE_SCFLAGS, LEVEL_FORCETEAMPLAYON, ~LEVEL_FORCETEAMPLAYOFF },
{ MITYPE_SCFLAGS, LEVEL_FORCETEAMPLAYOFF, ~LEVEL_FORCETEAMPLAYON }, { MITYPE_SCFLAGS, LEVEL_FORCETEAMPLAYOFF, ~LEVEL_FORCETEAMPLAYON },
{ MITYPE_SETFLAG, LEVEL_CHECKSWITCHRANGE, 0 },
{ MITYPE_CLRFLAG, LEVEL_CHECKSWITCHRANGE, 0 },
}; };
static const char *MapInfoClusterLevel[] = static const char *MapInfoClusterLevel[] =
@ -2426,20 +2430,20 @@ void G_InitLevelLocals ()
bool level_locals_s::IsJumpingAllowed() const bool level_locals_s::IsJumpingAllowed() const
{ {
if (level.flags & LEVEL_JUMP_NO) if (dmflags & DF_NO_JUMP)
return false; return false;
if (level.flags & LEVEL_JUMP_YES) if (dmflags & DF_YES_JUMP)
return true; return true;
return !(dmflags & DF_NO_JUMP); return !(level.flags & LEVEL_JUMP_NO);
} }
bool level_locals_s::IsCrouchingAllowed() const bool level_locals_s::IsCrouchingAllowed() const
{ {
if (level.flags & LEVEL_CROUCH_NO) if (dmflags & DF_NO_CROUCH)
return false; return false;
if (level.flags & LEVEL_CROUCH_YES) if (dmflags & DF_YES_CROUCH)
return true; return true;
return !(dmflags & DF_NO_CROUCH); return !(level.flags & LEVEL_CROUCH_NO);
} }
bool level_locals_s::IsFreelookAllowed() const bool level_locals_s::IsFreelookAllowed() const

View file

@ -62,8 +62,8 @@
#define LEVEL_SNDSEQTOTALCTRL UCONST64(0x00001000) #define LEVEL_SNDSEQTOTALCTRL UCONST64(0x00001000)
#define LEVEL_FORCENOSKYSTRETCH UCONST64(0x00002000) #define LEVEL_FORCENOSKYSTRETCH UCONST64(0x00002000)
#define LEVEL_JUMP_NO UCONST64(0x00004000) #define LEVEL_CROUCH_NO UCONST64(0x00004000)
#define LEVEL_JUMP_YES UCONST64(0x00008000) #define LEVEL_JUMP_NO UCONST64(0x00008000)
#define LEVEL_FREELOOK_NO UCONST64(0x00010000) #define LEVEL_FREELOOK_NO UCONST64(0x00010000)
#define LEVEL_FREELOOK_YES UCONST64(0x00020000) #define LEVEL_FREELOOK_YES UCONST64(0x00020000)
@ -103,20 +103,20 @@
#define LEVEL_CLIPMIDTEX UCONST64(0x20000000000) #define LEVEL_CLIPMIDTEX UCONST64(0x20000000000)
#define LEVEL_WRAPMIDTEX UCONST64(0x40000000000) #define LEVEL_WRAPMIDTEX UCONST64(0x40000000000)
#define LEVEL_CROUCH_NO UCONST64(0x80000000000) #define LEVEL_CHECKSWITCHRANGE UCONST64(0x80000000000)
#define LEVEL_CROUCH_YES UCONST64(0x100000000000)
#define LEVEL_PAUSE_MUSIC_IN_MENUS UCONST64(0x200000000000) #define LEVEL_PAUSE_MUSIC_IN_MENUS UCONST64(0x100000000000)
#define LEVEL_TOTALINFIGHTING UCONST64(0x400000000000) #define LEVEL_TOTALINFIGHTING UCONST64(0x200000000000)
#define LEVEL_NOINFIGHTING UCONST64(0x800000000000) #define LEVEL_NOINFIGHTING UCONST64(0x400000000000)
#define LEVEL_NOMONSTERS UCONST64(0x1000000000000) #define LEVEL_NOMONSTERS UCONST64(0x800000000000)
#define LEVEL_INFINITE_FLIGHT UCONST64(0x2000000000000) #define LEVEL_INFINITE_FLIGHT UCONST64(0x1000000000000)
#define LEVEL_ALLOWRESPAWN UCONST64(0x4000000000000) #define LEVEL_ALLOWRESPAWN UCONST64(0x2000000000000)
#define LEVEL_FORCETEAMPLAYON UCONST64(0x4000000000000)
#define LEVEL_FORCETEAMPLAYOFF UCONST64(0x8000000000000)
#define LEVEL_FORCETEAMPLAYON UCONST64(0x8000000000000)
#define LEVEL_FORCETEAMPLAYOFF UCONST64(0x10000000000000)
struct acsdefered_s; struct acsdefered_s;

View file

@ -1007,6 +1007,18 @@ value_t FallingDM[4] = {
{ DF_FORCE_FALLINGZD|DF_FORCE_FALLINGHX, "Strife" } { DF_FORCE_FALLINGZD|DF_FORCE_FALLINGHX, "Strife" }
}; };
value_t DF_Jump[3] = {
{ 0, "Default" },
{ DF_NO_JUMP, "Off" },
{ DF_YES_JUMP, "On" }
};
value_t DF_Crouch[3] = {
{ 0, "Default" },
{ DF_NO_CROUCH, "Off" },
{ DF_YES_CROUCH, "On" }
};
static menuitem_t DMFlagsItems[] = { static menuitem_t DMFlagsItems[] = {
{ discrete, "Teamplay", {&teamplay}, {2.0}, {0.0}, {0.0}, {OnOff} }, { discrete, "Teamplay", {&teamplay}, {2.0}, {0.0}, {0.0}, {OnOff} },
@ -1015,8 +1027,6 @@ static menuitem_t DMFlagsItems[] = {
{ discrete, "Smart Autoaim", {&sv_smartaim}, {4.0}, {0.0}, {0.0}, {SmartAim} }, { discrete, "Smart Autoaim", {&sv_smartaim}, {4.0}, {0.0}, {0.0}, {SmartAim} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ bitmask, "Falling damage", {&dmflags}, {4.0}, {DF_FORCE_FALLINGZD|DF_FORCE_FALLINGHX}, {0}, {FallingDM} }, { bitmask, "Falling damage", {&dmflags}, {4.0}, {DF_FORCE_FALLINGZD|DF_FORCE_FALLINGHX}, {0}, {FallingDM} },
// { bitflag, "Falling damage (old)", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_FORCE_FALLINGZD} },
// { bitflag, "Falling damage (Hexen)",{&dmflags}, {0}, {0}, {0}, {(value_t *)DF_FORCE_FALLINGHX} },
{ bitflag, "Drop weapon", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_WEAPONDROP} }, { bitflag, "Drop weapon", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_WEAPONDROP} },
{ bitflag, "Double ammo", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_DOUBLEAMMO} }, { bitflag, "Double ammo", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_DOUBLEAMMO} },
{ bitflag, "Infinite ammo", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_INFINITE_AMMO} }, { bitflag, "Infinite ammo", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_INFINITE_AMMO} },
@ -1028,8 +1038,8 @@ static menuitem_t DMFlagsItems[] = {
{ bitflag, "Big powerups respawn", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_RESPAWN_SUPER} }, { bitflag, "Big powerups respawn", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_RESPAWN_SUPER} },
{ bitflag, "Fast monsters", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_FAST_MONSTERS} }, { bitflag, "Fast monsters", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_FAST_MONSTERS} },
{ bitflag, "Degeneration", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_DEGENERATION} }, { bitflag, "Degeneration", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_DEGENERATION} },
{ bitflag, "Allow jump", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_JUMP} }, { bitmask, "Allow jump", {&dmflags}, {3.0}, {DF_NO_JUMP|DF_YES_JUMP}, {0}, {DF_Jump} },
{ bitflag, "Allow crouch", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_CROUCH} }, { bitmask, "Allow crouch", {&dmflags}, {3.0}, {DF_NO_CROUCH|DF_YES_CROUCH}, {0}, {DF_Crouch} },
{ bitflag, "Allow freelook", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_FREELOOK} }, { bitflag, "Allow freelook", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_FREELOOK} },
{ bitflag, "Allow FOV", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_FOV} }, { bitflag, "Allow FOV", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_FOV} },
{ bitflag, "Allow BFG aiming", {&dmflags2}, {1}, {0}, {0}, {(value_t *)DF2_NO_FREEAIMBFG} }, { bitflag, "Allow BFG aiming", {&dmflags2}, {1}, {0}, {0}, {(value_t *)DF2_NO_FREEAIMBFG} },

308
src/p_3dmidtex.cpp Normal file
View file

@ -0,0 +1,308 @@
/*
** p_3dmidtex.cpp
**
** Eternity-style 3D-midtex handling
** (No original Eternity code here!)
**
**---------------------------------------------------------------------------
** Copyright 2008 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.
**---------------------------------------------------------------------------
**
*/
#include "templates.h"
#include "p_local.h"
#include "p_lnspec.h"
//============================================================================
//
// P_Scroll3dMidtex
//
// Scrolls all sidedefs belonging to 3dMidtex lines attached to this sector
//
//============================================================================
bool P_Scroll3dMidtex(sector_t *sector, int crush, fixed_t move, bool ceiling)
{
extsector_t::midtex::plane &scrollplane = ceiling? sector->e->Midtex.Ceiling : sector->e->Midtex.Floor;
// First step: Change all lines' texture offsets
for(unsigned i = 0; i < scrollplane.AttachedLines.Size(); i++)
{
line_t *l = scrollplane.AttachedLines[i];
sides[l->sidenum[0]].rowoffset += move;
sides[l->sidenum[1]].rowoffset += move;
}
// Second step: Check all sectors whether the move is ok.
bool res = false;
for(unsigned i = 0; i < scrollplane.AttachedSectors.Size(); i++)
{
res |= P_ChangeSector(scrollplane.AttachedSectors[i], crush, move, 2);
}
return !res;
}
//============================================================================
//
// P_Start3DMidtexInterpolations
//
// Starts interpolators for every sidedef that is being changed by moving
// this sector
//
//============================================================================
void P_Start3dMidtexInterpolations(sector_t *sector, bool ceiling)
{
extsector_t::midtex::plane &scrollplane = ceiling? sector->e->Midtex.Ceiling : sector->e->Midtex.Floor;
for(unsigned i = 0; i < scrollplane.AttachedLines.Size(); i++)
{
line_t *l = scrollplane.AttachedLines[i];
setinterpolation(INTERP_WallPanning, &sides[l->sidenum[0]]);
setinterpolation(INTERP_WallPanning, &sides[l->sidenum[1]]);
}
}
//============================================================================
//
// P_Stop3DMidtexInterpolations
//
// Stops interpolators for every sidedef that is being changed by moving
// this sector
//
//============================================================================
void P_Stop3dMidtexInterpolations(sector_t *sector, bool ceiling)
{
extsector_t::midtex::plane &scrollplane = ceiling? sector->e->Midtex.Ceiling : sector->e->Midtex.Floor;
for(unsigned i = 0; i < scrollplane.AttachedLines.Size(); i++)
{
line_t *l = scrollplane.AttachedLines[i];
stopinterpolation(INTERP_WallPanning, &sides[l->sidenum[0]]);
stopinterpolation(INTERP_WallPanning, &sides[l->sidenum[1]]);
}
}
//============================================================================
//
// P_Attach3dMidtexLinesToSector
//
// Attaches 3dMidtex lines to a sector.
// If lineid is != 0, all lines with the matching line id will be added
// If tag is != 0, all lines touching a sector with the matching tag will be added
// If both are != 0, all lines with the matching line id that touch a sector with
// the matching tag will be added.
//
//============================================================================
void P_Attach3dMidtexLinesToSector(sector_t *sector, int lineid, int tag, bool ceiling)
{
int v;
if (lineid == 0 && tag == 0)
{
// invalid set of parameters
return;
}
extsector_t::midtex::plane &scrollplane = ceiling? sector->e->Midtex.Ceiling : sector->e->Midtex.Floor;
// Bit arrays that mark whether a line or sector is to be attached.
BYTE *found_lines = new BYTE[(numlines+7)/8];
BYTE *found_sectors = new BYTE[(numsectors+7)/8];
memset(found_lines, 0, sizeof (BYTE) * ((numlines+7)/8));
memset(found_sectors, 0, sizeof (BYTE) * ((numsectors+7)/8));
// mark all lines and sectors that are already attached to this one
// and clear the arrays. The old data will be re-added automatically
// from the marker arrays.
for (unsigned i=0; i < scrollplane.AttachedLines.Size(); i++)
{
int line = int(scrollplane.AttachedLines[i] - lines);
found_lines[line>>3] |= 1 << (line&7);
}
for (unsigned i=0; i < scrollplane.AttachedSectors.Size(); i++)
{
int sec = int(scrollplane.AttachedSectors[i] - sectors);
found_sectors[sec>>3] |= 1 << (sec&7);
}
scrollplane.AttachedLines.Clear();
scrollplane.AttachedSectors.Clear();
if (tag == 0)
{
for(int line = -1; (line = P_FindLineFromID(lineid,line)) >= 0; )
{
line_t *ln = &lines[line];
if (ln->frontsector == NULL || ln->backsector == NULL || !(ln->flags & ML_3DMIDTEX))
{
// Only consider two-sided lines with the 3DMIDTEX flag
continue;
}
found_lines[line>>3] |= 1 << (line&7);
}
}
else
{
for(int sec = -1; (sec = P_FindSectorFromTag(tag, sec)) >= 0; )
{
for (int line = 0; line < sectors[sec].linecount; line ++)
{
line_t *ln = sectors[sec].lines[line];
if (lineid != 0 && ln->id != lineid) continue;
if (ln->frontsector == NULL || ln->backsector == NULL || !(ln->flags & ML_3DMIDTEX))
{
// Only consider two-sided lines with the 3DMIDTEX flag
continue;
}
found_lines[line>>3] |= 1 << (line&7);
}
}
}
for(int i=0; i < numlines; i++)
{
if (found_lines[i>>3] & (1 << (i&7)))
{
scrollplane.AttachedLines.Push(&lines[i]);
v = int(lines[i].frontsector - sectors);
found_sectors[v>>3] |= 1 << (v&7);
v = int(lines[i].backsector - sectors);
found_sectors[v>>3] |= 1 << (v&7);
}
}
for (int i=0; i < numsectors; i++)
{
if (found_sectors[i>>3] & (1 << (i&7)))
{
scrollplane.AttachedSectors.Push(&sectors[i]);
}
}
delete[] found_lines;
delete[] found_sectors;
}
//============================================================================
//
// P_GetMidTexturePosition
//
// Retrieves top and bottom of the current line's mid texture.
//
//============================================================================
bool P_GetMidTexturePosition(const line_t *line, int sideno, fixed_t *ptextop, fixed_t *ptexbot)
{
side_t *side = &sides[line->sidenum[sideno]];
if (line->sidenum[0]==NO_SIDE || line->sidenum[1]==NO_SIDE || !side->midtexture) return false;
FTexture * tex= TexMan(side->midtexture);
if (!tex) return false;
fixed_t rowoffset = side->rowoffset;
fixed_t textureheight = tex->GetScaledHeight() << FRACBITS;
if (tex->yScale != FRACUNIT && !tex->bWorldPanning)
{
rowoffset = FixedDiv(rowoffset, tex->yScale);
}
if(line->flags & ML_DONTPEGBOTTOM)
{
*ptexbot = rowoffset +
MAX<fixed_t>(line->frontsector->floortexz, line->backsector->floortexz);
*ptextop = *ptexbot + textureheight;
}
else
{
*ptextop = rowoffset +
MIN<fixed_t>(line->frontsector->ceilingtexz, line->backsector->ceilingtexz);
*ptexbot = *ptextop - textureheight;
}
return true;
}
//============================================================================
//
// P_LineOpening_3dMidtex
//
// 3dMidtex part of P_LineOpening
//
//============================================================================
bool P_LineOpening_3dMidtex(AActor *thing, const line_t *linedef, fixed_t &opentop, fixed_t &openbottom)
{
fixed_t tt, tb;
if (P_GetMidTexturePosition(linedef, 0, &tt, &tb))
{
if (thing->z + (thing->height/2) < (tt + tb)/2)
{
if(tb < opentop) opentop = tb;
}
else
{
if(tt > openbottom) openbottom = tt;
// returns true if it touches the midtexture
return (abs(thing->z - tt) <= thing->MaxStepHeight);
}
}
return false;
/* still have to figure out what this code from Eternity means...
if((linedef->flags & ML_BLOCKMONSTERS) &&
!(mo->flags & (MF_FLOAT | MF_DROPOFF)) &&
D_abs(mo->z - textop) <= 24*FRACUNIT)
{
opentop = openbottom;
openrange = 0;
return;
}
*/
}

19
src/p_3dmidtex.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef __3DMIDTEX_H
#define __3DMIDTEX_H
#include "doomtype.h"
#include "r_defs.h"
class AActor;
bool P_Scroll3dMidtex(sector_t *sector, int crush, fixed_t move, bool ceiling);
void P_Start3dMidtexInterpolations(sector_t *sec, bool ceiling);
void P_Stop3dMidtexInterpolations(sector_t *sec, bool ceiling);
void P_Attach3dMidtexLinesToSector(sector_t *dest, int lineid, int tag, bool ceiling);
bool P_GetMidTexturePosition(const line_t *line, int sideno, fixed_t *ptextop, fixed_t *ptexbot);
bool P_Check3dMidSwitch(AActor *actor, line_t *line, int side);
bool P_LineOpening_3dMidtex(AActor *thing, const line_t *linedef, fixed_t &opentop, fixed_t &openbottom);
#endif

View file

@ -198,6 +198,20 @@ void DDoor::Tick ()
break; break;
} }
} }
else if (res == crushed)
{
switch (m_Type)
{
case doorRaise:
case doorRaiseIn5Mins:
m_Direction = -1;
DoorSound(false);
break;
default:
break;
}
}
break; break;
} }
} }

View file

@ -2831,7 +2831,7 @@ lnSpecFunc LineSpecials[256] =
LS_Ceiling_CrushRaiseAndStay, LS_Ceiling_CrushRaiseAndStay,
LS_Floor_CrushStop, LS_Floor_CrushStop,
LS_Ceiling_MoveToValue, LS_Ceiling_MoveToValue,
LS_NOP, // 48 LS_NOP, // Sector_Attach3dMidtex
LS_GlassBreak, LS_GlassBreak,
LS_NOP, // 50: ExtraFloor_LightOnly LS_NOP, // 50: ExtraFloor_LightOnly
LS_NOP, // 51 LS_NOP, // 51

View file

@ -98,6 +98,7 @@ typedef enum {
Floor_CrushStop = 46, Floor_CrushStop = 46,
Ceiling_MoveToValue = 47, Ceiling_MoveToValue = 47,
Sector_Attach3dMidtex = 48,
GlassBreak = 49, GlassBreak = 49,
ExtraFloor_LightOnly = 50, ExtraFloor_LightOnly = 50,

View file

@ -212,12 +212,20 @@ inline void P_MakeDivline (const line_t *li, divline_t *dl)
fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1); fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1);
int P_BoxOnLineSide (const fixed_t *tmbox, const line_t *ld); int P_BoxOnLineSide (const fixed_t *tmbox, const line_t *ld);
extern fixed_t opentop; struct FLineOpening
extern fixed_t openbottom; {
extern fixed_t openrange; fixed_t top;
extern fixed_t lowfloor; fixed_t bottom;
fixed_t range;
fixed_t lowfloor;
sector_t *bottomsec;
sector_t *topsec;
int ceilingpic;
int floorpic;
bool touchmidtex;
};
void P_LineOpening (const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx=FIXED_MIN, fixed_t refy=0); 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);
bool P_BlockLinesIterator (int x, int y, bool(*func)(line_t*)); bool P_BlockLinesIterator (int x, int y, bool(*func)(line_t*));
bool P_BlockThingsIterator (int x, int y, bool(*func)(AActor*), TArray<AActor *> &checkarray, AActor *start=NULL); bool P_BlockThingsIterator (int x, int y, bool(*func)(AActor*), TArray<AActor *> &checkarray, AActor *start=NULL);

View file

@ -32,6 +32,7 @@
#include "m_bbox.h" #include "m_bbox.h"
#include "m_random.h" #include "m_random.h"
#include "i_system.h" #include "i_system.h"
#include "c_dispatch.h"
#include "doomdef.h" #include "doomdef.h"
#include "p_local.h" #include "p_local.h"
@ -97,6 +98,7 @@ int tmfloorpic;
sector_t *tmfloorsector; sector_t *tmfloorsector;
int tmceilingpic; int tmceilingpic;
sector_t *tmceilingsector; sector_t *tmceilingsector;
bool tmtouchmidtex;
static fixed_t tmfbbox[4]; static fixed_t tmfbbox[4];
static AActor *tmfthing; static AActor *tmfthing;
@ -107,6 +109,7 @@ fixed_t tmffloorpic;
sector_t *tmffloorsector; sector_t *tmffloorsector;
fixed_t tmfceilingpic; fixed_t tmfceilingpic;
sector_t *tmfceilingsector; sector_t *tmfceilingsector;
bool tmftouchmidtex;
//Added by MC: So bot will know what kind of sector it's entering. //Added by MC: So bot will know what kind of sector it's entering.
sector_t* tmsector; sector_t* tmsector;
@ -158,6 +161,7 @@ static bool PIT_FindFloorCeiling (line_t *ld)
} }
fixed_t sx, sy; fixed_t sx, sy;
FLineOpening open;
// set openrange, opentop, openbottom // set openrange, opentop, openbottom
if (((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) | if (((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) |
@ -165,7 +169,7 @@ static bool PIT_FindFloorCeiling (line_t *ld)
(ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) | (ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) |
(ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0) (ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0)
{ {
P_LineOpening (ld, sx=tmx, sy=tmy, tmx, tmy); P_LineOpening (open, tmfthing, ld, sx=tmx, sy=tmy, tmx, tmy);
} }
else else
{ // Find the point on the line closest to the actor's center, and use { // Find the point on the line closest to the actor's center, and use
@ -177,35 +181,36 @@ static bool PIT_FindFloorCeiling (line_t *ld)
(dx*dx + dy*dy) * 16777216.f); (dx*dx + dy*dy) * 16777216.f);
if (r <= 0) if (r <= 0)
{ {
P_LineOpening (ld, sx=ld->v1->x, sy=ld->v1->y, tmx, tmy); P_LineOpening (open, tmfthing, ld, sx=ld->v1->x, sy=ld->v1->y, tmx, tmy);
} }
else if (r >= (1<<24)) else if (r >= (1<<24))
{ {
P_LineOpening (ld, sx=ld->v2->x, sy=ld->v2->y, tmfthing->x, tmfthing->y); P_LineOpening (open, tmfthing, ld, sx=ld->v2->x, sy=ld->v2->y, tmfthing->x, tmfthing->y);
} }
else else
{ {
P_LineOpening (ld, sx=ld->v1->x + MulScale24 (r, ld->dx), P_LineOpening (open, tmfthing, ld, sx=ld->v1->x + MulScale24 (r, ld->dx),
sy=ld->v1->y + MulScale24 (r, ld->dy), tmx, tmy); sy=ld->v1->y + MulScale24 (r, ld->dy), tmx, tmy);
} }
} }
// adjust floor / ceiling heights // adjust floor / ceiling heights
if (opentop < tmfceilingz) if (open.top < tmfceilingz)
{ {
tmfceilingz = opentop; tmfceilingz = open.top;
BlockingLine = ld; BlockingLine = ld;
} }
if (openbottom > tmffloorz) if (open.bottom > tmffloorz)
{ {
tmffloorz = openbottom; tmffloorz = open.bottom;
tmffloorsector = openbottomsec; tmffloorsector = open.bottomsec;
tmftouchmidtex = open.touchmidtex;
BlockingLine = ld; BlockingLine = ld;
} }
if (lowfloor < tmfdropoffz) if (open.lowfloor < tmfdropoffz)
tmfdropoffz = lowfloor; tmfdropoffz = open.lowfloor;
return true; return true;
} }
@ -249,6 +254,8 @@ void P_FindFloorCeiling (AActor *actor)
for (by = yl; by <= yh; by++) for (by = yl; by <= yh; by++)
if (!P_BlockLinesIterator (bx, by, PIT_FindFloorCeiling)) if (!P_BlockLinesIterator (bx, by, PIT_FindFloorCeiling))
return; return;
if (tmftouchmidtex) tmfdropoffz = tmffloorz;
} }
// //
@ -374,6 +381,8 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr
} }
} }
if (tmftouchmidtex) tmfdropoffz = tmffloorz;
fixed_t savefloorz = tmffloorz; fixed_t savefloorz = tmffloorz;
fixed_t saveceilingz = tmfceilingz; fixed_t saveceilingz = tmfceilingz;
sector_t *savesector = tmffloorsector; sector_t *savesector = tmffloorsector;
@ -719,7 +728,8 @@ bool PIT_CheckLine (line_t *ld)
} }
} }
fixed_t sx, sy; fixed_t sx=0, sy=0;
FLineOpening open;
// set openrange, opentop, openbottom // set openrange, opentop, openbottom
if (((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) | if (((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) |
@ -727,7 +737,7 @@ bool PIT_CheckLine (line_t *ld)
(ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) | (ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) |
(ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0) (ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0)
{ {
P_LineOpening (ld, sx=tmx, sy=tmy, tmx, tmy); P_LineOpening (open, tmthing, ld, sx=tmx, sy=tmy, tmx, tmy);
} }
else else
{ // Find the point on the line closest to the actor's center, and use { // Find the point on the line closest to the actor's center, and use
@ -748,15 +758,15 @@ bool PIT_CheckLine (line_t *ld)
ld->backsector->floorplane.ic);*/ ld->backsector->floorplane.ic);*/
if (r <= 0) if (r <= 0)
{ {
P_LineOpening (ld, sx=ld->v1->x, sy=ld->v1->y, tmx, tmy); P_LineOpening (open, tmthing, ld, sx=ld->v1->x, sy=ld->v1->y, tmx, tmy);
} }
else if (r >= (1<<24)) else if (r >= (1<<24))
{ {
P_LineOpening (ld, sx=ld->v2->x, sy=ld->v2->y, tmthing->x, tmthing->y); P_LineOpening (open, tmthing, ld, sx=ld->v2->x, sy=ld->v2->y, tmthing->x, tmthing->y);
} }
else else
{ {
P_LineOpening (ld, sx=ld->v1->x + MulScale24 (r, ld->dx), P_LineOpening (open, tmthing, ld, sx=ld->v1->x + MulScale24 (r, ld->dx),
sy=ld->v1->y + MulScale24 (r, ld->dy), tmx, tmy); sy=ld->v1->y + MulScale24 (r, ld->dy), tmx, tmy);
} }
/* Printf (" %d %d %d\n", sx, sy, openbottom);*/ /* Printf (" %d %d %d\n", sx, sy, openbottom);*/
@ -772,31 +782,32 @@ bool PIT_CheckLine (line_t *ld)
// forced to say, "It's not a bug. It's a feature?" Ugh. // forced to say, "It's not a bug. It's a feature?" Ugh.
(gameinfo.gametype != GAME_Strife || (gameinfo.gametype != GAME_Strife ||
level.flags & LEVEL_HEXENFORMAT || level.flags & LEVEL_HEXENFORMAT ||
openbottom == tmthing->Sector->floorplane.ZatPoint (sx, sy))) open.bottom == tmthing->Sector->floorplane.ZatPoint (sx, sy)))
{ {
openbottom += 32*FRACUNIT; open.bottom += 32*FRACUNIT;
} }
// adjust floor / ceiling heights // adjust floor / ceiling heights
if (opentop < tmceilingz) if (open.top < tmceilingz)
{ {
tmceilingz = opentop; tmceilingz = open.top;
tmceilingsector = opentopsec; tmceilingsector = open.topsec;
tmceilingpic = opentopsec->ceilingpic; tmceilingpic = open.ceilingpic;
ceilingline = ld; ceilingline = ld;
BlockingLine = ld; BlockingLine = ld;
} }
if (openbottom > tmfloorz) if (open.bottom > tmfloorz)
{ {
tmfloorz = openbottom; tmfloorz = open.bottom;
tmfloorsector = openbottomsec; tmfloorsector = open.bottomsec;
tmfloorpic = openbottomsec->floorpic; tmfloorpic = open.floorpic;
tmtouchmidtex = open.touchmidtex;
BlockingLine = ld; BlockingLine = ld;
} }
if (lowfloor < tmdropoffz) if (open.lowfloor < tmdropoffz)
tmdropoffz = lowfloor; tmdropoffz = open.lowfloor;
// if contacted a special line, add it to the list // if contacted a special line, add it to the list
if (ld->special) if (ld->special)
@ -1413,7 +1424,7 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y)
if (tmceilingz - tmfloorz < thing->height) if (tmceilingz - tmfloorz < thing->height)
return false; return false;
if (stepthing != NULL) if (stepthing != NULL || tmtouchmidtex)
{ {
tmdropoffz = thingdropoffz; tmdropoffz = thingdropoffz;
} }
@ -2096,25 +2107,30 @@ bool PTR_SlideTraverse (intercept_t* in)
{ {
goto isblocking; goto isblocking;
} }
if (li->flags & ML_BLOCKMONSTERS && !(slidemo->flags3 & MF3_NOBLOCKMONST))
{
goto isblocking;
}
FLineOpening open;
// set openrange, opentop, openbottom // set openrange, opentop, openbottom
P_LineOpening (li, trace.x + FixedMul (trace.dx, in->frac), P_LineOpening (open, slidemo, li, trace.x + FixedMul (trace.dx, in->frac),
trace.y + FixedMul (trace.dy, in->frac)); trace.y + FixedMul (trace.dy, in->frac));
if (openrange < slidemo->height) if (open.range < slidemo->height)
goto isblocking; // doesn't fit goto isblocking; // doesn't fit
if (opentop - slidemo->z < slidemo->height) if (open.top - slidemo->z < slidemo->height)
goto isblocking; // mobj is too high goto isblocking; // mobj is too high
if (openbottom - slidemo->z > slidemo->MaxStepHeight) if (open.bottom - slidemo->z > slidemo->MaxStepHeight)
{ {
goto isblocking; // too big a step up goto isblocking; // too big a step up
} }
else if (slidemo->z < openbottom) else if (slidemo->z < open.bottom)
{ // [RH] Check to make sure there's nothing in the way for the step up { // [RH] Check to make sure there's nothing in the way for the step up
fixed_t savedz = slidemo->z; fixed_t savedz = slidemo->z;
slidemo->z = openbottom; slidemo->z = open.bottom;
bool good = P_TestMobjZ (slidemo); bool good = P_TestMobjZ (slidemo);
slidemo->z = savedz; slidemo->z = savedz;
if (!good) if (!good)
@ -2261,6 +2277,7 @@ void P_SlideMove (AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps)
} }
} }
//============================================================================ //============================================================================
// //
// P_CheckSlopeWalk // P_CheckSlopeWalk
@ -2384,15 +2401,17 @@ bool PTR_BounceTraverse (intercept_t *in)
goto bounceblocking; goto bounceblocking;
} }
P_LineOpening (li, trace.x + FixedMul (trace.dx, in->frac), FLineOpening open;
P_LineOpening (open, slidemo, li, trace.x + FixedMul (trace.dx, in->frac),
trace.y + FixedMul (trace.dy, in->frac)); // set openrange, opentop, openbottom trace.y + FixedMul (trace.dy, in->frac)); // set openrange, opentop, openbottom
if (openrange < slidemo->height) if (open.range < slidemo->height)
goto bounceblocking; // doesn't fit goto bounceblocking; // doesn't fit
if (opentop - slidemo->z < slidemo->height) if (open.top - slidemo->z < slidemo->height)
goto bounceblocking; // mobj is too high goto bounceblocking; // mobj is too high
if (openbottom > slidemo->z) if (open.bottom > slidemo->z)
goto bounceblocking; // mobj is too low goto bounceblocking; // mobj is too low
return true; // this line doesn't block movement return true; // this line doesn't block movement
@ -2573,19 +2592,20 @@ bool PTR_AimTraverse (intercept_t* in)
// Crosses a two sided line. // Crosses a two sided line.
// A two sided line will restrict the possible target ranges. // A two sided line will restrict the possible target ranges.
P_LineOpening (li, trace.x + FixedMul (trace.dx, in->frac), FLineOpening open;
P_LineOpening (open, NULL, li, trace.x + FixedMul (trace.dx, in->frac),
trace.y + FixedMul (trace.dy, in->frac)); trace.y + FixedMul (trace.dy, in->frac));
if (openbottom >= opentop) if (open.bottom >= open.top)
return false; // stop return false; // stop
dist = FixedMul (attackrange, in->frac); dist = FixedMul (attackrange, in->frac);
pitch = -(int)R_PointToAngle2 (0, shootz, dist, openbottom); pitch = -(int)R_PointToAngle2 (0, shootz, dist, open.bottom);
if (pitch < bottompitch) if (pitch < bottompitch)
bottompitch = pitch; bottompitch = pitch;
pitch = -(int)R_PointToAngle2 (0, shootz, dist, opentop); pitch = -(int)R_PointToAngle2 (0, shootz, dist, open.top);
if (pitch > toppitch) if (pitch > toppitch)
toppitch = pitch; toppitch = pitch;
@ -3337,14 +3357,16 @@ bool PTR_UseTraverse (intercept_t *in)
return true; return true;
} }
FLineOpening open;
// [RH] The range passed to P_PathTraverse was doubled so that it could // [RH] The range passed to P_PathTraverse was doubled so that it could
// find things up to 128 units away (for Strife), but it should still reject // find things up to 128 units away (for Strife), but it should still reject
// lines further than 64 units away. // lines further than 64 units away.
if (in->frac > FRACUNIT/2) if (in->frac > FRACUNIT/2)
{ {
P_LineOpening (in->d.line, trace.x + FixedMul (trace.dx, in->frac), // don't pass usething here. It will not do what might be expected!
P_LineOpening (open, NULL, in->d.line, trace.x + FixedMul (trace.dx, in->frac),
trace.y + FixedMul (trace.dy, in->frac)); trace.y + FixedMul (trace.dy, in->frac));
return openrange>0; return open.range>0;
} }
if (in->d.line->special == 0 || (GET_SPAC(in->d.line->flags) != SPAC_USETHROUGH && if (in->d.line->special == 0 || (GET_SPAC(in->d.line->flags) != SPAC_USETHROUGH &&
@ -3353,14 +3375,14 @@ bool PTR_UseTraverse (intercept_t *in)
blocked: blocked:
if (in->d.line->flags & ML_BLOCKEVERYTHING) if (in->d.line->flags & ML_BLOCKEVERYTHING)
{ {
openrange = 0; open.range = 0;
} }
else else
{ {
P_LineOpening (in->d.line, trace.x + FixedMul (trace.dx, in->frac), P_LineOpening (open, NULL, in->d.line, trace.x + FixedMul (trace.dx, in->frac),
trace.y + FixedMul (trace.dy, in->frac)); trace.y + FixedMul (trace.dy, in->frac));
} }
if (openrange <= 0 || if (open.range <= 0 ||
(in->d.line->special != 0 && (i_compatflags & COMPATF_USEBLOCKING))) (in->d.line->special != 0 && (i_compatflags & COMPATF_USEBLOCKING)))
{ {
// [RH] Give sector a chance to intercept the use // [RH] Give sector a chance to intercept the use
@ -3428,15 +3450,16 @@ blocked:
bool PTR_NoWayTraverse (intercept_t *in) bool PTR_NoWayTraverse (intercept_t *in)
{ {
line_t *ld = in->d.line; line_t *ld = in->d.line;
FLineOpening open;
// [GrafZahl] de-obfuscated. Was I the only one who was unable to makes sense out of // [GrafZahl] de-obfuscated. Was I the only one who was unable to makes sense out of
// this convoluted mess? // this convoluted mess?
if (ld->special) return true; if (ld->special) return true;
if (ld->flags&(ML_BLOCKING|ML_BLOCKEVERYTHING|ML_BLOCK_PLAYERS)) return false; if (ld->flags&(ML_BLOCKING|ML_BLOCKEVERYTHING|ML_BLOCK_PLAYERS)) return false;
P_LineOpening(ld, trace.x+FixedMul(trace.dx, in->frac),trace.y+FixedMul(trace.dy, in->frac)); P_LineOpening(open, NULL, ld, trace.x+FixedMul(trace.dx, in->frac),trace.y+FixedMul(trace.dy, in->frac));
return openrange >0 && return open.range >0 &&
openbottom <= usething->z + usething->MaxStepHeight && open.bottom <= usething->z + usething->MaxStepHeight &&
opentop >= usething->z + usething->height; open.top >= usething->z + usething->height;
} }
/* /*
@ -3496,14 +3519,15 @@ static bool PuzzleActivated;
bool PTR_PuzzleItemTraverse (intercept_t *in) bool PTR_PuzzleItemTraverse (intercept_t *in)
{ {
AActor *mobj; AActor *mobj;
FLineOpening open;
if (in->isaline) if (in->isaline)
{ // Check line { // Check line
if (in->d.line->special != USE_PUZZLE_ITEM_SPECIAL) if (in->d.line->special != USE_PUZZLE_ITEM_SPECIAL)
{ {
P_LineOpening (in->d.line, trace.x + FixedMul (trace.dx, in->frac), P_LineOpening (open, NULL, in->d.line, trace.x + FixedMul (trace.dx, in->frac),
trace.y + FixedMul (trace.dy, in->frac)); trace.y + FixedMul (trace.dy, in->frac));
if (openrange <= 0) if (open.range <= 0)
{ {
return false; // can't use through a wall return false; // can't use through a wall
} }
@ -3811,10 +3835,15 @@ void P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance, FNa
// DOOM crushing behavior set crushchange to 10 or -1 // DOOM crushing behavior set crushchange to 10 or -1
// if no crushing is desired. // if no crushing is desired.
// //
static int moveamt;
int crushchange; struct FChangePosition
static sector_t *movesec; {
bool nofit; int moveamt;
int crushchange;
bool nofit;
bool movemidtex;
};
TArray<AActor *> intersectors; TArray<AActor *> intersectors;
EXTERN_CVAR (Int, cl_bloodtype) EXTERN_CVAR (Int, cl_bloodtype)
@ -3825,8 +3854,18 @@ EXTERN_CVAR (Int, cl_bloodtype)
// //
//============================================================================= //=============================================================================
bool P_AdjustFloorCeil (AActor *thing) bool P_AdjustFloorCeil (AActor *thing, FChangePosition *cpos)
{ {
int flags2 = thing->flags2 & MF2_PASSMOBJ;
if (cpos->movemidtex)
{
// From Eternity:
// ALL things must be treated as PASSMOBJ when moving
// 3DMidTex lines, otherwise you get stuck in them.
thing->flags2 |= MF2_PASSMOBJ;
}
bool isgood = P_CheckPosition (thing, thing->x, thing->y); bool isgood = P_CheckPosition (thing, thing->x, thing->y);
thing->floorz = tmfloorz; thing->floorz = tmfloorz;
thing->ceilingz = tmceilingz; thing->ceilingz = tmceilingz;
@ -3835,6 +3874,10 @@ bool P_AdjustFloorCeil (AActor *thing)
thing->floorsector = tmfloorsector; thing->floorsector = tmfloorsector;
thing->ceilingpic = tmceilingpic; thing->ceilingpic = tmceilingpic;
thing->ceilingsector = tmceilingsector; thing->ceilingsector = tmceilingsector;
// restore the PASSMOBJ flag but leave the other flags alone.
thing->flags2 = (thing->flags2 & ~MF2_PASSMOBJ) | flags2;
return isgood; return isgood;
} }
@ -4004,7 +4047,7 @@ void P_FindBelowIntersectors (AActor *actor)
// //
//============================================================================= //=============================================================================
void P_DoCrunch (AActor *thing) void P_DoCrunch (AActor *thing, FChangePosition *cpos)
{ {
// crunch bodies to giblets // crunch bodies to giblets
if ((thing->flags & MF_CORPSE) && if ((thing->flags & MF_CORPSE) &&
@ -4067,11 +4110,11 @@ void P_DoCrunch (AActor *thing)
return; // assume it is bloody gibs or something return; // assume it is bloody gibs or something
} }
nofit = true; cpos->nofit = true;
if ((crushchange > 0) && !(level.maptime & 3)) if ((cpos->crushchange > 0) && !(level.maptime & 3))
{ {
P_DamageMobj (thing, NULL, NULL, crushchange, NAME_Crush); P_DamageMobj (thing, NULL, NULL, cpos->crushchange, NAME_Crush);
// spray blood in a random direction // spray blood in a random direction
if ((!(thing->flags&MF_NOBLOOD)) && if ((!(thing->flags&MF_NOBLOOD)) &&
@ -4080,7 +4123,7 @@ void P_DoCrunch (AActor *thing)
PalEntry bloodcolor = (PalEntry)thing->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); PalEntry bloodcolor = (PalEntry)thing->GetClass()->Meta.GetMetaInt(AMETA_BloodColor);
const PClass *bloodcls = PClass::FindClass((ENamedName)thing->GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood)); const PClass *bloodcls = PClass::FindClass((ENamedName)thing->GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood));
P_TraceBleed (crushchange, thing); P_TraceBleed (cpos->crushchange, thing);
if (cl_bloodtype <= 1 && bloodcls != NULL) if (cl_bloodtype <= 1 && bloodcls != NULL)
{ {
AActor *mo; AActor *mo;
@ -4118,7 +4161,7 @@ void P_DoCrunch (AActor *thing)
// above it didn't fit. // above it didn't fit.
//============================================================================= //=============================================================================
int P_PushUp (AActor *thing) int P_PushUp (AActor *thing, FChangePosition *cpos)
{ {
unsigned int firstintersect = intersectors.Size (); unsigned int firstintersect = intersectors.Size ();
unsigned int lastintersect; unsigned int lastintersect;
@ -4140,11 +4183,11 @@ int P_PushUp (AActor *thing)
return 2; return 2;
} }
fixed_t oldz = intersect->z; fixed_t oldz = intersect->z;
P_AdjustFloorCeil (intersect); P_AdjustFloorCeil (intersect, cpos);
intersect->z = thing->z + thing->height + 1; intersect->z = thing->z + thing->height + 1;
if (P_PushUp (intersect)) if (P_PushUp (intersect, cpos))
{ // Move blocked { // Move blocked
P_DoCrunch (intersect); P_DoCrunch (intersect, cpos);
intersect->z = oldz; intersect->z = oldz;
return 2; return 2;
} }
@ -4160,7 +4203,7 @@ int P_PushUp (AActor *thing)
// below it didn't fit. // below it didn't fit.
//============================================================================= //=============================================================================
int P_PushDown (AActor *thing) int P_PushDown (AActor *thing, FChangePosition *cpos)
{ {
unsigned int firstintersect = intersectors.Size (); unsigned int firstintersect = intersectors.Size ();
unsigned int lastintersect; unsigned int lastintersect;
@ -4182,13 +4225,13 @@ int P_PushDown (AActor *thing)
return 2; return 2;
} }
fixed_t oldz = intersect->z; fixed_t oldz = intersect->z;
P_AdjustFloorCeil (intersect); P_AdjustFloorCeil (intersect, cpos);
if (oldz > thing->z - intersect->height) if (oldz > thing->z - intersect->height)
{ // Only push things down, not up. { // Only push things down, not up.
intersect->z = thing->z - intersect->height; intersect->z = thing->z - intersect->height;
if (P_PushDown (intersect)) if (P_PushDown (intersect, cpos))
{ // Move blocked { // Move blocked
P_DoCrunch (intersect); P_DoCrunch (intersect, cpos);
intersect->z = oldz; intersect->z = oldz;
return 2; return 2;
} }
@ -4203,11 +4246,11 @@ int P_PushDown (AActor *thing)
// //
//============================================================================= //=============================================================================
void PIT_FloorDrop (AActor *thing) void PIT_FloorDrop (AActor *thing, FChangePosition *cpos)
{ {
fixed_t oldfloorz = thing->floorz; fixed_t oldfloorz = thing->floorz;
P_AdjustFloorCeil (thing); P_AdjustFloorCeil (thing, cpos);
if (thing->momz == 0 && if (thing->momz == 0 &&
(!(thing->flags & MF_NOGRAVITY) || (!(thing->flags & MF_NOGRAVITY) ||
@ -4224,8 +4267,8 @@ void PIT_FloorDrop (AActor *thing)
P_CheckFakeFloorTriggers (thing, oldz); P_CheckFakeFloorTriggers (thing, oldz);
} }
else if ((thing->flags & MF_NOGRAVITY) || else if ((thing->flags & MF_NOGRAVITY) ||
((!(level.flags & LEVEL_HEXENFORMAT) || moveamt < 9*FRACUNIT) ((!(level.flags & LEVEL_HEXENFORMAT) || cpos->moveamt < 9*FRACUNIT)
&& thing->z - thing->floorz <= moveamt)) && thing->z - thing->floorz <= cpos->moveamt))
{ {
thing->z = thing->floorz; thing->z = thing->floorz;
P_CheckFakeFloorTriggers (thing, oldz); P_CheckFakeFloorTriggers (thing, oldz);
@ -4239,11 +4282,11 @@ void PIT_FloorDrop (AActor *thing)
// //
//============================================================================= //=============================================================================
void PIT_FloorRaise (AActor *thing) void PIT_FloorRaise (AActor *thing, FChangePosition *cpos)
{ {
fixed_t oldfloorz = thing->floorz; fixed_t oldfloorz = thing->floorz;
P_AdjustFloorCeil (thing); P_AdjustFloorCeil (thing, cpos);
// Move things intersecting the floor up // Move things intersecting the floor up
if (thing->z <= thing->floorz || if (thing->z <= thing->floorz ||
@ -4259,17 +4302,17 @@ void PIT_FloorRaise (AActor *thing)
{ {
thing->z = thing->z - oldfloorz + thing->floorz; thing->z = thing->z - oldfloorz + thing->floorz;
} }
switch (P_PushUp (thing)) switch (P_PushUp (thing, cpos))
{ {
default: default:
P_CheckFakeFloorTriggers (thing, oldz); P_CheckFakeFloorTriggers (thing, oldz);
break; break;
case 1: case 1:
P_DoCrunch (thing); P_DoCrunch (thing, cpos);
P_CheckFakeFloorTriggers (thing, oldz); P_CheckFakeFloorTriggers (thing, oldz);
break; break;
case 2: case 2:
P_DoCrunch (thing); P_DoCrunch (thing, cpos);
thing->z = oldz; thing->z = oldz;
break; break;
} }
@ -4282,12 +4325,12 @@ void PIT_FloorRaise (AActor *thing)
// //
//============================================================================= //=============================================================================
void PIT_CeilingLower (AActor *thing) void PIT_CeilingLower (AActor *thing, FChangePosition *cpos)
{ {
bool onfloor; bool onfloor;
onfloor = thing->z <= thing->floorz; onfloor = thing->z <= thing->floorz;
P_AdjustFloorCeil (thing); P_AdjustFloorCeil (thing, cpos);
if (thing->z + thing->height > thing->ceilingz) if (thing->z + thing->height > thing->ceilingz)
{ {
@ -4301,14 +4344,14 @@ void PIT_CeilingLower (AActor *thing)
{ {
thing->z = thing->floorz; thing->z = thing->floorz;
} }
switch (P_PushDown (thing)) switch (P_PushDown (thing, cpos))
{ {
case 2: case 2:
// intentional fall-through // intentional fall-through
case 1: case 1:
if (onfloor) if (onfloor)
thing->z = thing->floorz; thing->z = thing->floorz;
P_DoCrunch (thing); P_DoCrunch (thing, cpos);
P_CheckFakeFloorTriggers (thing, oldz); P_CheckFakeFloorTriggers (thing, oldz);
break; break;
default: default:
@ -4324,15 +4367,15 @@ void PIT_CeilingLower (AActor *thing)
// //
//============================================================================= //=============================================================================
void PIT_CeilingRaise (AActor *thing) void PIT_CeilingRaise (AActor *thing, FChangePosition *cpos)
{ {
bool isgood = P_AdjustFloorCeil (thing); bool isgood = P_AdjustFloorCeil (thing, cpos);
// For DOOM compatibility, only move things that are inside the floor. // For DOOM compatibility, only move things that are inside the floor.
// (or something else?) Things marked as hanging from the ceiling will // (or something else?) Things marked as hanging from the ceiling will
// stay where they are. // stay where they are.
if (thing->z < thing->floorz && if (thing->z < thing->floorz &&
thing->z + thing->height >= thing->ceilingz - moveamt && thing->z + thing->height >= thing->ceilingz - cpos->moveamt &&
!(thing->flags & MF_NOLIFTDROP)) !(thing->flags & MF_NOLIFTDROP))
{ {
fixed_t oldz = thing->z; fixed_t oldz = thing->z;
@ -4365,25 +4408,44 @@ void PIT_CeilingRaise (AActor *thing)
bool P_ChangeSector (sector_t *sector, int crunch, int amt, int floorOrCeil) bool P_ChangeSector (sector_t *sector, int crunch, int amt, int floorOrCeil)
{ {
void (*iterator)(AActor *); FChangePosition cpos;
void (*iterator)(AActor *, FChangePosition *);
void (*iterator2)(AActor *, FChangePosition *) = NULL;
msecnode_t *n; msecnode_t *n;
nofit = false; cpos.nofit = false;
crushchange = crunch; cpos.crushchange = crunch;
moveamt = abs (amt); cpos.moveamt = abs (amt);
movesec = sector; cpos.movemidtex = false;
// [RH] Use different functions for the four different types of sector // [RH] Use different functions for the four different types of sector
// movement. Also update the soundorg's z-coordinate for 3D sound. // movement. Also update the soundorg's z-coordinate for 3D sound.
if (floorOrCeil == 0) switch (floorOrCeil)
{ // floor {
case 0:
// floor
iterator = (amt < 0) ? PIT_FloorDrop : PIT_FloorRaise; iterator = (amt < 0) ? PIT_FloorDrop : PIT_FloorRaise;
sector->soundorg[2] = sector->floorplane.ZatPoint (sector->soundorg[0], sector->soundorg[1]); sector->soundorg[2] = sector->floorplane.ZatPoint (sector->soundorg[0], sector->soundorg[1]);
} break;
else
{ // ceiling case 1:
// ceiling
iterator = (amt < 0) ? PIT_CeilingLower : PIT_CeilingRaise; iterator = (amt < 0) ? PIT_CeilingLower : PIT_CeilingRaise;
sector->soundorg[2] = sector->ceilingplane.ZatPoint (sector->soundorg[0], sector->soundorg[1]); sector->soundorg[2] = sector->ceilingplane.ZatPoint (sector->soundorg[0], sector->soundorg[1]);
break;
case 2:
// 3dmidtex
// This must check both floor and ceiling
iterator = (amt < 0) ? PIT_FloorDrop : PIT_FloorRaise;
iterator2 = (amt < 0) ? PIT_CeilingLower : PIT_CeilingRaise;
cpos.movemidtex = true;
break;
default:
// invalid
assert(floorOrCeil > 0 && floorOrCeil < 2);
return false;
} }
// killough 4/4/98: scan list front-to-back until empty or exhausted, // killough 4/4/98: scan list front-to-back until empty or exhausted,
@ -4407,13 +4469,16 @@ bool P_ChangeSector (sector_t *sector, int crunch, int amt, int floorOrCeil)
{ {
n->visited = true; // mark thing as processed n->visited = true; // mark thing as processed
if (!(n->m_thing->flags & MF_NOBLOCKMAP)) //jff 4/7/98 don't do these if (!(n->m_thing->flags & MF_NOBLOCKMAP)) //jff 4/7/98 don't do these
iterator (n->m_thing); // process it {
iterator (n->m_thing, &cpos); // process it
if (iterator2 != NULL) iterator2 (n->m_thing, &cpos);
}
break; // exit and start over break; // exit and start over
} }
} }
} while (n); // repeat from scratch until all things left are marked valid } while (n); // repeat from scratch until all things left are marked valid
return nofit; return cpos.nofit;
} }
//============================================================================= //=============================================================================

View file

@ -34,6 +34,7 @@
#include "doomdef.h" #include "doomdef.h"
#include "doomstat.h" #include "doomstat.h"
#include "p_local.h" #include "p_local.h"
#include "p_3dmidtex.h"
// State. // State.
#include "r_state.h" #include "r_state.h"
@ -184,15 +185,8 @@ fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1)
// //
//========================================================================== //==========================================================================
fixed_t opentop; void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef,
fixed_t openbottom; fixed_t x, fixed_t y, fixed_t refx, fixed_t refy)
fixed_t openrange;
fixed_t lowfloor;
extern int tmfloorpic;
sector_t *openbottomsec;
sector_t *opentopsec;
void P_LineOpening (const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx, fixed_t refy)
{ {
sector_t *front, *back; sector_t *front, *back;
fixed_t fc, ff, bc, bf; fixed_t fc, ff, bc, bf;
@ -200,7 +194,7 @@ void P_LineOpening (const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx, f
if (linedef->sidenum[1] == NO_SIDE) if (linedef->sidenum[1] == NO_SIDE)
{ {
// single sided line // single sided line
openrange = 0; open.range = 0;
return; return;
} }
@ -214,8 +208,9 @@ void P_LineOpening (const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx, f
/*Printf ("]]]]]] %d %d\n", ff, bf);*/ /*Printf ("]]]]]] %d %d\n", ff, bf);*/
opentopsec = fc < bc? front : back; open.topsec = fc < bc? front : back;
opentop = fc < bc ? fc : bc; open.ceilingpic = open.topsec->ceilingpic;
open.top = fc < bc ? fc : bc;
bool usefront; bool usefront;
@ -241,20 +236,27 @@ void P_LineOpening (const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx, f
if (usefront) if (usefront)
{ {
openbottom = ff; open.bottom = ff;
openbottomsec = front; open.bottomsec = front;
lowfloor = bf; open.floorpic = front->floorpic;
//tmfloorpic = front->floorpic; open.lowfloor = bf;
} }
else else
{ {
openbottom = bf; open.bottom = bf;
openbottomsec = back; open.bottomsec = back;
lowfloor = ff; open.floorpic = back->floorpic;
//tmfloorpic = back->floorpic; open.lowfloor = ff;
} }
openrange = opentop - openbottom; if (actor != NULL && linedef->frontsector != NULL && linedef->backsector != NULL &&
linedef->flags & ML_3DMIDTEX)
{
open.touchmidtex = P_LineOpening_3dMidtex(actor, linedef, open.top, open.bottom);
}
else open.touchmidtex = false;
open.range = open.top - open.bottom;
} }

View file

@ -143,6 +143,12 @@ void DPlat::Tick ()
m_Status = in_stasis; //for reactivation of toggle m_Status = in_stasis; //for reactivation of toggle
} }
} }
else if (res == crushed && m_Crush < 0 && m_Type != platToggle)
{
m_Status = up;
m_Count = m_Wait;
PlayPlatSound ("Platform");
}
//jff 1/26/98 remove the plat if it bounced so it can be tried again //jff 1/26/98 remove the plat if it bounced so it can be tried again
//only affects plats that raise and bounce //only affects plats that raise and bounce

View file

@ -333,6 +333,8 @@ void P_SerializeWorld (FArchive &arc)
<< sec->FloorSkyBox << sec->CeilingSkyBox << sec->FloorSkyBox << sec->CeilingSkyBox
<< sec->ZoneNumber << sec->ZoneNumber
<< sec->oldspecial; << sec->oldspecial;
sec->e->Serialize(arc);
if (arc.IsStoring ()) if (arc.IsStoring ())
{ {
arc << sec->ColorMap->Color arc << sec->ColorMap->Color
@ -406,6 +408,48 @@ void P_SerializeWorld (FArchive &arc)
} }
} }
#if 0
// VC++ produces a linker error when using the templated << operator
void extsector_t::Serialize(FArchive &arc)
{
arc << Midtex.Floor.AttachedLines
<< Midtex.Floor.AttachedSectors
<< Midtex.Ceiling.AttachedLines
<< Midtex.Ceiling.AttachedSectors;
}
#else
// Remove this when the problem above has been sorted out.
template<class T>
void SaveArray (FArchive &arc, TArray<T> &self)
{
unsigned int i;
if (arc.IsStoring())
{
arc.WriteCount(self.Size());
}
else
{
DWORD numStored = arc.ReadCount();
self.Resize(numStored);
}
for (i = 0; i < self.Size(); ++i)
{
arc << self[i];
}
}
void extsector_t::Serialize(FArchive &arc)
{
SaveArray(arc, Midtex.Floor.AttachedLines);
SaveArray(arc, Midtex.Floor.AttachedSectors);
SaveArray(arc, Midtex.Ceiling.AttachedLines);
SaveArray(arc, Midtex.Ceiling.AttachedSectors);
}
#endif
// //
// Thinkers // Thinkers

View file

@ -1043,8 +1043,13 @@ void P_LoadSectors (MapData * map)
map->Read(ML_SECTORS, msp); map->Read(ML_SECTORS, msp);
ms = (mapsector_t*)msp; ms = (mapsector_t*)msp;
ss = sectors; ss = sectors;
// Extended properties
sectors[0].e = new extsector_t[numsectors];
for (i = 0; i < numsectors; i++, ss++, ms++) for (i = 0; i < numsectors; i++, ss++, ms++)
{ {
ss->e = &sectors[0].e[i];
ss->floortexz = LittleShort(ms->floorheight)<<FRACBITS; ss->floortexz = LittleShort(ms->floorheight)<<FRACBITS;
ss->floorplane.d = -ss->floortexz; ss->floorplane.d = -ss->floortexz;
ss->floorplane.c = FRACUNIT; ss->floorplane.c = FRACUNIT;
@ -1971,6 +1976,7 @@ void P_LoadLineDefs (MapData * map)
P_SaveLineSpecial (ld); P_SaveLineSpecial (ld);
if (level.flags & LEVEL_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX; if (level.flags & LEVEL_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX;
if (level.flags & LEVEL_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX; if (level.flags & LEVEL_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX;
if (level.flags & LEVEL_CHECKSWITCHRANGE) ld->flags |= ML_CHECKSWITCHRANGE;
} }
delete[] mldf; delete[] mldf;
} }
@ -2047,6 +2053,7 @@ void P_LoadLineDefs2 (MapData * map)
P_SaveLineSpecial (ld); P_SaveLineSpecial (ld);
if (level.flags & LEVEL_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX; if (level.flags & LEVEL_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX;
if (level.flags & LEVEL_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX; if (level.flags & LEVEL_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX;
if (level.flags & LEVEL_CHECKSWITCHRANGE) ld->flags |= ML_CHECKSWITCHRANGE;
} }
delete[] mldf; delete[] mldf;
} }
@ -3347,6 +3354,7 @@ void P_FreeLevelData ()
level.total_monsters = level.total_items = level.total_secrets = level.total_monsters = level.total_items = level.total_secrets =
level.killed_monsters = level.found_items = level.found_secrets = level.killed_monsters = level.found_items = level.found_secrets =
wminfo.maxfrags = 0; wminfo.maxfrags = 0;
FBehavior::StaticUnloadModules (); FBehavior::StaticUnloadModules ();
if (vertexes != NULL) if (vertexes != NULL)
{ {
@ -3360,6 +3368,7 @@ void P_FreeLevelData ()
} }
if (sectors != NULL) if (sectors != NULL)
{ {
delete[] sectors[0].e;
delete[] sectors; delete[] sectors;
sectors = NULL; sectors = NULL;
numsectors = 0; // needed for the pointer cleanup code numsectors = 0; // needed for the pointer cleanup code
@ -3723,7 +3732,7 @@ void P_SetupLevel (char *lumpname, int position)
subsectors, numsubsectors, subsectors, numsubsectors,
vertexes, numvertexes); vertexes, numvertexes);
endTime = I_MSTime (); endTime = I_MSTime ();
Printf ("BSP generation took %.3f sec (%d segs)\n", (endTime - startTime) * 0.001, numsegs); DPrintf ("BSP generation took %.3f sec (%d segs)\n", (endTime - startTime) * 0.001, numsegs);
} }
clock (times[10]); clock (times[10]);
@ -3780,6 +3789,9 @@ void P_SetupLevel (char *lumpname, int position)
} }
delete map; delete map;
// set up world state
P_SpawnSpecials ();
clock (times[16]); clock (times[16]);
PO_Init (); // Initialize the polyobjs PO_Init (); // Initialize the polyobjs
unclock (times[16]); unclock (times[16]);
@ -3797,8 +3809,6 @@ void P_SetupLevel (char *lumpname, int position)
} }
} }
// set up world state
P_SpawnSpecials ();
// build subsector connect matrix // build subsector connect matrix
// UNUSED P_ConnectSubsectors (); // UNUSED P_ConnectSubsectors ();

View file

@ -59,25 +59,26 @@ static bool PTR_SightTraverse (intercept_t *in)
{ {
line_t *li; line_t *li;
fixed_t slope; fixed_t slope;
FLineOpening open;
li = in->d.line; li = in->d.line;
// //
// crosses a two sided line // crosses a two sided line
// //
P_LineOpening (li, trace.x + FixedMul (trace.dx, in->frac), P_LineOpening (open, NULL, li, trace.x + FixedMul (trace.dx, in->frac),
trace.y + FixedMul (trace.dy, in->frac)); trace.y + FixedMul (trace.dy, in->frac));
if (openrange <= 0) // quick test for totally closed doors if (open.range <= 0) // quick test for totally closed doors
return false; // stop return false; // stop
// check bottom // check bottom
slope = FixedDiv (openbottom - sightzstart, in->frac); slope = FixedDiv (open.bottom - sightzstart, in->frac);
if (slope > bottomslope) if (slope > bottomslope)
bottomslope = slope; bottomslope = slope;
// check top // check top
slope = FixedDiv (opentop - sightzstart, in->frac); slope = FixedDiv (open.top - sightzstart, in->frac);
if (slope < topslope) if (slope < topslope)
topslope = slope; topslope = slope;

View file

@ -51,6 +51,7 @@
#include "p_lnspec.h" #include "p_lnspec.h"
#include "p_terrain.h" #include "p_terrain.h"
#include "p_acs.h" #include "p_acs.h"
#include "p_3dmidtex.h"
#include "g_game.h" #include "g_game.h"
@ -300,6 +301,12 @@ bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType)
{ {
return false; return false;
} }
if (activationType == SPAC_USE)
{
if (!P_CheckSwitchRange(mo, line, side)) return false;
}
if (mo && !mo->player && if (mo && !mo->player &&
!(mo->flags & MF_MISSILE) && !(mo->flags & MF_MISSILE) &&
!(line->flags & ML_MONSTERSCANACTIVATE) && !(line->flags & ML_MONSTERSCANACTIVATE) &&
@ -993,6 +1000,10 @@ void P_SpawnSpecials (void)
new DWallLightTransfer (sides[*lines[i].sidenum].sector, lines[i].args[0], lines[i].args[1]); new DWallLightTransfer (sides[*lines[i].sidenum].sector, lines[i].args[0], lines[i].args[1]);
break; break;
case Sector_Attach3dMidtex:
P_Attach3dMidtexLinesToSector(lines[i].frontsector, lines[i].args[0], lines[i].args[1], !!lines[i].args[2]);
break;
// [RH] ZDoom Static_Init settings // [RH] ZDoom Static_Init settings
case Static_Init: case Static_Init:
switch (lines[i].args[1]) switch (lines[i].args[1])

View file

@ -385,6 +385,7 @@ void EV_StartLightFading (int tag, int value, int tics);
#define BUTTONTIME TICRATE // 1 second, in ticks. #define BUTTONTIME TICRATE // 1 second, in ticks.
bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *quest=NULL); bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *quest=NULL);
bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno);
void P_InitSwitchList (); void P_InitSwitchList ();
void P_ProcessSwitchDef (FScanner &sc); void P_ProcessSwitchDef (FScanner &sc);

View file

@ -37,6 +37,7 @@
#include "doomdef.h" #include "doomdef.h"
#include "p_local.h" #include "p_local.h"
#include "p_lnspec.h" #include "p_lnspec.h"
#include "p_3dmidtex.h"
#include "m_random.h" #include "m_random.h"
#include "g_game.h" #include "g_game.h"
#include "s_sound.h" #include "s_sound.h"
@ -488,30 +489,88 @@ static int TryFindSwitch (SWORD texture)
return -1; return -1;
} }
//
// Checks whether a switch is reachable
// This is optional because old maps can rely on being able to
// use non-reachable switches.
//
bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno)
{
fixed_t checktop;
fixed_t checkbot;
side_t *side = &sides[line->sidenum[sideno]];
sector_t *front = sides[line->sidenum[sideno]].sector;
sector_t *back = sides[line->sidenum[1-sideno]].sector;
FLineOpening open;
// 3DMIDTEX forces CHECKSWITCHRANGE because otherwise it might cause problems.
if (!(line->flags & (ML_3DMIDTEX|ML_CHECKSWITCHRANGE))) return true;
// calculate the point where the user would touch the wall.
divline_t dll, dlu;
fixed_t inter, checkx, checky;
P_MakeDivline (line, &dll);
dlu.x = user->x;
dlu.y = user->y;
dlu.dx = finecosine[user->angle >> ANGLETOFINESHIFT];
dlu.dy = finesine[user->angle >> ANGLETOFINESHIFT];
inter = P_InterceptVector(&dll, &dlu);
checkx = dll.x + FixedMul(dll.dx, inter);
checky = dll.y + FixedMul(dll.dy, inter);
// Now get the information from the line.
P_LineOpening(open, NULL, line, checkx, checky, user->x, user->y);
if (open.range <= 0) return true;
if ((TryFindSwitch (side->toptexture)) != -1)
{
return (user->z + user->height >= open.top);
}
else if ((TryFindSwitch (side->bottomtexture)) != -1)
{
return (user->z <= open.bottom);
}
else if ((line->flags & (ML_3DMIDTEX)) || (TryFindSwitch (side->midtexture)) != -1)
{
// 3DMIDTEX lines will force a mid texture check if no switch is found on this line
// to keep compatibility with Eternity's implementation.
if (!P_GetMidTexturePosition(line, sideno, &checktop, &checkbot)) return false;
return user->z < checktop || user->z + user->height > checkbot;
}
else
{
// no switch found. Check whether the player can touch either top or bottom texture
return (user->z + user->height >= open.top) || (user->z <= open.bottom);
}
}
// //
// Function that changes wall texture. // Function that changes wall texture.
// Tell it if switch is ok to use again (1=yes, it's a button). // Tell it if switch is ok to use again (1=yes, it's a button).
// //
bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *quest) bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *quest)
{ {
DActiveButton::EWhere where; DActiveButton::EWhere Where;
int *texture; int *texture;
int i, sound; int i, sound;
if ((i = TryFindSwitch (side->toptexture)) != -1) if ((i = TryFindSwitch (side->toptexture)) != -1)
{ {
texture = &side->toptexture; texture = &side->toptexture;
where = DActiveButton::BUTTON_Top; Where = DActiveButton::BUTTON_Top;
} }
else if ((i = TryFindSwitch (side->bottomtexture)) != -1) else if ((i = TryFindSwitch (side->bottomtexture)) != -1)
{ {
texture = &side->bottomtexture; texture = &side->bottomtexture;
where = DActiveButton::BUTTON_Bottom; Where = DActiveButton::BUTTON_Bottom;
} }
else if ((i = TryFindSwitch (side->midtexture)) != -1) else if ((i = TryFindSwitch (side->midtexture)) != -1)
{ {
texture = &side->midtexture; texture = &side->midtexture;
where = DActiveButton::BUTTON_Middle; Where = DActiveButton::BUTTON_Middle;
} }
else else
{ {
@ -549,7 +608,7 @@ bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *ques
pt[1] = line->v1->y + (line->dy >> 1); pt[1] = line->v1->y + (line->dy >> 1);
*texture = SwitchList[i]->u.Textures[SwitchList[i]->NumFrames*2]; *texture = SwitchList[i]->u.Textures[SwitchList[i]->NumFrames*2];
if (useAgain || SwitchList[i]->NumFrames > 1) if (useAgain || SwitchList[i]->NumFrames > 1)
playsound = P_StartButton (side, where, i, pt[0], pt[1], !!useAgain); playsound = P_StartButton (side, Where, i, pt[0], pt[1], !!useAgain);
else else
playsound = true; playsound = true;
if (playsound) S_SoundID (pt, CHAN_VOICE|CHAN_LISTENERZ|CHAN_IMMOBILE, sound, 1, ATTN_STATIC); if (playsound) S_SoundID (pt, CHAN_VOICE|CHAN_LISTENERZ|CHAN_IMMOBILE, sound, 1, ATTN_STATIC);

View file

@ -101,6 +101,10 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld)
flags &= 0x1FF; flags &= 0x1FF;
} }
} }
if (flags & ML_3DMIDTEX_ETERNITY)
{
flags |= ML_3DMIDTEX;
}
passthrough = (flags & ML_PASSUSE_BOOM); passthrough = (flags & ML_PASSUSE_BOOM);
} }
flags = flags & 0xFFFF01FF; // Ignore flags unknown to DOOM flags = flags & 0xFFFF01FF; // Ignore flags unknown to DOOM

View file

@ -184,12 +184,24 @@ struct secplane_t
d = d - FixedMul (hdiff, c); d = d - FixedMul (hdiff, c);
} }
// Moves a plane up/down by hdiff units
fixed_t GetChangedHeight (fixed_t hdiff)
{
return d - FixedMul (hdiff, c);
}
// Returns how much this plane's height would change if d were set to oldd // Returns how much this plane's height would change if d were set to oldd
fixed_t HeightDiff (fixed_t oldd) const fixed_t HeightDiff (fixed_t oldd) const
{ {
return FixedMul (oldd - d, ic); return FixedMul (oldd - d, ic);
} }
// Returns how much this plane's height would change if d were set to oldd
fixed_t HeightDiff (fixed_t oldd, fixed_t newd) const
{
return FixedMul (oldd - newd, ic);
}
fixed_t PointToDist (fixed_t x, fixed_t y, fixed_t z) const fixed_t PointToDist (fixed_t x, fixed_t y, fixed_t z) const
{ {
return -TMulScale16 (a, x, y, b, z, c); return -TMulScale16 (a, x, y, b, z, c);
@ -253,6 +265,27 @@ struct FExtraLight
void InsertLight (const secplane_t &plane, line_s *line, int type); void InsertLight (const secplane_t &plane, line_s *line, int type);
}; };
// this substructure contains a few sector properties that are stored in dynamic arrays
// These must not be copied by R_FakeFlat etc. or bad things will happen.
struct line_s;
struct sector_t;
struct extsector_t
{
struct midtex
{
struct plane
{
TArray<sector_t *> AttachedSectors; // all sectors containing 3dMidtex lines attached to this sector
TArray<line_s *> AttachedLines; // all 3dMidtex lines attached to this sector
} Floor, Ceiling;
} Midtex;
void Serialize(FArchive &arc);
};
struct sector_t struct sector_t
{ {
// Member functions // Member functions
@ -371,6 +404,8 @@ struct sector_t
vertex_t *Triangle[3]; // Three points that can define a plane vertex_t *Triangle[3]; // Three points that can define a plane
short oldspecial; //jff 2/16/98 remembers if sector WAS secret (automap) short oldspecial; //jff 2/16/98 remembers if sector WAS secret (automap)
extsector_t * e; // This stores data that requires construction/destruction. Such data must not be copied by R_FakeFlat.
}; };
struct ReverbContainer; struct ReverbContainer;

View file

@ -47,6 +47,7 @@
#include "vectors.h" #include "vectors.h"
#include "a_sharedglobal.h" #include "a_sharedglobal.h"
#include "r_translate.h" #include "r_translate.h"
#include "p_3dmidtex.h"
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
@ -2008,6 +2009,9 @@ void setinterpolation(EInterpType type, void *posptr)
interp->Next = *interp_p; interp->Next = *interp_p;
*interp_p = interp; *interp_p = interp;
interp->CopyInterpToOld (); interp->CopyInterpToOld ();
if (type == INTERP_SectorFloor) P_Start3dMidtexInterpolations((sector_t*)posptr, false);
else if (type == INTERP_SectorCeiling) P_Start3dMidtexInterpolations((sector_t*)posptr, true);
} }
void stopinterpolation(EInterpType type, void *posptr) void stopinterpolation(EInterpType type, void *posptr)
@ -2016,6 +2020,9 @@ void stopinterpolation(EInterpType type, void *posptr)
FActiveInterpolation *interp = FActiveInterpolation::FindInterpolation (type, posptr, interp_p); FActiveInterpolation *interp = FActiveInterpolation::FindInterpolation (type, posptr, interp_p);
if (interp != NULL) if (interp != NULL)
{ {
if (type == INTERP_SectorFloor) P_Start3dMidtexInterpolations((sector_t*)posptr, false);
else if (type == INTERP_SectorCeiling) P_Start3dMidtexInterpolations((sector_t*)posptr, true);
*interp_p = interp->Next; *interp_p = interp->Next;
delete interp; delete interp;
} }

View file

@ -40,6 +40,7 @@
#include <new> #include <new>
#include "m_alloc.h" #include "m_alloc.h"
class FArchive;
// TArray ------------------------------------------------------------------- // TArray -------------------------------------------------------------------
@ -48,6 +49,8 @@
template <class T, class TT=T> template <class T, class TT=T>
class TArray class TArray
{ {
friend FArchive &operator<< (FArchive &arc, TArray<T> &self);
public: public:
//////// ////////
// This is a dummy constructor that does nothing. The purpose of this // This is a dummy constructor that does nothing. The purpose of this

View file

@ -54,7 +54,7 @@
// Version identifier for network games. // Version identifier for network games.
// Bump it every time you do a release unless you're certain you // Bump it every time you do a release unless you're certain you
// didn't change anything that will affect sync. // didn't change anything that will affect sync.
#define NETGAMEVERSION 214 #define NETGAMEVERSION 215
// Version stored in the ini's [LastRun] section. // Version stored in the ini's [LastRun] section.
// Bump it if you made some configuration change that you want to // Bump it if you made some configuration change that you want to
@ -75,7 +75,7 @@
// SAVESIG should match SAVEVER. // SAVESIG should match SAVEVER.
// MINSAVEVER is the minimum level snapshot version that can be loaded. // MINSAVEVER is the minimum level snapshot version that can be loaded.
#define MINSAVEVER 795 #define MINSAVEVER 810
#if SVN_REVISION_NUMBER == 0 #if SVN_REVISION_NUMBER == 0
// This can happen if svnrevision is not updated properly (e.g. compiling while offline) // This can happen if svnrevision is not updated properly (e.g. compiling while offline)

File diff suppressed because it is too large Load diff