Skip to content

Commit

Permalink
implemented DSDA's sector scrolling properties.
Browse files Browse the repository at this point in the history
The major new additions are flags to specify which kind of actor is supposed to be scrolled and carrying ceiling scrollers.
  • Loading branch information
coelckers committed Oct 29, 2023
1 parent 2fb41a7 commit 2b0731a
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 17 deletions.
14 changes: 14 additions & 0 deletions specs/udmf_zdoom.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion src/maploader/maploader.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ class MapLoader
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();
Expand Down
4 changes: 2 additions & 2 deletions src/maploader/specials.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
59 changes: 48 additions & 11 deletions src/maploader/udmf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include "xlat/xlat.h"
#include "maploader.h"
#include "texturemanager.h"
#include "a_scroll.h"

//===========================================================================
//
Expand Down Expand Up @@ -431,7 +432,7 @@ struct UDMFScroll
bool ceiling;
int index;
double x, y;
FName type;
int scrolltype;
};

class UDMFParser : public UDMFParserBase
Expand Down Expand Up @@ -1589,11 +1590,13 @@ class UDMFParser : public UDMFParserBase
// 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;
Expand Down Expand Up @@ -2007,28 +2010,64 @@ class UDMFParser : public UDMFParserBase
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_scrollceilingmode:
scroll_ceil_type = CheckInt(key);
break;

case NAME_scroll_ceil_type:
scroll_ceil_type = CheckString(key);
{
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_scrollfloormode:
scroll_floor_type = CheckInt(key);
break;

case NAME_scroll_floor_type:
scroll_floor_type = CheckString(key);
{
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:
Expand Down Expand Up @@ -2470,15 +2509,13 @@ class UDMFParser : public UDMFParserBase
// 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);
}
}

Expand Down
53 changes: 51 additions & 2 deletions src/playsim/mapthinkers/a_scroll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -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;
}
}
Expand All @@ -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;
Expand All @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
12 changes: 11 additions & 1 deletion src/playsim/mapthinkers/a_scroll.h
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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;

Expand All @@ -29,6 +38,7 @@ class DScroller : public DThinker

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
Expand Down

0 comments on commit 2b0731a

Please sign in to comment.