mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 23:01:50 +00:00
Merge branch 'master' into floatcvt
# Conflicts: # src/p_lnspec.cpp # src/p_spec.cpp # src/p_spec.h
This commit is contained in:
commit
a46a4c81b1
12 changed files with 840 additions and 711 deletions
|
@ -1071,6 +1071,7 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
|
|||
p_plats.cpp
|
||||
p_pspr.cpp
|
||||
p_saveg.cpp
|
||||
p_scroll.cpp
|
||||
p_sectors.cpp
|
||||
p_setup.cpp
|
||||
p_sight.cpp
|
||||
|
|
|
@ -42,6 +42,7 @@ class PClass;
|
|||
class FArchive;
|
||||
|
||||
class DObject;
|
||||
/*
|
||||
class DArgs;
|
||||
class DCanvas;
|
||||
class DConsoleCommand;
|
||||
|
@ -77,6 +78,7 @@ class DFloor;
|
|||
class DFloorWaggle;
|
||||
class DPlat;
|
||||
class DPillar;
|
||||
*/
|
||||
|
||||
class PClassActor;
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ class AActor;
|
|||
class player_t;
|
||||
struct pspdef_s;
|
||||
struct FState;
|
||||
class DThinker;
|
||||
|
||||
class FThinkerIterator;
|
||||
|
||||
|
|
|
@ -2019,7 +2019,7 @@ void FLevelLocals::Tick ()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FLevelLocals::AddScroller (DScroller *scroller, int secnum)
|
||||
void FLevelLocals::AddScroller (int secnum)
|
||||
{
|
||||
if (secnum < 0)
|
||||
{
|
||||
|
|
|
@ -383,7 +383,7 @@ struct FSectorScrollValues
|
|||
struct FLevelLocals
|
||||
{
|
||||
void Tick ();
|
||||
void AddScroller (DScroller *, int secnum);
|
||||
void AddScroller (int secnum);
|
||||
|
||||
int time; // time in the hub
|
||||
int maptime; // time in the map
|
||||
|
|
|
@ -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;
|
||||
|
|
213
src/p_lnspec.cpp
213
src/p_lnspec.cpp
|
@ -86,9 +86,21 @@ static const BYTE ChangeMap[8] = { 0, 1, 5, 3, 7, 2, 6, 0 };
|
|||
#define _f_BYTEANGLE(a) ((angle_t)((a)<<24))
|
||||
#define BYTEANGLE(a) ((a) * (360./256.))
|
||||
#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.
|
||||
|
@ -630,43 +642,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)
|
||||
|
@ -678,141 +690,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)
|
||||
|
@ -843,14 +855,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)
|
||||
|
@ -858,7 +870,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)
|
||||
|
@ -1943,7 +1955,7 @@ FUNC(LS_FloorAndCeiling_RaiseByValue)
|
|||
FUNC(LS_FloorAndCeiling_LowerRaise)
|
||||
// FloorAndCeiling_LowerRaise (tag, fspeed, cspeed, boomemu)
|
||||
{
|
||||
bool res = EV_DoCeiling (DCeiling::ceilRaiseToHighest, ln, arg0, _f_SPEED(arg2), 0, 0, 0, 0, 0, false);
|
||||
bool res = EV_DoCeiling (DCeiling::ceilRaiseToHighest, ln, arg0, SPEED(arg2), 0, 0, 0, 0, 0, false);
|
||||
// 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
|
||||
|
@ -2132,17 +2144,11 @@ FUNC(LS_Sector_ChangeFlags)
|
|||
return rtn;
|
||||
}
|
||||
|
||||
struct FThinkerCollection
|
||||
{
|
||||
int RefNum;
|
||||
DThinker *Obj;
|
||||
};
|
||||
|
||||
static TArray<FThinkerCollection> Collection;
|
||||
|
||||
void AdjustPusher (int tag, int magnitude, int angle, DPusher::EPusher type)
|
||||
{
|
||||
// Find pushers already attached to the sector, and change their parameters.
|
||||
TArray<FThinkerCollection> Collection;
|
||||
{
|
||||
TThinkerIterator<DPusher> iterator;
|
||||
FThinkerCollection collect;
|
||||
|
@ -2175,7 +2181,6 @@ void AdjustPusher (int tag, int magnitude, int angle, DPusher::EPusher type)
|
|||
new DPusher (type, NULL, magnitude, angle, NULL, secnum);
|
||||
}
|
||||
}
|
||||
Collection.Clear ();
|
||||
}
|
||||
|
||||
FUNC(LS_Sector_SetWind)
|
||||
|
@ -2236,76 +2241,9 @@ FUNC(LS_Sector_SetLink)
|
|||
return false;
|
||||
}
|
||||
|
||||
void SetWallScroller(int id, int sidechoice, fixed_t dx, fixed_t dy, EScrollPos Where);
|
||||
void SetScroller(int tag, EScroll type, fixed_t dx, fixed_t dy);
|
||||
|
||||
static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy, int Where)
|
||||
{
|
||||
Where &=7;
|
||||
if (Where == 0) return;
|
||||
|
||||
if ((dx | dy) == 0)
|
||||
{
|
||||
// Special case: Remove the scroller, because the deltas are both 0.
|
||||
TThinkerIterator<DScroller> iterator (STAT_SCROLLER);
|
||||
DScroller *scroller;
|
||||
|
||||
while ( (scroller = iterator.Next ()) )
|
||||
{
|
||||
int wallnum = scroller->GetWallNum ();
|
||||
|
||||
if (wallnum >= 0 && tagManager.LineHasID(sides[wallnum].linedef, id) &&
|
||||
int(sides[wallnum].linedef->sidedef[sidechoice] - sides) == wallnum &&
|
||||
Where == scroller->GetScrollParts())
|
||||
{
|
||||
scroller->Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find scrollers already attached to the matching walls, and change
|
||||
// their rates.
|
||||
{
|
||||
TThinkerIterator<DScroller> iterator (STAT_SCROLLER);
|
||||
FThinkerCollection collect;
|
||||
|
||||
while ( (collect.Obj = iterator.Next ()) )
|
||||
{
|
||||
if ((collect.RefNum = ((DScroller *)collect.Obj)->GetWallNum ()) != -1 &&
|
||||
tagManager.LineHasID(sides[collect.RefNum].linedef, id) &&
|
||||
int(sides[collect.RefNum].linedef->sidedef[sidechoice] - sides) == collect.RefNum &&
|
||||
Where == ((DScroller *)collect.Obj)->GetScrollParts())
|
||||
{
|
||||
((DScroller *)collect.Obj)->SetRate (dx, dy);
|
||||
Collection.Push (collect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t numcollected = Collection.Size ();
|
||||
int linenum;
|
||||
|
||||
// Now create scrollers for any walls that don't already have them.
|
||||
FLineIdIterator itr(id);
|
||||
while ((linenum = itr.Next()) >= 0)
|
||||
{
|
||||
if (lines[linenum].sidedef[sidechoice] != NULL)
|
||||
{
|
||||
int sidenum = int(lines[linenum].sidedef[sidechoice] - sides);
|
||||
unsigned int i;
|
||||
for (i = 0; i < numcollected; i++)
|
||||
{
|
||||
if (Collection[i].RefNum == sidenum)
|
||||
break;
|
||||
}
|
||||
if (i == numcollected)
|
||||
{
|
||||
new DScroller (DScroller::sc_side, dx, dy, -1, sidenum, 0, Where);
|
||||
}
|
||||
}
|
||||
}
|
||||
Collection.Clear ();
|
||||
}
|
||||
}
|
||||
|
||||
FUNC(LS_Scroll_Texture_Both)
|
||||
// Scroll_Texture_Both (id, left, right, up, down)
|
||||
|
@ -2327,7 +2265,7 @@ FUNC(LS_Scroll_Texture_Both)
|
|||
sidechoice = 0;
|
||||
}
|
||||
|
||||
SetWallScroller (arg0, sidechoice, dx, dy, 7);
|
||||
SetWallScroller (arg0, sidechoice, dx, dy, scw_all);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2338,47 +2276,10 @@ FUNC(LS_Scroll_Wall)
|
|||
if (arg0 == 0)
|
||||
return false;
|
||||
|
||||
SetWallScroller (arg0, !!arg3, arg1, arg2, arg4);
|
||||
SetWallScroller (arg0, !!arg3, arg1, arg2, EScrollPos(arg4));
|
||||
return true;
|
||||
}
|
||||
|
||||
static void SetScroller (int tag, DScroller::EScrollType type, fixed_t dx, fixed_t dy)
|
||||
{
|
||||
TThinkerIterator<DScroller> iterator (STAT_SCROLLER);
|
||||
DScroller *scroller;
|
||||
int i;
|
||||
|
||||
// Check if there is already a scroller for this tag
|
||||
// If at least one sector with this tag is scrolling, then they all are.
|
||||
// If the deltas are both 0, we don't remove the scroller, because a
|
||||
// displacement/accelerative scroller might have been set up, and there's
|
||||
// no way to create one after the level is fully loaded.
|
||||
i = 0;
|
||||
while ( (scroller = iterator.Next ()) )
|
||||
{
|
||||
if (scroller->IsType (type))
|
||||
{
|
||||
if (tagManager.SectorHasTag(scroller->GetAffectee (), tag))
|
||||
{
|
||||
i++;
|
||||
scroller->SetRate (dx, dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 0 || (dx|dy) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Need to create scrollers for the sector(s)
|
||||
FSectorTagIterator itr(tag);
|
||||
while ((i = itr.Next()) >= 0)
|
||||
{
|
||||
new DScroller (type, dx, dy, -1, i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: For the next two functions, x-move and y-move are
|
||||
// 0-based, not 128-based as they are if they appear on lines.
|
||||
// Note also that parameter ordering is different.
|
||||
|
@ -2391,19 +2292,19 @@ FUNC(LS_Scroll_Floor)
|
|||
|
||||
if (arg3 == 0 || arg3 == 2)
|
||||
{
|
||||
SetScroller (arg0, DScroller::sc_floor, -dx, dy);
|
||||
SetScroller (arg0, EScroll::sc_floor, -dx, dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetScroller (arg0, DScroller::sc_floor, 0, 0);
|
||||
SetScroller (arg0, EScroll::sc_floor, 0, 0);
|
||||
}
|
||||
if (arg3 > 0)
|
||||
{
|
||||
SetScroller (arg0, DScroller::sc_carry, dx, dy);
|
||||
SetScroller (arg0, EScroll::sc_carry, dx, dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetScroller (arg0, DScroller::sc_carry, 0, 0);
|
||||
SetScroller (arg0, EScroll::sc_carry, 0, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2414,7 +2315,7 @@ FUNC(LS_Scroll_Ceiling)
|
|||
fixed_t dx = arg1 * FRACUNIT/32;
|
||||
fixed_t dy = arg2 * FRACUNIT/32;
|
||||
|
||||
SetScroller (arg0, DScroller::sc_ceiling, -dx, dy);
|
||||
SetScroller (arg0, EScroll::sc_ceiling, -dx, dy);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
719
src/p_scroll.cpp
Normal file
719
src/p_scroll.cpp
Normal file
|
@ -0,0 +1,719 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// $Log:$
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Initializes and implements BOOM linedef triggers for
|
||||
// Scrollers/Conveyors
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "actor.h"
|
||||
#include "p_spec.h"
|
||||
#include "farchive.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "r_data/r_interpolate.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// killough 3/7/98: Add generalized scroll effects
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class DScroller : public DThinker
|
||||
{
|
||||
DECLARE_CLASS (DScroller, DThinker)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
|
||||
DScroller (EScroll type, fixed_t dx, fixed_t dy, int control, int affectee, int accel, EScrollPos scrollpos = EScrollPos::scw_all);
|
||||
DScroller (fixed_t dx, fixed_t dy, const line_t *l, int control, int accel, EScrollPos scrollpos = EScrollPos::scw_all);
|
||||
void Destroy();
|
||||
|
||||
void Serialize (FArchive &arc);
|
||||
void Tick ();
|
||||
|
||||
bool AffectsWall (int wallnum) const { return m_Type == EScroll::sc_side && m_Affectee == wallnum; }
|
||||
int GetWallNum () const { return m_Type == EScroll::sc_side ? m_Affectee : -1; }
|
||||
void SetRate (fixed_t dx, fixed_t dy) { m_dx = dx; m_dy = dy; }
|
||||
bool IsType (EScroll type) const { return type == m_Type; }
|
||||
int GetAffectee () const { return m_Affectee; }
|
||||
EScrollPos GetScrollParts() const { return m_Parts; }
|
||||
|
||||
protected:
|
||||
EScroll m_Type; // Type of scroll effect
|
||||
fixed_t m_dx, m_dy; // (dx,dy) scroll speeds
|
||||
int m_Affectee; // Number of affected sidedef, sector, tag, or whatever
|
||||
int m_Control; // Control sector (-1 if none) used to control scrolling
|
||||
fixed_t m_LastHeight; // Last known height of control sector
|
||||
fixed_t m_vdx, m_vdy; // Accumulated velocity if accelerative
|
||||
int m_Accel; // Whether it's accelerative
|
||||
EScrollPos m_Parts; // Which parts of a sidedef are being scrolled?
|
||||
TObjPtr<DInterpolation> m_Interpolations[3];
|
||||
|
||||
private:
|
||||
DScroller ()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
IMPLEMENT_POINTY_CLASS (DScroller)
|
||||
DECLARE_POINTER (m_Interpolations[0])
|
||||
DECLARE_POINTER (m_Interpolations[1])
|
||||
DECLARE_POINTER (m_Interpolations[2])
|
||||
END_POINTERS
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline FArchive &operator<< (FArchive &arc, EScroll &type)
|
||||
{
|
||||
BYTE val = (BYTE)type;
|
||||
arc << val;
|
||||
type = (EScroll)val;
|
||||
return arc;
|
||||
}
|
||||
|
||||
inline FArchive &operator<< (FArchive &arc, EScrollPos &type)
|
||||
{
|
||||
int val = (int)type;
|
||||
arc << val;
|
||||
type = (EScrollPos)val;
|
||||
return arc;
|
||||
}
|
||||
|
||||
EScrollPos operator &(EScrollPos one, EScrollPos two)
|
||||
{
|
||||
return EScrollPos(int(one) & int(two));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void DScroller::Serialize (FArchive &arc)
|
||||
{
|
||||
Super::Serialize (arc);
|
||||
arc << m_Type
|
||||
<< m_dx << m_dy
|
||||
<< m_Affectee
|
||||
<< m_Control
|
||||
<< m_LastHeight
|
||||
<< m_vdx << m_vdy
|
||||
<< m_Accel
|
||||
<< m_Parts
|
||||
<< m_Interpolations[0]
|
||||
<< m_Interpolations[1]
|
||||
<< m_Interpolations[2];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// [RH] Compensate for rotated sector textures by rotating the scrolling
|
||||
// in the opposite direction.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void RotationComp(const sector_t *sec, int which, fixed_t dx, fixed_t dy, fixed_t &tdx, fixed_t &tdy)
|
||||
{
|
||||
angle_t an = sec->GetAngle(which);
|
||||
if (an == 0)
|
||||
{
|
||||
tdx = dx;
|
||||
tdy = dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
an = an >> ANGLETOFINESHIFT;
|
||||
fixed_t ca = -finecosine[an];
|
||||
fixed_t sa = -finesine[an];
|
||||
tdx = DMulScale16(dx, ca, -dy, sa);
|
||||
tdy = DMulScale16(dy, ca, dx, sa);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// killough 2/28/98:
|
||||
//
|
||||
// This function, with the help of r_plane.c and r_bsp.c, supports generalized
|
||||
// scrolling floors and walls, with optional mobj-carrying properties, e.g.
|
||||
// conveyor belts, rivers, etc. A linedef with a special type affects all
|
||||
// tagged sectors the same way, by creating scrolling and/or object-carrying
|
||||
// properties. Multiple linedefs may be used on the same sector and are
|
||||
// cumulative, although the special case of scrolling a floor and carrying
|
||||
// things on it, requires only one linedef. The linedef's direction determines
|
||||
// the scrolling direction, and the linedef's length determines the scrolling
|
||||
// speed. This was designed so that an edge around the sector could be used to
|
||||
// control the direction of the sector's scrolling, which is usually what is
|
||||
// desired.
|
||||
//
|
||||
// Process the active scrollers.
|
||||
//
|
||||
// This is the main scrolling code
|
||||
// killough 3/7/98
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void DScroller::Tick ()
|
||||
{
|
||||
fixed_t dx = m_dx, dy = m_dy, tdx, tdy;
|
||||
|
||||
if (m_Control != -1)
|
||||
{ // compute scroll amounts based on a sector's height changes
|
||||
fixed_t height = sectors[m_Control].CenterFloor () +
|
||||
sectors[m_Control].CenterCeiling ();
|
||||
fixed_t delta = height - m_LastHeight;
|
||||
m_LastHeight = height;
|
||||
dx = FixedMul(dx, delta);
|
||||
dy = FixedMul(dy, delta);
|
||||
}
|
||||
|
||||
// killough 3/14/98: Add acceleration
|
||||
if (m_Accel)
|
||||
{
|
||||
m_vdx = dx += m_vdx;
|
||||
m_vdy = dy += m_vdy;
|
||||
}
|
||||
|
||||
if (!(dx | dy)) // no-op if both (x,y) offsets are 0
|
||||
return;
|
||||
|
||||
switch (m_Type)
|
||||
{
|
||||
case EScroll::sc_side: // killough 3/7/98: Scroll wall texture
|
||||
if (m_Parts & EScrollPos::scw_top)
|
||||
{
|
||||
sides[m_Affectee].AddTextureXOffset(side_t::top, dx);
|
||||
sides[m_Affectee].AddTextureYOffset(side_t::top, dy);
|
||||
}
|
||||
if (m_Parts & EScrollPos::scw_mid && (sides[m_Affectee].linedef->backsector == NULL ||
|
||||
!(sides[m_Affectee].linedef->flags&ML_3DMIDTEX)))
|
||||
{
|
||||
sides[m_Affectee].AddTextureXOffset(side_t::mid, dx);
|
||||
sides[m_Affectee].AddTextureYOffset(side_t::mid, dy);
|
||||
}
|
||||
if (m_Parts & EScrollPos::scw_bottom)
|
||||
{
|
||||
sides[m_Affectee].AddTextureXOffset(side_t::bottom, dx);
|
||||
sides[m_Affectee].AddTextureYOffset(side_t::bottom, dy);
|
||||
}
|
||||
break;
|
||||
|
||||
case EScroll::sc_floor: // killough 3/7/98: Scroll floor texture
|
||||
RotationComp(§ors[m_Affectee], sector_t::floor, dx, dy, tdx, tdy);
|
||||
sectors[m_Affectee].AddXOffset(sector_t::floor, tdx);
|
||||
sectors[m_Affectee].AddYOffset(sector_t::floor, tdy);
|
||||
break;
|
||||
|
||||
case EScroll::sc_ceiling: // killough 3/7/98: Scroll ceiling texture
|
||||
RotationComp(§ors[m_Affectee], sector_t::ceiling, dx, dy, tdx, tdy);
|
||||
sectors[m_Affectee].AddXOffset(sector_t::ceiling, tdx);
|
||||
sectors[m_Affectee].AddYOffset(sector_t::ceiling, tdy);
|
||||
break;
|
||||
|
||||
// [RH] Don't actually carry anything here. That happens later.
|
||||
case EScroll::sc_carry:
|
||||
level.Scrolls[m_Affectee].Scroll.X += FIXED2DBL(dx);
|
||||
level.Scrolls[m_Affectee].Scroll.Y += FIXED2DBL(dy);
|
||||
break;
|
||||
|
||||
case EScroll::sc_carry_ceiling: // to be added later
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Add_Scroller()
|
||||
//
|
||||
// Add a generalized scroller to the thinker list.
|
||||
//
|
||||
// type: the enumerated type of scrolling: floor, ceiling, floor carrier,
|
||||
// wall, floor carrier & scroller
|
||||
//
|
||||
// (dx,dy): the direction and speed of the scrolling or its acceleration
|
||||
//
|
||||
// control: the sector whose heights control this scroller's effect
|
||||
// remotely, or -1 if no control sector
|
||||
//
|
||||
// affectee: the index of the affected object (sector or sidedef)
|
||||
//
|
||||
// accel: non-zero if this is an accelerative effect
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DScroller::DScroller (EScroll type, fixed_t dx, fixed_t dy,
|
||||
int control, int affectee, int accel, EScrollPos scrollpos)
|
||||
: DThinker (STAT_SCROLLER)
|
||||
{
|
||||
m_Type = type;
|
||||
m_dx = dx;
|
||||
m_dy = dy;
|
||||
m_Accel = accel;
|
||||
m_Parts = scrollpos;
|
||||
m_vdx = m_vdy = 0;
|
||||
if ((m_Control = control) != -1)
|
||||
m_LastHeight =
|
||||
sectors[control].CenterFloor () + sectors[control].CenterCeiling ();
|
||||
m_Affectee = affectee;
|
||||
m_Interpolations[0] = m_Interpolations[1] = m_Interpolations[2] = NULL;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case EScroll::sc_carry:
|
||||
level.AddScroller (affectee);
|
||||
break;
|
||||
|
||||
case EScroll::sc_side:
|
||||
sides[affectee].Flags |= WALLF_NOAUTODECALS;
|
||||
if (m_Parts & EScrollPos::scw_top)
|
||||
{
|
||||
m_Interpolations[0] = sides[m_Affectee].SetInterpolation(side_t::top);
|
||||
}
|
||||
if (m_Parts & EScrollPos::scw_mid && (sides[m_Affectee].linedef->backsector == NULL ||
|
||||
!(sides[m_Affectee].linedef->flags&ML_3DMIDTEX)))
|
||||
{
|
||||
m_Interpolations[1] = sides[m_Affectee].SetInterpolation(side_t::mid);
|
||||
}
|
||||
if (m_Parts & EScrollPos::scw_bottom)
|
||||
{
|
||||
m_Interpolations[2] = sides[m_Affectee].SetInterpolation(side_t::bottom);
|
||||
}
|
||||
break;
|
||||
|
||||
case EScroll::sc_floor:
|
||||
m_Interpolations[0] = sectors[affectee].SetInterpolation(sector_t::FloorScroll, false);
|
||||
break;
|
||||
|
||||
case EScroll::sc_ceiling:
|
||||
m_Interpolations[0] = sectors[affectee].SetInterpolation(sector_t::CeilingScroll, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DScroller::Destroy ()
|
||||
{
|
||||
for(int i=0;i<3;i++)
|
||||
{
|
||||
if (m_Interpolations[i] != NULL)
|
||||
{
|
||||
m_Interpolations[i]->DelRef();
|
||||
m_Interpolations[i] = NULL;
|
||||
}
|
||||
}
|
||||
Super::Destroy();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Adds wall scroller. Scroll amount is rotated with respect to wall's
|
||||
// linedef first, so that scrolling towards the wall in a perpendicular
|
||||
// direction is translated into vertical motion, while scrolling along
|
||||
// the wall in a parallel direction is translated into horizontal motion.
|
||||
//
|
||||
// killough 5/25/98: cleaned up arithmetic to avoid drift due to roundoff
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DScroller::DScroller (fixed_t dx, fixed_t dy, const line_t *l,
|
||||
int control, int accel, EScrollPos scrollpos)
|
||||
: DThinker (STAT_SCROLLER)
|
||||
{
|
||||
fixed_t x = abs(l->dx), y = abs(l->dy), d;
|
||||
if (y > x)
|
||||
d = x, x = y, y = d;
|
||||
d = FixedDiv (x, finesine[(tantoangle[FixedDiv(y,x) >> DBITS] + ANG90)
|
||||
>> ANGLETOFINESHIFT]);
|
||||
x = -FixedDiv (FixedMul(dy, l->dy) + FixedMul(dx, l->dx), d);
|
||||
y = -FixedDiv (FixedMul(dx, l->dy) - FixedMul(dy, l->dx), d);
|
||||
|
||||
m_Type = EScroll::sc_side;
|
||||
m_dx = x;
|
||||
m_dy = y;
|
||||
m_vdx = m_vdy = 0;
|
||||
m_Accel = accel;
|
||||
m_Parts = scrollpos;
|
||||
if ((m_Control = control) != -1)
|
||||
m_LastHeight = sectors[control].CenterFloor() + sectors[control].CenterCeiling();
|
||||
m_Affectee = int(l->sidedef[0] - sides);
|
||||
sides[m_Affectee].Flags |= WALLF_NOAUTODECALS;
|
||||
m_Interpolations[0] = m_Interpolations[1] = m_Interpolations[2] = NULL;
|
||||
|
||||
if (m_Parts & EScrollPos::scw_top)
|
||||
{
|
||||
m_Interpolations[0] = sides[m_Affectee].SetInterpolation(side_t::top);
|
||||
}
|
||||
if (m_Parts & EScrollPos::scw_mid && (sides[m_Affectee].linedef->backsector == NULL ||
|
||||
!(sides[m_Affectee].linedef->flags&ML_3DMIDTEX)))
|
||||
{
|
||||
m_Interpolations[1] = sides[m_Affectee].SetInterpolation(side_t::mid);
|
||||
}
|
||||
if (m_Parts & EScrollPos::scw_bottom)
|
||||
{
|
||||
m_Interpolations[2] = sides[m_Affectee].SetInterpolation(side_t::bottom);
|
||||
}
|
||||
}
|
||||
|
||||
// Amount (dx,dy) vector linedef is shifted right to get scroll amount
|
||||
#define SCROLL_SHIFT 5
|
||||
#define SCROLLTYPE(i) EScrollPos(((i) <= 0) || ((i) & ~7) ? 7 : (i))
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Initialize the scrollers
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void P_SpawnScrollers(void)
|
||||
{
|
||||
int i;
|
||||
line_t *l = lines;
|
||||
TArray<int> copyscrollers;
|
||||
|
||||
for (i = 0; i < numlines; i++)
|
||||
{
|
||||
if (lines[i].special == Sector_CopyScroller)
|
||||
{
|
||||
// don't allow copying the scroller if the sector has the same tag as it would just duplicate it.
|
||||
if (!tagManager.SectorHasTag(lines[i].frontsector, lines[i].args[0]))
|
||||
{
|
||||
copyscrollers.Push(i);
|
||||
}
|
||||
lines[i].special = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < numlines; i++, l++)
|
||||
{
|
||||
fixed_t dx; // direction and speed of scrolling
|
||||
fixed_t dy;
|
||||
int control = -1, accel = 0; // no control sector or acceleration
|
||||
int special = l->special;
|
||||
|
||||
// Check for undefined parameters that are non-zero and output messages for them.
|
||||
// We don't report for specials we don't understand.
|
||||
FLineSpecial *spec = P_GetLineSpecialInfo(special);
|
||||
if (spec != NULL)
|
||||
{
|
||||
int max = spec->map_args;
|
||||
for (unsigned arg = max; arg < countof(l->args); ++arg)
|
||||
{
|
||||
if (l->args[arg] != 0)
|
||||
{
|
||||
Printf("Line %d (type %d:%s), arg %u is %d (should be 0)\n",
|
||||
i, special, spec->name, arg+1, l->args[arg]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// killough 3/7/98: Types 245-249 are same as 250-254 except that the
|
||||
// first side's sector's heights cause scrolling when they change, and
|
||||
// this linedef controls the direction and speed of the scrolling. The
|
||||
// most complicated linedef since donuts, but powerful :)
|
||||
//
|
||||
// killough 3/15/98: Add acceleration. Types 214-218 are the same but
|
||||
// are accelerative.
|
||||
|
||||
// [RH] Assume that it's a scroller and zero the line's special.
|
||||
l->special = 0;
|
||||
|
||||
dx = dy = 0; // Shut up, GCC
|
||||
|
||||
if (special == Scroll_Ceiling ||
|
||||
special == Scroll_Floor ||
|
||||
special == Scroll_Texture_Model)
|
||||
{
|
||||
if (l->args[1] & 3)
|
||||
{
|
||||
// if 1, then displacement
|
||||
// if 2, then accelerative (also if 3)
|
||||
control = int(l->sidedef[0]->sector - sectors);
|
||||
if (l->args[1] & 2)
|
||||
accel = 1;
|
||||
}
|
||||
if (special == Scroll_Texture_Model ||
|
||||
l->args[1] & 4)
|
||||
{
|
||||
// The line housing the special controls the
|
||||
// direction and speed of scrolling.
|
||||
dx = l->dx >> SCROLL_SHIFT;
|
||||
dy = l->dy >> SCROLL_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The speed and direction are parameters to the special.
|
||||
dx = (l->args[3] - 128) * (FRACUNIT / 32);
|
||||
dy = (l->args[4] - 128) * (FRACUNIT / 32);
|
||||
}
|
||||
}
|
||||
|
||||
switch (special)
|
||||
{
|
||||
int s;
|
||||
|
||||
case Scroll_Ceiling:
|
||||
{
|
||||
FSectorTagIterator itr(l->args[0]);
|
||||
while ((s = itr.Next()) >= 0)
|
||||
{
|
||||
new DScroller(EScroll::sc_ceiling, -dx, dy, control, s, accel);
|
||||
}
|
||||
for (unsigned j = 0; j < copyscrollers.Size(); j++)
|
||||
{
|
||||
line_t *line = &lines[copyscrollers[j]];
|
||||
|
||||
if (line->args[0] == l->args[0] && (line->args[1] & 1))
|
||||
{
|
||||
new DScroller(EScroll::sc_ceiling, -dx, dy, control, int(line->frontsector - sectors), accel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Scroll_Floor:
|
||||
if (l->args[2] != 1)
|
||||
{ // scroll the floor texture
|
||||
FSectorTagIterator itr(l->args[0]);
|
||||
while ((s = itr.Next()) >= 0)
|
||||
{
|
||||
new DScroller (EScroll::sc_floor, -dx, dy, control, s, accel);
|
||||
}
|
||||
for(unsigned j = 0;j < copyscrollers.Size(); j++)
|
||||
{
|
||||
line_t *line = &lines[copyscrollers[j]];
|
||||
|
||||
if (line->args[0] == l->args[0] && (line->args[1] & 2))
|
||||
{
|
||||
new DScroller (EScroll::sc_floor, -dx, dy, control, int(line->frontsector-sectors), accel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (l->args[2] > 0)
|
||||
{ // carry objects on the floor
|
||||
FSectorTagIterator itr(l->args[0]);
|
||||
while ((s = itr.Next()) >= 0)
|
||||
{
|
||||
new DScroller (EScroll::sc_carry, dx, dy, control, s, accel);
|
||||
}
|
||||
for(unsigned j = 0;j < copyscrollers.Size(); j++)
|
||||
{
|
||||
line_t *line = &lines[copyscrollers[j]];
|
||||
|
||||
if (line->args[0] == l->args[0] && (line->args[1] & 4))
|
||||
{
|
||||
new DScroller (EScroll::sc_carry, dx, dy, control, int(line->frontsector-sectors), accel);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// killough 3/1/98: scroll wall according to linedef
|
||||
// (same direction and speed as scrolling floors)
|
||||
case Scroll_Texture_Model:
|
||||
{
|
||||
FLineIdIterator itr(l->args[0]);
|
||||
while ((s = itr.Next()) >= 0)
|
||||
{
|
||||
if (s != i)
|
||||
new DScroller(dx, dy, lines + s, control, accel);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Scroll_Texture_Offsets:
|
||||
// killough 3/2/98: scroll according to sidedef offsets
|
||||
s = int(lines[i].sidedef[0] - sides);
|
||||
new DScroller (EScroll::sc_side, -sides[s].GetTextureXOffset(side_t::mid),
|
||||
sides[s].GetTextureYOffset(side_t::mid), -1, s, accel, SCROLLTYPE(l->args[0]));
|
||||
break;
|
||||
|
||||
case Scroll_Texture_Left:
|
||||
l->special = special; // Restore the special, for compat_useblocking's benefit.
|
||||
s = int(lines[i].sidedef[0] - sides);
|
||||
new DScroller (EScroll::sc_side, l->args[0] * (FRACUNIT/64), 0,
|
||||
-1, s, accel, SCROLLTYPE(l->args[1]));
|
||||
break;
|
||||
|
||||
case Scroll_Texture_Right:
|
||||
l->special = special;
|
||||
s = int(lines[i].sidedef[0] - sides);
|
||||
new DScroller (EScroll::sc_side, l->args[0] * (-FRACUNIT/64), 0,
|
||||
-1, s, accel, SCROLLTYPE(l->args[1]));
|
||||
break;
|
||||
|
||||
case Scroll_Texture_Up:
|
||||
l->special = special;
|
||||
s = int(lines[i].sidedef[0] - sides);
|
||||
new DScroller (EScroll::sc_side, 0, l->args[0] * (FRACUNIT/64),
|
||||
-1, s, accel, SCROLLTYPE(l->args[1]));
|
||||
break;
|
||||
|
||||
case Scroll_Texture_Down:
|
||||
l->special = special;
|
||||
s = int(lines[i].sidedef[0] - sides);
|
||||
new DScroller (EScroll::sc_side, 0, l->args[0] * (-FRACUNIT/64),
|
||||
-1, s, accel, SCROLLTYPE(l->args[1]));
|
||||
break;
|
||||
|
||||
case Scroll_Texture_Both:
|
||||
s = int(lines[i].sidedef[0] - sides);
|
||||
if (l->args[0] == 0) {
|
||||
dx = (l->args[1] - l->args[2]) * (FRACUNIT/64);
|
||||
dy = (l->args[4] - l->args[3]) * (FRACUNIT/64);
|
||||
new DScroller (EScroll::sc_side, dx, dy, -1, s, accel);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// [RH] It wasn't a scroller after all, so restore the special.
|
||||
l->special = special;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Modify a wall scroller
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy, EScrollPos Where)
|
||||
{
|
||||
Where = Where & scw_all;
|
||||
if (Where == 0) return;
|
||||
|
||||
if ((dx | dy) == 0)
|
||||
{
|
||||
// Special case: Remove the scroller, because the deltas are both 0.
|
||||
TThinkerIterator<DScroller> iterator (STAT_SCROLLER);
|
||||
DScroller *scroller;
|
||||
|
||||
while ( (scroller = iterator.Next ()) )
|
||||
{
|
||||
int wallnum = scroller->GetWallNum ();
|
||||
|
||||
if (wallnum >= 0 && tagManager.LineHasID(sides[wallnum].linedef, id) &&
|
||||
int(sides[wallnum].linedef->sidedef[sidechoice] - sides) == wallnum &&
|
||||
Where == scroller->GetScrollParts())
|
||||
{
|
||||
scroller->Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find scrollers already attached to the matching walls, and change
|
||||
// their rates.
|
||||
TArray<FThinkerCollection> Collection;
|
||||
{
|
||||
TThinkerIterator<DScroller> iterator (STAT_SCROLLER);
|
||||
FThinkerCollection collect;
|
||||
|
||||
while ( (collect.Obj = iterator.Next ()) )
|
||||
{
|
||||
if ((collect.RefNum = ((DScroller *)collect.Obj)->GetWallNum ()) != -1 &&
|
||||
tagManager.LineHasID(sides[collect.RefNum].linedef, id) &&
|
||||
int(sides[collect.RefNum].linedef->sidedef[sidechoice] - sides) == collect.RefNum &&
|
||||
Where == ((DScroller *)collect.Obj)->GetScrollParts())
|
||||
{
|
||||
((DScroller *)collect.Obj)->SetRate (dx, dy);
|
||||
Collection.Push (collect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t numcollected = Collection.Size ();
|
||||
int linenum;
|
||||
|
||||
// Now create scrollers for any walls that don't already have them.
|
||||
FLineIdIterator itr(id);
|
||||
while ((linenum = itr.Next()) >= 0)
|
||||
{
|
||||
if (lines[linenum].sidedef[sidechoice] != NULL)
|
||||
{
|
||||
int sidenum = int(lines[linenum].sidedef[sidechoice] - sides);
|
||||
unsigned int i;
|
||||
for (i = 0; i < numcollected; i++)
|
||||
{
|
||||
if (Collection[i].RefNum == sidenum)
|
||||
break;
|
||||
}
|
||||
if (i == numcollected)
|
||||
{
|
||||
new DScroller (EScroll::sc_side, dx, dy, -1, sidenum, 0, Where);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetScroller (int tag, EScroll type, fixed_t dx, fixed_t dy)
|
||||
{
|
||||
TThinkerIterator<DScroller> iterator (STAT_SCROLLER);
|
||||
DScroller *scroller;
|
||||
int i;
|
||||
|
||||
// Check if there is already a scroller for this tag
|
||||
// If at least one sector with this tag is scrolling, then they all are.
|
||||
// If the deltas are both 0, we don't remove the scroller, because a
|
||||
// displacement/accelerative scroller might have been set up, and there's
|
||||
// no way to create one after the level is fully loaded.
|
||||
i = 0;
|
||||
while ( (scroller = iterator.Next ()) )
|
||||
{
|
||||
if (scroller->IsType (type))
|
||||
{
|
||||
if (tagManager.SectorHasTag(scroller->GetAffectee (), tag))
|
||||
{
|
||||
i++;
|
||||
scroller->SetRate (dx, dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 0 || (dx|dy) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Need to create scrollers for the sector(s)
|
||||
FSectorTagIterator itr(tag);
|
||||
while ((i = itr.Next()) >= 0)
|
||||
{
|
||||
new DScroller (type, dx, dy, -1, i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void P_CreateScroller(EScroll type, fixed_t dx, fixed_t dy, int control, int affectee, int accel, EScrollPos scrollpos)
|
||||
{
|
||||
new DScroller(type, dx, dy, control, affectee, accel, scrollpos);
|
||||
}
|
|
@ -950,7 +950,7 @@ fixed_t sector_t::NextHighestCeilingAt(fixed_t x, fixed_t y, fixed_t bottomz, fi
|
|||
fixed_t delta1 = bottomz - (ff_bottom + ((ff_top - ff_bottom) / 2));
|
||||
fixed_t delta2 = topz - (ff_bottom + ((ff_top - ff_bottom) / 2));
|
||||
|
||||
if (ff_bottom < realceil && abs(delta1) >= abs(delta2))
|
||||
if (ff_bottom < realceil && abs(delta1) > abs(delta2))
|
||||
{
|
||||
if (resultsec) *resultsec = sec;
|
||||
if (resultffloor) *resultffloor = rover;
|
||||
|
|
494
src/p_spec.cpp
494
src/p_spec.cpp
|
@ -84,44 +84,10 @@ static FRandom pr_playerinspecialsector ("PlayerInSpecialSector");
|
|||
|
||||
EXTERN_CVAR(Bool, cl_predict_specials)
|
||||
|
||||
IMPLEMENT_POINTY_CLASS (DScroller)
|
||||
DECLARE_POINTER (m_Interpolations[0])
|
||||
DECLARE_POINTER (m_Interpolations[1])
|
||||
DECLARE_POINTER (m_Interpolations[2])
|
||||
END_POINTERS
|
||||
|
||||
IMPLEMENT_POINTY_CLASS (DPusher)
|
||||
DECLARE_POINTER (m_Source)
|
||||
END_POINTERS
|
||||
|
||||
inline FArchive &operator<< (FArchive &arc, DScroller::EScrollType &type)
|
||||
{
|
||||
BYTE val = (BYTE)type;
|
||||
arc << val;
|
||||
type = (DScroller::EScrollType)val;
|
||||
return arc;
|
||||
}
|
||||
|
||||
DScroller::DScroller ()
|
||||
{
|
||||
}
|
||||
|
||||
void DScroller::Serialize (FArchive &arc)
|
||||
{
|
||||
Super::Serialize (arc);
|
||||
arc << m_Type
|
||||
<< m_dx << m_dy
|
||||
<< m_Affectee
|
||||
<< m_Control
|
||||
<< m_LastHeight
|
||||
<< m_vdx << m_vdy
|
||||
<< m_Accel
|
||||
<< m_Parts
|
||||
<< m_Interpolations[0]
|
||||
<< m_Interpolations[1]
|
||||
<< m_Interpolations[2];
|
||||
}
|
||||
|
||||
DPusher::DPusher ()
|
||||
{
|
||||
}
|
||||
|
@ -146,7 +112,7 @@ void DPusher::Serialize (FArchive &arc)
|
|||
}
|
||||
|
||||
// killough 3/7/98: Initialize generalized scrolling
|
||||
static void P_SpawnScrollers();
|
||||
void P_SpawnScrollers();
|
||||
static void P_SpawnFriction (); // phares 3/16/98
|
||||
static void P_SpawnPushers (); // phares 3/20/98
|
||||
|
||||
|
@ -1237,7 +1203,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers)
|
|||
if (!nothinkers)
|
||||
{
|
||||
new DStrobe(sector, STROBEBRIGHT, FASTDARK, false);
|
||||
new DScroller(DScroller::sc_floor, -((FRACUNIT / 2) << 3),
|
||||
P_CreateScroller(EScroll::sc_floor, -((FRACUNIT / 2) << 3),
|
||||
0, -1, int(sector - sectors), 0);
|
||||
}
|
||||
keepspecial = true;
|
||||
|
@ -1298,13 +1264,13 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers)
|
|||
int i = sector->special - Scroll_North_Slow;
|
||||
fixed_t dx = hexenScrollies[i][0] * (FRACUNIT/2);
|
||||
fixed_t dy = hexenScrollies[i][1] * (FRACUNIT/2);
|
||||
if (!nothinkers) new DScroller (DScroller::sc_floor, dx, dy, -1, int(sector-sectors), 0);
|
||||
if (!nothinkers) P_CreateScroller(EScroll::sc_floor, dx, dy, -1, int(sector-sectors), 0);
|
||||
}
|
||||
else if (sector->special >= Carry_East5 &&
|
||||
sector->special <= Carry_East35)
|
||||
{ // Heretic scroll special
|
||||
// Only east scrollers also scroll the texture
|
||||
if (!nothinkers) new DScroller (DScroller::sc_floor,
|
||||
if (!nothinkers) P_CreateScroller(EScroll::sc_floor,
|
||||
(-FRACUNIT/2)<<(sector->special - Carry_East5),
|
||||
0, -1, int(sector-sectors), 0);
|
||||
}
|
||||
|
@ -1527,458 +1493,6 @@ void P_SpawnSpecials (void)
|
|||
FBehavior::StaticStartTypedScripts (SCRIPT_Open, NULL, false);
|
||||
}
|
||||
|
||||
// killough 2/28/98:
|
||||
//
|
||||
// This function, with the help of r_plane.c and r_bsp.c, supports generalized
|
||||
// scrolling floors and walls, with optional mobj-carrying properties, e.g.
|
||||
// conveyor belts, rivers, etc. A linedef with a special type affects all
|
||||
// tagged sectors the same way, by creating scrolling and/or object-carrying
|
||||
// properties. Multiple linedefs may be used on the same sector and are
|
||||
// cumulative, although the special case of scrolling a floor and carrying
|
||||
// things on it, requires only one linedef. The linedef's direction determines
|
||||
// the scrolling direction, and the linedef's length determines the scrolling
|
||||
// speed. This was designed so that an edge around the sector could be used to
|
||||
// control the direction of the sector's scrolling, which is usually what is
|
||||
// desired.
|
||||
//
|
||||
// Process the active scrollers.
|
||||
//
|
||||
// This is the main scrolling code
|
||||
// killough 3/7/98
|
||||
|
||||
// [RH] Compensate for rotated sector textures by rotating the scrolling
|
||||
// in the opposite direction.
|
||||
static void RotationComp(const sector_t *sec, int which, fixed_t dx, fixed_t dy, fixed_t &tdx, fixed_t &tdy)
|
||||
{
|
||||
angle_t an = sec->GetAngle(which);
|
||||
if (an == 0)
|
||||
{
|
||||
tdx = dx;
|
||||
tdy = dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
an = an >> ANGLETOFINESHIFT;
|
||||
fixed_t ca = -finecosine[an];
|
||||
fixed_t sa = -finesine[an];
|
||||
tdx = DMulScale16(dx, ca, -dy, sa);
|
||||
tdy = DMulScale16(dy, ca, dx, sa);
|
||||
}
|
||||
}
|
||||
|
||||
void DScroller::Tick ()
|
||||
{
|
||||
fixed_t dx = m_dx, dy = m_dy, tdx, tdy;
|
||||
|
||||
if (m_Control != -1)
|
||||
{ // compute scroll amounts based on a sector's height changes
|
||||
fixed_t height = sectors[m_Control].CenterFloor () +
|
||||
sectors[m_Control].CenterCeiling ();
|
||||
fixed_t delta = height - m_LastHeight;
|
||||
m_LastHeight = height;
|
||||
dx = FixedMul(dx, delta);
|
||||
dy = FixedMul(dy, delta);
|
||||
}
|
||||
|
||||
// killough 3/14/98: Add acceleration
|
||||
if (m_Accel)
|
||||
{
|
||||
m_vdx = dx += m_vdx;
|
||||
m_vdy = dy += m_vdy;
|
||||
}
|
||||
|
||||
if (!(dx | dy)) // no-op if both (x,y) offsets are 0
|
||||
return;
|
||||
|
||||
switch (m_Type)
|
||||
{
|
||||
case sc_side: // killough 3/7/98: Scroll wall texture
|
||||
if (m_Parts & scw_top)
|
||||
{
|
||||
sides[m_Affectee].AddTextureXOffset(side_t::top, dx);
|
||||
sides[m_Affectee].AddTextureYOffset(side_t::top, dy);
|
||||
}
|
||||
if (m_Parts & scw_mid && (sides[m_Affectee].linedef->backsector == NULL ||
|
||||
!(sides[m_Affectee].linedef->flags&ML_3DMIDTEX)))
|
||||
{
|
||||
sides[m_Affectee].AddTextureXOffset(side_t::mid, dx);
|
||||
sides[m_Affectee].AddTextureYOffset(side_t::mid, dy);
|
||||
}
|
||||
if (m_Parts & scw_bottom)
|
||||
{
|
||||
sides[m_Affectee].AddTextureXOffset(side_t::bottom, dx);
|
||||
sides[m_Affectee].AddTextureYOffset(side_t::bottom, dy);
|
||||
}
|
||||
break;
|
||||
|
||||
case sc_floor: // killough 3/7/98: Scroll floor texture
|
||||
RotationComp(§ors[m_Affectee], sector_t::floor, dx, dy, tdx, tdy);
|
||||
sectors[m_Affectee].AddXOffset(sector_t::floor, tdx);
|
||||
sectors[m_Affectee].AddYOffset(sector_t::floor, tdy);
|
||||
break;
|
||||
|
||||
case sc_ceiling: // killough 3/7/98: Scroll ceiling texture
|
||||
RotationComp(§ors[m_Affectee], sector_t::ceiling, dx, dy, tdx, tdy);
|
||||
sectors[m_Affectee].AddXOffset(sector_t::ceiling, tdx);
|
||||
sectors[m_Affectee].AddYOffset(sector_t::ceiling, tdy);
|
||||
break;
|
||||
|
||||
// [RH] Don't actually carry anything here. That happens later.
|
||||
case sc_carry:
|
||||
level.Scrolls[m_Affectee].Scroll.X += FIXED2DBL(dx);
|
||||
level.Scrolls[m_Affectee].Scroll.Y += FIXED2DBL(dy);
|
||||
break;
|
||||
|
||||
case sc_carry_ceiling: // to be added later
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Add_Scroller()
|
||||
//
|
||||
// Add a generalized scroller to the thinker list.
|
||||
//
|
||||
// type: the enumerated type of scrolling: floor, ceiling, floor carrier,
|
||||
// wall, floor carrier & scroller
|
||||
//
|
||||
// (dx,dy): the direction and speed of the scrolling or its acceleration
|
||||
//
|
||||
// control: the sector whose heights control this scroller's effect
|
||||
// remotely, or -1 if no control sector
|
||||
//
|
||||
// affectee: the index of the affected object (sector or sidedef)
|
||||
//
|
||||
// accel: non-zero if this is an accelerative effect
|
||||
//
|
||||
|
||||
DScroller::DScroller (EScrollType type, fixed_t dx, fixed_t dy,
|
||||
int control, int affectee, int accel, int scrollpos)
|
||||
: DThinker (STAT_SCROLLER)
|
||||
{
|
||||
m_Type = type;
|
||||
m_dx = dx;
|
||||
m_dy = dy;
|
||||
m_Accel = accel;
|
||||
m_Parts = scrollpos;
|
||||
m_vdx = m_vdy = 0;
|
||||
if ((m_Control = control) != -1)
|
||||
m_LastHeight =
|
||||
sectors[control].CenterFloor () + sectors[control].CenterCeiling ();
|
||||
m_Affectee = affectee;
|
||||
m_Interpolations[0] = m_Interpolations[1] = m_Interpolations[2] = NULL;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case sc_carry:
|
||||
level.AddScroller (this, affectee);
|
||||
break;
|
||||
|
||||
case sc_side:
|
||||
sides[affectee].Flags |= WALLF_NOAUTODECALS;
|
||||
if (m_Parts & scw_top)
|
||||
{
|
||||
m_Interpolations[0] = sides[m_Affectee].SetInterpolation(side_t::top);
|
||||
}
|
||||
if (m_Parts & scw_mid && (sides[m_Affectee].linedef->backsector == NULL ||
|
||||
!(sides[m_Affectee].linedef->flags&ML_3DMIDTEX)))
|
||||
{
|
||||
m_Interpolations[1] = sides[m_Affectee].SetInterpolation(side_t::mid);
|
||||
}
|
||||
if (m_Parts & scw_bottom)
|
||||
{
|
||||
m_Interpolations[2] = sides[m_Affectee].SetInterpolation(side_t::bottom);
|
||||
}
|
||||
break;
|
||||
|
||||
case sc_floor:
|
||||
m_Interpolations[0] = sectors[affectee].SetInterpolation(sector_t::FloorScroll, false);
|
||||
break;
|
||||
|
||||
case sc_ceiling:
|
||||
m_Interpolations[0] = sectors[affectee].SetInterpolation(sector_t::CeilingScroll, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DScroller::Destroy ()
|
||||
{
|
||||
for(int i=0;i<3;i++)
|
||||
{
|
||||
if (m_Interpolations[i] != NULL)
|
||||
{
|
||||
m_Interpolations[i]->DelRef();
|
||||
m_Interpolations[i] = NULL;
|
||||
}
|
||||
}
|
||||
Super::Destroy();
|
||||
}
|
||||
|
||||
// Adds wall scroller. Scroll amount is rotated with respect to wall's
|
||||
// linedef first, so that scrolling towards the wall in a perpendicular
|
||||
// direction is translated into vertical motion, while scrolling along
|
||||
// the wall in a parallel direction is translated into horizontal motion.
|
||||
//
|
||||
// killough 5/25/98: cleaned up arithmetic to avoid drift due to roundoff
|
||||
|
||||
DScroller::DScroller (fixed_t dx, fixed_t dy, const line_t *l,
|
||||
int control, int accel, int scrollpos)
|
||||
: DThinker (STAT_SCROLLER)
|
||||
{
|
||||
fixed_t x = abs(l->dx), y = abs(l->dy), d;
|
||||
if (y > x)
|
||||
d = x, x = y, y = d;
|
||||
d = FixedDiv (x, finesine[(tantoangle[FixedDiv(y,x) >> DBITS] + ANG90)
|
||||
>> ANGLETOFINESHIFT]);
|
||||
x = -FixedDiv (FixedMul(dy, l->dy) + FixedMul(dx, l->dx), d);
|
||||
y = -FixedDiv (FixedMul(dx, l->dy) - FixedMul(dy, l->dx), d);
|
||||
|
||||
m_Type = sc_side;
|
||||
m_dx = x;
|
||||
m_dy = y;
|
||||
m_vdx = m_vdy = 0;
|
||||
m_Accel = accel;
|
||||
m_Parts = scrollpos;
|
||||
if ((m_Control = control) != -1)
|
||||
m_LastHeight = sectors[control].CenterFloor() + sectors[control].CenterCeiling();
|
||||
m_Affectee = int(l->sidedef[0] - sides);
|
||||
sides[m_Affectee].Flags |= WALLF_NOAUTODECALS;
|
||||
m_Interpolations[0] = m_Interpolations[1] = m_Interpolations[2] = NULL;
|
||||
|
||||
if (m_Parts & scw_top)
|
||||
{
|
||||
m_Interpolations[0] = sides[m_Affectee].SetInterpolation(side_t::top);
|
||||
}
|
||||
if (m_Parts & scw_mid && (sides[m_Affectee].linedef->backsector == NULL ||
|
||||
!(sides[m_Affectee].linedef->flags&ML_3DMIDTEX)))
|
||||
{
|
||||
m_Interpolations[1] = sides[m_Affectee].SetInterpolation(side_t::mid);
|
||||
}
|
||||
if (m_Parts & scw_bottom)
|
||||
{
|
||||
m_Interpolations[2] = sides[m_Affectee].SetInterpolation(side_t::bottom);
|
||||
}
|
||||
}
|
||||
|
||||
// Amount (dx,dy) vector linedef is shifted right to get scroll amount
|
||||
#define SCROLL_SHIFT 5
|
||||
#define SCROLLTYPE(i) (((i) <= 0) || ((i) & ~7) ? 7 : (i))
|
||||
|
||||
// Initialize the scrollers
|
||||
static void P_SpawnScrollers(void)
|
||||
{
|
||||
int i;
|
||||
line_t *l = lines;
|
||||
TArray<int> copyscrollers;
|
||||
|
||||
for (i = 0; i < numlines; i++)
|
||||
{
|
||||
if (lines[i].special == Sector_CopyScroller)
|
||||
{
|
||||
// don't allow copying the scroller if the sector has the same tag as it would just duplicate it.
|
||||
if (!tagManager.SectorHasTag(lines[i].frontsector, lines[i].args[0]))
|
||||
{
|
||||
copyscrollers.Push(i);
|
||||
}
|
||||
lines[i].special = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < numlines; i++, l++)
|
||||
{
|
||||
fixed_t dx; // direction and speed of scrolling
|
||||
fixed_t dy;
|
||||
int control = -1, accel = 0; // no control sector or acceleration
|
||||
int special = l->special;
|
||||
|
||||
// Check for undefined parameters that are non-zero and output messages for them.
|
||||
// We don't report for specials we don't understand.
|
||||
FLineSpecial *spec = P_GetLineSpecialInfo(special);
|
||||
if (spec != NULL)
|
||||
{
|
||||
int max = spec->map_args;
|
||||
for (unsigned arg = max; arg < countof(l->args); ++arg)
|
||||
{
|
||||
if (l->args[arg] != 0)
|
||||
{
|
||||
Printf("Line %d (type %d:%s), arg %u is %d (should be 0)\n",
|
||||
i, special, spec->name, arg+1, l->args[arg]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// killough 3/7/98: Types 245-249 are same as 250-254 except that the
|
||||
// first side's sector's heights cause scrolling when they change, and
|
||||
// this linedef controls the direction and speed of the scrolling. The
|
||||
// most complicated linedef since donuts, but powerful :)
|
||||
//
|
||||
// killough 3/15/98: Add acceleration. Types 214-218 are the same but
|
||||
// are accelerative.
|
||||
|
||||
// [RH] Assume that it's a scroller and zero the line's special.
|
||||
l->special = 0;
|
||||
|
||||
dx = dy = 0; // Shut up, GCC
|
||||
|
||||
if (special == Scroll_Ceiling ||
|
||||
special == Scroll_Floor ||
|
||||
special == Scroll_Texture_Model)
|
||||
{
|
||||
if (l->args[1] & 3)
|
||||
{
|
||||
// if 1, then displacement
|
||||
// if 2, then accelerative (also if 3)
|
||||
control = int(l->sidedef[0]->sector - sectors);
|
||||
if (l->args[1] & 2)
|
||||
accel = 1;
|
||||
}
|
||||
if (special == Scroll_Texture_Model ||
|
||||
l->args[1] & 4)
|
||||
{
|
||||
// The line housing the special controls the
|
||||
// direction and speed of scrolling.
|
||||
dx = l->dx >> SCROLL_SHIFT;
|
||||
dy = l->dy >> SCROLL_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The speed and direction are parameters to the special.
|
||||
dx = (l->args[3] - 128) * (FRACUNIT / 32);
|
||||
dy = (l->args[4] - 128) * (FRACUNIT / 32);
|
||||
}
|
||||
}
|
||||
|
||||
switch (special)
|
||||
{
|
||||
int s;
|
||||
|
||||
case Scroll_Ceiling:
|
||||
{
|
||||
FSectorTagIterator itr(l->args[0]);
|
||||
while ((s = itr.Next()) >= 0)
|
||||
{
|
||||
new DScroller(DScroller::sc_ceiling, -dx, dy, control, s, accel);
|
||||
}
|
||||
for (unsigned j = 0; j < copyscrollers.Size(); j++)
|
||||
{
|
||||
line_t *line = &lines[copyscrollers[j]];
|
||||
|
||||
if (line->args[0] == l->args[0] && (line->args[1] & 1))
|
||||
{
|
||||
new DScroller(DScroller::sc_ceiling, -dx, dy, control, int(line->frontsector - sectors), accel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Scroll_Floor:
|
||||
if (l->args[2] != 1)
|
||||
{ // scroll the floor texture
|
||||
FSectorTagIterator itr(l->args[0]);
|
||||
while ((s = itr.Next()) >= 0)
|
||||
{
|
||||
new DScroller (DScroller::sc_floor, -dx, dy, control, s, accel);
|
||||
}
|
||||
for(unsigned j = 0;j < copyscrollers.Size(); j++)
|
||||
{
|
||||
line_t *line = &lines[copyscrollers[j]];
|
||||
|
||||
if (line->args[0] == l->args[0] && (line->args[1] & 2))
|
||||
{
|
||||
new DScroller (DScroller::sc_floor, -dx, dy, control, int(line->frontsector-sectors), accel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (l->args[2] > 0)
|
||||
{ // carry objects on the floor
|
||||
FSectorTagIterator itr(l->args[0]);
|
||||
while ((s = itr.Next()) >= 0)
|
||||
{
|
||||
new DScroller (DScroller::sc_carry, dx, dy, control, s, accel);
|
||||
}
|
||||
for(unsigned j = 0;j < copyscrollers.Size(); j++)
|
||||
{
|
||||
line_t *line = &lines[copyscrollers[j]];
|
||||
|
||||
if (line->args[0] == l->args[0] && (line->args[1] & 4))
|
||||
{
|
||||
new DScroller (DScroller::sc_carry, dx, dy, control, int(line->frontsector-sectors), accel);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// killough 3/1/98: scroll wall according to linedef
|
||||
// (same direction and speed as scrolling floors)
|
||||
case Scroll_Texture_Model:
|
||||
{
|
||||
FLineIdIterator itr(l->args[0]);
|
||||
while ((s = itr.Next()) >= 0)
|
||||
{
|
||||
if (s != i)
|
||||
new DScroller(dx, dy, lines + s, control, accel);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Scroll_Texture_Offsets:
|
||||
// killough 3/2/98: scroll according to sidedef offsets
|
||||
s = int(lines[i].sidedef[0] - sides);
|
||||
new DScroller (DScroller::sc_side, -sides[s].GetTextureXOffset(side_t::mid),
|
||||
sides[s].GetTextureYOffset(side_t::mid), -1, s, accel, SCROLLTYPE(l->args[0]));
|
||||
break;
|
||||
|
||||
case Scroll_Texture_Left:
|
||||
l->special = special; // Restore the special, for compat_useblocking's benefit.
|
||||
s = int(lines[i].sidedef[0] - sides);
|
||||
new DScroller (DScroller::sc_side, l->args[0] * (FRACUNIT/64), 0,
|
||||
-1, s, accel, SCROLLTYPE(l->args[1]));
|
||||
break;
|
||||
|
||||
case Scroll_Texture_Right:
|
||||
l->special = special;
|
||||
s = int(lines[i].sidedef[0] - sides);
|
||||
new DScroller (DScroller::sc_side, l->args[0] * (-FRACUNIT/64), 0,
|
||||
-1, s, accel, SCROLLTYPE(l->args[1]));
|
||||
break;
|
||||
|
||||
case Scroll_Texture_Up:
|
||||
l->special = special;
|
||||
s = int(lines[i].sidedef[0] - sides);
|
||||
new DScroller (DScroller::sc_side, 0, l->args[0] * (FRACUNIT/64),
|
||||
-1, s, accel, SCROLLTYPE(l->args[1]));
|
||||
break;
|
||||
|
||||
case Scroll_Texture_Down:
|
||||
l->special = special;
|
||||
s = int(lines[i].sidedef[0] - sides);
|
||||
new DScroller (DScroller::sc_side, 0, l->args[0] * (-FRACUNIT/64),
|
||||
-1, s, accel, SCROLLTYPE(l->args[1]));
|
||||
break;
|
||||
|
||||
case Scroll_Texture_Both:
|
||||
s = int(lines[i].sidedef[0] - sides);
|
||||
if (l->args[0] == 0) {
|
||||
dx = (l->args[1] - l->args[2]) * (FRACUNIT/64);
|
||||
dy = (l->args[4] - l->args[3]) * (FRACUNIT/64);
|
||||
new DScroller (DScroller::sc_side, dx, dy, -1, s, accel);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// [RH] It wasn't a scroller after all, so restore the special.
|
||||
l->special = special;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// killough 3/7/98 -- end generalized scroll effects
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FRICTION EFFECTS
|
||||
|
|
92
src/p_spec.h
92
src/p_spec.h
|
@ -32,6 +32,32 @@
|
|||
class FScanner;
|
||||
struct level_info_t;
|
||||
|
||||
struct FThinkerCollection
|
||||
{
|
||||
int RefNum;
|
||||
DThinker *Obj;
|
||||
};
|
||||
|
||||
enum class EScroll : int
|
||||
{
|
||||
sc_side,
|
||||
sc_floor,
|
||||
sc_ceiling,
|
||||
sc_carry,
|
||||
sc_carry_ceiling, // killough 4/11/98: carry objects hanging on ceilings
|
||||
};
|
||||
|
||||
enum EScrollPos : int
|
||||
{
|
||||
scw_top = 1,
|
||||
scw_mid = 2,
|
||||
scw_bottom = 4,
|
||||
scw_all = 7,
|
||||
};
|
||||
|
||||
void P_CreateScroller(EScroll type, fixed_t dx, fixed_t dy, int control, int affectee, int accel, EScrollPos scrollpos = EScrollPos::scw_all);
|
||||
|
||||
|
||||
//jff 2/23/98 identify the special classes that can share sectors
|
||||
|
||||
typedef enum
|
||||
|
@ -41,58 +67,6 @@ typedef enum
|
|||
lighting_special,
|
||||
} special_e;
|
||||
|
||||
// killough 3/7/98: Add generalized scroll effects
|
||||
|
||||
class DScroller : public DThinker
|
||||
{
|
||||
DECLARE_CLASS (DScroller, DThinker)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
enum EScrollType
|
||||
{
|
||||
sc_side,
|
||||
sc_floor,
|
||||
sc_ceiling,
|
||||
sc_carry,
|
||||
sc_carry_ceiling, // killough 4/11/98: carry objects hanging on ceilings
|
||||
};
|
||||
enum EScrollPos
|
||||
{
|
||||
scw_top=1,
|
||||
scw_mid=2,
|
||||
scw_bottom=4,
|
||||
scw_all=7,
|
||||
};
|
||||
|
||||
DScroller (EScrollType type, fixed_t dx, fixed_t dy, int control, int affectee, int accel, int scrollpos = scw_all);
|
||||
DScroller (fixed_t dx, fixed_t dy, const line_t *l, int control, int accel, int scrollpos = scw_all);
|
||||
void Destroy();
|
||||
|
||||
void Serialize (FArchive &arc);
|
||||
void Tick ();
|
||||
|
||||
bool AffectsWall (int wallnum) const { return m_Type == sc_side && m_Affectee == wallnum; }
|
||||
int GetWallNum () const { return m_Type == sc_side ? m_Affectee : -1; }
|
||||
void SetRate (fixed_t dx, fixed_t dy) { m_dx = dx; m_dy = dy; }
|
||||
bool IsType (EScrollType type) const { return type == m_Type; }
|
||||
int GetAffectee () const { return m_Affectee; }
|
||||
int GetScrollParts() const { return m_Parts; }
|
||||
|
||||
protected:
|
||||
EScrollType m_Type; // Type of scroll effect
|
||||
fixed_t m_dx, m_dy; // (dx,dy) scroll speeds
|
||||
int m_Affectee; // Number of affected sidedef, sector, tag, or whatever
|
||||
int m_Control; // Control sector (-1 if none) used to control scrolling
|
||||
fixed_t m_LastHeight; // Last known height of control sector
|
||||
fixed_t m_vdx, m_vdy; // Accumulated velocity if accelerative
|
||||
int m_Accel; // Whether it's accelerative
|
||||
int m_Parts; // Which parts of a sidedef are being scrolled?
|
||||
TObjPtr<DInterpolation> m_Interpolations[3];
|
||||
|
||||
private:
|
||||
DScroller ();
|
||||
};
|
||||
|
||||
// Factor to scale scrolling effect into mobj-carrying properties = 3/32.
|
||||
// (This is so scrolling floors and objects on them can move at same speed.)
|
||||
enum { _f_CARRYFACTOR = (3*FRACUNIT >> 5) };
|
||||
|
@ -633,6 +607,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);
|
||||
|
||||
|
@ -641,7 +623,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;
|
||||
|
@ -651,7 +633,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
|
||||
|
||||
|
@ -674,7 +656,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);
|
||||
|
||||
inline bool EV_DoCeiling(DCeiling::ECeiling type, line_t *line,
|
||||
int tag, double speed, double speed2, fixed_t height,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "r_defs.h"
|
||||
#include "m_bbox.h"
|
||||
|
||||
class DPolyAction;
|
||||
|
||||
struct FPolyVertex
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue