Skip to content

Commit

Permalink
added DSDA's thrust properties for UDMF
Browse files Browse the repository at this point in the history
  • Loading branch information
coelckers committed Oct 29, 2023
1 parent bdee1f3 commit ad778b0
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 1 deletion.
6 changes: 6 additions & 0 deletions specs/udmf_zdoom.txt
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,12 @@ Note: All <bool> fields default to false unless mentioned otherwise.
skyceiling2 = <string> // defines secondary upper sky for this sector.

colormap = <string>; // only provided for backwards compatibility. Do not use in GZDoom projects.

xthrust = <float>; // applies thrust to actors - x-magnitude
ythrust = <float>; // applies thrust to actors - y-magnitude
thrustgroup = <int>; // specifies which actors get thrusted. Bitfield with (1 = static objects, 2 = player, 4 = monsters, 8 = projectiles, 16 = actors with +WINDTHRUST)
thrustlocation = <int>; // specifies where in the sector actors get thrusted: (1 = on the ground, 2 = in the air, 4 = on the ceiling)


* Note about dropactors

Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,7 @@ set (PCH_SOURCES
playsim/mapthinkers/a_pillar.cpp
playsim/mapthinkers/a_plats.cpp
playsim/mapthinkers/a_pusher.cpp
playsim/mapthinkers/a_thruster.cpp
playsim/mapthinkers/a_scroll.cpp
playsim/mapthinkers/dsectoreffect.cpp
playsim/a_pickups.cpp
Expand Down
32 changes: 31 additions & 1 deletion src/maploader/udmf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "maploader.h"
#include "texturemanager.h"
#include "a_scroll.h"
#include "p_spec_thinkers.h"

//===========================================================================
//
Expand Down Expand Up @@ -450,6 +451,7 @@ class UDMFParser : public UDMFParserBase
TArray<vertex_t> ParsedVertices;
TArray<UDMFScroll> UDMFSectorScrollers;
TArray<UDMFScroll> UDMFWallScrollers;
TArray<UDMFScroll> UDMFThrusters;

FDynamicColormap *fogMap = nullptr, *normMap = nullptr;
FMissingTextureTracker &missingTex;
Expand Down Expand Up @@ -1639,6 +1641,10 @@ class UDMFParser : public UDMFParserBase

double friction = -FLT_MAX, movefactor = -FLT_MAX;

DVector2 thrust = { 0,0 };
int thrustgroup = 0;
int thrustlocation = 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));
Expand Down Expand Up @@ -2140,6 +2146,22 @@ class UDMFParser : public UDMFParserBase
sec->planes[sector_t::ceiling].skytexture[1] = TexMan.CheckForTexture(CheckString(key), ETextureType::Wall, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ReturnFirst);
break;

case NAME_xthrust:
thrust.X = CheckFloat(key);
break;

case NAME_ythrust:
thrust.Y = CheckFloat(key);
break;

case NAME_thrustgroup:
thrustgroup = CheckInt(key);
break;

case NAME_thrustlocation:
thrustlocation = CheckInt(key);
break;

// These two are used by Eternity for something I do not understand.
//case NAME_portal_ceil_useglobaltex:
//case NAME_portal_floor_useglobaltex:
Expand Down Expand Up @@ -2205,7 +2227,7 @@ class UDMFParser : public UDMFParserBase
sec->Flags &= ~SECF_DAMAGEFLAGS;
}

// Cannot be initialized yet because they need the final sector array.
// These cannot be initialized yet because they need the final sector array.
if (scroll_ceil_type != NAME_None)
{
UDMFSectorScrollers.Push({ true, index, scroll_ceil_x, scroll_ceil_y, scroll_ceil_type });
Expand All @@ -2214,6 +2236,10 @@ class UDMFParser : public UDMFParserBase
{
UDMFSectorScrollers.Push({ false, index, scroll_floor_x, scroll_floor_y, scroll_floor_type });
}
if (!thrust.isZero())
{
UDMFThrusters.Push({ thrustlocation, index, thrust.X, thrust.Y, thrustgroup });
}


// Reset the planes to their defaults if not all of the plane equation's parameters were found.
Expand Down Expand Up @@ -2613,6 +2639,10 @@ class UDMFParser : public UDMFParserBase
loader->CreateScroller(EScroll::sc_side, scroll.x, scroll.y, nullptr, &Level->sides[sd], 0);
}
}
for (auto& scroll : UDMFThrusters)
{
Level->CreateThinker<DThruster>(&Level->sectors[scroll.index], scroll.x, scroll.y, scroll.scrolltype, scroll.where);
}
}
};

Expand Down
15 changes: 15 additions & 0 deletions src/playsim/mapthinkers/a_pusher.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,18 @@ class DPusher : public DThinker
friend bool PIT_PushThing (AActor *thing);
};

class DThruster : public DThinker
{
DECLARE_CLASS(DThruster, DThinker)

DVector2 m_PushVec;
sector_t* m_Sector;
int m_Type;
int m_Location;

public:
void Construct(sector_t* sec, double dx, double dy, int type, int location);
void Serialize(FSerializer& arc);
void Tick();

};
155 changes: 155 additions & 0 deletions src/playsim/mapthinkers/a_thruster.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
//-----------------------------------------------------------------------------
//
// Copyright 2023 Ryan Krafnick
// Copyright 2023 Christoph Oelckers
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//
//-----------------------------------------------------------------------------
//
// DESCRIPTION:
// UDMF-style thruster
//
//-----------------------------------------------------------------------------


#include <stdlib.h>
#include "actor.h"
#include "p_spec.h"
#include "serializer.h"
#include "serializer_doom.h"
#include "p_spec_thinkers.h"

EXTERN_CVAR(Bool, var_pushers);

IMPLEMENT_CLASS(DThruster, false, false)

enum
{
THRUST_STATIC = 0x01,
THRUST_PLAYER = 0x02,
THRUST_MONSTER = 0x04,
THRUST_PROJECTILE = 0x08,
THRUST_WINDTHRUST = 0x10,

THRUST_GROUNDED = 1,
THRUST_AIRBORNE = 2,
THRUST_CEILING = 4
};


//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------

void DThruster::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc("type", m_Type)
("location", m_Location)
("pushvec", m_PushVec)
("sector", m_Sector);
}


//-----------------------------------------------------------------------------
//
// Add a thrust thinker to the thinker list
//
//-----------------------------------------------------------------------------

void DThruster::Construct(sector_t* sec, double dx, double dy, int type, int location)
{
m_Type = type;
m_Location = location;
m_Sector = sec;
m_PushVec = { dx, dy };
}

//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------

void DThruster::Tick ()
{
sector_t* sec = m_Sector;

if (m_PushVec.isZero())
return;

for (auto node = sec->touching_thinglist; node; node = node->m_snext)
{
bool thrust_it = false;
AActor* thing = node->m_thing;

if (thing->flags & MF_NOCLIP)
continue;

if (!(thing->flags & MF_NOGRAVITY) && thing->Z() <= thing->floorz)
{
if (m_Location & THRUST_GROUNDED)
thrust_it = true;
}
else if (
thing->flags & MF_SPAWNCEILING &&
thing->flags & MF_NOGRAVITY &&
thing->Top() == thing->ceilingz
)
{
if (m_Location & THRUST_CEILING)
thrust_it = true;
}
else if (thing->flags & MF_NOGRAVITY || thing->Z() > thing->floorz)
{
if (m_Location & THRUST_AIRBORNE)
thrust_it = true;
}

if (thrust_it)
{
thrust_it = false;

if (thing->flags2 & MF2_WINDTHRUST && m_Type & THRUST_WINDTHRUST)
thrust_it = true;
else if (thing->flags3 & MF3_ISMONSTER)
{
if (m_Type & THRUST_MONSTER)
thrust_it = true;
}
else if (thing->player)
{
if (m_Type & THRUST_PLAYER)
thrust_it = true;
}
else if (thing->flags & MF_MISSILE)
{
if (m_Type & THRUST_PROJECTILE)
thrust_it = true;
}
else
{
if (m_Type & THRUST_STATIC)
thrust_it = true;
}

if (thrust_it)
{
thing->Vel += m_PushVec;
}
}
}
}

0 comments on commit ad778b0

Please sign in to comment.