- give thinkers a 'level' member and change linking to the chain to happen outside the constructor.

This commit is contained in:
Christoph Oelckers 2019-01-27 01:49:20 +01:00
parent df4c7d8f56
commit 8323524014
43 changed files with 201 additions and 228 deletions

View file

@ -64,7 +64,6 @@ IMPLEMENT_POINTERS_END
DEFINE_FIELD(DBot, dest) DEFINE_FIELD(DBot, dest)
DBot::DBot () DBot::DBot ()
: DThinker(STAT_BOT)
{ {
Clear (); Clear ();
} }

View file

@ -166,6 +166,7 @@ class DBot : public DThinker
DECLARE_CLASS(DBot,DThinker) DECLARE_CLASS(DBot,DThinker)
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
public: public:
static const int DEFAULT_STAT = STAT_BOT;
DBot (); DBot ();
void Clear (); void Clear ();

View file

@ -405,7 +405,7 @@ bool FCajunMaster::DoAddBot (uint8_t *info, botskill_t skill)
D_ReadUserInfoStrings (bnum, &info, false); D_ReadUserInfoStrings (bnum, &info, false);
multiplayer = true; //Prevents cheating and so on; emulates real netgame (almost). multiplayer = true; //Prevents cheating and so on; emulates real netgame (almost).
players[bnum].Bot = Create<DBot>(); players[bnum].Bot = level.CreateThinker<DBot>();
players[bnum].Bot->player = &players[bnum]; players[bnum].Bot->player = &players[bnum];
players[bnum].Bot->skill = skill; players[bnum].Bot->skill = skill;
playeringame[bnum] = true; playeringame[bnum] = true;

View file

@ -54,6 +54,7 @@
#include "serializer.h" #include "serializer.h"
#include "menu/menu.h" #include "menu/menu.h"
#include "vm.h" #include "vm.h"
#include "g_levellocals.h"
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
@ -656,7 +657,7 @@ void C_DoCommand (const char *cmd, int keynum)
} }
else else
{ {
Create<DStoredCommand> (com, beg); currentUILevel->CreateThinker<DStoredCommand> (com, beg);
} }
} }
} }
@ -752,7 +753,7 @@ void AddCommandString (char *cmd, int keynum)
// Note that deferred commands lose track of which key // Note that deferred commands lose track of which key
// (if any) they were pressed from. // (if any) they were pressed from.
*brkpt = ';'; *brkpt = ';';
Create<DWaitingCommand> (brkpt, tics, UnsafeExecutionContext); currentUILevel->CreateThinker<DWaitingCommand> (brkpt, tics, UnsafeExecutionContext);
} }
return; return;
} }

View file

@ -109,11 +109,12 @@ struct DDecalThinker : public DThinker
DECLARE_CLASS (DDecalThinker, DThinker) DECLARE_CLASS (DDecalThinker, DThinker)
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
public: public:
DDecalThinker (DBaseDecal *decal) : DThinker (STAT_DECALTHINKER), TheDecal (decal) {} static const int DEFAULT_STAT = STAT_DECALTHINKER;
DDecalThinker (DBaseDecal *decal) : TheDecal (decal) {}
void Serialize(FSerializer &arc); void Serialize(FSerializer &arc);
TObjPtr<DBaseDecal*> TheDecal; TObjPtr<DBaseDecal*> TheDecal;
protected: protected:
DDecalThinker () : DThinker (STAT_DECALTHINKER) {} DDecalThinker() = default;
}; };
IMPLEMENT_CLASS(DDecalThinker, false, true) IMPLEMENT_CLASS(DDecalThinker, false, true)
@ -1201,9 +1202,10 @@ void DDecalFader::Tick ()
DThinker *FDecalFaderAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const DThinker *FDecalFaderAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const
{ {
DDecalFader *fader = Create<DDecalFader> (actor); auto Level = actor->Level;
DDecalFader *fader = Level->CreateThinker<DDecalFader> (actor);
fader->TimeToStartDecay = level.maptime + DecayStart; fader->TimeToStartDecay = Level->maptime + DecayStart;
fader->TimeToEndDecay = fader->TimeToStartDecay + DecayTime; fader->TimeToEndDecay = fader->TimeToStartDecay + DecayTime;
fader->StartTrans = -1; fader->StartTrans = -1;
return fader; return fader;
@ -1227,9 +1229,10 @@ void DDecalStretcher::Serialize(FSerializer &arc)
DThinker *FDecalStretcherAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const DThinker *FDecalStretcherAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const
{ {
DDecalStretcher *thinker = Create<DDecalStretcher> (actor); auto Level = actor->Level;
DDecalStretcher *thinker = Level->CreateThinker<DDecalStretcher> (actor);
thinker->TimeToStart = level.maptime + StretchStart; thinker->TimeToStart = Level->maptime + StretchStart;
thinker->TimeToStop = thinker->TimeToStart + StretchTime; thinker->TimeToStop = thinker->TimeToStart + StretchTime;
if (GoalX >= 0) if (GoalX >= 0)
@ -1313,9 +1316,10 @@ void DDecalSlider::Serialize(FSerializer &arc)
DThinker *FDecalSliderAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const DThinker *FDecalSliderAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const
{ {
DDecalSlider *thinker = Create<DDecalSlider> (actor); auto Level = actor->Level;
DDecalSlider *thinker = Level->CreateThinker<DDecalSlider> (actor);
thinker->TimeToStart = level.maptime + SlideStart; thinker->TimeToStart = Level->maptime + SlideStart;
thinker->TimeToStop = thinker->TimeToStart + SlideTime; thinker->TimeToStop = thinker->TimeToStart + SlideTime;
/*thinker->DistX = DistX;*/ /*thinker->DistX = DistX;*/
thinker->DistY = DistY; thinker->DistY = DistY;
@ -1432,9 +1436,10 @@ void DDecalColorer::Tick ()
DThinker *FDecalColorerAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const DThinker *FDecalColorerAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const
{ {
DDecalColorer *Colorer = Create<DDecalColorer>(actor); auto Level = actor->Level;
DDecalColorer *Colorer = Level->CreateThinker<DDecalColorer>(actor);
Colorer->TimeToStartDecay = level.maptime + DecayStart; Colorer->TimeToStartDecay = Level->maptime + DecayStart;
Colorer->TimeToEndDecay = Colorer->TimeToStartDecay + DecayTime; Colorer->TimeToEndDecay = Colorer->TimeToStartDecay + DecayTime;
Colorer->StartColor = 0xff000000; Colorer->StartColor = 0xff000000;
Colorer->GoalColor = GoalColor; Colorer->GoalColor = GoalColor;

View file

@ -36,12 +36,6 @@
IMPLEMENT_CLASS(DSectorEffect, false, false) IMPLEMENT_CLASS(DSectorEffect, false, false)
DSectorEffect::DSectorEffect ()
: DThinker(STAT_SECTOREFFECT)
{
m_Sector = nullptr;
}
void DSectorEffect::OnDestroy() void DSectorEffect::OnDestroy()
{ {
if (m_Sector) if (m_Sector)
@ -63,7 +57,6 @@ void DSectorEffect::OnDestroy()
} }
DSectorEffect::DSectorEffect (sector_t *sector) DSectorEffect::DSectorEffect (sector_t *sector)
: DThinker(STAT_SECTOREFFECT)
{ {
m_Sector = sector; m_Sector = sector;
} }

View file

@ -8,6 +8,7 @@ class DSectorEffect : public DThinker
{ {
DECLARE_CLASS (DSectorEffect, DThinker) DECLARE_CLASS (DSectorEffect, DThinker)
public: public:
static const int DEFAULT_STAT = STAT_SECTOREFFECT;
DSectorEffect (sector_t *sector); DSectorEffect (sector_t *sector);
@ -19,7 +20,7 @@ public:
sector_t *m_Sector; sector_t *m_Sector;
protected: protected:
DSectorEffect(); DSectorEffect() = default;
}; };

View file

@ -70,8 +70,8 @@ void FThinkerList::AddTail(DThinker *thinker)
assert(!(thinker->ObjectFlags & OF_EuthanizeMe)); assert(!(thinker->ObjectFlags & OF_EuthanizeMe));
if (Sentinel == NULL) if (Sentinel == NULL)
{ {
Sentinel = Create<DThinker>(DThinker::NO_LINK); Sentinel = Create<DThinker>();
Sentinel->ObjectFlags |= OF_Sentinel; Sentinel->ObjectFlags = OF_Sentinel;
Sentinel->NextThinker = Sentinel; Sentinel->NextThinker = Sentinel;
Sentinel->PrevThinker = Sentinel; Sentinel->PrevThinker = Sentinel;
GC::WriteBarrier(Sentinel); GC::WriteBarrier(Sentinel);
@ -232,21 +232,10 @@ void DThinker::SerializeThinkers(FSerializer &arc, bool hubLoad)
// //
//========================================================================== //==========================================================================
DThinker::DThinker (int statnum) throw() DThinker::DThinker () throw()
{ {
NextThinker = NULL; NextThinker = nullptr;
PrevThinker = NULL; PrevThinker = nullptr;
if (bSerialOverride)
{ // The serializer will insert us into the right list
return;
}
ObjectFlags |= OF_JustSpawned;
if ((unsigned)statnum > MAX_STATNUM)
{
statnum = MAX_STATNUM;
}
FreshThinkers[statnum].AddTail (this);
} }
DThinker::DThinker(no_link_type foo) throw() DThinker::DThinker(no_link_type foo) throw()
@ -270,6 +259,12 @@ void DThinker::OnDestroy ()
Super::OnDestroy(); Super::OnDestroy();
} }
void DThinker::Serialize(FSerializer &arc)
{
Super::Serialize(arc);
arc("level", Level);
}
//========================================================================== //==========================================================================
// //
// //

View file

@ -44,6 +44,7 @@ struct pspdef_s;
struct FState; struct FState;
class DThinker; class DThinker;
class FSerializer; class FSerializer;
struct FLevelLocals;
class FThinkerIterator; class FThinkerIterator;
@ -65,7 +66,8 @@ class DThinker : public DObject
{ {
DECLARE_CLASS (DThinker, DObject) DECLARE_CLASS (DThinker, DObject)
public: public:
DThinker (int statnum = STAT_DEFAULT) throw(); static const int DEFAULT_STAT = STAT_DEFAULT;
DThinker () throw();
void OnDestroy () override; void OnDestroy () override;
virtual ~DThinker (); virtual ~DThinker ();
virtual void Tick (); virtual void Tick ();
@ -73,6 +75,7 @@ public:
virtual void PostBeginPlay (); // Called just before the first tick virtual void PostBeginPlay (); // Called just before the first tick
virtual void CallPostBeginPlay(); // different in actor. virtual void CallPostBeginPlay(); // different in actor.
virtual void PostSerialize(); virtual void PostSerialize();
void Serialize(FSerializer &arc) override;
size_t PropagateMark(); size_t PropagateMark();
void ChangeStatNum (int statnum); void ChangeStatNum (int statnum);
@ -111,6 +114,11 @@ private:
friend class FSerializer; friend class FSerializer;
DThinker *NextThinker, *PrevThinker; DThinker *NextThinker, *PrevThinker;
public:
FLevelLocals *Level;
friend struct FLevelLocals; // Needs access to FreshThinkers until the thinker storage gets refactored.
}; };
class FThinkerIterator class FThinkerIterator

View file

@ -1835,7 +1835,7 @@ void FParser::SF_FadeLight(void)
auto it = Level->GetSectorTagIterator(sectag); auto it = Level->GetSectorTagIterator(sectag);
while ((i = it.Next()) >= 0) while ((i = it.Next()) >= 0)
{ {
if (!Level->sectors[i].lightingdata) Create<DLightLevel>(&Level->sectors[i],destlevel,speed); if (!Level->sectors[i].lightingdata) Level->CreateThinker<DLightLevel>(&Level->sectors[i],destlevel,speed);
} }
} }
} }

View file

@ -262,7 +262,7 @@ bool FScriptLoader::ParseInfo(MapData * map)
I_Error("Only one FraggleThinker is allowed to exist at a time.\nCheck your code."); I_Error("Only one FraggleThinker is allowed to exist at a time.\nCheck your code.");
} }
auto th = Create<DFraggleThinker>(); auto th = Level->CreateThinker<DFraggleThinker>();
th->LevelScript->data = copystring(scriptsrc.GetChars()); th->LevelScript->data = copystring(scriptsrc.GetChars());
Level->FraggleScriptThinker = th; Level->FraggleScriptThinker = th;

View file

@ -366,7 +366,6 @@ IMPLEMENT_POINTERS_END
//========================================================================== //==========================================================================
DFraggleThinker::DFraggleThinker() DFraggleThinker::DFraggleThinker()
: DThinker(STAT_SCRIPTS)
{ {
GlobalScript = Create<DFsScript>(); GlobalScript = Create<DFsScript>();
GC::WriteBarrier(this, GlobalScript); GC::WriteBarrier(this, GlobalScript);

View file

@ -688,7 +688,7 @@ class DFraggleThinker : public DThinker
DECLARE_CLASS(DFraggleThinker, DThinker) DECLARE_CLASS(DFraggleThinker, DThinker)
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
public: public:
static const int DEFAULT_STAT = STAT_SCRIPTS;
int zoom = 1; int zoom = 1;
AActor *trigger_obj; // this is a transient pointer not being subjected to GC. AActor *trigger_obj; // this is a transient pointer not being subjected to GC.
TObjPtr<DFsScript*> GlobalScript; TObjPtr<DFsScript*> GlobalScript;

View file

@ -1119,7 +1119,7 @@ void G_DoLoadLevel (int position, bool autosave, bool newGame)
// [RH] Always save the game when entering a new level. // [RH] Always save the game when entering a new level.
if (autosave && !savegamerestore && disableautosave < 1) if (autosave && !savegamerestore && disableautosave < 1)
{ {
DAutosaver GCCNOWARN *dummy = Create<DAutosaver>(); level.CreateThinker<DAutosaver>();
} }
if (pnumerr > 0) if (pnumerr > 0)
{ {

View file

@ -202,6 +202,7 @@ public:
void ActivateInStasisCeiling(int tag); void ActivateInStasisCeiling(int tag);
bool CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line, double speed, double height, int crush, int change, bool hexencrush, bool hereticlower); bool CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line, double speed, double height, int crush, int change, bool hexencrush, bool hereticlower);
void DoDeferedScripts(); void DoDeferedScripts();
void AdjustPusher(int tag, int magnitude, int angle, bool wind);
bool EV_DoPlat(int tag, line_t *line, DPlat::EPlatType type, double height, double speed, int delay, int lip, int change); bool EV_DoPlat(int tag, line_t *line, DPlat::EPlatType type, double height, double speed, int delay, int lip, int change);
void EV_StopPlat(int tag, bool remove); void EV_StopPlat(int tag, bool remove);
@ -352,6 +353,27 @@ public:
return true; return true;
} }
template<typename T, typename... Args>
T* CreateThinker(Args&&... args)
{
auto thinker = Create<T>(std::forward<Args>(args)...);
auto statnum = T::DEFAULT_STAT;
thinker->ObjectFlags |= OF_JustSpawned;
DThinker::FreshThinkers[statnum].AddTail(thinker);
thinker->Level = this;
return thinker;
}
DThinker *CreateThinker(PClass *cls, int statnum = STAT_DEFAULT)
{
DThinker *thinker = static_cast<DThinker*>(cls->CreateNew());
assert(thinker->IsKindOf(RUNTIME_CLASS(DThinker)));
thinker->ObjectFlags |= OF_JustSpawned;
DThinker::FreshThinkers[statnum].AddTail(thinker);
thinker->Level = this;
return thinker;
}
uint8_t md5[16]; // for savegame validation. If the MD5 does not match the savegame won't be loaded. uint8_t md5[16]; // for savegame validation. If the MD5 does not match the savegame won't be loaded.
int time; // time in the hub int time; // time in the hub
@ -378,7 +400,7 @@ public:
static const int BODYQUESIZE = 32; static const int BODYQUESIZE = 32;
TObjPtr<AActor*> bodyque[BODYQUESIZE]; TObjPtr<AActor*> bodyque[BODYQUESIZE];
TObjPtr<DAutomapBase*> automap; TObjPtr<DAutomapBase*> automap = nullptr;
int bodyqueslot; int bodyqueslot;
int NumMapSections; int NumMapSections;

View file

@ -67,27 +67,8 @@ IMPLEMENT_POINTERS_END
IMPLEMENT_CLASS(DImpactDecal, false, false) IMPLEMENT_CLASS(DImpactDecal, false, false)
DBaseDecal::DBaseDecal ()
: DThinker(STAT_DECAL),
WallNext(0), WallPrev(0), LeftDistance(0), Z(0), ScaleX(1.), ScaleY(1.), Alpha(1.),
AlphaColor(0), Translation(0), RenderFlags(0)
{
RenderStyle = STYLE_None;
PicNum.SetInvalid();
}
DBaseDecal::DBaseDecal (double z) DBaseDecal::DBaseDecal (double z)
: DThinker(STAT_DECAL), : WallNext(0), WallPrev(0), LeftDistance(0), Z(z), ScaleX(1.), ScaleY(1.), Alpha(1.),
WallNext(0), WallPrev(0), LeftDistance(0), Z(z), ScaleX(1.), ScaleY(1.), Alpha(1.),
AlphaColor(0), Translation(0), RenderFlags(0), Side(nullptr), Sector(nullptr)
{
RenderStyle = STYLE_None;
PicNum.SetInvalid();
}
DBaseDecal::DBaseDecal (int statnum, double z)
: DThinker(statnum),
WallNext(nullptr), WallPrev(nullptr), LeftDistance(0), Z(z), ScaleX(1.), ScaleY(1.), Alpha(1.),
AlphaColor(0), Translation(0), RenderFlags(0), Side(nullptr), Sector(nullptr) AlphaColor(0), Translation(0), RenderFlags(0), Side(nullptr), Sector(nullptr)
{ {
RenderStyle = STYLE_None; RenderStyle = STYLE_None;
@ -95,16 +76,14 @@ DBaseDecal::DBaseDecal (int statnum, double z)
} }
DBaseDecal::DBaseDecal (const AActor *basis) DBaseDecal::DBaseDecal (const AActor *basis)
: DThinker(STAT_DECAL), : WallNext(nullptr), WallPrev(nullptr), LeftDistance(0), Z(basis->Z()), ScaleX(basis->Scale.X), ScaleY(basis->Scale.Y),
WallNext(nullptr), WallPrev(nullptr), LeftDistance(0), Z(basis->Z()), ScaleX(basis->Scale.X), ScaleY(basis->Scale.Y),
Alpha(basis->Alpha), AlphaColor(basis->fillcolor), Translation(basis->Translation), PicNum(basis->picnum), Alpha(basis->Alpha), AlphaColor(basis->fillcolor), Translation(basis->Translation), PicNum(basis->picnum),
RenderFlags(basis->renderflags), RenderStyle(basis->RenderStyle), Side(nullptr), Sector(nullptr) RenderFlags(basis->renderflags), RenderStyle(basis->RenderStyle), Side(nullptr), Sector(nullptr)
{ {
} }
DBaseDecal::DBaseDecal (const DBaseDecal *basis) DBaseDecal::DBaseDecal (const DBaseDecal *basis)
: DThinker(STAT_DECAL), : WallNext(nullptr), WallPrev(nullptr), LeftDistance(basis->LeftDistance), Z(basis->Z), ScaleX(basis->ScaleX),
WallNext(nullptr), WallPrev(nullptr), LeftDistance(basis->LeftDistance), Z(basis->Z), ScaleX(basis->ScaleX),
ScaleY(basis->ScaleY), Alpha(basis->Alpha), AlphaColor(basis->AlphaColor), Translation(basis->Translation), ScaleY(basis->ScaleY), Alpha(basis->Alpha), AlphaColor(basis->AlphaColor), Translation(basis->Translation),
PicNum(basis->PicNum), RenderFlags(basis->RenderFlags), RenderStyle(basis->RenderStyle), Side(nullptr), Sector(nullptr) PicNum(basis->PicNum), RenderFlags(basis->RenderFlags), RenderStyle(basis->RenderStyle), Side(nullptr), Sector(nullptr)
{ {
@ -521,7 +500,7 @@ void DBaseDecal::Spread (const FDecalTemplate *tpl, side_t *wall, double x, doub
DBaseDecal *DBaseDecal::CloneSelf (const FDecalTemplate *tpl, double ix, double iy, double iz, side_t *wall, F3DFloor * ffloor) const DBaseDecal *DBaseDecal::CloneSelf (const FDecalTemplate *tpl, double ix, double iy, double iz, side_t *wall, F3DFloor * ffloor) const
{ {
DBaseDecal *decal = Create<DBaseDecal>(iz); DBaseDecal *decal = Level->CreateThinker<DBaseDecal>(iz);
if (decal != NULL) if (decal != NULL)
{ {
if (decal->StickToWall (wall, ix, iy, ffloor).isValid()) if (decal->StickToWall (wall, ix, iy, ffloor).isValid())
@ -559,16 +538,6 @@ CUSTOM_CVAR (Int, cl_maxdecals, 1024, CVAR_ARCHIVE)
} }
} }
DImpactDecal::DImpactDecal ()
: DBaseDecal (STAT_AUTODECAL, 0.)
{
}
DImpactDecal::DImpactDecal (double z)
: DBaseDecal (STAT_AUTODECAL, z)
{
}
void DImpactDecal::CheckMax () void DImpactDecal::CheckMax ()
{ {
if (++level.ImpactDecalCount >= cl_maxdecals) if (++level.ImpactDecalCount >= cl_maxdecals)
@ -582,7 +551,7 @@ void DImpactDecal::CheckMax ()
} }
} }
DImpactDecal *DImpactDecal::StaticCreate (const char *name, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color) DImpactDecal *DImpactDecal::StaticCreate (FLevelLocals *Level, const char *name, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color)
{ {
if (cl_maxdecals > 0) if (cl_maxdecals > 0)
{ {
@ -590,13 +559,13 @@ DImpactDecal *DImpactDecal::StaticCreate (const char *name, const DVector3 &pos,
if (tpl != NULL && (tpl = tpl->GetDecal()) != NULL) if (tpl != NULL && (tpl = tpl->GetDecal()) != NULL)
{ {
return StaticCreate (tpl, pos, wall, ffloor, color); return StaticCreate (Level, tpl, pos, wall, ffloor, color);
} }
} }
return NULL; return NULL;
} }
DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color) DImpactDecal *DImpactDecal::StaticCreate (FLevelLocals *Level, const FDecalTemplate *tpl, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color)
{ {
DImpactDecal *decal = NULL; DImpactDecal *decal = NULL;
if (tpl != NULL && cl_maxdecals > 0 && !(wall->Flags & WALLF_NOAUTODECALS)) if (tpl != NULL && cl_maxdecals > 0 && !(wall->Flags & WALLF_NOAUTODECALS))
@ -610,9 +579,9 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, const DVect
// apply the custom color as well. // apply the custom color as well.
if (tpl->ShadeColor != tpl_low->ShadeColor) lowercolor=0; if (tpl->ShadeColor != tpl_low->ShadeColor) lowercolor=0;
else lowercolor = color; else lowercolor = color;
StaticCreate (tpl_low, pos, wall, ffloor, lowercolor); StaticCreate (Level, tpl_low, pos, wall, ffloor, lowercolor);
} }
decal = Create<DImpactDecal>(pos.Z); decal = Level->CreateThinker<DImpactDecal>(pos.Z);
if (decal == NULL) if (decal == NULL)
{ {
return NULL; return NULL;
@ -648,7 +617,7 @@ DBaseDecal *DImpactDecal::CloneSelf (const FDecalTemplate *tpl, double ix, doubl
return NULL; return NULL;
} }
DImpactDecal *decal = Create<DImpactDecal>(iz); DImpactDecal *decal = Level->CreateThinker<DImpactDecal>(iz);
if (decal != NULL) if (decal != NULL)
{ {
if (decal->StickToWall (wall, ix, iy, ffloor).isValid()) if (decal->StickToWall (wall, ix, iy, ffloor).isValid())
@ -709,12 +678,12 @@ void SprayDecal(AActor *shooter, const char *name, double distance)
{ {
if (trace.HitType == TRACE_HitWall) if (trace.HitType == TRACE_HitWall)
{ {
DImpactDecal::StaticCreate(name, trace.HitPos, trace.Line->sidedef[trace.Side], NULL); DImpactDecal::StaticCreate(shooter->Level, name, trace.HitPos, trace.Line->sidedef[trace.Side], NULL);
} }
} }
} }
DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *sec, double x, double y, double z, DAngle angle, double tracedist, bool permanent) DBaseDecal *ShootDecal(FLevelLocals *Level, const FDecalTemplate *tpl, sector_t *sec, double x, double y, double z, DAngle angle, double tracedist, bool permanent)
{ {
if (tpl == NULL || (tpl = tpl->GetDecal()) == NULL) if (tpl == NULL || (tpl = tpl->GetDecal()) == NULL)
{ {
@ -731,7 +700,7 @@ DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *
{ {
if (permanent) if (permanent)
{ {
decal = Create<DBaseDecal>(trace.HitPos.Z); decal = Level->CreateThinker<DBaseDecal>(trace.HitPos.Z);
wall = trace.Line->sidedef[trace.Side]; wall = trace.Line->sidedef[trace.Side];
decal->StickToWall(wall, trace.HitPos.X, trace.HitPos.Y, trace.ffloor); decal->StickToWall(wall, trace.HitPos.X, trace.HitPos.Y, trace.ffloor);
tpl->ApplyToDecal(decal, wall); tpl->ApplyToDecal(decal, wall);
@ -744,7 +713,7 @@ DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *
} }
else else
{ {
return DImpactDecal::StaticCreate(tpl, trace.HitPos, trace.Line->sidedef[trace.Side], NULL); return DImpactDecal::StaticCreate(Level, tpl, trace.HitPos, trace.Line->sidedef[trace.Side], NULL);
} }
} }
return NULL; return NULL;
@ -779,7 +748,7 @@ DEFINE_ACTION_FUNCTION(ADecal, SpawnDecal)
// Look for a wall within 64 units behind the actor. If none can be // Look for a wall within 64 units behind the actor. If none can be
// found, then no decal is created, and this actor is destroyed // found, then no decal is created, and this actor is destroyed
// without effectively doing anything. // without effectively doing anything.
if (NULL == ShootDecal(tpl, self, self->Sector, self->X(), self->Y(), self->Z(), self->Angles.Yaw + 180, 64., true)) if (!ShootDecal(self->Level, tpl, self->Sector, self->X(), self->Y(), self->Z(), self->Angles.Yaw + 180, 64., true))
{ {
DPrintf (DMSG_WARNING, "Could not find a wall to stick decal to at (%f,%f)\n", self->X(), self->Y()); DPrintf (DMSG_WARNING, "Could not find a wall to stick decal to at (%f,%f)\n", self->X(), self->Y());
} }

View file

@ -42,7 +42,6 @@ static FRandom pr_lightning ("Lightning");
IMPLEMENT_CLASS(DLightningThinker, false, false) IMPLEMENT_CLASS(DLightningThinker, false, false)
DLightningThinker::DLightningThinker () DLightningThinker::DLightningThinker ()
: DThinker (STAT_LIGHTNING)
{ {
Stopped = false; Stopped = false;
LightningFlashCount = 0; LightningFlashCount = 0;
@ -232,20 +231,20 @@ void P_StartLightning ()
} }
DLightningThinker *lightning = LocateLightning (); DLightningThinker *lightning = LocateLightning ();
if (lightning == NULL) if (lightning == nullptr)
{ {
Create<DLightningThinker>(); level.CreateThinker<DLightningThinker>();
} }
} }
void P_ForceLightning (int mode) void P_ForceLightning (int mode)
{ {
DLightningThinker *lightning = LocateLightning (); DLightningThinker *lightning = LocateLightning ();
if (lightning == NULL) if (lightning == nullptr)
{ {
lightning = Create<DLightningThinker>(); lightning = level.CreateThinker<DLightningThinker>();
} }
if (lightning != NULL) if (lightning != nullptr)
{ {
lightning->ForceLightning (mode); lightning->ForceLightning (mode);
} }

View file

@ -11,6 +11,7 @@ class DLightningThinker : public DThinker
{ {
DECLARE_CLASS (DLightningThinker, DThinker); DECLARE_CLASS (DLightningThinker, DThinker);
public: public:
static const int DEFAULT_STAT = STAT_LIGHTNING;
DLightningThinker (); DLightningThinker ();
~DLightningThinker (); ~DLightningThinker ();
void Serialize(FSerializer &arc); void Serialize(FSerializer &arc);

View file

@ -41,17 +41,6 @@ IMPLEMENT_POINTERS_START(DEarthquake)
IMPLEMENT_POINTER(m_Spot) IMPLEMENT_POINTER(m_Spot)
IMPLEMENT_POINTERS_END IMPLEMENT_POINTERS_END
//==========================================================================
//
// DEarthquake :: DEarthquake private constructor
//
//==========================================================================
DEarthquake::DEarthquake()
: DThinker(STAT_EARTHQUAKE)
{
}
//========================================================================== //==========================================================================
// //
// DEarthquake :: DEarthquake public constructor // DEarthquake :: DEarthquake public constructor
@ -62,7 +51,6 @@ DEarthquake::DEarthquake(AActor *center, int intensityX, int intensityY, int int
int damrad, int tremrad, FSoundID quakesound, int flags, int damrad, int tremrad, FSoundID quakesound, int flags,
double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint, double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint,
double rollIntensity, double rollWave) double rollIntensity, double rollWave)
: DThinker(STAT_EARTHQUAKE)
{ {
m_QuakeSFX = quakesound; m_QuakeSFX = quakesound;
m_Spot = center; m_Spot = center;
@ -395,7 +383,7 @@ bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY,
{ {
if (activator != NULL) if (activator != NULL)
{ {
Create<DEarthquake>(activator, intensityX, intensityY, intensityZ, duration, damrad, tremrad, level.CreateThinker<DEarthquake>(activator, intensityX, intensityY, intensityZ, duration, damrad, tremrad,
quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ, falloff, highpoint, rollIntensity, rollWave); quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ, falloff, highpoint, rollIntensity, rollWave);
return true; return true;
} }
@ -406,7 +394,7 @@ bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY,
while ( (center = iterator.Next ()) ) while ( (center = iterator.Next ()) )
{ {
res = true; res = true;
Create<DEarthquake>(center, intensityX, intensityY, intensityZ, duration, damrad, tremrad, level.CreateThinker<DEarthquake>(center, intensityX, intensityY, intensityZ, duration, damrad, tremrad,
quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ, falloff, highpoint, rollIntensity, rollWave); quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ, falloff, highpoint, rollIntensity, rollWave);
} }
} }

View file

@ -11,7 +11,7 @@ struct F3DFloor;
class DBaseDecal; class DBaseDecal;
struct SpreadInfo; struct SpreadInfo;
class DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *sec, double x, double y, double z, DAngle angle, double tracedist, bool permanent); DBaseDecal *ShootDecal(FLevelLocals *Level, const FDecalTemplate *tpl, sector_t *sec, double x, double y, double z, DAngle angle, double tracedist, bool permanent);
void SprayDecal(AActor *shooter, const char *name,double distance = 172.); void SprayDecal(AActor *shooter, const char *name,double distance = 172.);
class DBaseDecal : public DThinker class DBaseDecal : public DThinker
@ -19,9 +19,8 @@ class DBaseDecal : public DThinker
DECLARE_CLASS (DBaseDecal, DThinker) DECLARE_CLASS (DBaseDecal, DThinker)
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
public: public:
DBaseDecal (); static const int DEFAULT_STAT = STAT_DECAL;
DBaseDecal(double z); DBaseDecal(double z = 0);
DBaseDecal(int statnum, double z);
DBaseDecal (const AActor *actor); DBaseDecal (const AActor *actor);
DBaseDecal (const DBaseDecal *basis); DBaseDecal (const DBaseDecal *basis);
@ -61,20 +60,18 @@ class DImpactDecal : public DBaseDecal
{ {
DECLARE_CLASS (DImpactDecal, DBaseDecal) DECLARE_CLASS (DImpactDecal, DBaseDecal)
public: public:
DImpactDecal(double z); static const int DEFAULT_STAT = STAT_AUTODECAL;
DImpactDecal(double z = 0) : DBaseDecal(z) {}
DImpactDecal (side_t *wall, const FDecalTemplate *templ); DImpactDecal (side_t *wall, const FDecalTemplate *templ);
static DImpactDecal *StaticCreate(const char *name, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color = 0); static DImpactDecal *StaticCreate(FLevelLocals *Level, const char *name, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color = 0);
static DImpactDecal *StaticCreate(const FDecalTemplate *tpl, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color = 0); static DImpactDecal *StaticCreate(FLevelLocals *Level, const FDecalTemplate *tpl, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color = 0);
void BeginPlay (); void BeginPlay ();
protected: protected:
DBaseDecal *CloneSelf(const FDecalTemplate *tpl, double x, double y, double z, side_t *wall, F3DFloor * ffloor) const; DBaseDecal *CloneSelf(const FDecalTemplate *tpl, double x, double y, double z, side_t *wall, F3DFloor * ffloor) const;
void CheckMax (); void CheckMax ();
private:
DImpactDecal();
}; };
class DFlashFader : public DThinker class DFlashFader : public DThinker
@ -126,6 +123,7 @@ class DEarthquake : public DThinker
DECLARE_CLASS (DEarthquake, DThinker) DECLARE_CLASS (DEarthquake, DThinker)
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
public: public:
static const int DEFAULT_STAT = STAT_EARTHQUAKE;
DEarthquake(AActor *center, int intensityX, int intensityY, int intensityZ, int duration, DEarthquake(AActor *center, int intensityX, int intensityY, int intensityZ, int duration,
int damrad, int tremrad, FSoundID quakesfx, int flags, int damrad, int tremrad, FSoundID quakesfx, int flags,
double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint, double rollIntensity, double rollWave); double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint, double rollIntensity, double rollWave);
@ -151,7 +149,7 @@ public:
static int StaticGetQuakeIntensities(double ticFrac, AActor *viewer, FQuakeJiggers &jiggers); static int StaticGetQuakeIntensities(double ticFrac, AActor *viewer, FQuakeJiggers &jiggers);
private: private:
DEarthquake (); DEarthquake() = default;
}; };
#endif //__A_SHAREDGLOBAL_H__ #endif //__A_SHAREDGLOBAL_H__

View file

@ -636,7 +636,7 @@ void cht_Suicide (player_t *plyr)
// the initial tick. // the initial tick.
if (plyr->mo != NULL) if (plyr->mo != NULL)
{ {
DSuicider *suicide = Create<DSuicider>(); DSuicider *suicide = plyr->mo->Level->CreateThinker<DSuicider>();
suicide->Pawn = plyr->mo; suicide->Pawn = plyr->mo;
GC::WriteBarrier(suicide, suicide->Pawn); GC::WriteBarrier(suicide, suicide->Pawn);
} }

View file

@ -514,7 +514,7 @@ void MapLoader::InitSectorSpecial(sector_t *sector, int special)
break; break;
case dSector_DoorCloseIn30: case dSector_DoorCloseIn30:
Create<DDoor>(sector, DDoor::doorWaitClose, 2, 0, 0, 30 * TICRATE); Level->CreateThinker<DDoor>(sector, DDoor::doorWaitClose, 2, 0, 0, 30 * TICRATE);
break; break;
case dDamage_End: case dDamage_End:
@ -522,7 +522,7 @@ void MapLoader::InitSectorSpecial(sector_t *sector, int special)
break; break;
case dSector_DoorRaiseIn5Mins: case dSector_DoorRaiseIn5Mins:
Create<DDoor> (sector, DDoor::doorWaitRaise, 2, TICRATE*30/7, 0, 5*60*TICRATE); Level->CreateThinker<DDoor> (sector, DDoor::doorWaitRaise, 2, TICRATE*30/7, 0, 5*60*TICRATE);
break; break;
case dFriction_Low: case dFriction_Low:
@ -703,19 +703,19 @@ void MapLoader::SpawnSpecials ()
// killough 3/16/98: Add support for setting // killough 3/16/98: Add support for setting
// floor lighting independently (e.g. lava) // floor lighting independently (e.g. lava)
case Transfer_FloorLight: case Transfer_FloorLight:
Create<DLightTransfer> (line.frontsector, line.args[0], true); Level->CreateThinker<DLightTransfer> (line.frontsector, line.args[0], true);
break; break;
// killough 4/11/98: Add support for setting // killough 4/11/98: Add support for setting
// ceiling lighting independently // ceiling lighting independently
case Transfer_CeilingLight: case Transfer_CeilingLight:
Create<DLightTransfer> (line.frontsector, line.args[0], false); Level->CreateThinker<DLightTransfer> (line.frontsector, line.args[0], false);
break; break;
// [Graf Zahl] Add support for setting lighting // [Graf Zahl] Add support for setting lighting
// per wall independently // per wall independently
case Transfer_WallLight: case Transfer_WallLight:
Create<DWallLightTransfer> (line.frontsector, line.args[0], line.args[1]); Level->CreateThinker<DWallLightTransfer> (line.frontsector, line.args[0], line.args[1]);
break; break;
case Sector_Attach3dMidtex: case Sector_Attach3dMidtex:
@ -1029,52 +1029,52 @@ void MapLoader::SpawnLights(sector_t *sector)
switch (sector->special) switch (sector->special)
{ {
case Light_Phased: case Light_Phased:
Create<DPhased>(sector, 48, 63 - (sector->lightlevel & 63)); Level->CreateThinker<DPhased>(sector, 48, 63 - (sector->lightlevel & 63));
break; break;
// [RH] Hexen-like phased lighting // [RH] Hexen-like phased lighting
case LightSequenceStart: case LightSequenceStart:
Create<DPhased>(sector); Level->CreateThinker<DPhased>(sector);
break; break;
case dLight_Flicker: case dLight_Flicker:
Create<DLightFlash>(sector); Level->CreateThinker<DLightFlash>(sector);
break; break;
case dLight_StrobeFast: case dLight_StrobeFast:
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false); Level->CreateThinker<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
break; break;
case dLight_StrobeSlow: case dLight_StrobeSlow:
Create<DStrobe>(sector, STROBEBRIGHT, SLOWDARK, false); Level->CreateThinker<DStrobe>(sector, STROBEBRIGHT, SLOWDARK, false);
break; break;
case dLight_Strobe_Hurt: case dLight_Strobe_Hurt:
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false); Level->CreateThinker<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
break; break;
case dLight_Glow: case dLight_Glow:
Create<DGlow>(sector); Level->CreateThinker<DGlow>(sector);
break; break;
case dLight_StrobeSlowSync: case dLight_StrobeSlowSync:
Create<DStrobe>(sector, STROBEBRIGHT, SLOWDARK, true); Level->CreateThinker<DStrobe>(sector, STROBEBRIGHT, SLOWDARK, true);
break; break;
case dLight_StrobeFastSync: case dLight_StrobeFastSync:
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, true); Level->CreateThinker<DStrobe>(sector, STROBEBRIGHT, FASTDARK, true);
break; break;
case dLight_FireFlicker: case dLight_FireFlicker:
Create<DFireFlicker>(sector); Level->CreateThinker<DFireFlicker>(sector);
break; break;
case dScroll_EastLavaDamage: case dScroll_EastLavaDamage:
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false); Level->CreateThinker<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
break; break;
case sLight_Strobe_Hurt: case sLight_Strobe_Hurt:
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false); Level->CreateThinker<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
break; break;
default: default:
@ -1122,7 +1122,7 @@ void MapLoader::SpawnPushers()
{ {
auto itr = Level->GetSectorTagIterator(l->args[0]); auto itr = Level->GetSectorTagIterator(l->args[0]);
while ((s = itr.Next()) >= 0) while ((s = itr.Next()) >= 0)
Create<DPusher>(DPusher::p_wind, l->args[3] ? l : nullptr, l->args[1], l->args[2], nullptr, s); Level->CreateThinker<DPusher>(DPusher::p_wind, l->args[3] ? l : nullptr, l->args[1], l->args[2], nullptr, s);
l->special = 0; l->special = 0;
break; break;
} }
@ -1131,7 +1131,7 @@ void MapLoader::SpawnPushers()
{ {
auto itr = Level->GetSectorTagIterator(l->args[0]); auto itr = Level->GetSectorTagIterator(l->args[0]);
while ((s = itr.Next()) >= 0) while ((s = itr.Next()) >= 0)
Create<DPusher>(DPusher::p_current, l->args[3] ? l : nullptr, l->args[1], l->args[2], nullptr, s); Level->CreateThinker<DPusher>(DPusher::p_current, l->args[3] ? l : nullptr, l->args[1], l->args[2], nullptr, s);
l->special = 0; l->special = 0;
break; break;
} }
@ -1145,7 +1145,7 @@ void MapLoader::SpawnPushers()
if (thing) { // No MT_P* means no effect if (thing) { // No MT_P* means no effect
// [RH] Allow narrowing it down by tid // [RH] Allow narrowing it down by tid
if (!l->args[1] || l->args[1] == thing->tid) if (!l->args[1] || l->args[1] == thing->tid)
Create<DPusher>(DPusher::p_push, l->args[3] ? l : NULL, l->args[2], Level->CreateThinker<DPusher>(DPusher::p_push, l->args[3] ? l : NULL, l->args[2],
0, thing, s); 0, thing, s);
} }
} }
@ -1159,7 +1159,7 @@ void MapLoader::SpawnPushers()
if (thing->GetClass()->TypeName == NAME_PointPusher || if (thing->GetClass()->TypeName == NAME_PointPusher ||
thing->GetClass()->TypeName == NAME_PointPuller) thing->GetClass()->TypeName == NAME_PointPuller)
{ {
Create<DPusher>(DPusher::p_push, l->args[3] ? l : NULL, l->args[2], 0, thing, thing->Sector->Index()); Level->CreateThinker<DPusher>(DPusher::p_push, l->args[3] ? l : NULL, l->args[2], 0, thing, thing->Sector->Index());
} }
} }
} }
@ -1269,7 +1269,7 @@ void MapLoader::SpawnScrollers()
auto itr = Level->GetSectorTagIterator(l->args[0]); auto itr = Level->GetSectorTagIterator(l->args[0]);
while ((s = itr.Next()) >= 0) while ((s = itr.Next()) >= 0)
{ {
Create<DScroller>(EScroll::sc_ceiling, -dx, dy, control, &Level->sectors[s], nullptr, accel); Level->CreateThinker<DScroller>(EScroll::sc_ceiling, -dx, dy, control, &Level->sectors[s], nullptr, accel);
} }
for (unsigned j = 0; j < copyscrollers.Size(); j++) for (unsigned j = 0; j < copyscrollers.Size(); j++)
{ {
@ -1277,7 +1277,7 @@ void MapLoader::SpawnScrollers()
if (line->args[0] == l->args[0] && (line->args[1] & 1)) if (line->args[0] == l->args[0] && (line->args[1] & 1))
{ {
Create<DScroller>(EScroll::sc_ceiling, -dx, dy, control, line->frontsector, nullptr, accel); Level->CreateThinker<DScroller>(EScroll::sc_ceiling, -dx, dy, control, line->frontsector, nullptr, accel);
} }
} }
break; break;
@ -1289,7 +1289,7 @@ void MapLoader::SpawnScrollers()
auto itr = Level->GetSectorTagIterator(l->args[0]); auto itr = Level->GetSectorTagIterator(l->args[0]);
while ((s = itr.Next()) >= 0) while ((s = itr.Next()) >= 0)
{ {
Create<DScroller>(EScroll::sc_floor, -dx, dy, control, &Level->sectors[s], nullptr, accel); Level->CreateThinker<DScroller>(EScroll::sc_floor, -dx, dy, control, &Level->sectors[s], nullptr, accel);
} }
for (unsigned j = 0; j < copyscrollers.Size(); j++) for (unsigned j = 0; j < copyscrollers.Size(); j++)
{ {
@ -1297,7 +1297,7 @@ void MapLoader::SpawnScrollers()
if (line->args[0] == l->args[0] && (line->args[1] & 2)) if (line->args[0] == l->args[0] && (line->args[1] & 2))
{ {
Create<DScroller>(EScroll::sc_floor, -dx, dy, control, line->frontsector, nullptr, accel); Level->CreateThinker<DScroller>(EScroll::sc_floor, -dx, dy, control, line->frontsector, nullptr, accel);
} }
} }
} }
@ -1307,7 +1307,7 @@ void MapLoader::SpawnScrollers()
auto itr = Level->GetSectorTagIterator(l->args[0]); auto itr = Level->GetSectorTagIterator(l->args[0]);
while ((s = itr.Next()) >= 0) while ((s = itr.Next()) >= 0)
{ {
Create<DScroller>(EScroll::sc_carry, dx, dy, control, &Level->sectors[s], nullptr, accel); Level->CreateThinker<DScroller>(EScroll::sc_carry, dx, dy, control, &Level->sectors[s], nullptr, accel);
} }
for (unsigned j = 0; j < copyscrollers.Size(); j++) for (unsigned j = 0; j < copyscrollers.Size(); j++)
{ {
@ -1315,7 +1315,7 @@ void MapLoader::SpawnScrollers()
if (line->args[0] == l->args[0] && (line->args[1] & 4)) if (line->args[0] == l->args[0] && (line->args[1] & 4))
{ {
Create<DScroller>(EScroll::sc_carry, dx, dy, control, line->frontsector, nullptr, accel); Level->CreateThinker<DScroller>(EScroll::sc_carry, dx, dy, control, line->frontsector, nullptr, accel);
} }
} }
} }
@ -1329,7 +1329,7 @@ void MapLoader::SpawnScrollers()
while ((s = itr.Next()) >= 0) while ((s = itr.Next()) >= 0)
{ {
if (s != (int)i) if (s != (int)i)
Create<DScroller>(dx, dy, &Level->lines[s], control, accel); Level->CreateThinker<DScroller>(dx, dy, &Level->lines[s], control, accel);
} }
break; break;
} }
@ -1337,32 +1337,32 @@ void MapLoader::SpawnScrollers()
case Scroll_Texture_Offsets: case Scroll_Texture_Offsets:
// killough 3/2/98: scroll according to sidedef offsets // killough 3/2/98: scroll according to sidedef offsets
side = Level->lines[i].sidedef[0]; side = Level->lines[i].sidedef[0];
Create<DScroller>(EScroll::sc_side, -side->GetTextureXOffset(side_t::mid), Level->CreateThinker<DScroller>(EScroll::sc_side, -side->GetTextureXOffset(side_t::mid),
side->GetTextureYOffset(side_t::mid), nullptr, nullptr, side, accel, SCROLLTYPE(l->args[0])); side->GetTextureYOffset(side_t::mid), nullptr, nullptr, side, accel, SCROLLTYPE(l->args[0]));
break; break;
case Scroll_Texture_Left: case Scroll_Texture_Left:
l->special = special; // Restore the special, for compat_useblocking's benefit. l->special = special; // Restore the special, for compat_useblocking's benefit.
side = Level->lines[i].sidedef[0]; side = Level->lines[i].sidedef[0];
Create<DScroller>(EScroll::sc_side, l->args[0] / 64., 0, nullptr, nullptr, side, accel, SCROLLTYPE(l->args[1])); Level->CreateThinker<DScroller>(EScroll::sc_side, l->args[0] / 64., 0, nullptr, nullptr, side, accel, SCROLLTYPE(l->args[1]));
break; break;
case Scroll_Texture_Right: case Scroll_Texture_Right:
l->special = special; l->special = special;
side = Level->lines[i].sidedef[0]; side = Level->lines[i].sidedef[0];
Create<DScroller>(EScroll::sc_side, -l->args[0] / 64., 0, nullptr, nullptr, side, accel, SCROLLTYPE(l->args[1])); Level->CreateThinker<DScroller>(EScroll::sc_side, -l->args[0] / 64., 0, nullptr, nullptr, side, accel, SCROLLTYPE(l->args[1]));
break; break;
case Scroll_Texture_Up: case Scroll_Texture_Up:
l->special = special; l->special = special;
side = Level->lines[i].sidedef[0]; side = Level->lines[i].sidedef[0];
Create<DScroller>(EScroll::sc_side, 0, l->args[0] / 64., nullptr, nullptr, side, accel, SCROLLTYPE(l->args[1])); Level->CreateThinker<DScroller>(EScroll::sc_side, 0, l->args[0] / 64., nullptr, nullptr, side, accel, SCROLLTYPE(l->args[1]));
break; break;
case Scroll_Texture_Down: case Scroll_Texture_Down:
l->special = special; l->special = special;
side = Level->lines[i].sidedef[0]; side = Level->lines[i].sidedef[0];
Create<DScroller>(EScroll::sc_side, 0, -l->args[0] / 64., nullptr, nullptr, side, accel, SCROLLTYPE(l->args[1])); Level->CreateThinker<DScroller>(EScroll::sc_side, 0, -l->args[0] / 64., nullptr, nullptr, side, accel, SCROLLTYPE(l->args[1]));
break; break;
case Scroll_Texture_Both: case Scroll_Texture_Both:
@ -1370,7 +1370,7 @@ void MapLoader::SpawnScrollers()
if (l->args[0] == 0) { if (l->args[0] == 0) {
dx = (l->args[1] - l->args[2]) / 64.; dx = (l->args[1] - l->args[2]) / 64.;
dy = (l->args[4] - l->args[3]) / 64.; dy = (l->args[4] - l->args[3]) / 64.;
Create<DScroller>(EScroll::sc_side, dx, dy, nullptr, nullptr, side, accel); Level->CreateThinker<DScroller>(EScroll::sc_side, dx, dy, nullptr, nullptr, side, accel);
} }
break; break;
@ -1385,5 +1385,5 @@ 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)
{ {
Create<DScroller>(type, dx, dy, nullptr, affectee, nullptr, accel, scrollpos); Level->CreateThinker<DScroller>(type, dx, dy, nullptr, affectee, nullptr, accel, scrollpos);
} }

View file

@ -3300,7 +3300,6 @@ IMPLEMENT_POINTERS_START(DACSThinker)
IMPLEMENT_POINTERS_END IMPLEMENT_POINTERS_END
DACSThinker::DACSThinker () DACSThinker::DACSThinker ()
: DThinker(STAT_SCRIPTS)
{ {
Scripts = nullptr; Scripts = nullptr;
LastScript = nullptr; LastScript = nullptr;
@ -3880,7 +3879,7 @@ showme:
fa1 = viewer->BlendA; fa1 = viewer->BlendA;
} }
} }
Create<DFlashFader> (fr1, fg1, fb1, fa1, fr2, fg2, fb2, fa2, ftime, viewer->mo); Level->CreateThinker<DFlashFader> (fr1, fg1, fb1, fa1, fr2, fg2, fb2, fa2, ftime, viewer->mo);
} }
} }
} }
@ -5016,7 +5015,7 @@ static bool DoSpawnDecal(AActor *actor, const FDecalTemplate *tpl, int flags, DA
{ {
angle += actor->Angles.Yaw; angle += actor->Angles.Yaw;
} }
return NULL != ShootDecal(tpl, actor, actor->Sector, actor->X(), actor->Y(), return nullptr != ShootDecal(actor->Level, tpl, actor->Sector, actor->X(), actor->Y(),
actor->Center() - actor->Floorclip + actor->GetBobOffset() + zofs, actor->Center() - actor->Floorclip + actor->GetBobOffset() + zofs,
angle, distance, !!(flags & SDF_PERMANENT)); angle, distance, !!(flags & SDF_PERMANENT));
} }
@ -9471,7 +9470,7 @@ scriptwait:
int secnum = Level->FindFirstSectorFromTag(STACK(8)); int secnum = Level->FindFirstSectorFromTag(STACK(8));
if (secnum >= 0) if (secnum >= 0)
{ {
Create<DPlaneWatcher>(activator, activationline, backSide, pcd == PCD_SETCEILINGTRIGGER, &Level->sectors[secnum], Level->CreateThinker<DPlaneWatcher>(activator, activationline, backSide, pcd == PCD_SETCEILINGTRIGGER, &Level->sectors[secnum],
STACK(7), STACK(6), STACK(5), STACK(4), STACK(3), STACK(2), STACK(1)); STACK(7), STACK(6), STACK(5), STACK(4), STACK(3), STACK(2), STACK(1));
} }
@ -10234,7 +10233,7 @@ DLevelScript::DLevelScript (FLevelLocals *l, AActor *who, line_t *where, int num
{ {
Level = l; Level = l;
if (Level->ACSThinker == nullptr) if (Level->ACSThinker == nullptr)
Level->ACSThinker = Create<DACSThinker>(); Level->ACSThinker = Level->CreateThinker<DACSThinker>();
script = num; script = num;
assert(code->VarCount >= code->ArgCount); assert(code->VarCount >= code->ArgCount);

View file

@ -453,6 +453,7 @@ class DACSThinker : public DThinker
DECLARE_CLASS(DACSThinker, DThinker) DECLARE_CLASS(DACSThinker, DThinker)
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
public: public:
static const int DEFAULT_STAT = STAT_SCRIPTS;
DACSThinker(); DACSThinker();
~DACSThinker(); ~DACSThinker();

View file

@ -1835,7 +1835,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetBlend)
// if (color2.a == 0) // if (color2.a == 0)
// color2 = color; // color2 = color;
Create<DFlashFader>(color.r/255.f, color.g/255.f, color.b/255.f, float(alpha), self->Level->CreateThinker<DFlashFader>(color.r/255.f, color.g/255.f, color.b/255.f, float(alpha),
color2.r/255.f, color2.g/255.f, color2.b/255.f, float(alpha2), color2.r/255.f, color2.g/255.f, color2.b/255.f, float(alpha2),
float(tics)/TICRATE, self, true); float(tics)/TICRATE, self, true);
return 0; return 0;

View file

@ -244,7 +244,7 @@ bool FLevelLocals::CreateCeiling(sector_t *sec, DCeiling::ECeiling type, line_t
} }
// new door thinker // new door thinker
DCeiling *ceiling = Create<DCeiling> (sec, speed, speed2, silent & ~4); DCeiling *ceiling = CreateThinker<DCeiling> (sec, speed, speed2, silent & ~4);
vertex_t *spot = sec->Lines[0]->v1; vertex_t *spot = sec->Lines[0]->v1;
switch (type) switch (type)

View file

@ -480,7 +480,7 @@ bool FLevelLocals::EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
} }
return false; return false;
} }
if (Create<DDoor> (sec, type, speed, delay, lightTag, topcountdown)) if (CreateThinker<DDoor> (sec, type, speed, delay, lightTag, topcountdown))
rtn = true; rtn = true;
} }
else else
@ -494,7 +494,7 @@ bool FLevelLocals::EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
if (sec->PlaneMoving(sector_t::ceiling)) if (sec->PlaneMoving(sector_t::ceiling))
continue; continue;
if (Create<DDoor>(sec, type, speed, delay, lightTag, topcountdown)) if (CreateThinker<DDoor>(sec, type, speed, delay, lightTag, topcountdown))
rtn = true; rtn = true;
} }
@ -773,7 +773,7 @@ bool FLevelLocals::EV_SlidingDoor (line_t *line, AActor *actor, int tag, int spe
FDoorAnimation *anim = TexMan.FindAnimatedDoor (line->sidedef[0]->GetTexture(side_t::top)); FDoorAnimation *anim = TexMan.FindAnimatedDoor (line->sidedef[0]->GetTexture(side_t::top));
if (anim != NULL) if (anim != NULL)
{ {
Create<DAnimatedDoor>(sec, line, speed, delay, anim, type); CreateThinker<DAnimatedDoor>(sec, line, speed, delay, anim, type);
return true; return true;
} }
return false; return false;
@ -798,7 +798,7 @@ bool FLevelLocals::EV_SlidingDoor (line_t *line, AActor *actor, int tag, int spe
if (anim != NULL) if (anim != NULL)
{ {
rtn = true; rtn = true;
Create<DAnimatedDoor>(sec, line, speed, delay, anim, type); CreateThinker<DAnimatedDoor>(sec, line, speed, delay, anim, type);
break; break;
} }
} }

View file

@ -283,7 +283,7 @@ bool FLevelLocals::CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *
// new floor thinker // new floor thinker
rtn = true; rtn = true;
floor = Create<DFloor>(sec); floor = CreateThinker<DFloor>(sec);
floor->m_Type = floortype; floor->m_Type = floortype;
floor->m_Crush = crush; floor->m_Crush = crush;
floor->m_Hexencrush = hexencrush; floor->m_Hexencrush = hexencrush;
@ -631,7 +631,7 @@ bool FLevelLocals::EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, d
// new floor thinker // new floor thinker
rtn = true; rtn = true;
floor = Create<DFloor> (sec); floor = CreateThinker<DFloor> (sec);
floor->m_Direction = (type == DFloor::buildUp) ? 1 : -1; floor->m_Direction = (type == DFloor::buildUp) ? 1 : -1;
stairstep = stairsize * floor->m_Direction; stairstep = stairsize * floor->m_Direction;
floor->m_Type = DFloor::buildStair; //jff 3/31/98 do not leave uninited floor->m_Type = DFloor::buildStair; //jff 3/31/98 do not leave uninited
@ -734,7 +734,7 @@ bool FLevelLocals::EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, d
secnum = newsecnum; secnum = newsecnum;
// create and initialize a thinker for the next step // create and initialize a thinker for the next step
floor = Create<DFloor> (sec); floor = CreateThinker<DFloor> (sec);
floor->StartFloorSound (); floor->StartFloorSound ();
floor->m_Direction = (type == DFloor::buildUp) ? 1 : -1; floor->m_Direction = (type == DFloor::buildUp) ? 1 : -1;
floor->m_FloorDestDist = sec->floorplane.PointToDist (DVector2(0, 0), height); floor->m_FloorDestDist = sec->floorplane.PointToDist (DVector2(0, 0), height);
@ -813,7 +813,7 @@ bool FLevelLocals::EV_DoDonut (int tag, line_t *line, double pillarspeed, double
s3 = ln->backsector; s3 = ln->backsector;
// Spawn rising slime // Spawn rising slime
floor = Create<DFloor> (s2); floor = CreateThinker<DFloor> (s2);
floor->m_Type = DFloor::donutRaise; floor->m_Type = DFloor::donutRaise;
floor->m_Crush = -1; floor->m_Crush = -1;
floor->m_Hexencrush = false; floor->m_Hexencrush = false;
@ -828,7 +828,7 @@ bool FLevelLocals::EV_DoDonut (int tag, line_t *line, double pillarspeed, double
floor->StartFloorSound (); floor->StartFloorSound ();
// Spawn lowering donut-hole // Spawn lowering donut-hole
floor = Create<DFloor> (s1); floor = CreateThinker<DFloor> (s1);
floor->m_Type = DFloor::floorLowerToNearest; floor->m_Type = DFloor::floorLowerToNearest;
floor->m_Crush = -1; floor->m_Crush = -1;
floor->m_Hexencrush = false; floor->m_Hexencrush = false;
@ -1013,7 +1013,7 @@ bool FLevelLocals::EV_DoElevator (line_t *line, DElevator::EElevator elevtype,
// create and initialize new elevator thinker // create and initialize new elevator thinker
rtn = true; rtn = true;
elevator = Create<DElevator> (sec); elevator = CreateThinker<DElevator> (sec);
elevator->m_Type = elevtype; elevator->m_Type = elevtype;
elevator->m_Speed = speed; elevator->m_Speed = speed;
elevator->StartFloorSound (); elevator->StartFloorSound ();
@ -1310,12 +1310,12 @@ bool FLevelLocals::EV_StartWaggle (int tag, line_t *line, int height, int speed,
retCode = true; retCode = true;
if (ceiling) if (ceiling)
{ {
waggle = Create<DCeilingWaggle> (sector); waggle = CreateThinker<DCeilingWaggle> (sector);
waggle->m_OriginalDist = sector->ceilingplane.fD(); waggle->m_OriginalDist = sector->ceilingplane.fD();
} }
else else
{ {
waggle = Create<DFloorWaggle> (sector); waggle = CreateThinker<DFloorWaggle> (sector);
waggle->m_OriginalDist = sector->floorplane.fD(); waggle->m_OriginalDist = sector->floorplane.fD();
} }
waggle->m_Accumulator = offset; waggle->m_Accumulator = offset;

View file

@ -60,7 +60,6 @@ IMPLEMENT_CLASS(DLighting, false, false)
DLighting::DLighting (sector_t *sector) DLighting::DLighting (sector_t *sector)
: DSectorEffect (sector) : DSectorEffect (sector)
{ {
ChangeStatNum (STAT_LIGHT);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -525,7 +524,7 @@ int DPhased::PhaseHelper (sector_t *sector, int index, int light, sector_t *prev
m_BaseLevel = baselevel; m_BaseLevel = baselevel;
} }
else else
l = Create<DPhased> (sector, baselevel); l = Level->CreateThinker<DPhased> (sector, baselevel);
int numsteps = PhaseHelper (sector->NextSpecialSector ( int numsteps = PhaseHelper (sector->NextSpecialSector (
sector->special == LightSequenceSpecial1 ? sector->special == LightSequenceSpecial1 ?
@ -545,17 +544,10 @@ int DPhased::PhaseHelper (sector_t *sector, int index, int light, sector_t *prev
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
DPhased::DPhased (sector_t *sector, int baselevel) void DPhased::Propagate()
: DLighting (sector)
{
m_BaseLevel = baselevel;
}
DPhased::DPhased (sector_t *sector)
: DLighting (sector)
{ {
validcount++; validcount++;
PhaseHelper (sector, 0, 0, NULL); PhaseHelper (m_Sector, 0, 0, nullptr);
} }
DPhased::DPhased (sector_t *sector, int baselevel, int phase) DPhased::DPhased (sector_t *sector, int baselevel, int phase)
@ -577,7 +569,7 @@ void FLevelLocals::EV_StartLightFlickering(int tag, int upper, int lower)
auto it = GetSectorTagIterator(tag); auto it = GetSectorTagIterator(tag);
while ((secnum = it.Next()) >= 0) while ((secnum = it.Next()) >= 0)
{ {
Create<DFlicker>(&sectors[secnum], upper, lower); CreateThinker<DFlicker>(&sectors[secnum], upper, lower);
} }
} }
@ -599,7 +591,7 @@ void FLevelLocals::EV_StartLightStrobing(int tag, int upper, int lower, int utic
if (sec->lightingdata) if (sec->lightingdata)
continue; continue;
Create<DStrobe>(sec, upper, lower, utics, ltics); CreateThinker<DStrobe>(sec, upper, lower, utics, ltics);
} }
} }
@ -613,7 +605,7 @@ void FLevelLocals::EV_StartLightStrobing(int tag, int utics, int ltics)
if (sec->lightingdata) if (sec->lightingdata)
continue; continue;
Create<DStrobe>(sec, utics, ltics, false); CreateThinker<DStrobe>(sec, utics, ltics, false);
} }
} }
@ -783,7 +775,7 @@ void FLevelLocals::EV_StartLightGlowing(int tag, int upper, int lower, int tics)
if (sec->lightingdata) if (sec->lightingdata)
continue; continue;
Create<DGlow2>(sec, upper, lower, tics, false); CreateThinker<DGlow2>(sec, upper, lower, tics, false);
} }
} }
@ -813,7 +805,7 @@ void FLevelLocals::EV_StartLightFading(int tag, int value, int tics)
if (sec->lightlevel == value) if (sec->lightlevel == value)
continue; continue;
Create<DGlow2>(sec, sec->lightlevel, value, tics, true); CreateThinker<DGlow2>(sec, sec->lightlevel, value, tics, true);
} }
} }
} }

View file

@ -2227,7 +2227,6 @@ FUNC(LS_Sector_ChangeFlags)
void AdjustPusher(int tag, int magnitude, int angle, bool wind);
FUNC(LS_Sector_SetWind) FUNC(LS_Sector_SetWind)
// Sector_SetWind (tag, amount, angle) // Sector_SetWind (tag, amount, angle)
@ -2235,7 +2234,7 @@ FUNC(LS_Sector_SetWind)
if (arg3) if (arg3)
return false; return false;
AdjustPusher (arg0, arg1, arg2, true); Level->AdjustPusher (arg0, arg1, arg2, true);
return true; return true;
} }
@ -2245,7 +2244,7 @@ FUNC(LS_Sector_SetCurrent)
if (arg3) if (arg3)
return false; return false;
AdjustPusher (arg0, arg1, arg2, false); Level->AdjustPusher (arg0, arg1, arg2, false);
return true; return true;
} }

View file

@ -4952,7 +4952,7 @@ void P_TraceBleed(int damage, const DVector3 &pos, AActor *actor, DAngle angle,
bloodcolor.a = 1; bloodcolor.a = 1;
} }
DImpactDecal::StaticCreate(bloodType, bleedtrace.HitPos, DImpactDecal::StaticCreate(actor->Level, bloodType, bleedtrace.HitPos,
bleedtrace.Line->sidedef[bleedtrace.Side], bleedtrace.ffloor, bloodcolor); bleedtrace.Line->sidedef[bleedtrace.Side], bleedtrace.ffloor, bloodcolor);
} }
} }
@ -6751,7 +6751,7 @@ void SpawnShootDecal(AActor *t1, const FTraceResults &trace)
} }
if (decalbase != NULL) if (decalbase != NULL)
{ {
DImpactDecal::StaticCreate(decalbase->GetDecal(), DImpactDecal::StaticCreate(t1->Level, decalbase->GetDecal(),
trace.HitPos, trace.Line->sidedef[trace.Side], trace.ffloor); trace.HitPos, trace.Line->sidedef[trace.Side], trace.ffloor);
} }
} }

View file

@ -1415,7 +1415,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target, bool onsky)
} }
} }
DImpactDecal::StaticCreate(base->GetDecal(), linepos, line->sidedef[side], ffloor); DImpactDecal::StaticCreate(mo->Level, base->GetDecal(), linepos, line->sidedef[side], ffloor);
} }
} }
} }
@ -4369,7 +4369,7 @@ AActor *AActor::StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t a
AActor *actor; AActor *actor;
actor = static_cast<AActor *>(const_cast<PClassActor *>(type)->CreateNew ()); actor = static_cast<AActor *>(level.CreateThinker(type));
actor->SpawnTime = level.totaltime; actor->SpawnTime = level.totaltime;
actor->SpawnOrder = level.spawnindex++; actor->SpawnOrder = level.spawnindex++;

View file

@ -234,7 +234,7 @@ bool FLevelLocals::EV_DoPillar (DPillar::EPillar type, line_t *line, int tag,
continue; continue;
rtn = true; rtn = true;
Create<DPillar> (sec, type, speed, height, height2, crush, hexencrush); CreateThinker<DPillar> (sec, type, speed, height, height2, crush, hexencrush);
} }
return rtn; return rtn;
} }

View file

@ -266,7 +266,7 @@ bool FLevelLocals::EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, doub
// Find lowest & highest floors around sector // Find lowest & highest floors around sector
rtn = true; rtn = true;
plat = Create<DPlat> (sec); plat = CreateThinker<DPlat> (sec);
plat->m_Type = type; plat->m_Type = type;
plat->m_Crush = -1; plat->m_Crush = -1;

View file

@ -293,14 +293,14 @@ void DPusher::Tick ()
} }
void AdjustPusher(int tag, int magnitude, int angle, bool wind) void FLevelLocals::AdjustPusher(int tag, int magnitude, int angle, bool wind)
{ {
DPusher::EPusher type = wind ? DPusher::p_wind : DPusher::p_current; DPusher::EPusher type = wind ? DPusher::p_wind : DPusher::p_current;
// Find pushers already attached to the sector, and change their parameters. // Find pushers already attached to the sector, and change their parameters.
TArray<FThinkerCollection> Collection; TArray<FThinkerCollection> Collection;
{ {
TThinkerIterator<DPusher> iterator; auto iterator = GetThinkerIterator<DPusher>();
FThinkerCollection collect; FThinkerCollection collect;
while ((collect.Obj = iterator.Next())) while ((collect.Obj = iterator.Next()))
@ -328,7 +328,7 @@ void AdjustPusher(int tag, int magnitude, int angle, bool wind)
} }
if (i == numcollected) if (i == numcollected)
{ {
Create<DPusher>(type, nullptr, magnitude, angle, nullptr, secnum); CreateThinker<DPusher>(type, nullptr, magnitude, angle, nullptr, secnum);
} }
} }
} }

View file

@ -247,7 +247,6 @@ void DScroller::Tick ()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
DScroller::DScroller (EScroll type, double dx, double dy, sector_t *ctrl, sector_t *sec, side_t *side, int accel, EScrollPos scrollpos) DScroller::DScroller (EScroll type, double dx, double dy, sector_t *ctrl, sector_t *sec, side_t *side, int accel, EScrollPos scrollpos)
: DThinker (STAT_SCROLLER)
{ {
m_Type = type; m_Type = type;
m_dx = dx; m_dx = dx;
@ -329,7 +328,6 @@ void DScroller::OnDestroy ()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
DScroller::DScroller (double dx, double dy, const line_t *l, sector_t * control, int accel, EScrollPos scrollpos) DScroller::DScroller (double dx, double dy, const line_t *l, sector_t * control, int accel, EScrollPos scrollpos)
: DThinker (STAT_SCROLLER)
{ {
double x = fabs(l->Delta().X), y = fabs(l->Delta().Y), d; double x = fabs(l->Delta().X), y = fabs(l->Delta().Y), d;
if (y > x) d = x, x = y, y = d; if (y > x) d = x, x = y, y = d;
@ -432,7 +430,7 @@ void SetWallScroller (FLevelLocals *Level, int id, int sidechoice, double dx, do
{ {
if (Collection.FindEx([=](const DScroller *element) { return element->GetWall() == side; }) == Collection.Size()) if (Collection.FindEx([=](const DScroller *element) { return element->GetWall() == side; }) == Collection.Size())
{ {
Create<DScroller> (EScroll::sc_side, dx, dy, nullptr, nullptr, side, 0, Where); Level->CreateThinker<DScroller> (EScroll::sc_side, dx, dy, nullptr, nullptr, side, 0, Where);
} }
} }
} }
@ -472,6 +470,6 @@ void SetScroller (FLevelLocals *Level, int tag, EScroll type, double dx, double
auto itr = Level->GetSectorTagIterator(tag); auto itr = Level->GetSectorTagIterator(tag);
while ((i = itr.Next()) >= 0) while ((i = itr.Next()) >= 0)
{ {
Create<DScroller> (type, dx, dy, nullptr, &Level->sectors[i], nullptr, 0); Level->CreateThinker<DScroller> (type, dx, dy, nullptr, &Level->sectors[i], nullptr, 0);
} }
} }

View file

@ -333,7 +333,7 @@ void FLevelLocals::ClearLevelData()
AllPlayerStarts.Clear(); AllPlayerStarts.Clear();
memset(playerstarts, 0, sizeof(playerstarts)); memset(playerstarts, 0, sizeof(playerstarts));
Scrolls.Clear(); Scrolls.Clear();
if (automap) automap->Destroy();
} }
//========================================================================== //==========================================================================

View file

@ -718,7 +718,6 @@ DLightTransfer::DLightTransfer (sector_t *srcSec, int target, bool copyFloor)
while ((secnum = itr.Next()) >= 0) while ((secnum = itr.Next()) >= 0)
Level->sectors[secnum].ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING); Level->sectors[secnum].ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING);
} }
ChangeStatNum (STAT_LIGHTTRANSFER);
} }
void DLightTransfer::Tick () void DLightTransfer::Tick ()
@ -796,7 +795,6 @@ DWallLightTransfer::DWallLightTransfer (sector_t *srcSec, int target, uint8_t fl
Level->lines[linenum].sidedef[1]->Flags |= wallflags; Level->lines[linenum].sidedef[1]->Flags |= wallflags;
} }
} }
ChangeStatNum(STAT_LIGHTTRANSFER);
} }
void DWallLightTransfer::Tick () void DWallLightTransfer::Tick ()

View file

@ -125,6 +125,7 @@ class DLighting : public DSectorEffect
{ {
DECLARE_CLASS(DLighting, DSectorEffect) DECLARE_CLASS(DLighting, DSectorEffect)
public: public:
static const int DEFAULT_STAT = STAT_LIGHT;
DLighting(sector_t *sector); DLighting(sector_t *sector);
protected: protected:
DLighting() = default; DLighting() = default;

View file

@ -9,6 +9,7 @@ class DLightTransfer : public DThinker
DLightTransfer() = default; DLightTransfer() = default;
public: public:
static const int DEFAULT_STAT = STAT_LIGHTTRANSFER;
DLightTransfer (sector_t *srcSec, int target, bool copyFloor); DLightTransfer (sector_t *srcSec, int target, bool copyFloor);
void Serialize(FSerializer &arc); void Serialize(FSerializer &arc);
void Tick (); void Tick ();
@ -34,6 +35,7 @@ class DWallLightTransfer : public DThinker
DECLARE_CLASS (DWallLightTransfer, DThinker) DECLARE_CLASS (DWallLightTransfer, DThinker)
DWallLightTransfer() = default; DWallLightTransfer() = default;
public: public:
static const int DEFAULT_STAT = STAT_LIGHTTRANSFER;
DWallLightTransfer (sector_t *srcSec, int target, uint8_t flags); DWallLightTransfer (sector_t *srcSec, int target, uint8_t flags);
void Serialize(FSerializer &arc); void Serialize(FSerializer &arc);
void Tick (); void Tick ();
@ -153,11 +155,10 @@ class DPhased : public DLighting
{ {
DECLARE_CLASS(DPhased, DLighting) DECLARE_CLASS(DPhased, DLighting)
public: public:
DPhased(sector_t *sector); DPhased(sector_t *sector, int baselevel = 0, int phase = 0);
DPhased(sector_t *sector, int baselevel, int phase);
// These are for internal use only but the Create template needs access to them. // These are for internal use only but the Create template needs access to them.
DPhased() = default; DPhased() = default;
DPhased(sector_t *sector, int baselevel); void Propagate();
void Serialize(FSerializer &arc); void Serialize(FSerializer &arc);
void Tick(); void Tick();
@ -218,6 +219,7 @@ class DScroller : public DThinker
DECLARE_CLASS (DScroller, DThinker) DECLARE_CLASS (DScroller, DThinker)
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
public: public:
static const int DEFAULT_STAT = STAT_SCROLLER;
DScroller(EScroll type, double dx, double dy, sector_t *control, sector_t *sec, side_t *side, int accel, EScrollPos scrollpos = EScrollPos::scw_all); DScroller(EScroll type, double dx, double dy, sector_t *control, sector_t *sec, side_t *side, int accel, EScrollPos scrollpos = EScrollPos::scw_all);
DScroller (double dx, double dy, const line_t *l, sector_t *control, int accel, EScrollPos scrollpos = EScrollPos::scw_all); DScroller (double dx, double dy, const line_t *l, sector_t *control, int accel, EScrollPos scrollpos = EScrollPos::scw_all);

View file

@ -98,7 +98,7 @@ static bool P_StartButton (side_t *side, int Where, FSwitchDef *Switch, const DV
} }
} }
Create<DActiveButton> (side, Where, Switch, pos, useagain); level.CreateThinker<DActiveButton> (side, Where, Switch, pos, useagain);
return true; return true;
} }

View file

@ -369,7 +369,7 @@ bool EV_RotatePoly (FLevelLocals *Level, line_t *line, int polyNum, int speed, i
// cannot do rotations on linked polyportals. // cannot do rotations on linked polyportals.
break; break;
} }
pe = Create<DRotatePoly>(poly); pe = Level->CreateThinker<DRotatePoly>(poly);
poly->specialdata = pe; poly->specialdata = pe;
poly->bBlocked = false; poly->bBlocked = false;
if (byteAngle != 0) if (byteAngle != 0)
@ -448,7 +448,7 @@ bool EV_MovePoly (FLevelLocals *Level, line_t *line, int polyNum, double speed,
{ // poly is already in motion { // poly is already in motion
break; break;
} }
pe = Create<DMovePoly>(poly); pe = Level->CreateThinker<DMovePoly>(poly);
poly->specialdata = pe; poly->specialdata = pe;
poly->bBlocked = false; poly->bBlocked = false;
pe->m_Dist = dist; // Distance pe->m_Dist = dist; // Distance
@ -528,7 +528,7 @@ bool EV_MovePolyTo(FLevelLocals *Level, line_t *line, int polyNum, double speed,
{ // poly is already in motion { // poly is already in motion
break; break;
} }
pe = Create<DMovePolyTo>(poly); pe = Level->CreateThinker<DMovePolyTo>(poly);
poly->specialdata = pe; poly->specialdata = pe;
poly->bBlocked = false; poly->bBlocked = false;
pe->m_Dist = distlen; pe->m_Dist = distlen;
@ -681,7 +681,7 @@ bool EV_OpenPolyDoor(FLevelLocals *Level, line_t *line, int polyNum, double spee
break; break;
} }
pd = Create<DPolyDoor>(poly, type); pd = Level->CreateThinker<DPolyDoor>(poly, type);
poly->specialdata = pd; poly->specialdata = pd;
if (type == PODOOR_SLIDE) if (type == PODOOR_SLIDE)
{ {
@ -1223,7 +1223,7 @@ void FPolyObj::LinkPolyobj ()
{ {
link = &Level->PolyBlockMap[j+i]; link = &Level->PolyBlockMap[j+i];
if(!(*link)) if(!(*link))
{ // Create a new link at the current block cell { // CreateThinker a new link at the current block cell
*link = new polyblock_t; *link = new polyblock_t;
(*link)->next = nullptr; (*link)->next = nullptr;
(*link)->prev = nullptr; (*link)->prev = nullptr;

View file

@ -47,6 +47,7 @@
#include "v_text.h" #include "v_text.h"
#include "w_wad.h" #include "w_wad.h"
#include "doomstat.h" #include "doomstat.h"
#include "g_levellocals.h"
extern FRandom pr_exrandom; extern FRandom pr_exrandom;
FMemArena FxAlloc(65536); FMemArena FxAlloc(65536);
@ -5173,18 +5174,21 @@ static DObject *BuiltinNew(PClass *cls, int outerside, int backwardscompatible)
ThrowAbortException(X_OTHER, "Cannot create actors with 'new'"); ThrowAbortException(X_OTHER, "Cannot create actors with 'new'");
return nullptr; return nullptr;
} }
if (vm_warnthinkercreation && cls->IsDescendantOf(NAME_Thinker)) if ((vm_warnthinkercreation || !backwardscompatible) && cls->IsDescendantOf(NAME_Thinker))
{ {
// This must output a diagnostic warning // This must output a diagnostic warning
//ThrowAbortException(X_OTHER, "Cannot create actors with 'new'"); Printf("Using 'new' to create thinkers is deprecated.");
//return nullptr;
} }
// [ZZ] validate readonly and between scope construction // [ZZ] validate readonly and between scope construction
if (outerside) FScopeBarrier::ValidateNew(cls, outerside - 1); if (outerside) FScopeBarrier::ValidateNew(cls, outerside - 1);
auto object = cls->CreateNew(); DObject *object;
if (backwardscompatible && object->IsKindOf(NAME_Thinker)) if (!cls->IsDescendantOf(NAME_Thinker))
{ {
// Todo: Link thinker to current primary level. object = cls->CreateNew();
}
else
{
object = level.CreateThinker(cls);
} }
return object; return object;
} }