added UDMF wall scrolling properties from DSDA.

This commit is contained in:
Christoph Oelckers 2023-10-29 16:07:27 +01:00
parent 2b0731a5a7
commit 4ddffd233a
4 changed files with 80 additions and 17 deletions

View file

@ -238,6 +238,16 @@ Note: All <bool> fields default to false unless mentioned otherwise.
skew_middle = <int>; // Vertical texture alignment defines the position at the leftmost point of the wall.
skew_bottom = <int>; // Possible values: 0 = no skewing, 1 = align to front floor, 2 = align to front ceiling, 3 = align to back floor, 4 = align to back ceiling.
// Front/Back are relative to the sidedef, not the owning linedef. Default = 0.
xscroll = <float>; // wall scrolling X speed in map units per tic.
yscroll = <float>; // wall scrolling Y speed in map units per tic.
xscrolltop = <float>; // upper wall scrolling X speed in map units per tic.
yscrolltop = <float>; // upper wall scrolling Y speed in map units per tic.
xscrollmid = <float>; // mid wall scrolling X speed in map units per tic.
yscrollmid = <float>; // mid wall scrolling Y speed in map units per tic.
xscrollbottom = <float>; // lower wall scrolling X speed in map units per tic.
yscrollbottom = <float>; // lower wall scrolling Y speed in map units per tic.
}

View file

@ -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, int scrollmode = 15/*SCROLL_All*/);
void CreateScroller(EScroll type, double dx, double dy, sector_t *sect, side_t* side, int accel, EScrollPos scrollpos = EScrollPos::scw_all, int scrollmode = 15/*SCROLL_All*/);
void SpawnScrollers();
void SpawnFriction();
void SpawnPushers();

View file

@ -574,7 +574,7 @@ void MapLoader::InitSectorSpecial(sector_t *sector, int special)
case dScroll_EastLavaDamage:
SetupSectorDamage(sector, 5, 16, 256, NAME_Fire, SECF_DMGTERRAINFX);
CreateScroller(EScroll::sc_floor, -4., 0, sector, 0);
CreateScroller(EScroll::sc_floor, -4., 0, sector, nullptr, 0);
keepspecial = true;
break;
@ -631,13 +631,13 @@ void MapLoader::InitSectorSpecial(sector_t *sector, int special)
int i = sector->special - Scroll_North_Slow;
double dx = hexenScrollies[i][0] / 2.;
double dy = hexenScrollies[i][1] / 2.;
CreateScroller(EScroll::sc_floor, dx, dy, sector, 0);
CreateScroller(EScroll::sc_floor, dx, dy, sector, nullptr, 0);
}
else if (sector->special >= Carry_East5 && sector->special <= Carry_East35)
{
// Heretic scroll special
// Only east scrollers also scroll the texture
CreateScroller(EScroll::sc_floor, -0.5 * (1 << ((sector->special & 0xff) - Carry_East5)), 0, sector, 0);
CreateScroller(EScroll::sc_floor, -0.5 * (1 << ((sector->special & 0xff) - Carry_East5)), 0, sector, nullptr, 0);
}
keepspecial = true;
break;
@ -1466,7 +1466,8 @@ void MapLoader::SpawnScrollers()
}
void MapLoader::CreateScroller(EScroll type, double dx, double dy, sector_t *affectee, int accel, EScrollPos scrollpos, int scrollmode)
void MapLoader::CreateScroller(EScroll type, double dx, double dy, sector_t *sect, side_t* side, int accel, EScrollPos scrollpos, int scrollmode)
{
Level->CreateThinker<DScroller>(type, dx, dy, nullptr, affectee, nullptr, accel, scrollpos, scrollmode);
Level->CreateThinker<DScroller>(type, dx, dy, nullptr, sect, side, accel, scrollpos, scrollmode);
}

View file

@ -429,7 +429,7 @@ FString GetUDMFString(FLevelLocals *Level, int type, int index, FName key)
struct UDMFScroll
{
bool ceiling;
int where;
int index;
double x, y;
int scrolltype;
@ -448,7 +448,8 @@ class UDMFParser : public UDMFParserBase
TArray<intmapsidedef_t> ParsedSideTextures;
TArray<sector_t> ParsedSectors;
TArray<vertex_t> ParsedVertices;
TArray<UDMFScroll> UDMFScrollers;
TArray<UDMFScroll> UDMFSectorScrollers;
TArray<UDMFScroll> UDMFWallScrollers;
FDynamicColormap *fogMap = nullptr, *normMap = nullptr;
FMissingTextureTracker &missingTex;
@ -1245,6 +1246,7 @@ public:
void ParseSidedef(side_t *sd, intmapsidedef_t *sdt, int index)
{
double texOfs[2]={0,0};
DVector2 scrolls[4] = {};
memset(sd, 0, sizeof(*sd));
sdt->bottomtexture = "-";
@ -1551,6 +1553,30 @@ public:
sd->textures[side_t::bottom].skew = CheckInt(key);
break;
case NAME_xscroll:
scrolls[0].X = CheckFloat(key);
break;
case NAME_yscroll:
scrolls[0].Y = CheckFloat(key);
break;
case NAME_xscrolltop:
scrolls[1].X = CheckFloat(key);
break;
case NAME_yscrolltop:
scrolls[1].Y = CheckFloat(key);
break;
case NAME_xscrollmid:
scrolls[2].X = CheckFloat(key);
break;
case NAME_yscrollmid:
scrolls[2].Y = CheckFloat(key);
break;
case NAME_xscrollbottom:
scrolls[3].X = CheckFloat(key);
break;
case NAME_yscrollbottom:
scrolls[3].Y = CheckFloat(key);
break;
default:
if (strnicmp("user_", key.GetChars(), 5))
DPrintf(DMSG_WARNING, "Unknown UDMF sidedef key %s\n", key.GetChars());
@ -1569,6 +1595,21 @@ public:
sd->AddTextureYOffset(side_t::top, texOfs[1]);
sd->AddTextureYOffset(side_t::mid, texOfs[1]);
sd->AddTextureYOffset(side_t::bottom, texOfs[1]);
int scroll = scw_all;
for (int i = 1; i < 4; i++)
{
auto& scrl = scrolls[i];
if (!scrl.isZero())
{
int where = 1 << (i - 1);
scroll &= ~where;
UDMFWallScrollers.Push({ where, index, scrl.X, scrl.Y, 0 });
}
}
if (!scrolls[0].isZero() && scroll)
{
UDMFWallScrollers.Push({ scroll, index, scrolls[0].X, scrolls[0].Y, 0});
}
}
//===========================================================================
@ -2137,11 +2178,11 @@ public:
// Cannot be initialized yet because they need the final sector array.
if (scroll_ceil_type != NAME_None)
{
UDMFScrollers.Push({ true, index, scroll_ceil_x, scroll_ceil_y, scroll_ceil_type });
UDMFSectorScrollers.Push({ true, index, scroll_ceil_x, scroll_ceil_y, scroll_ceil_type });
}
if (scroll_floor_type != NAME_None)
{
UDMFScrollers.Push({ false, index, scroll_floor_x, scroll_floor_y, scroll_floor_type });
UDMFSectorScrollers.Push({ false, index, scroll_floor_x, scroll_floor_y, scroll_floor_type });
}
@ -2246,7 +2287,7 @@ public:
//
//===========================================================================
void ProcessLineDefs()
void ProcessLineDefs(TArray<TArray<int>>& siderefs)
{
int sidecount = 0;
for(unsigned i = 0, skipped = 0; i < ParsedLines.Size();)
@ -2281,6 +2322,7 @@ public:
}
}
unsigned numlines = ParsedLines.Size();
siderefs.Resize(ParsedSides.Size());
Level->sides.Alloc(sidecount);
Level->lines.Alloc(numlines);
int line, side;
@ -2300,6 +2342,7 @@ public:
int mapside = int(intptr_t(lines[line].sidedef[sd]))-1;
if (mapside < sidecount)
{
siderefs[mapside].Push(side);
sides[side] = ParsedSides[mapside];
sides[side].linedef = &lines[line];
sides[side].sector = &Level->sectors[intptr_t(sides[side].sector)];
@ -2506,21 +2549,30 @@ public:
{
Level->sectors[i].e = &Level->extsectors[i];
}
// Create the real linedefs and decompress the sidedefs. Must be done before
TArray<TArray<int>> siderefs;
ProcessLineDefs(siderefs);
// Now create the scrollers.
for (auto &scroll : UDMFScrollers)
for (auto &scroll : UDMFSectorScrollers)
{
if (scroll.scrolltype & SCROLL_Textures)
{
loader->CreateScroller(scroll.ceiling ? EScroll::sc_ceiling : EScroll::sc_floor, -scroll.x, scroll.y, &Level->sectors[scroll.index], 0);
loader->CreateScroller(scroll.where == 1 ? EScroll::sc_ceiling : EScroll::sc_floor, -scroll.x, scroll.y, &Level->sectors[scroll.index], nullptr, 0);
}
if (scroll.scrolltype & (SCROLL_StaticObjects | SCROLL_Players | SCROLL_Monsters))
{
loader->CreateScroller(scroll.ceiling ? EScroll::sc_carry_ceiling : EScroll::sc_carry, scroll.x, scroll.y, &Level->sectors[scroll.index], 0, scw_all, scroll.scrolltype);
loader->CreateScroller(scroll.where == 1 ? EScroll::sc_carry_ceiling : EScroll::sc_carry, scroll.x, scroll.y, &Level->sectors[scroll.index], nullptr, 0, scw_all, scroll.scrolltype);
}
}
for (auto& scroll : UDMFWallScrollers)
{
for(auto sd : siderefs[scroll.index])
{
loader->CreateScroller(EScroll::sc_side, scroll.x, scroll.y, nullptr, &Level->sides[sd], 0);
}
}
// Create the real linedefs and decompress the sidedefs
ProcessLineDefs();
}
};