diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 949523e8a..a7e768133 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -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 - Fixed: The botinfo field of DCajunMaster was improperly listed as an object pointer. diff --git a/src/d_main.cpp b/src/d_main.cpp index 7c726cdbb..095eed9f3 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -376,11 +376,13 @@ CVAR (Flag, sv_monsterrespawn, dmflags, DF_MONSTERS_RESPAWN); CVAR (Flag, sv_itemrespawn, dmflags, DF_ITEMS_RESPAWN); CVAR (Flag, sv_fastmonsters, dmflags, DF_FAST_MONSTERS); 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_respawnsuper, dmflags, DF_RESPAWN_SUPER); CVAR (Flag, sv_nofov, dmflags, DF_NO_FOV); CVAR (Flag, sv_noweaponspawn, dmflags, DF_NO_COOP_WEAPON_SPAWN); CVAR (Flag, sv_nocrouch, dmflags, DF_NO_CROUCH); +CVAR (Flag, sv_allowcrouch, dmflags, DF_YES_CROUCH); //========================================================================== // diff --git a/src/doomdata.h b/src/doomdata.h index bac559f85..e6b3ea5a2 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -149,9 +149,6 @@ static inline int GET_SPAC (int flags) #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) #define ML_PASSUSE_BOOM 0x0200 @@ -169,13 +166,17 @@ static inline int GET_SPAC (int flags) #define ML_RAILING_STRIFE 0x0200 #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_ZONEBOUNDARY 0x00010000 #define ML_RAILING 0x00020000 #define ML_BLOCK_FLOATERS 0x00040000 #define ML_CLIP_MIDTEX 0x00080000 // Automatic for every Strife line #define ML_WRAP_MIDTEX 0x00100000 +#define ML_3DMIDTEX 0x00200000 +#define ML_CHECKSWITCHRANGE 0x00400000 // Sector definition, from editing typedef struct diff --git a/src/doomdef.h b/src/doomdef.h index 7f0338a3f..e2374b0e3 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -218,18 +218,20 @@ enum DF_ITEMS_RESPAWN = 1 << 14, // Items other than invuln. and invis. respawn DF_FAST_MONSTERS = 1 << 15, // Monsters are fast (replaces -fast parm) DF_NO_JUMP = 1 << 16, // Don't allow jumping - DF_NO_FREELOOK = 1 << 17, // Don't allow freelook - DF_RESPAWN_SUPER = 1 << 18, // Respawn invulnerability and invisibility - DF_NO_FOV = 1 << 19, // Only let the arbitrator set FOV (for all players) - DF_NO_COOP_WEAPON_SPAWN = 1 << 20, // Don't spawn multiplayer weapons in coop games - DF_NO_CROUCH = 1 << 21, // Don't allow crouching - DF_COOP_LOSE_INVENTORY = 1 << 22, // Lose all your old inventory when respawning in coop - DF_COOP_LOSE_KEYS = 1 << 23, // Lose keys when respawning in coop - DF_COOP_LOSE_WEAPONS = 1 << 24, // Lose weapons when respawning in coop - DF_COOP_LOSE_ARMOR = 1 << 25, // Lose armor when respawning in coop - DF_COOP_LOSE_POWERUPS = 1 << 26, // Lose powerups when respawning in coop - DF_COOP_LOSE_AMMO = 1 << 27, // Lose ammo 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_YES_JUMP = 2 << 16, + DF_NO_FREELOOK = 1 << 18, // Don't allow freelook + DF_RESPAWN_SUPER = 1 << 19, // Respawn invulnerability and invisibility + DF_NO_FOV = 1 << 20, // Only let the arbitrator set FOV (for all players) + DF_NO_COOP_WEAPON_SPAWN = 1 << 21, // Don't spawn multiplayer weapons in coop games + DF_NO_CROUCH = 1 << 22, // Don't allow crouching + DF_YES_CROUCH = 2 << 22, // + DF_COOP_LOSE_INVENTORY = 1 << 24, // Lose all your old inventory when respawning in coop + DF_COOP_LOSE_KEYS = 1 << 25, // Lose keys when respawning in coop + DF_COOP_LOSE_WEAPONS = 1 << 26, // Lose weapons when respawning in coop + DF_COOP_LOSE_ARMOR = 1 << 27, // Lose armor when respawning in coop + 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! diff --git a/src/dsectoreffect.cpp b/src/dsectoreffect.cpp index 3a4a4c43c..57d821c44 100644 --- a/src/dsectoreffect.cpp +++ b/src/dsectoreffect.cpp @@ -25,6 +25,7 @@ #include "dsectoreffect.h" #include "gi.h" #include "p_local.h" +#include "p_3dmidtex.h" IMPLEMENT_CLASS (DSectorEffect) @@ -103,6 +104,16 @@ DMovingCeiling::DMovingCeiling (sector_t *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 // [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; fixed_t lastpos; + fixed_t movedest; + fixed_t move; //fixed_t destheight; //jff 02/04/98 used to keep floors/ceilings // from moving thru each other switch (floorOrCeiling) @@ -125,32 +138,40 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, { case -1: // DOWN - 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; - flag = P_ChangeSector (m_Sector, crush, - m_Sector->floorplane.HeightDiff (lastpos), 0); + flag = P_ChangeSector (m_Sector, crush, move, 0); if (flag) { m_Sector->floorplane.d = lastpos; - P_ChangeSector (m_Sector, crush, - m_Sector->floorplane.HeightDiff (dest), 0); + P_ChangeSector (m_Sector, crush, -move, 0); + MoveAttached(crush, -move, 0, false); } else { - m_Sector->floortexz += m_Sector->floorplane.HeightDiff (lastpos); + m_Sector->floortexz += move; m_Sector->AdjustFloorClip (); } return pastdest; } else { + if (!MoveAttached(crush, -speed, 0, true)) return crushed; + + m_Sector->floorplane.d = movedest; + flag = P_ChangeSector (m_Sector, crush, -speed, 0); if (flag) { m_Sector->floorplane.d = lastpos; P_ChangeSector (m_Sector, crush, speed, 0); + MoveAttached(crush, speed, 0, false); return crushed; } else @@ -172,27 +193,37 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, { 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; - flag = P_ChangeSector (m_Sector, crush, - m_Sector->floorplane.HeightDiff (lastpos), 0); + + flag = P_ChangeSector (m_Sector, crush, move, 0); if (flag) { m_Sector->floorplane.d = lastpos; - P_ChangeSector (m_Sector, crush, - m_Sector->floorplane.HeightDiff (dest), 0); + P_ChangeSector (m_Sector, crush, -move, 0); + MoveAttached(crush, -move, 0, false); } else { - m_Sector->floortexz += m_Sector->floorplane.HeightDiff (lastpos); + m_Sector->floortexz += move; m_Sector->AdjustFloorClip (); } return pastdest; } else { + if (!MoveAttached(crush, speed, 0, true)) return crushed; + + m_Sector->floorplane.d = movedest; + // COULD GET CRUSHED flag = P_ChangeSector (m_Sector, crush, speed, 0); if (flag) @@ -205,6 +236,7 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, } m_Sector->floorplane.d = lastpos; P_ChangeSector (m_Sector, crush, -speed, 0); + MoveAttached(crush, -speed, 0, false); return crushed; } 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; } - m_Sector->ceilingplane.ChangeHeight (-speed); - if (m_Sector->ceilingplane.d <= dest) + movedest = m_Sector->ceilingplane.GetChangedHeight (-speed); + if (movedest <= dest) { + move = m_Sector->ceilingplane.HeightDiff (lastpos, dest); + + if (!MoveAttached(crush, move, 1, true)) return crushed; + 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) { m_Sector->ceilingplane.d = lastpos; - P_ChangeSector (m_Sector, crush, - m_Sector->ceilingplane.HeightDiff (dest), 1); + P_ChangeSector (m_Sector, crush, -move, 1); + MoveAttached(crush, -move, 1, false); } else { - m_Sector->ceilingtexz += m_Sector->ceilingplane.HeightDiff (lastpos); + m_Sector->ceilingtexz += move; } return pastdest; } else { + if (!MoveAttached(crush, -speed, 1, true)) return crushed; + + m_Sector->ceilingplane.d = movedest; + // COULD GET CRUSHED flag = P_ChangeSector (m_Sector, crush, -speed, 1); if (flag) @@ -262,6 +301,7 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, } m_Sector->ceilingplane.d = lastpos; P_ChangeSector (m_Sector, crush, speed, 1); + MoveAttached(crush, speed, 1, false); return crushed; } 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: // UP - m_Sector->ceilingplane.ChangeHeight (speed); - if (m_Sector->ceilingplane.d >= dest) + movedest = m_Sector->ceilingplane.GetChangedHeight (speed); + if (movedest >= dest) { + move = m_Sector->ceilingplane.HeightDiff (lastpos, dest); + + if (!MoveAttached(crush, move, 1, true)) return crushed; + 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) { m_Sector->ceilingplane.d = lastpos; - P_ChangeSector (m_Sector, crush, - m_Sector->ceilingplane.HeightDiff (dest), 1); + P_ChangeSector (m_Sector, crush, move, 1); + MoveAttached(crush, move, 1, false); } else { - m_Sector->ceilingtexz += m_Sector->ceilingplane.HeightDiff (lastpos); + m_Sector->ceilingtexz += move; } return pastdest; } else { + if (!MoveAttached(crush, speed, 1, true)) return crushed; + + m_Sector->ceilingplane.d = movedest; + flag = P_ChangeSector (m_Sector, crush, speed, 1); -// UNUSED -#if 0 if (flag) { m_Sector->ceilingplane.d = lastpos; P_ChangeSector (m_Sector, crush, -speed, 1); + MoveAttached(crush, -speed, 1, false); return crushed; } -#endif m_Sector->ceilingtexz += m_Sector->ceilingplane.HeightDiff (lastpos); } break; diff --git a/src/dsectoreffect.h b/src/dsectoreffect.h index 64e1e6583..9c1673913 100644 --- a/src/dsectoreffect.h +++ b/src/dsectoreffect.h @@ -29,6 +29,7 @@ public: protected: enum EResult { ok, crushed, pastdest }; 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); protected: DMover (); diff --git a/src/g_level.cpp b/src/g_level.cpp index 6e166fd29..8bc495004 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -307,6 +307,8 @@ static const char *MapInfoMapLevel[] = "skyfog", "teamplayon", "teamplayoff", + "checkswitchrange", + "nocheckswitchrange", NULL }; @@ -377,8 +379,8 @@ MapHandlers[] = { MITYPE_SETFLAG, LEVEL_FORCENOSKYSTRETCH, 0 }, { MITYPE_SCFLAGS, LEVEL_FREELOOK_YES, ~LEVEL_FREELOOK_NO }, { MITYPE_SCFLAGS, LEVEL_FREELOOK_NO, ~LEVEL_FREELOOK_YES }, - { MITYPE_SCFLAGS, LEVEL_JUMP_YES, ~LEVEL_JUMP_NO }, - { MITYPE_SCFLAGS, LEVEL_JUMP_NO, ~LEVEL_JUMP_YES }, + { MITYPE_CLRFLAG, LEVEL_JUMP_NO, 0 }, + { MITYPE_SETFLAG, LEVEL_JUMP_NO, 0 }, { MITYPE_SCFLAGS, LEVEL_FALLDMG_HX, ~LEVEL_FALLDMG_ZD }, { 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_SETFLAG, LEVEL_CLIPMIDTEX, 0 }, { MITYPE_SETFLAG, LEVEL_WRAPMIDTEX, 0 }, - { MITYPE_SCFLAGS, LEVEL_CROUCH_YES, ~LEVEL_CROUCH_NO }, - { MITYPE_SCFLAGS, LEVEL_CROUCH_NO, ~LEVEL_CROUCH_YES }, + { MITYPE_CLRFLAG, LEVEL_CROUCH_NO, 0 }, + { MITYPE_SETFLAG, LEVEL_CROUCH_NO, 0 }, { MITYPE_SCFLAGS, LEVEL_PAUSE_MUSIC_IN_MENUS, 0 }, { MITYPE_COMPATFLAG, COMPATF_SHORTTEX}, { MITYPE_COMPATFLAG, COMPATF_STAIRINDEX}, @@ -454,6 +456,8 @@ MapHandlers[] = { MITYPE_INT, lioffset(skyfog), 0 }, { MITYPE_SCFLAGS, LEVEL_FORCETEAMPLAYON, ~LEVEL_FORCETEAMPLAYOFF }, { MITYPE_SCFLAGS, LEVEL_FORCETEAMPLAYOFF, ~LEVEL_FORCETEAMPLAYON }, + { MITYPE_SETFLAG, LEVEL_CHECKSWITCHRANGE, 0 }, + { MITYPE_CLRFLAG, LEVEL_CHECKSWITCHRANGE, 0 }, }; static const char *MapInfoClusterLevel[] = @@ -2426,20 +2430,20 @@ void G_InitLevelLocals () bool level_locals_s::IsJumpingAllowed() const { - if (level.flags & LEVEL_JUMP_NO) + if (dmflags & DF_NO_JUMP) return false; - if (level.flags & LEVEL_JUMP_YES) + if (dmflags & DF_YES_JUMP) return true; - return !(dmflags & DF_NO_JUMP); + return !(level.flags & LEVEL_JUMP_NO); } bool level_locals_s::IsCrouchingAllowed() const { - if (level.flags & LEVEL_CROUCH_NO) + if (dmflags & DF_NO_CROUCH) return false; - if (level.flags & LEVEL_CROUCH_YES) + if (dmflags & DF_YES_CROUCH) return true; - return !(dmflags & DF_NO_CROUCH); + return !(level.flags & LEVEL_CROUCH_NO); } bool level_locals_s::IsFreelookAllowed() const diff --git a/src/g_level.h b/src/g_level.h index 56e2dd0b5..69c3e0ac0 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -62,8 +62,8 @@ #define LEVEL_SNDSEQTOTALCTRL UCONST64(0x00001000) #define LEVEL_FORCENOSKYSTRETCH UCONST64(0x00002000) -#define LEVEL_JUMP_NO UCONST64(0x00004000) -#define LEVEL_JUMP_YES UCONST64(0x00008000) +#define LEVEL_CROUCH_NO UCONST64(0x00004000) +#define LEVEL_JUMP_NO UCONST64(0x00008000) #define LEVEL_FREELOOK_NO UCONST64(0x00010000) #define LEVEL_FREELOOK_YES UCONST64(0x00020000) @@ -103,20 +103,20 @@ #define LEVEL_CLIPMIDTEX UCONST64(0x20000000000) #define LEVEL_WRAPMIDTEX UCONST64(0x40000000000) -#define LEVEL_CROUCH_NO UCONST64(0x80000000000) -#define LEVEL_CROUCH_YES UCONST64(0x100000000000) +#define LEVEL_CHECKSWITCHRANGE UCONST64(0x80000000000) -#define LEVEL_PAUSE_MUSIC_IN_MENUS UCONST64(0x200000000000) -#define LEVEL_TOTALINFIGHTING UCONST64(0x400000000000) -#define LEVEL_NOINFIGHTING UCONST64(0x800000000000) +#define LEVEL_PAUSE_MUSIC_IN_MENUS UCONST64(0x100000000000) +#define LEVEL_TOTALINFIGHTING UCONST64(0x200000000000) +#define LEVEL_NOINFIGHTING UCONST64(0x400000000000) -#define LEVEL_NOMONSTERS UCONST64(0x1000000000000) -#define LEVEL_INFINITE_FLIGHT UCONST64(0x2000000000000) +#define LEVEL_NOMONSTERS UCONST64(0x800000000000) +#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; diff --git a/src/m_options.cpp b/src/m_options.cpp index c3a7ddf46..c0dec0f85 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -1007,6 +1007,18 @@ value_t FallingDM[4] = { { 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[] = { { 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} }, { redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { 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, "Double ammo", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_DOUBLEAMMO} }, { 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, "Fast monsters", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_FAST_MONSTERS} }, { bitflag, "Degeneration", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_DEGENERATION} }, - { bitflag, "Allow jump", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_JUMP} }, - { bitflag, "Allow crouch", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_CROUCH} }, + { bitmask, "Allow jump", {&dmflags}, {3.0}, {DF_NO_JUMP|DF_YES_JUMP}, {0}, {DF_Jump} }, + { 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 FOV", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_FOV} }, { bitflag, "Allow BFG aiming", {&dmflags2}, {1}, {0}, {0}, {(value_t *)DF2_NO_FREEAIMBFG} }, diff --git a/src/p_3dmidtex.cpp b/src/p_3dmidtex.cpp new file mode 100644 index 000000000..3e48771cb --- /dev/null +++ b/src/p_3dmidtex.cpp @@ -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(§ors[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(line->frontsector->floortexz, line->backsector->floortexz); + + *ptextop = *ptexbot + textureheight; + } + else + { + *ptextop = rowoffset + + MIN(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; + } + */ +} \ No newline at end of file diff --git a/src/p_3dmidtex.h b/src/p_3dmidtex.h new file mode 100644 index 000000000..f1faadaf5 --- /dev/null +++ b/src/p_3dmidtex.h @@ -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 \ No newline at end of file diff --git a/src/p_doors.cpp b/src/p_doors.cpp index c4b7d4868..863e47a47 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -198,6 +198,20 @@ void DDoor::Tick () break; } } + else if (res == crushed) + { + switch (m_Type) + { + case doorRaise: + case doorRaiseIn5Mins: + m_Direction = -1; + DoorSound(false); + break; + + default: + break; + } + } break; } } diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 555b542a1..318ef3306 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2831,7 +2831,7 @@ lnSpecFunc LineSpecials[256] = LS_Ceiling_CrushRaiseAndStay, LS_Floor_CrushStop, LS_Ceiling_MoveToValue, - LS_NOP, // 48 + LS_NOP, // Sector_Attach3dMidtex LS_GlassBreak, LS_NOP, // 50: ExtraFloor_LightOnly LS_NOP, // 51 diff --git a/src/p_lnspec.h b/src/p_lnspec.h index 347f69172..0f0d3f234 100644 --- a/src/p_lnspec.h +++ b/src/p_lnspec.h @@ -98,6 +98,7 @@ typedef enum { Floor_CrushStop = 46, Ceiling_MoveToValue = 47, + Sector_Attach3dMidtex = 48, GlassBreak = 49, ExtraFloor_LightOnly = 50, diff --git a/src/p_local.h b/src/p_local.h index e11f7fdf0..3fe53764f 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -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); int P_BoxOnLineSide (const fixed_t *tmbox, const line_t *ld); -extern fixed_t opentop; -extern fixed_t openbottom; -extern fixed_t openrange; -extern fixed_t lowfloor; +struct FLineOpening +{ + fixed_t top; + 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_BlockThingsIterator (int x, int y, bool(*func)(AActor*), TArray &checkarray, AActor *start=NULL); diff --git a/src/p_map.cpp b/src/p_map.cpp index 3fbf855a9..b90482724 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -32,6 +32,7 @@ #include "m_bbox.h" #include "m_random.h" #include "i_system.h" +#include "c_dispatch.h" #include "doomdef.h" #include "p_local.h" @@ -97,6 +98,7 @@ int tmfloorpic; sector_t *tmfloorsector; int tmceilingpic; sector_t *tmceilingsector; +bool tmtouchmidtex; static fixed_t tmfbbox[4]; static AActor *tmfthing; @@ -107,6 +109,7 @@ fixed_t tmffloorpic; sector_t *tmffloorsector; fixed_t tmfceilingpic; sector_t *tmfceilingsector; +bool tmftouchmidtex; //Added by MC: So bot will know what kind of sector it's entering. sector_t* tmsector; @@ -158,6 +161,7 @@ static bool PIT_FindFloorCeiling (line_t *ld) } fixed_t sx, sy; + FLineOpening open; // set openrange, opentop, openbottom 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->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 { // 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); 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)) { - 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 { - 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); } } // adjust floor / ceiling heights - if (opentop < tmfceilingz) + if (open.top < tmfceilingz) { - tmfceilingz = opentop; + tmfceilingz = open.top; BlockingLine = ld; } - if (openbottom > tmffloorz) + if (open.bottom > tmffloorz) { - tmffloorz = openbottom; - tmffloorsector = openbottomsec; + tmffloorz = open.bottom; + tmffloorsector = open.bottomsec; + tmftouchmidtex = open.touchmidtex; BlockingLine = ld; } - if (lowfloor < tmfdropoffz) - tmfdropoffz = lowfloor; + if (open.lowfloor < tmfdropoffz) + tmfdropoffz = open.lowfloor; return true; } @@ -249,6 +254,8 @@ void P_FindFloorCeiling (AActor *actor) for (by = yl; by <= yh; by++) if (!P_BlockLinesIterator (bx, by, PIT_FindFloorCeiling)) 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 saveceilingz = tmfceilingz; 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 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->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 { // 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);*/ 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)) { - 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 { - 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); } /* 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. (gameinfo.gametype != GAME_Strife || 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 - if (opentop < tmceilingz) + if (open.top < tmceilingz) { - tmceilingz = opentop; - tmceilingsector = opentopsec; - tmceilingpic = opentopsec->ceilingpic; + tmceilingz = open.top; + tmceilingsector = open.topsec; + tmceilingpic = open.ceilingpic; ceilingline = ld; BlockingLine = ld; } - if (openbottom > tmfloorz) + if (open.bottom > tmfloorz) { - tmfloorz = openbottom; - tmfloorsector = openbottomsec; - tmfloorpic = openbottomsec->floorpic; + tmfloorz = open.bottom; + tmfloorsector = open.bottomsec; + tmfloorpic = open.floorpic; + tmtouchmidtex = open.touchmidtex; BlockingLine = ld; } - if (lowfloor < tmdropoffz) - tmdropoffz = lowfloor; + if (open.lowfloor < tmdropoffz) + tmdropoffz = open.lowfloor; // if contacted a special line, add it to the list if (ld->special) @@ -1413,7 +1424,7 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y) if (tmceilingz - tmfloorz < thing->height) return false; - if (stepthing != NULL) + if (stepthing != NULL || tmtouchmidtex) { tmdropoffz = thingdropoffz; } @@ -2096,25 +2107,30 @@ bool PTR_SlideTraverse (intercept_t* in) { goto isblocking; } + if (li->flags & ML_BLOCKMONSTERS && !(slidemo->flags3 & MF3_NOBLOCKMONST)) + { + goto isblocking; + } + FLineOpening open; // 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)); - if (openrange < slidemo->height) + if (open.range < slidemo->height) goto isblocking; // doesn't fit - if (opentop - slidemo->z < slidemo->height) + if (open.top - slidemo->z < slidemo->height) 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 } - 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 fixed_t savedz = slidemo->z; - slidemo->z = openbottom; + slidemo->z = open.bottom; bool good = P_TestMobjZ (slidemo); slidemo->z = savedz; if (!good) @@ -2261,6 +2277,7 @@ void P_SlideMove (AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps) } } + //============================================================================ // // P_CheckSlopeWalk @@ -2384,15 +2401,17 @@ bool PTR_BounceTraverse (intercept_t *in) 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 - if (openrange < slidemo->height) + if (open.range < slidemo->height) goto bounceblocking; // doesn't fit - if (opentop - slidemo->z < slidemo->height) + if (open.top - slidemo->z < slidemo->height) goto bounceblocking; // mobj is too high - if (openbottom > slidemo->z) + if (open.bottom > slidemo->z) goto bounceblocking; // mobj is too low return true; // this line doesn't block movement @@ -2573,19 +2592,20 @@ bool PTR_AimTraverse (intercept_t* in) // Crosses a two sided line. // 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)); - if (openbottom >= opentop) + if (open.bottom >= open.top) return false; // stop 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) bottompitch = pitch; - pitch = -(int)R_PointToAngle2 (0, shootz, dist, opentop); + pitch = -(int)R_PointToAngle2 (0, shootz, dist, open.top); if (pitch > toppitch) toppitch = pitch; @@ -3337,14 +3357,16 @@ bool PTR_UseTraverse (intercept_t *in) return true; } + FLineOpening open; // [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 // lines further than 64 units away. 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)); - return openrange>0; + return open.range>0; } 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: if (in->d.line->flags & ML_BLOCKEVERYTHING) { - openrange = 0; + open.range = 0; } 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)); } - if (openrange <= 0 || + if (open.range <= 0 || (in->d.line->special != 0 && (i_compatflags & COMPATF_USEBLOCKING))) { // [RH] Give sector a chance to intercept the use @@ -3428,15 +3450,16 @@ blocked: bool PTR_NoWayTraverse (intercept_t *in) { line_t *ld = in->d.line; + FLineOpening open; // [GrafZahl] de-obfuscated. Was I the only one who was unable to makes sense out of // this convoluted mess? if (ld->special) return true; 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)); - return openrange >0 && - openbottom <= usething->z + usething->MaxStepHeight && - opentop >= usething->z + usething->height; + P_LineOpening(open, NULL, ld, trace.x+FixedMul(trace.dx, in->frac),trace.y+FixedMul(trace.dy, in->frac)); + return open.range >0 && + open.bottom <= usething->z + usething->MaxStepHeight && + open.top >= usething->z + usething->height; } /* @@ -3496,14 +3519,15 @@ static bool PuzzleActivated; bool PTR_PuzzleItemTraverse (intercept_t *in) { AActor *mobj; + FLineOpening open; if (in->isaline) { // Check line 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)); - if (openrange <= 0) + if (open.range <= 0) { 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 // if no crushing is desired. // -static int moveamt; -int crushchange; -static sector_t *movesec; -bool nofit; + +struct FChangePosition +{ + int moveamt; + int crushchange; + bool nofit; + bool movemidtex; +}; + TArray intersectors; 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); thing->floorz = tmfloorz; thing->ceilingz = tmceilingz; @@ -3835,6 +3874,10 @@ bool P_AdjustFloorCeil (AActor *thing) thing->floorsector = tmfloorsector; thing->ceilingpic = tmceilingpic; thing->ceilingsector = tmceilingsector; + + // restore the PASSMOBJ flag but leave the other flags alone. + thing->flags2 = (thing->flags2 & ~MF2_PASSMOBJ) | flags2; + 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 if ((thing->flags & MF_CORPSE) && @@ -4067,11 +4110,11 @@ void P_DoCrunch (AActor *thing) 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 if ((!(thing->flags&MF_NOBLOOD)) && @@ -4080,7 +4123,7 @@ void P_DoCrunch (AActor *thing) PalEntry bloodcolor = (PalEntry)thing->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); 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) { AActor *mo; @@ -4118,7 +4161,7 @@ void P_DoCrunch (AActor *thing) // above it didn't fit. //============================================================================= -int P_PushUp (AActor *thing) +int P_PushUp (AActor *thing, FChangePosition *cpos) { unsigned int firstintersect = intersectors.Size (); unsigned int lastintersect; @@ -4140,11 +4183,11 @@ int P_PushUp (AActor *thing) return 2; } fixed_t oldz = intersect->z; - P_AdjustFloorCeil (intersect); + P_AdjustFloorCeil (intersect, cpos); intersect->z = thing->z + thing->height + 1; - if (P_PushUp (intersect)) + if (P_PushUp (intersect, cpos)) { // Move blocked - P_DoCrunch (intersect); + P_DoCrunch (intersect, cpos); intersect->z = oldz; return 2; } @@ -4160,7 +4203,7 @@ int P_PushUp (AActor *thing) // below it didn't fit. //============================================================================= -int P_PushDown (AActor *thing) +int P_PushDown (AActor *thing, FChangePosition *cpos) { unsigned int firstintersect = intersectors.Size (); unsigned int lastintersect; @@ -4182,13 +4225,13 @@ int P_PushDown (AActor *thing) return 2; } fixed_t oldz = intersect->z; - P_AdjustFloorCeil (intersect); + P_AdjustFloorCeil (intersect, cpos); if (oldz > thing->z - intersect->height) { // Only push things down, not up. intersect->z = thing->z - intersect->height; - if (P_PushDown (intersect)) + if (P_PushDown (intersect, cpos)) { // Move blocked - P_DoCrunch (intersect); + P_DoCrunch (intersect, cpos); intersect->z = oldz; 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; - P_AdjustFloorCeil (thing); + P_AdjustFloorCeil (thing, cpos); if (thing->momz == 0 && (!(thing->flags & MF_NOGRAVITY) || @@ -4224,8 +4267,8 @@ void PIT_FloorDrop (AActor *thing) P_CheckFakeFloorTriggers (thing, oldz); } else if ((thing->flags & MF_NOGRAVITY) || - ((!(level.flags & LEVEL_HEXENFORMAT) || moveamt < 9*FRACUNIT) - && thing->z - thing->floorz <= moveamt)) + ((!(level.flags & LEVEL_HEXENFORMAT) || cpos->moveamt < 9*FRACUNIT) + && thing->z - thing->floorz <= cpos->moveamt)) { thing->z = thing->floorz; 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; - P_AdjustFloorCeil (thing); + P_AdjustFloorCeil (thing, cpos); // Move things intersecting the floor up if (thing->z <= thing->floorz || @@ -4259,17 +4302,17 @@ void PIT_FloorRaise (AActor *thing) { thing->z = thing->z - oldfloorz + thing->floorz; } - switch (P_PushUp (thing)) + switch (P_PushUp (thing, cpos)) { default: P_CheckFakeFloorTriggers (thing, oldz); break; case 1: - P_DoCrunch (thing); + P_DoCrunch (thing, cpos); P_CheckFakeFloorTriggers (thing, oldz); break; case 2: - P_DoCrunch (thing); + P_DoCrunch (thing, cpos); thing->z = oldz; break; } @@ -4282,12 +4325,12 @@ void PIT_FloorRaise (AActor *thing) // //============================================================================= -void PIT_CeilingLower (AActor *thing) +void PIT_CeilingLower (AActor *thing, FChangePosition *cpos) { bool onfloor; onfloor = thing->z <= thing->floorz; - P_AdjustFloorCeil (thing); + P_AdjustFloorCeil (thing, cpos); if (thing->z + thing->height > thing->ceilingz) { @@ -4301,14 +4344,14 @@ void PIT_CeilingLower (AActor *thing) { thing->z = thing->floorz; } - switch (P_PushDown (thing)) + switch (P_PushDown (thing, cpos)) { case 2: // intentional fall-through case 1: if (onfloor) thing->z = thing->floorz; - P_DoCrunch (thing); + P_DoCrunch (thing, cpos); P_CheckFakeFloorTriggers (thing, oldz); break; 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. // (or something else?) Things marked as hanging from the ceiling will // stay where they are. if (thing->z < thing->floorz && - thing->z + thing->height >= thing->ceilingz - moveamt && + thing->z + thing->height >= thing->ceilingz - cpos->moveamt && !(thing->flags & MF_NOLIFTDROP)) { 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) { - void (*iterator)(AActor *); + FChangePosition cpos; + void (*iterator)(AActor *, FChangePosition *); + void (*iterator2)(AActor *, FChangePosition *) = NULL; msecnode_t *n; - nofit = false; - crushchange = crunch; - moveamt = abs (amt); - movesec = sector; + cpos.nofit = false; + cpos.crushchange = crunch; + cpos.moveamt = abs (amt); + cpos.movemidtex = false; // [RH] Use different functions for the four different types of sector // movement. Also update the soundorg's z-coordinate for 3D sound. - if (floorOrCeil == 0) - { // floor + switch (floorOrCeil) + { + case 0: + // floor iterator = (amt < 0) ? PIT_FloorDrop : PIT_FloorRaise; sector->soundorg[2] = sector->floorplane.ZatPoint (sector->soundorg[0], sector->soundorg[1]); - } - else - { // ceiling + break; + + case 1: + // ceiling iterator = (amt < 0) ? PIT_CeilingLower : PIT_CeilingRaise; 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, @@ -4407,13 +4469,16 @@ bool P_ChangeSector (sector_t *sector, int crunch, int amt, int floorOrCeil) { n->visited = true; // mark thing as processed 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 } } } while (n); // repeat from scratch until all things left are marked valid - return nofit; + return cpos.nofit; } //============================================================================= diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index bbebba40e..547b854a3 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -34,6 +34,7 @@ #include "doomdef.h" #include "doomstat.h" #include "p_local.h" +#include "p_3dmidtex.h" // State. #include "r_state.h" @@ -184,15 +185,8 @@ fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1) // //========================================================================== -fixed_t opentop; -fixed_t openbottom; -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) +void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, + fixed_t x, fixed_t y, fixed_t refx, fixed_t refy) { sector_t *front, *back; 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) { // single sided line - openrange = 0; + open.range = 0; 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);*/ - opentopsec = fc < bc? front : back; - opentop = fc < bc ? fc : bc; + open.topsec = fc < bc? front : back; + open.ceilingpic = open.topsec->ceilingpic; + open.top = fc < bc ? fc : bc; 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) { - openbottom = ff; - openbottomsec = front; - lowfloor = bf; - //tmfloorpic = front->floorpic; + open.bottom = ff; + open.bottomsec = front; + open.floorpic = front->floorpic; + open.lowfloor = bf; } else { - openbottom = bf; - openbottomsec = back; - lowfloor = ff; - //tmfloorpic = back->floorpic; + open.bottom = bf; + open.bottomsec = back; + open.floorpic = 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; } diff --git a/src/p_plats.cpp b/src/p_plats.cpp index 02be48cd1..f1da29306 100644 --- a/src/p_plats.cpp +++ b/src/p_plats.cpp @@ -143,6 +143,12 @@ void DPlat::Tick () 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 //only affects plats that raise and bounce diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index aac9a22dc..837370298 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -333,6 +333,8 @@ void P_SerializeWorld (FArchive &arc) << sec->FloorSkyBox << sec->CeilingSkyBox << sec->ZoneNumber << sec->oldspecial; + + sec->e->Serialize(arc); if (arc.IsStoring ()) { 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 +void SaveArray (FArchive &arc, TArray &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 diff --git a/src/p_setup.cpp b/src/p_setup.cpp index f8cbcacb2..11c50d1c8 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1043,8 +1043,13 @@ void P_LoadSectors (MapData * map) map->Read(ML_SECTORS, msp); ms = (mapsector_t*)msp; ss = sectors; + + // Extended properties + sectors[0].e = new extsector_t[numsectors]; + for (i = 0; i < numsectors; i++, ss++, ms++) { + ss->e = §ors[0].e[i]; ss->floortexz = LittleShort(ms->floorheight)<floorplane.d = -ss->floortexz; ss->floorplane.c = FRACUNIT; @@ -1971,6 +1976,7 @@ void P_LoadLineDefs (MapData * map) P_SaveLineSpecial (ld); if (level.flags & LEVEL_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX; if (level.flags & LEVEL_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX; + if (level.flags & LEVEL_CHECKSWITCHRANGE) ld->flags |= ML_CHECKSWITCHRANGE; } delete[] mldf; } @@ -2047,6 +2053,7 @@ void P_LoadLineDefs2 (MapData * map) P_SaveLineSpecial (ld); if (level.flags & LEVEL_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX; if (level.flags & LEVEL_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX; + if (level.flags & LEVEL_CHECKSWITCHRANGE) ld->flags |= ML_CHECKSWITCHRANGE; } delete[] mldf; } @@ -3347,6 +3354,7 @@ void P_FreeLevelData () level.total_monsters = level.total_items = level.total_secrets = level.killed_monsters = level.found_items = level.found_secrets = wminfo.maxfrags = 0; + FBehavior::StaticUnloadModules (); if (vertexes != NULL) { @@ -3360,6 +3368,7 @@ void P_FreeLevelData () } if (sectors != NULL) { + delete[] sectors[0].e; delete[] sectors; sectors = NULL; numsectors = 0; // needed for the pointer cleanup code @@ -3723,7 +3732,7 @@ void P_SetupLevel (char *lumpname, int position) subsectors, numsubsectors, vertexes, numvertexes); 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]); @@ -3780,6 +3789,9 @@ void P_SetupLevel (char *lumpname, int position) } delete map; + // set up world state + P_SpawnSpecials (); + clock (times[16]); PO_Init (); // Initialize the polyobjs unclock (times[16]); @@ -3797,8 +3809,6 @@ void P_SetupLevel (char *lumpname, int position) } } - // set up world state - P_SpawnSpecials (); // build subsector connect matrix // UNUSED P_ConnectSubsectors (); diff --git a/src/p_sight.cpp b/src/p_sight.cpp index a1e964c1c..1db00c9e6 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -59,25 +59,26 @@ static bool PTR_SightTraverse (intercept_t *in) { line_t *li; fixed_t slope; + FLineOpening open; li = in->d.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)); - if (openrange <= 0) // quick test for totally closed doors + if (open.range <= 0) // quick test for totally closed doors return false; // stop // check bottom - slope = FixedDiv (openbottom - sightzstart, in->frac); + slope = FixedDiv (open.bottom - sightzstart, in->frac); if (slope > bottomslope) bottomslope = slope; // check top - slope = FixedDiv (opentop - sightzstart, in->frac); + slope = FixedDiv (open.top - sightzstart, in->frac); if (slope < topslope) topslope = slope; diff --git a/src/p_spec.cpp b/src/p_spec.cpp index f8699a9e6..c083383f1 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -51,6 +51,7 @@ #include "p_lnspec.h" #include "p_terrain.h" #include "p_acs.h" +#include "p_3dmidtex.h" #include "g_game.h" @@ -300,6 +301,12 @@ bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType) { return false; } + + if (activationType == SPAC_USE) + { + if (!P_CheckSwitchRange(mo, line, side)) return false; + } + if (mo && !mo->player && !(mo->flags & MF_MISSILE) && !(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]); 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 case Static_Init: switch (lines[i].args[1]) diff --git a/src/p_spec.h b/src/p_spec.h index 72aea8a95..713f18bca 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -385,6 +385,7 @@ void EV_StartLightFading (int tag, int value, int tics); #define BUTTONTIME TICRATE // 1 second, in ticks. 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_ProcessSwitchDef (FScanner &sc); diff --git a/src/p_switch.cpp b/src/p_switch.cpp index 238b3dc92..cbf173f2c 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -37,6 +37,7 @@ #include "doomdef.h" #include "p_local.h" #include "p_lnspec.h" +#include "p_3dmidtex.h" #include "m_random.h" #include "g_game.h" #include "s_sound.h" @@ -488,30 +489,88 @@ static int TryFindSwitch (SWORD texture) 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. // 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) { - DActiveButton::EWhere where; + DActiveButton::EWhere Where; int *texture; int i, sound; if ((i = TryFindSwitch (side->toptexture)) != -1) { texture = &side->toptexture; - where = DActiveButton::BUTTON_Top; + Where = DActiveButton::BUTTON_Top; } else if ((i = TryFindSwitch (side->bottomtexture)) != -1) { texture = &side->bottomtexture; - where = DActiveButton::BUTTON_Bottom; + Where = DActiveButton::BUTTON_Bottom; } else if ((i = TryFindSwitch (side->midtexture)) != -1) { texture = &side->midtexture; - where = DActiveButton::BUTTON_Middle; + Where = DActiveButton::BUTTON_Middle; } 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); *texture = SwitchList[i]->u.Textures[SwitchList[i]->NumFrames*2]; 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 playsound = true; if (playsound) S_SoundID (pt, CHAN_VOICE|CHAN_LISTENERZ|CHAN_IMMOBILE, sound, 1, ATTN_STATIC); diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index 39050491d..af3549a61 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -101,6 +101,10 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) flags &= 0x1FF; } } + if (flags & ML_3DMIDTEX_ETERNITY) + { + flags |= ML_3DMIDTEX; + } passthrough = (flags & ML_PASSUSE_BOOM); } flags = flags & 0xFFFF01FF; // Ignore flags unknown to DOOM diff --git a/src/r_defs.h b/src/r_defs.h index 1e34ba9c6..09e8672d3 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -184,12 +184,24 @@ struct secplane_t 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 fixed_t HeightDiff (fixed_t oldd) const { 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 { 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); }; +// 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 AttachedSectors; // all sectors containing 3dMidtex lines attached to this sector + TArray AttachedLines; // all 3dMidtex lines attached to this sector + } Floor, Ceiling; + } Midtex; + + + void Serialize(FArchive &arc); +}; + + struct sector_t { // Member functions @@ -371,6 +404,8 @@ struct sector_t vertex_t *Triangle[3]; // Three points that can define a plane 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; diff --git a/src/r_main.cpp b/src/r_main.cpp index d1debc263..2413d863a 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -47,6 +47,7 @@ #include "vectors.h" #include "a_sharedglobal.h" #include "r_translate.h" +#include "p_3dmidtex.h" // MACROS ------------------------------------------------------------------ @@ -2008,6 +2009,9 @@ void setinterpolation(EInterpType type, void *posptr) interp->Next = *interp_p; *interp_p = interp; 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) @@ -2016,6 +2020,9 @@ void stopinterpolation(EInterpType type, void *posptr) FActiveInterpolation *interp = FActiveInterpolation::FindInterpolation (type, posptr, interp_p); 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; delete interp; } diff --git a/src/tarray.h b/src/tarray.h index 44ea0537a..ed31a28a1 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -40,6 +40,7 @@ #include #include "m_alloc.h" +class FArchive; // TArray ------------------------------------------------------------------- @@ -48,6 +49,8 @@ template class TArray { + friend FArchive &operator<< (FArchive &arc, TArray &self); + public: //////// // This is a dummy constructor that does nothing. The purpose of this diff --git a/src/version.h b/src/version.h index 951b42d51..b305d5c79 100644 --- a/src/version.h +++ b/src/version.h @@ -54,7 +54,7 @@ // Version identifier for network games. // Bump it every time you do a release unless you're certain you // didn't change anything that will affect sync. -#define NETGAMEVERSION 214 +#define NETGAMEVERSION 215 // Version stored in the ini's [LastRun] section. // Bump it if you made some configuration change that you want to @@ -75,7 +75,7 @@ // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 795 +#define MINSAVEVER 810 #if SVN_REVISION_NUMBER == 0 // This can happen if svnrevision is not updated properly (e.g. compiling while offline) diff --git a/zdoom.vcproj b/zdoom.vcproj index 8b4276e10..9c7dd700b 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -1,7 +1,7 @@ + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - @@ -484,13 +477,6 @@ Name="VCCLCompilerTool" /> - - - @@ -502,27 +488,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1409,28 +946,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1665,28 +1076,11 @@ - - - - - - @@ -1705,28 +1098,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - @@ -1853,28 +1174,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2366,31 +1453,18 @@ RelativePath=".\src\nodebuild_utility.cpp" > + + - - - - - - - - - - - - - - - - - - @@ -2481,28 +1518,11 @@ - - - - - - - - - - - - - - - - - - @@ -2593,28 +1576,11 @@ - - - - - - - - - - - - - - - - - - @@ -2702,11 +1631,11 @@ RelativePath=".\src\p_lnspec.cpp" > - - - @@ -2739,28 +1657,11 @@ - - - - - - - - - - - - @@ -2816,16 +1698,6 @@ > - - - @@ -2834,7 +1706,14 @@ > + + + @@ -2843,7 +1722,6 @@ > @@ -2851,28 +1729,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3539,28 +2075,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - @@ -3697,16 +2161,6 @@ Outputs=""src/$(InputName).h"" /> - - - @@ -3717,6 +2171,16 @@ Outputs=""src/$(InputName).h"" /> + + + @@ -3731,28 +2195,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3915,28 +2289,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -4605,6 +2799,10 @@ RelativePath=".\src\nodebuild.h" > + + @@ -4783,16 +2981,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -4803,6 +2991,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -4827,16 +3025,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -4847,6 +3035,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -4871,16 +3069,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -4891,6 +3079,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -4915,16 +3113,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -4935,6 +3123,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -4959,16 +3157,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -4979,6 +3167,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -5057,28 +3255,11 @@ - - - - - - @@ -5097,28 +3277,11 @@ - - - - - - @@ -5137,28 +3299,11 @@ - - - - - - @@ -5177,28 +3321,11 @@ - - - - - - @@ -5217,28 +3343,11 @@ - - - - - - - - - - - - - - - - - - @@ -5349,28 +3421,11 @@ - - - - - - @@ -5395,14 +3449,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -5413,6 +3459,14 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + - - - - - - @@ -5473,28 +3509,11 @@ - - - - - - @@ -5513,28 +3531,11 @@ - - - - - - - - - - - - - - - - - - @@ -5626,7 +3590,6 @@ > @@ -5635,52 +3598,25 @@ > - - - - - - - - - - - - - - - @@ -5743,28 +3660,11 @@ - - - - - - @@ -5791,28 +3690,11 @@ - - - - - - - - - - - - @@ -5871,28 +3734,11 @@ - - - - - - - - - - - - - - - - - - @@ -5987,28 +3796,11 @@ - - - - - - @@ -6031,28 +3822,11 @@ - - - - - - - - - - - - @@ -6111,28 +3866,11 @@ - - - - - - - - - - - - @@ -6199,28 +3918,11 @@ - - - - - - @@ -6239,28 +3940,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -6495,28 +4070,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -6931,28 +4290,11 @@ - - - - - - - - - - - - @@ -7011,28 +4334,11 @@ - - - - - - - - - - - - - - - - - - @@ -7123,28 +4392,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -7379,28 +4522,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -7891,28 +4782,11 @@ - - - - - - - - - - - - - - - - - - @@ -8003,28 +4840,11 @@ - - - - - - @@ -8043,28 +4862,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -8335,28 +5010,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - @@ -8483,28 +5086,11 @@ - - - - - - @@ -8642,28 +5227,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -8862,28 +5339,11 @@ - - - - - - - - - - - - - - - - - - @@ -9172,14 +5595,6 @@ AdditionalIncludeDirectories="src\win32;$(NoInherit)" /> - - - @@ -9189,6 +5604,14 @@ AdditionalIncludeDirectories="src\win32;$(NoInherit)" /> + + + @@ -9343,7 +5766,7 @@ />