- changed the means how to control the slowdown of crushing ceilings encountering an obstacle and corrected a few mistakes in the implementation

* there is a new crushing mode 3, which means that the crusher will always slow down if it hits an obstacle.
* crushing mode 1 (Doom mode) will never slow down.
* crushing mode 0 (compatibility) will only slow down for the specials that did so before, and only if both up and downspeed are 8 and the game is not Hexen. The following specials are affected:
  * Ceiling_LowerAndCrush
  * Ceiling_LowerAndCrushDist
  * Ceiling_CrushAndRaise
  * Ceiling_CrushAndRaiseA
  * Ceiling_CrushAndRaiseDist
  * Ceiling_CrushAndRaiseSilentA
  * Ceiling_CrushAndRaiseSilentDist
* Generic_Crusher was fixed to act like in Boom: Not only a speed value of 8 will cause slowdown, but all speed values up to 24.
* Hexen crushing mode will never cause slowdowns because Hexen never did this. (which also makes no real sense, considering that the crusher waits for the obstacle to die.)
This commit is contained in:
Christoph Oelckers 2016-03-25 02:08:22 +01:00
parent 8add60ed38
commit b70fee8ed8
3 changed files with 73 additions and 45 deletions

View File

@ -46,6 +46,14 @@ inline FArchive &operator<< (FArchive &arc, DCeiling::ECeiling &type)
return arc; return arc;
} }
inline FArchive &operator<< (FArchive &arc, DCeiling::ECrushMode &type)
{
BYTE val = (BYTE)type;
arc << val;
type = (DCeiling::ECrushMode)val;
return arc;
}
//============================================================================ //============================================================================
// //
// CEILINGS // CEILINGS
@ -80,7 +88,7 @@ void DCeiling::Serialize (FArchive &arc)
<< m_NewSpecial << m_NewSpecial
<< m_Tag << m_Tag
<< m_OldDirection << m_OldDirection
<< m_Hexencrush; << m_CrushMode;
} }
//============================================================================ //============================================================================
@ -159,7 +167,7 @@ void DCeiling::Tick ()
case -1: case -1:
// DOWN // 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) if (res == pastdest)
{ {
@ -196,7 +204,7 @@ void DCeiling::Tick ()
{ {
case ceilCrushAndRaise: case ceilCrushAndRaise:
case ceilLowerAndCrush: case ceilLowerAndCrush:
if (m_Speed1 == FRACUNIT && m_Speed2 == FRACUNIT) if (m_CrushMode == ECrushMode::crushSlowdown)
m_Speed = FRACUNIT / 8; m_Speed = FRACUNIT / 8;
break; break;
@ -224,7 +232,7 @@ DCeiling::DCeiling (sector_t *sec, fixed_t speed1, fixed_t speed2, int silent)
: DMovingCeiling (sec) : DMovingCeiling (sec)
{ {
m_Crush = -1; m_Crush = -1;
m_Hexencrush = false; m_CrushMode = ECrushMode::crushDoom;
m_Speed = m_Speed1 = speed1; m_Speed = m_Speed1 = speed1;
m_Speed2 = speed2; m_Speed2 = speed2;
m_Silent = silent; 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, DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, int tag,
fixed_t speed, fixed_t speed2, fixed_t height, 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 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_Tag = tag;
ceiling->m_Type = type; ceiling->m_Type = type;
ceiling->m_Crush = crush; ceiling->m_Crush = crush;
ceiling->m_Hexencrush = hexencrush; ceiling->m_CrushMode = hexencrush;
// Do not interpolate instant movement ceilings. // Do not interpolate instant movement ceilings.
// Note for ZDoomGL: Check to make sure that you update the sector // 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, bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line,
int tag, fixed_t speed, fixed_t speed2, fixed_t height, 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; int secnum;
bool rtn; bool rtn;

View File

@ -84,9 +84,21 @@ static const BYTE ChangeMap[8] = { 0, 1, 5, 3, 7, 2, 6, 0 };
#define OCTICS(a) (((a)*TICRATE)/8) #define OCTICS(a) (((a)*TICRATE)/8)
#define BYTEANGLE(a) ((angle_t)((a)<<24)) #define BYTEANGLE(a) ((angle_t)((a)<<24))
#define CRUSH(a) ((a) > 0? (a) : -1) #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) #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"); static FRandom pr_glass ("GlassBreak");
// There are aliases for the ACS specials that take names instead of numbers. // 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) FUNC(LS_Ceiling_LowerByValue)
// Ceiling_LowerByValue (tag, speed, height, change, crush) // 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) FUNC(LS_Ceiling_RaiseByValue)
// Ceiling_RaiseByValue (tag, speed, height, change) // 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) FUNC(LS_Ceiling_LowerByValueTimes8)
// Ceiling_LowerByValueTimes8 (tag, speed, height, change, crush) // 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) FUNC(LS_Ceiling_RaiseByValueTimes8)
// Ceiling_RaiseByValueTimes8 (tag, speed, height, change) // 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) FUNC(LS_Ceiling_CrushAndRaise)
// Ceiling_CrushAndRaise (tag, speed, crush, crushtype) // 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) FUNC(LS_Ceiling_LowerAndCrush)
// Ceiling_LowerAndCrush (tag, speed, crush, crushtype) // 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) FUNC(LS_Ceiling_LowerAndCrushDist)
// Ceiling_LowerAndCrush (tag, speed, crush, dist, crushtype) // 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) FUNC(LS_Ceiling_CrushStop)
@ -676,141 +688,141 @@ FUNC(LS_Ceiling_CrushStop)
FUNC(LS_Ceiling_CrushRaiseAndStay) FUNC(LS_Ceiling_CrushRaiseAndStay)
// Ceiling_CrushRaiseAndStay (tag, speed, crush, crushtype) // 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) FUNC(LS_Ceiling_MoveToValueTimes8)
// Ceiling_MoveToValueTimes8 (tag, speed, height, negative, change) // Ceiling_MoveToValueTimes8 (tag, speed, height, negative, change)
{ {
return EV_DoCeiling (DCeiling::ceilMoveToValue, ln, arg0, SPEED(arg1), 0, 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) FUNC(LS_Ceiling_MoveToValue)
// Ceiling_MoveToValue (tag, speed, height, negative, change) // Ceiling_MoveToValue (tag, speed, height, negative, change)
{ {
return EV_DoCeiling (DCeiling::ceilMoveToValue, ln, arg0, SPEED(arg1), 0, 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) FUNC(LS_Ceiling_LowerToHighestFloor)
// Ceiling_LowerToHighestFloor (tag, speed, change, crush) // 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) FUNC(LS_Ceiling_LowerInstant)
// Ceiling_LowerInstant (tag, unused, height, change, crush) // 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) FUNC(LS_Ceiling_RaiseInstant)
// Ceiling_RaiseInstant (tag, unused, height, change) // 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) FUNC(LS_Ceiling_CrushRaiseAndStayA)
// Ceiling_CrushRaiseAndStayA (tag, dnspeed, upspeed, damage, crushtype) // 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) FUNC(LS_Ceiling_CrushRaiseAndStaySilA)
// Ceiling_CrushRaiseAndStaySilA (tag, dnspeed, upspeed, damage, crushtype) // 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) FUNC(LS_Ceiling_CrushAndRaiseA)
// Ceiling_CrushAndRaiseA (tag, dnspeed, upspeed, damage, crushtype) // 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) FUNC(LS_Ceiling_CrushAndRaiseDist)
// Ceiling_CrushAndRaiseDist (tag, dist, speed, damage, crushtype) // 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) FUNC(LS_Ceiling_CrushAndRaiseSilentA)
// Ceiling_CrushAndRaiseSilentA (tag, dnspeed, upspeed, damage, crushtype) // 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) FUNC(LS_Ceiling_CrushAndRaiseSilentDist)
// Ceiling_CrushAndRaiseSilentDist (tag, dist, upspeed, damage, crushtype) // 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) FUNC(LS_Ceiling_RaiseToNearest)
// Ceiling_RaiseToNearest (tag, speed, change) // 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) FUNC(LS_Ceiling_RaiseToHighest)
// Ceiling_RaiseToHighest (tag, speed, change) // 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) FUNC(LS_Ceiling_RaiseToLowest)
// Ceiling_RaiseToLowest (tag, speed, change) // 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) FUNC(LS_Ceiling_RaiseToHighestFloor)
// Ceiling_RaiseToHighestFloor (tag, speed, change) // 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) FUNC(LS_Ceiling_RaiseByTexture)
// Ceiling_RaiseByTexture (tag, speed, change) // 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) FUNC(LS_Ceiling_LowerToLowest)
// Ceiling_LowerToLowest (tag, speed, change, crush) // 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) FUNC(LS_Ceiling_LowerToNearest)
// Ceiling_LowerToNearest (tag, speed, change, crush) // 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) FUNC(LS_Ceiling_ToHighestInstant)
// Ceiling_ToHighestInstant (tag, change, crush) // 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) FUNC(LS_Ceiling_ToFloorInstant)
// Ceiling_ToFloorInstant (tag, change, crush) // 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) FUNC(LS_Ceiling_LowerToFloor)
// Ceiling_LowerToFloor (tag, speed, change, crush) // 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) FUNC(LS_Ceiling_LowerByTexture)
// Ceiling_LowerByTexture (tag, speed, change, crush) // 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) FUNC(LS_Generic_Ceiling)
@ -841,14 +853,14 @@ FUNC(LS_Generic_Ceiling)
} }
return EV_DoCeiling (type, ln, arg0, SPEED(arg1), SPEED(arg1), arg2*FRACUNIT, 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) FUNC(LS_Generic_Crusher)
// Generic_Crusher (tag, dnspeed, upspeed, silent, damage) // Generic_Crusher (tag, dnspeed, upspeed, silent, damage)
{ {
return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), 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) FUNC(LS_Generic_Crusher2)
@ -856,7 +868,7 @@ FUNC(LS_Generic_Crusher2)
{ {
// same as above but uses Hexen's crushing method. // same as above but uses Hexen's crushing method.
return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), 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) FUNC(LS_Plat_PerpetualRaise)
@ -1944,7 +1956,7 @@ FUNC(LS_FloorAndCeiling_RaiseByValue)
FUNC(LS_FloorAndCeiling_LowerRaise) FUNC(LS_FloorAndCeiling_LowerRaise)
// FloorAndCeiling_LowerRaise (tag, fspeed, cspeed, boomemu) // 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 // 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. // 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 // To avoid problems with maps that have incorrect args this only uses a

View File

@ -647,6 +647,14 @@ public:
genCeilingChg genCeilingChg
}; };
enum class ECrushMode
{
crushDoom = 0,
crushHexen = 1,
crushSlowdown = 2
};
DCeiling (sector_t *sec); DCeiling (sector_t *sec);
DCeiling (sector_t *sec, fixed_t speed1, fixed_t speed2, int silent); 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, static DCeiling *Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, int tag,
fixed_t speed, fixed_t speed2, fixed_t height, 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: protected:
ECeiling m_Type; ECeiling m_Type;
@ -665,7 +673,7 @@ protected:
fixed_t m_Speed1; // [RH] dnspeed of crushers fixed_t m_Speed1; // [RH] dnspeed of crushers
fixed_t m_Speed2; // [RH] upspeed of crushers fixed_t m_Speed2; // [RH] upspeed of crushers
int m_Crush; int m_Crush;
bool m_Hexencrush; ECrushMode m_CrushMode;
int m_Silent; int m_Silent;
int m_Direction; // 1 = up, 0 = waiting, -1 = down int m_Direction; // 1 = up, 0 = waiting, -1 = down
@ -688,7 +696,7 @@ private:
bool EV_DoCeiling (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 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); bool EV_CeilingCrushStop (int tag);
void P_ActivateInStasisCeiling (int tag); void P_ActivateInStasisCeiling (int tag);