diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index 7b4fb2118..95be8f7bc 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -46,6 +46,14 @@ inline FArchive &operator<< (FArchive &arc, DCeiling::ECeiling &type) return arc; } +inline FArchive &operator<< (FArchive &arc, DCeiling::ECrushMode &type) +{ + BYTE val = (BYTE)type; + arc << val; + type = (DCeiling::ECrushMode)val; + return arc; +} + //============================================================================ // // CEILINGS @@ -80,7 +88,7 @@ void DCeiling::Serialize (FArchive &arc) << m_NewSpecial << m_Tag << m_OldDirection - << m_Hexencrush; + << m_CrushMode; } //============================================================================ @@ -159,7 +167,7 @@ void DCeiling::Tick () case -1: // DOWN - res = MoveCeiling (m_Speed, m_BottomHeight, m_Crush, m_Direction, m_Hexencrush); + res = MoveCeiling (m_Speed, m_BottomHeight, m_Crush, m_Direction, m_CrushMode == ECrushMode::crushHexen); if (res == pastdest) { @@ -196,7 +204,7 @@ void DCeiling::Tick () { case ceilCrushAndRaise: case ceilLowerAndCrush: - if (m_Speed1 == FRACUNIT && m_Speed2 == FRACUNIT) + if (m_CrushMode == ECrushMode::crushSlowdown) m_Speed = FRACUNIT / 8; break; @@ -224,7 +232,7 @@ DCeiling::DCeiling (sector_t *sec, fixed_t speed1, fixed_t speed2, int silent) : DMovingCeiling (sec) { m_Crush = -1; - m_Hexencrush = false; + m_CrushMode = ECrushMode::crushDoom; m_Speed = m_Speed1 = speed1; m_Speed2 = speed2; m_Silent = silent; @@ -238,7 +246,7 @@ DCeiling::DCeiling (sector_t *sec, fixed_t speed1, fixed_t speed2, int silent) DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, int tag, fixed_t speed, fixed_t speed2, fixed_t height, - int crush, int silent, int change, bool hexencrush) + int crush, int silent, int change, ECrushMode hexencrush) { fixed_t targheight = 0; // Silence, GCC @@ -387,7 +395,7 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, ceiling->m_Tag = tag; ceiling->m_Type = type; ceiling->m_Crush = crush; - ceiling->m_Hexencrush = hexencrush; + ceiling->m_CrushMode = hexencrush; // Do not interpolate instant movement ceilings. // Note for ZDoomGL: Check to make sure that you update the sector @@ -476,7 +484,7 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line, int tag, fixed_t speed, fixed_t speed2, fixed_t height, - int crush, int silent, int change, bool hexencrush) + int crush, int silent, int change, DCeiling::ECrushMode hexencrush) { int secnum; bool rtn; diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 7c6f05b29..bc70388ae 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -84,9 +84,21 @@ static const BYTE ChangeMap[8] = { 0, 1, 5, 3, 7, 2, 6, 0 }; #define OCTICS(a) (((a)*TICRATE)/8) #define BYTEANGLE(a) ((angle_t)((a)<<24)) #define CRUSH(a) ((a) > 0? (a) : -1) -#define CRUSHTYPE(a) ((a)==1? false : (a)==2? true : gameinfo.gametype == GAME_Hexen) #define CHANGE(a) (((a) >= 0 && (a)<=7)? ChangeMap[a]:0) +static bool CRUSHTYPE(int a) +{ + return ((a) == 1 ? false : (a) == 2 ? true : gameinfo.gametype == GAME_Hexen); +} + +static DCeiling::ECrushMode CRUSHTYPE(int a, bool withslowdown) +{ + static DCeiling::ECrushMode map[] = { DCeiling::ECrushMode::crushDoom, DCeiling::ECrushMode::crushHexen, DCeiling::ECrushMode::crushSlowdown }; + if (a >= 1 && a <= 3) return map[a - 1]; + if (gameinfo.gametype == GAME_Hexen) return DCeiling::ECrushMode::crushHexen; + return withslowdown? DCeiling::ECrushMode::crushSlowdown : DCeiling::ECrushMode::crushDoom; +} + static FRandom pr_glass ("GlassBreak"); // There are aliases for the ACS specials that take names instead of numbers. @@ -628,43 +640,43 @@ FUNC(LS_Pillar_Open) FUNC(LS_Ceiling_LowerByValue) // Ceiling_LowerByValue (tag, speed, height, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT, CRUSH(arg4), 0, CHANGE(arg3), false); + return EV_DoCeiling (DCeiling::ceilLowerByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT, CRUSH(arg4), 0, CHANGE(arg3)); } FUNC(LS_Ceiling_RaiseByValue) // Ceiling_RaiseByValue (tag, speed, height, change) { - return EV_DoCeiling (DCeiling::ceilRaiseByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT, CRUSH(arg4), 0, CHANGE(arg3), false); + return EV_DoCeiling (DCeiling::ceilRaiseByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT, CRUSH(arg4), 0, CHANGE(arg3)); } FUNC(LS_Ceiling_LowerByValueTimes8) // Ceiling_LowerByValueTimes8 (tag, speed, height, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT*8, -1, 0, CHANGE(arg3), false); + return EV_DoCeiling (DCeiling::ceilLowerByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT*8, -1, 0, CHANGE(arg3)); } FUNC(LS_Ceiling_RaiseByValueTimes8) // Ceiling_RaiseByValueTimes8 (tag, speed, height, change) { - return EV_DoCeiling (DCeiling::ceilRaiseByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT*8, -1, 0, CHANGE(arg3), false); + return EV_DoCeiling (DCeiling::ceilRaiseByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT*8, -1, 0, CHANGE(arg3)); } FUNC(LS_Ceiling_CrushAndRaise) // Ceiling_CrushAndRaise (tag, speed, crush, crushtype) { - return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), SPEED(arg1)/2, 8*FRACUNIT, arg2, 0, 0, CRUSHTYPE(arg3)); + return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), SPEED(arg1)/2, 8*FRACUNIT, arg2, 0, 0, CRUSHTYPE(arg3, false)); } FUNC(LS_Ceiling_LowerAndCrush) // Ceiling_LowerAndCrush (tag, speed, crush, crushtype) { - return EV_DoCeiling (DCeiling::ceilLowerAndCrush, ln, arg0, SPEED(arg1), SPEED(arg1), 8*FRACUNIT, arg2, 0, 0, CRUSHTYPE(arg3)); + return EV_DoCeiling (DCeiling::ceilLowerAndCrush, ln, arg0, SPEED(arg1), SPEED(arg1), 8*FRACUNIT, arg2, 0, 0, CRUSHTYPE(arg3, arg1 == 8)); } FUNC(LS_Ceiling_LowerAndCrushDist) // Ceiling_LowerAndCrush (tag, speed, crush, dist, crushtype) { - return EV_DoCeiling (DCeiling::ceilLowerAndCrush, ln, arg0, SPEED(arg1), SPEED(arg1), arg3*FRACUNIT, arg2, 0, 0, CRUSHTYPE(arg4)); + return EV_DoCeiling (DCeiling::ceilLowerAndCrush, ln, arg0, SPEED(arg1), SPEED(arg1), arg3*FRACUNIT, arg2, 0, 0, CRUSHTYPE(arg4, arg1 == 8)); } FUNC(LS_Ceiling_CrushStop) @@ -676,141 +688,141 @@ FUNC(LS_Ceiling_CrushStop) FUNC(LS_Ceiling_CrushRaiseAndStay) // Ceiling_CrushRaiseAndStay (tag, speed, crush, crushtype) { - return EV_DoCeiling (DCeiling::ceilCrushRaiseAndStay, ln, arg0, SPEED(arg1), SPEED(arg1)/2, 8*FRACUNIT, arg2, 0, 0, CRUSHTYPE(arg3)); + return EV_DoCeiling (DCeiling::ceilCrushRaiseAndStay, ln, arg0, SPEED(arg1), SPEED(arg1)/2, 8*FRACUNIT, arg2, 0, 0, CRUSHTYPE(arg3, false)); } FUNC(LS_Ceiling_MoveToValueTimes8) // Ceiling_MoveToValueTimes8 (tag, speed, height, negative, change) { return EV_DoCeiling (DCeiling::ceilMoveToValue, ln, arg0, SPEED(arg1), 0, - arg2*FRACUNIT*8*((arg3) ? -1 : 1), -1, 0, CHANGE(arg4), false); + arg2*FRACUNIT*8*((arg3) ? -1 : 1), -1, 0, CHANGE(arg4)); } FUNC(LS_Ceiling_MoveToValue) // Ceiling_MoveToValue (tag, speed, height, negative, change) { return EV_DoCeiling (DCeiling::ceilMoveToValue, ln, arg0, SPEED(arg1), 0, - arg2*FRACUNIT*((arg3) ? -1 : 1), -1, 0, CHANGE(arg4), false); + arg2*FRACUNIT*((arg3) ? -1 : 1), -1, 0, CHANGE(arg4)); } FUNC(LS_Ceiling_LowerToHighestFloor) // Ceiling_LowerToHighestFloor (tag, speed, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerToHighestFloor, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg2), false); + return EV_DoCeiling (DCeiling::ceilLowerToHighestFloor, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg2)); } FUNC(LS_Ceiling_LowerInstant) // Ceiling_LowerInstant (tag, unused, height, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerInstant, ln, arg0, 0, 0, arg2*FRACUNIT*8, CRUSH(arg4), 0, CHANGE(arg3), false); + return EV_DoCeiling (DCeiling::ceilLowerInstant, ln, arg0, 0, 0, arg2*FRACUNIT*8, CRUSH(arg4), 0, CHANGE(arg3)); } FUNC(LS_Ceiling_RaiseInstant) // Ceiling_RaiseInstant (tag, unused, height, change) { - return EV_DoCeiling (DCeiling::ceilRaiseInstant, ln, arg0, 0, 0, arg2*FRACUNIT*8, -1, 0, CHANGE(arg3), false); + return EV_DoCeiling (DCeiling::ceilRaiseInstant, ln, arg0, 0, 0, arg2*FRACUNIT*8, -1, 0, CHANGE(arg3)); } FUNC(LS_Ceiling_CrushRaiseAndStayA) // Ceiling_CrushRaiseAndStayA (tag, dnspeed, upspeed, damage, crushtype) { - return EV_DoCeiling (DCeiling::ceilCrushRaiseAndStay, ln, arg0, SPEED(arg1), SPEED(arg2), 0, arg3, 0, 0, CRUSHTYPE(arg4)); + return EV_DoCeiling (DCeiling::ceilCrushRaiseAndStay, ln, arg0, SPEED(arg1), SPEED(arg2), 0, arg3, 0, 0, CRUSHTYPE(arg4, false)); } FUNC(LS_Ceiling_CrushRaiseAndStaySilA) // Ceiling_CrushRaiseAndStaySilA (tag, dnspeed, upspeed, damage, crushtype) { - return EV_DoCeiling (DCeiling::ceilCrushRaiseAndStay, ln, arg0, SPEED(arg1), SPEED(arg2), 0, arg3, 1, 0, CRUSHTYPE(arg4)); + return EV_DoCeiling (DCeiling::ceilCrushRaiseAndStay, ln, arg0, SPEED(arg1), SPEED(arg2), 0, arg3, 1, 0, CRUSHTYPE(arg4, false)); } FUNC(LS_Ceiling_CrushAndRaiseA) // Ceiling_CrushAndRaiseA (tag, dnspeed, upspeed, damage, crushtype) { - return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), SPEED(arg2), 0, arg3, 0, 0, CRUSHTYPE(arg4)); + return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), SPEED(arg2), 0, arg3, 0, 0, CRUSHTYPE(arg4, arg1 == 8 && arg2 == 8)); } FUNC(LS_Ceiling_CrushAndRaiseDist) // Ceiling_CrushAndRaiseDist (tag, dist, speed, damage, crushtype) { - return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg2), SPEED(arg2), arg1*FRACUNIT, arg3, 0, 0, CRUSHTYPE(arg4)); + return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg2), SPEED(arg2), arg1*FRACUNIT, arg3, 0, 0, CRUSHTYPE(arg4, arg2 == 8)); } FUNC(LS_Ceiling_CrushAndRaiseSilentA) // Ceiling_CrushAndRaiseSilentA (tag, dnspeed, upspeed, damage, crushtype) { - return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), SPEED(arg2), 0, arg3, 1, 0, CRUSHTYPE(arg4)); + return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), SPEED(arg2), 0, arg3, 1, 0, CRUSHTYPE(arg4, arg1 == 8 && arg2 == 8)); } FUNC(LS_Ceiling_CrushAndRaiseSilentDist) // Ceiling_CrushAndRaiseSilentDist (tag, dist, upspeed, damage, crushtype) { - return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg2), SPEED(arg2), arg1*FRACUNIT, arg3, 1, 0, CRUSHTYPE(arg4)); + return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg2), SPEED(arg2), arg1*FRACUNIT, arg3, 1, 0, CRUSHTYPE(arg4, arg2 == 8)); } FUNC(LS_Ceiling_RaiseToNearest) // Ceiling_RaiseToNearest (tag, speed, change) { - return EV_DoCeiling (DCeiling::ceilRaiseToNearest, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0, false); + return EV_DoCeiling (DCeiling::ceilRaiseToNearest, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0); } FUNC(LS_Ceiling_RaiseToHighest) // Ceiling_RaiseToHighest (tag, speed, change) { - return EV_DoCeiling (DCeiling::ceilRaiseToHighest, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0, false); + return EV_DoCeiling (DCeiling::ceilRaiseToHighest, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0); } FUNC(LS_Ceiling_RaiseToLowest) // Ceiling_RaiseToLowest (tag, speed, change) { - return EV_DoCeiling (DCeiling::ceilRaiseToLowest, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0, false); + return EV_DoCeiling (DCeiling::ceilRaiseToLowest, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0); } FUNC(LS_Ceiling_RaiseToHighestFloor) // Ceiling_RaiseToHighestFloor (tag, speed, change) { - return EV_DoCeiling (DCeiling::ceilRaiseToHighestFloor, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0, false); + return EV_DoCeiling (DCeiling::ceilRaiseToHighestFloor, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0); } FUNC(LS_Ceiling_RaiseByTexture) // Ceiling_RaiseByTexture (tag, speed, change) { - return EV_DoCeiling (DCeiling::ceilRaiseByTexture, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0, false); + return EV_DoCeiling (DCeiling::ceilRaiseByTexture, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0); } FUNC(LS_Ceiling_LowerToLowest) // Ceiling_LowerToLowest (tag, speed, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerToLowest, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg2), false); + return EV_DoCeiling (DCeiling::ceilLowerToLowest, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg2)); } FUNC(LS_Ceiling_LowerToNearest) // Ceiling_LowerToNearest (tag, speed, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerToNearest, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg2), false); + return EV_DoCeiling (DCeiling::ceilLowerToNearest, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg2)); } FUNC(LS_Ceiling_ToHighestInstant) // Ceiling_ToHighestInstant (tag, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerToHighest, ln, arg0, FRACUNIT*2, 0, 0, CRUSH(arg2), 0, CHANGE(arg1), false); + return EV_DoCeiling (DCeiling::ceilLowerToHighest, ln, arg0, FRACUNIT*2, 0, 0, CRUSH(arg2), 0, CHANGE(arg1)); } FUNC(LS_Ceiling_ToFloorInstant) // Ceiling_ToFloorInstant (tag, change, crush) { - return EV_DoCeiling (DCeiling::ceilRaiseToFloor, ln, arg0, FRACUNIT*2, 0, 0, CRUSH(arg2), 0, CHANGE(arg1), false); + return EV_DoCeiling (DCeiling::ceilRaiseToFloor, ln, arg0, FRACUNIT*2, 0, 0, CRUSH(arg2), 0, CHANGE(arg1)); } FUNC(LS_Ceiling_LowerToFloor) // Ceiling_LowerToFloor (tag, speed, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerToFloor, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg4), false); + return EV_DoCeiling (DCeiling::ceilLowerToFloor, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg4)); } FUNC(LS_Ceiling_LowerByTexture) // Ceiling_LowerByTexture (tag, speed, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerByTexture, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg4), false); + return EV_DoCeiling (DCeiling::ceilLowerByTexture, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg4)); } FUNC(LS_Generic_Ceiling) @@ -841,14 +853,14 @@ FUNC(LS_Generic_Ceiling) } return EV_DoCeiling (type, ln, arg0, SPEED(arg1), SPEED(arg1), arg2*FRACUNIT, - (arg4 & 16) ? 20 : -1, 0, arg4 & 7, false); + (arg4 & 16) ? 20 : -1, 0, arg4 & 7); } FUNC(LS_Generic_Crusher) // Generic_Crusher (tag, dnspeed, upspeed, silent, damage) { return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), - SPEED(arg2), 0, arg4, arg3 ? 2 : 0, 0, false); + SPEED(arg2), 0, arg4, arg3 ? 2 : 0, 0, (arg1 <= 24 && arg2 <= 24)? DCeiling::ECrushMode::crushSlowdown : DCeiling::ECrushMode::crushDoom); } FUNC(LS_Generic_Crusher2) @@ -856,7 +868,7 @@ FUNC(LS_Generic_Crusher2) { // same as above but uses Hexen's crushing method. return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), - SPEED(arg2), 0, arg4, arg3 ? 2 : 0, 0, true); + SPEED(arg2), 0, arg4, arg3 ? 2 : 0, 0, DCeiling::ECrushMode::crushHexen); } FUNC(LS_Plat_PerpetualRaise) @@ -1944,7 +1956,7 @@ FUNC(LS_FloorAndCeiling_RaiseByValue) FUNC(LS_FloorAndCeiling_LowerRaise) // FloorAndCeiling_LowerRaise (tag, fspeed, cspeed, boomemu) { - bool res = EV_DoCeiling (DCeiling::ceilRaiseToHighest, ln, arg0, SPEED(arg2), 0, 0, 0, 0, 0, false); + bool res = EV_DoCeiling (DCeiling::ceilRaiseToHighest, ln, arg0, SPEED(arg2), 0, 0, 0, 0, 0); // The switch based Boom equivalents of FloorandCeiling_LowerRaise do incorrect checks // which cause the floor only to move when the ceiling fails to do so. // To avoid problems with maps that have incorrect args this only uses a diff --git a/src/p_spec.h b/src/p_spec.h index d40fb3da7..b0baaa1ea 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -647,6 +647,14 @@ public: genCeilingChg }; + enum class ECrushMode + { + crushDoom = 0, + crushHexen = 1, + crushSlowdown = 2 + }; + + DCeiling (sector_t *sec); DCeiling (sector_t *sec, fixed_t speed1, fixed_t speed2, int silent); @@ -655,7 +663,7 @@ public: static DCeiling *Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, int tag, fixed_t speed, fixed_t speed2, fixed_t height, - int crush, int silent, int change, bool hexencrush); + int crush, int silent, int change, ECrushMode hexencrush); protected: ECeiling m_Type; @@ -665,7 +673,7 @@ protected: fixed_t m_Speed1; // [RH] dnspeed of crushers fixed_t m_Speed2; // [RH] upspeed of crushers int m_Crush; - bool m_Hexencrush; + ECrushMode m_CrushMode; int m_Silent; int m_Direction; // 1 = up, 0 = waiting, -1 = down @@ -688,7 +696,7 @@ private: bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line, int tag, fixed_t speed, fixed_t speed2, fixed_t height, - int crush, int silent, int change, bool hexencrush); + int crush, int silent, int change, DCeiling::ECrushMode hexencrush = DCeiling::ECrushMode::crushDoom); bool EV_CeilingCrushStop (int tag); void P_ActivateInStasisCeiling (int tag);