mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-03-21 18:31:10 +00:00
implemented DSDA's sector scrolling properties.
The major new additions are flags to specify which kind of actor is supposed to be scrolled and carrying ceiling scrollers.
This commit is contained in:
parent
2fb41a7956
commit
2b0731a5a7
6 changed files with 129 additions and 19 deletions
|
@ -337,6 +337,20 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
healthfloorgroup = <int>; // ID of destructible object to synchronize hitpoints (optional, default is 0)
|
||||
healthceiling = <int>; // Amount of hitpoints for this sector (includes ceiling and top-outside linedef sides)
|
||||
healthceilinggroup = <int>; // ID of destructible object to synchronize hitpoints (optional, default is 0)
|
||||
|
||||
xscrollfloor = <float>; // X map units per frame to scroll the floor.
|
||||
yscrollfloor = <float>; // Y map units per frame to scroll the floor.
|
||||
scrollfloormode = <int>; // Floor scroll mode bit mask (1 = scroll textures, 2 = carry static objects, 4 = carry players, 8 = carry monsters.
|
||||
xscrollceiling = <float>; // X map units per frame to scroll the ceiling.
|
||||
yscrollceiling = <float>; // Y map units per frame to scroll the ceiling.
|
||||
scrollceilingmode = <int>; // ceiling scroll mode bit mask (1 = scroll textures, 2 = carry static objects, 4 = carry players, 8 = carry monsters.
|
||||
|
||||
scroll_ceil_x = <float>; // deprecated Eternity based alternatives for the above.
|
||||
scroll_ceil_y = <float>; // Due to using unintuitive units of measurement and a more limited feature set they should not be used anymore.
|
||||
scroll_ceil_type = <string>;
|
||||
scroll_floor_x = <float>;
|
||||
scroll_floor_y = <float>;
|
||||
scroll_floor_type = <string>;
|
||||
|
||||
* Note about dropactors
|
||||
|
||||
|
|
|
@ -194,7 +194,7 @@ private:
|
|||
void SpawnSpecials();
|
||||
void InitSectorSpecial(sector_t *sector, int special);
|
||||
void SpawnLights(sector_t *sector);
|
||||
void CreateScroller(EScroll type, double dx, double dy, sector_t *affectee, int accel, EScrollPos scrollpos = EScrollPos::scw_all);
|
||||
void CreateScroller(EScroll type, double dx, double dy, sector_t *affectee, int accel, EScrollPos scrollpos = EScrollPos::scw_all, int scrollmode = 15/*SCROLL_All*/);
|
||||
void SpawnScrollers();
|
||||
void SpawnFriction();
|
||||
void SpawnPushers();
|
||||
|
|
|
@ -1466,7 +1466,7 @@ void MapLoader::SpawnScrollers()
|
|||
}
|
||||
|
||||
|
||||
void MapLoader::CreateScroller(EScroll type, double dx, double dy, sector_t *affectee, int accel, EScrollPos scrollpos)
|
||||
void MapLoader::CreateScroller(EScroll type, double dx, double dy, sector_t *affectee, int accel, EScrollPos scrollpos, int scrollmode)
|
||||
{
|
||||
Level->CreateThinker<DScroller>(type, dx, dy, nullptr, affectee, nullptr, accel, scrollpos);
|
||||
Level->CreateThinker<DScroller>(type, dx, dy, nullptr, affectee, nullptr, accel, scrollpos, scrollmode);
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "xlat/xlat.h"
|
||||
#include "maploader.h"
|
||||
#include "texturemanager.h"
|
||||
#include "a_scroll.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -431,7 +432,7 @@ struct UDMFScroll
|
|||
bool ceiling;
|
||||
int index;
|
||||
double x, y;
|
||||
FName type;
|
||||
int scrolltype;
|
||||
};
|
||||
|
||||
class UDMFParser : public UDMFParserBase
|
||||
|
@ -1589,11 +1590,13 @@ public:
|
|||
// Brand new UDMF scroller properties
|
||||
double scroll_ceil_x = 0;
|
||||
double scroll_ceil_y = 0;
|
||||
FName scroll_ceil_type = NAME_None;
|
||||
int scroll_ceil_type = 0;
|
||||
|
||||
double scroll_floor_x = 0;
|
||||
double scroll_floor_y = 0;
|
||||
FName scroll_floor_type = NAME_None;
|
||||
int scroll_floor_type = 0;
|
||||
|
||||
const double scrollfactor = 1 / 3.2; // I hope this is correct, it's just a guess taken from Eternity's code.
|
||||
|
||||
memset(sec, 0, sizeof(*sec));
|
||||
sec->Level = Level;
|
||||
|
@ -2007,29 +2010,65 @@ public:
|
|||
break;
|
||||
|
||||
case NAME_scroll_ceil_x:
|
||||
scroll_ceil_x = CheckFloat(key) * scrollfactor;
|
||||
break;
|
||||
|
||||
case NAME_xscrollceiling:
|
||||
scroll_ceil_x = CheckFloat(key);
|
||||
break;
|
||||
|
||||
case NAME_scroll_ceil_y:
|
||||
scroll_ceil_y = CheckFloat(key) * scrollfactor;
|
||||
break;
|
||||
|
||||
case NAME_yscrollceiling:
|
||||
scroll_ceil_y = CheckFloat(key);
|
||||
break;
|
||||
|
||||
case NAME_scroll_ceil_type:
|
||||
scroll_ceil_type = CheckString(key);
|
||||
case NAME_scrollceilingmode:
|
||||
scroll_ceil_type = CheckInt(key);
|
||||
break;
|
||||
|
||||
case NAME_scroll_ceil_type:
|
||||
{
|
||||
const char* val = CheckString(key);
|
||||
if (!stricmp(val, "both")) scroll_ceil_type = SCROLL_All;
|
||||
else if (!stricmp(val, "visual")) scroll_ceil_type = SCROLL_Textures;
|
||||
if (!stricmp(val, "physical")) scroll_ceil_type = SCROLL_All & ~SCROLL_Textures;
|
||||
else scroll_ceil_type = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case NAME_scroll_floor_x:
|
||||
scroll_floor_x = CheckFloat(key) * scrollfactor;
|
||||
break;
|
||||
|
||||
case NAME_xscrollfloor:
|
||||
scroll_floor_x = CheckFloat(key);
|
||||
break;
|
||||
|
||||
case NAME_scroll_floor_y:
|
||||
scroll_floor_y = CheckFloat(key) * scrollfactor;
|
||||
break;
|
||||
|
||||
case NAME_yscrollfloor:
|
||||
scroll_floor_y = CheckFloat(key);
|
||||
break;
|
||||
|
||||
case NAME_scroll_floor_type:
|
||||
scroll_floor_type = CheckString(key);
|
||||
case NAME_scrollfloormode:
|
||||
scroll_floor_type = CheckInt(key);
|
||||
break;
|
||||
|
||||
case NAME_scroll_floor_type:
|
||||
{
|
||||
const char* val = CheckString(key);
|
||||
if (!stricmp(val, "both")) scroll_floor_type = SCROLL_All;
|
||||
else if (!stricmp(val, "visual")) scroll_floor_type = SCROLL_Textures;
|
||||
if (!stricmp(val, "physical")) scroll_floor_type = SCROLL_All & ~SCROLL_Textures;
|
||||
else scroll_floor_type = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// These two are used by Eternity for something I do not understand.
|
||||
//case NAME_portal_ceil_useglobaltex:
|
||||
//case NAME_portal_floor_useglobaltex:
|
||||
|
@ -2470,15 +2509,13 @@ public:
|
|||
// Now create the scrollers.
|
||||
for (auto &scroll : UDMFScrollers)
|
||||
{
|
||||
const double scrollfactor = 1 / 3.2; // I hope this is correct, it's just a guess taken from Eternity's code.
|
||||
if (scroll.type == NAME_Both || scroll.type == NAME_Visual)
|
||||
if (scroll.scrolltype & SCROLL_Textures)
|
||||
{
|
||||
loader->CreateScroller(scroll.ceiling ? EScroll::sc_ceiling : EScroll::sc_floor, scroll.x * scrollfactor, scroll.y * scrollfactor, &Level->sectors[scroll.index], 0);
|
||||
loader->CreateScroller(scroll.ceiling ? EScroll::sc_ceiling : EScroll::sc_floor, -scroll.x, scroll.y, &Level->sectors[scroll.index], 0);
|
||||
}
|
||||
if (scroll.type == NAME_Both || scroll.type == NAME_Physical)
|
||||
if (scroll.scrolltype & (SCROLL_StaticObjects | SCROLL_Players | SCROLL_Monsters))
|
||||
{
|
||||
// sc_carry_ceiling doesn't do anything yet.
|
||||
loader->CreateScroller(scroll.ceiling ? EScroll::sc_carry_ceiling : EScroll::sc_carry, scroll.x * scrollfactor, scroll.y * scrollfactor, &Level->sectors[scroll.index], 0);
|
||||
loader->CreateScroller(scroll.ceiling ? EScroll::sc_carry_ceiling : EScroll::sc_carry, scroll.x, scroll.y, &Level->sectors[scroll.index], 0, scw_all, scroll.scrolltype);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -105,8 +105,11 @@ void DScroller::Serialize(FSerializer &arc)
|
|||
("vdx", m_vdx)
|
||||
("vdy", m_vdy)
|
||||
("accel", m_Accel)
|
||||
("affect", m_Affect)
|
||||
.Enum("parts", m_Parts)
|
||||
.Array("interpolations", m_Interpolations, 3);
|
||||
|
||||
if (arc.isReading() && m_Affect == 0) m_Affect = SCROLL_All;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -218,11 +221,55 @@ void DScroller::Tick ()
|
|||
// mark all potentially affected things here so that the very expensive calculation loop in AActor::Tick does not need to run for actors which do not touch a scrolling sector.
|
||||
for (auto n = m_Sector->touching_thinglist; n; n = n->m_snext)
|
||||
{
|
||||
AActor* actor = n->m_thing;
|
||||
if (actor->player)
|
||||
{
|
||||
if (!(m_Affect & SCROLL_Players))
|
||||
continue;
|
||||
}
|
||||
else if (actor->flags3 & MF3_ISMONSTER)
|
||||
{
|
||||
if (!(m_Affect & SCROLL_Monsters))
|
||||
continue;
|
||||
}
|
||||
else if (!(m_Affect & SCROLL_StaticObjects))
|
||||
continue;
|
||||
|
||||
n->m_thing->flags8 |= MF8_INSCROLLSEC;
|
||||
}
|
||||
break;
|
||||
|
||||
case EScroll::sc_carry_ceiling: // to be added later
|
||||
case EScroll::sc_carry_ceiling:
|
||||
// this just copies DSDA's implementation. Usability is limited.
|
||||
for (auto n = m_Sector->touching_thinglist; n; n = n->m_snext)
|
||||
{
|
||||
AActor* actor = n->m_thing;
|
||||
|
||||
if (
|
||||
!(actor->flags & MF_NOCLIP) &&
|
||||
actor->flags & MF_SPAWNCEILING &&
|
||||
actor->flags & MF_NOGRAVITY &&
|
||||
actor->Top() == m_Sector->ceilingplane.ZatPoint(actor->Pos().XY())
|
||||
)
|
||||
{
|
||||
|
||||
if (actor->player)
|
||||
{
|
||||
if (!(m_Affect & SCROLL_Players))
|
||||
continue;
|
||||
}
|
||||
else if (actor->flags3 & MF3_ISMONSTER)
|
||||
{
|
||||
if (!(m_Affect & SCROLL_Monsters))
|
||||
continue;
|
||||
}
|
||||
else if (!(m_Affect & SCROLL_StaticObjects))
|
||||
continue;
|
||||
|
||||
n->m_thing->Vel.X = m_dx;
|
||||
n->m_thing->Vel.Y = m_dy;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -247,7 +294,7 @@ void DScroller::Tick ()
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void DScroller::Construct (EScroll type, double dx, double dy, sector_t *ctrl, sector_t *sec, side_t *side, int accel, EScrollPos scrollpos)
|
||||
void DScroller::Construct (EScroll type, double dx, double dy, sector_t *ctrl, sector_t *sec, side_t *side, int accel, EScrollPos scrollpos, int aff)
|
||||
{
|
||||
m_Type = type;
|
||||
m_dx = dx;
|
||||
|
@ -256,6 +303,7 @@ void DScroller::Construct (EScroll type, double dx, double dy, sector_t *ctrl,
|
|||
m_Parts = scrollpos;
|
||||
m_vdx = m_vdy = 0;
|
||||
m_LastHeight = 0;
|
||||
m_Affect = aff;
|
||||
if ((m_Controller = ctrl) != nullptr)
|
||||
{
|
||||
m_LastHeight = m_Controller->CenterFloor() + m_Controller->CenterCeiling();
|
||||
|
@ -344,6 +392,7 @@ void DScroller::Construct(double dx, double dy, const line_t *l, sector_t * cont
|
|||
m_Accel = accel;
|
||||
m_Parts = scrollpos;
|
||||
m_LastHeight = 0;
|
||||
m_Affect = SCROLL_All; // not really relevant, so use the default.
|
||||
if ((m_Controller = control) != nullptr)
|
||||
{
|
||||
m_LastHeight = m_Controller->CenterFloor() + m_Controller->CenterCeiling();
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
enum EScrollAffect
|
||||
{
|
||||
SCROLL_Textures = 1,
|
||||
SCROLL_StaticObjects = 2,
|
||||
SCROLL_Players = 4,
|
||||
SCROLL_Monsters = 8,
|
||||
SCROLL_All = 15
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// killough 3/7/98: Add generalized scroll effects
|
||||
|
@ -13,7 +22,7 @@ class DScroller : public DThinker
|
|||
public:
|
||||
static const int DEFAULT_STAT = STAT_SCROLLER;
|
||||
|
||||
void Construct(EScroll type, double dx, double dy, sector_t *control, sector_t *sec, side_t *side, int accel, EScrollPos scrollpos = EScrollPos::scw_all);
|
||||
void Construct(EScroll type, double dx, double dy, sector_t *control, sector_t *sec, side_t *side, int accel, EScrollPos scrollpos = EScrollPos::scw_all, int aff = SCROLL_All);
|
||||
void Construct(double dx, double dy, const line_t *l, sector_t *control, int accel, EScrollPos scrollpos = EScrollPos::scw_all);
|
||||
void OnDestroy() override;
|
||||
|
||||
|
@ -29,6 +38,7 @@ public:
|
|||
|
||||
protected:
|
||||
EScroll m_Type; // Type of scroll effect
|
||||
int m_Affect;
|
||||
double m_dx, m_dy; // (dx,dy) scroll speeds
|
||||
sector_t *m_Sector; // Affected sector
|
||||
side_t *m_Side; // ... or side
|
||||
|
|
Loading…
Reference in a new issue