- 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)
DBot::DBot ()
: DThinker(STAT_BOT)
{
Clear ();
}

View file

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

View file

@ -405,7 +405,7 @@ bool FCajunMaster::DoAddBot (uint8_t *info, botskill_t skill)
D_ReadUserInfoStrings (bnum, &info, false);
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->skill = skill;
playeringame[bnum] = true;

View file

@ -54,6 +54,7 @@
#include "serializer.h"
#include "menu/menu.h"
#include "vm.h"
#include "g_levellocals.h"
// MACROS ------------------------------------------------------------------
@ -656,7 +657,7 @@ void C_DoCommand (const char *cmd, int keynum)
}
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
// (if any) they were pressed from.
*brkpt = ';';
Create<DWaitingCommand> (brkpt, tics, UnsafeExecutionContext);
currentUILevel->CreateThinker<DWaitingCommand> (brkpt, tics, UnsafeExecutionContext);
}
return;
}

View file

@ -109,11 +109,12 @@ struct DDecalThinker : public DThinker
DECLARE_CLASS (DDecalThinker, DThinker)
HAS_OBJECT_POINTERS
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);
TObjPtr<DBaseDecal*> TheDecal;
protected:
DDecalThinker () : DThinker (STAT_DECALTHINKER) {}
DDecalThinker() = default;
};
IMPLEMENT_CLASS(DDecalThinker, false, true)
@ -1201,9 +1202,10 @@ void DDecalFader::Tick ()
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->StartTrans = -1;
return fader;
@ -1227,9 +1229,10 @@ void DDecalStretcher::Serialize(FSerializer &arc)
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;
if (GoalX >= 0)
@ -1313,9 +1316,10 @@ void DDecalSlider::Serialize(FSerializer &arc)
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->DistX = DistX;*/
thinker->DistY = DistY;
@ -1432,9 +1436,10 @@ void DDecalColorer::Tick ()
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->StartColor = 0xff000000;
Colorer->GoalColor = GoalColor;

View file

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

View file

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

View file

@ -70,8 +70,8 @@ void FThinkerList::AddTail(DThinker *thinker)
assert(!(thinker->ObjectFlags & OF_EuthanizeMe));
if (Sentinel == NULL)
{
Sentinel = Create<DThinker>(DThinker::NO_LINK);
Sentinel->ObjectFlags |= OF_Sentinel;
Sentinel = Create<DThinker>();
Sentinel->ObjectFlags = OF_Sentinel;
Sentinel->NextThinker = Sentinel;
Sentinel->PrevThinker = 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;
PrevThinker = NULL;
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);
NextThinker = nullptr;
PrevThinker = nullptr;
}
DThinker::DThinker(no_link_type foo) throw()
@ -270,6 +259,12 @@ void DThinker::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;
class DThinker;
class FSerializer;
struct FLevelLocals;
class FThinkerIterator;
@ -65,7 +66,8 @@ class DThinker : public DObject
{
DECLARE_CLASS (DThinker, DObject)
public:
DThinker (int statnum = STAT_DEFAULT) throw();
static const int DEFAULT_STAT = STAT_DEFAULT;
DThinker () throw();
void OnDestroy () override;
virtual ~DThinker ();
virtual void Tick ();
@ -73,6 +75,7 @@ public:
virtual void PostBeginPlay (); // Called just before the first tick
virtual void CallPostBeginPlay(); // different in actor.
virtual void PostSerialize();
void Serialize(FSerializer &arc) override;
size_t PropagateMark();
void ChangeStatNum (int statnum);
@ -111,6 +114,11 @@ private:
friend class FSerializer;
DThinker *NextThinker, *PrevThinker;
public:
FLevelLocals *Level;
friend struct FLevelLocals; // Needs access to FreshThinkers until the thinker storage gets refactored.
};
class FThinkerIterator

View file

@ -1835,7 +1835,7 @@ void FParser::SF_FadeLight(void)
auto it = Level->GetSectorTagIterator(sectag);
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.");
}
auto th = Create<DFraggleThinker>();
auto th = Level->CreateThinker<DFraggleThinker>();
th->LevelScript->data = copystring(scriptsrc.GetChars());
Level->FraggleScriptThinker = th;

View file

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

View file

@ -688,7 +688,7 @@ class DFraggleThinker : public DThinker
DECLARE_CLASS(DFraggleThinker, DThinker)
HAS_OBJECT_POINTERS
public:
static const int DEFAULT_STAT = STAT_SCRIPTS;
int zoom = 1;
AActor *trigger_obj; // this is a transient pointer not being subjected to GC.
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.
if (autosave && !savegamerestore && disableautosave < 1)
{
DAutosaver GCCNOWARN *dummy = Create<DAutosaver>();
level.CreateThinker<DAutosaver>();
}
if (pnumerr > 0)
{

View file

@ -202,6 +202,7 @@ public:
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);
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);
void EV_StopPlat(int tag, bool remove);
@ -352,6 +353,27 @@ public:
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.
int time; // time in the hub
@ -378,7 +400,7 @@ public:
static const int BODYQUESIZE = 32;
TObjPtr<AActor*> bodyque[BODYQUESIZE];
TObjPtr<DAutomapBase*> automap;
TObjPtr<DAutomapBase*> automap = nullptr;
int bodyqueslot;
int NumMapSections;

View file

@ -67,44 +67,23 @@ IMPLEMENT_POINTERS_END
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)
: 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)
{
RenderStyle = STYLE_None;
PicNum.SetInvalid();
}
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),
RenderFlags(basis->renderflags), RenderStyle(basis->RenderStyle), Side(nullptr), Sector(nullptr)
{
}
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),
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 *decal = Create<DBaseDecal>(iz);
DBaseDecal *decal = Level->CreateThinker<DBaseDecal>(iz);
if (decal != NULL)
{
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 ()
{
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)
{
@ -590,13 +559,13 @@ DImpactDecal *DImpactDecal::StaticCreate (const char *name, const DVector3 &pos,
if (tpl != NULL && (tpl = tpl->GetDecal()) != NULL)
{
return StaticCreate (tpl, pos, wall, ffloor, color);
return StaticCreate (Level, tpl, pos, wall, ffloor, color);
}
}
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;
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.
if (tpl->ShadeColor != tpl_low->ShadeColor) lowercolor=0;
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)
{
return NULL;
@ -648,7 +617,7 @@ DBaseDecal *DImpactDecal::CloneSelf (const FDecalTemplate *tpl, double ix, doubl
return NULL;
}
DImpactDecal *decal = Create<DImpactDecal>(iz);
DImpactDecal *decal = Level->CreateThinker<DImpactDecal>(iz);
if (decal != NULL)
{
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)
{
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)
{
@ -731,7 +700,7 @@ DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *
{
if (permanent)
{
decal = Create<DBaseDecal>(trace.HitPos.Z);
decal = Level->CreateThinker<DBaseDecal>(trace.HitPos.Z);
wall = trace.Line->sidedef[trace.Side];
decal->StickToWall(wall, trace.HitPos.X, trace.HitPos.Y, trace.ffloor);
tpl->ApplyToDecal(decal, wall);
@ -744,7 +713,7 @@ DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *
}
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;
@ -779,7 +748,7 @@ DEFINE_ACTION_FUNCTION(ADecal, SpawnDecal)
// 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
// 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());
}

View file

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

View file

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

View file

@ -41,17 +41,6 @@ IMPLEMENT_POINTERS_START(DEarthquake)
IMPLEMENT_POINTER(m_Spot)
IMPLEMENT_POINTERS_END
//==========================================================================
//
// DEarthquake :: DEarthquake private constructor
//
//==========================================================================
DEarthquake::DEarthquake()
: DThinker(STAT_EARTHQUAKE)
{
}
//==========================================================================
//
// 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,
double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint,
double rollIntensity, double rollWave)
: DThinker(STAT_EARTHQUAKE)
{
m_QuakeSFX = quakesound;
m_Spot = center;
@ -395,7 +383,7 @@ bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY,
{
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);
return true;
}
@ -406,7 +394,7 @@ bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY,
while ( (center = iterator.Next ()) )
{
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);
}
}

View file

@ -11,7 +11,7 @@ struct F3DFloor;
class DBaseDecal;
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.);
class DBaseDecal : public DThinker
@ -19,9 +19,8 @@ class DBaseDecal : public DThinker
DECLARE_CLASS (DBaseDecal, DThinker)
HAS_OBJECT_POINTERS
public:
DBaseDecal ();
DBaseDecal(double z);
DBaseDecal(int statnum, double z);
static const int DEFAULT_STAT = STAT_DECAL;
DBaseDecal(double z = 0);
DBaseDecal (const AActor *actor);
DBaseDecal (const DBaseDecal *basis);
@ -61,20 +60,18 @@ class DImpactDecal : public DBaseDecal
{
DECLARE_CLASS (DImpactDecal, DBaseDecal)
public:
DImpactDecal(double z);
static const int DEFAULT_STAT = STAT_AUTODECAL;
DImpactDecal(double z = 0) : DBaseDecal(z) {}
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(const FDecalTemplate *tpl, 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(FLevelLocals *Level, const FDecalTemplate *tpl, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color = 0);
void BeginPlay ();
protected:
DBaseDecal *CloneSelf(const FDecalTemplate *tpl, double x, double y, double z, side_t *wall, F3DFloor * ffloor) const;
void CheckMax ();
private:
DImpactDecal();
};
class DFlashFader : public DThinker
@ -126,6 +123,7 @@ class DEarthquake : public DThinker
DECLARE_CLASS (DEarthquake, DThinker)
HAS_OBJECT_POINTERS
public:
static const int DEFAULT_STAT = STAT_EARTHQUAKE;
DEarthquake(AActor *center, int intensityX, int intensityY, int intensityZ, int duration,
int damrad, int tremrad, FSoundID quakesfx, int flags,
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);
private:
DEarthquake ();
DEarthquake() = default;
};
#endif //__A_SHAREDGLOBAL_H__

View file

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

View file

@ -514,7 +514,7 @@ void MapLoader::InitSectorSpecial(sector_t *sector, int special)
break;
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;
case dDamage_End:
@ -522,7 +522,7 @@ void MapLoader::InitSectorSpecial(sector_t *sector, int special)
break;
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;
case dFriction_Low:
@ -703,19 +703,19 @@ void MapLoader::SpawnSpecials ()
// killough 3/16/98: Add support for setting
// floor lighting independently (e.g. lava)
case Transfer_FloorLight:
Create<DLightTransfer> (line.frontsector, line.args[0], true);
Level->CreateThinker<DLightTransfer> (line.frontsector, line.args[0], true);
break;
// killough 4/11/98: Add support for setting
// ceiling lighting independently
case Transfer_CeilingLight:
Create<DLightTransfer> (line.frontsector, line.args[0], false);
Level->CreateThinker<DLightTransfer> (line.frontsector, line.args[0], false);
break;
// [Graf Zahl] Add support for setting lighting
// per wall independently
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;
case Sector_Attach3dMidtex:
@ -1029,52 +1029,52 @@ void MapLoader::SpawnLights(sector_t *sector)
switch (sector->special)
{
case Light_Phased:
Create<DPhased>(sector, 48, 63 - (sector->lightlevel & 63));
Level->CreateThinker<DPhased>(sector, 48, 63 - (sector->lightlevel & 63));
break;
// [RH] Hexen-like phased lighting
case LightSequenceStart:
Create<DPhased>(sector);
Level->CreateThinker<DPhased>(sector);
break;
case dLight_Flicker:
Create<DLightFlash>(sector);
Level->CreateThinker<DLightFlash>(sector);
break;
case dLight_StrobeFast:
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
Level->CreateThinker<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
break;
case dLight_StrobeSlow:
Create<DStrobe>(sector, STROBEBRIGHT, SLOWDARK, false);
Level->CreateThinker<DStrobe>(sector, STROBEBRIGHT, SLOWDARK, false);
break;
case dLight_Strobe_Hurt:
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
Level->CreateThinker<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
break;
case dLight_Glow:
Create<DGlow>(sector);
Level->CreateThinker<DGlow>(sector);
break;
case dLight_StrobeSlowSync:
Create<DStrobe>(sector, STROBEBRIGHT, SLOWDARK, true);
Level->CreateThinker<DStrobe>(sector, STROBEBRIGHT, SLOWDARK, true);
break;
case dLight_StrobeFastSync:
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, true);
Level->CreateThinker<DStrobe>(sector, STROBEBRIGHT, FASTDARK, true);
break;
case dLight_FireFlicker:
Create<DFireFlicker>(sector);
Level->CreateThinker<DFireFlicker>(sector);
break;
case dScroll_EastLavaDamage:
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
Level->CreateThinker<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
break;
case sLight_Strobe_Hurt:
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
Level->CreateThinker<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
break;
default:
@ -1122,7 +1122,7 @@ void MapLoader::SpawnPushers()
{
auto itr = Level->GetSectorTagIterator(l->args[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;
break;
}
@ -1131,7 +1131,7 @@ void MapLoader::SpawnPushers()
{
auto itr = Level->GetSectorTagIterator(l->args[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;
break;
}
@ -1145,7 +1145,7 @@ void MapLoader::SpawnPushers()
if (thing) { // No MT_P* means no effect
// [RH] Allow narrowing it down by 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);
}
}
@ -1159,7 +1159,7 @@ void MapLoader::SpawnPushers()
if (thing->GetClass()->TypeName == NAME_PointPusher ||
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]);
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++)
{
@ -1277,7 +1277,7 @@ void MapLoader::SpawnScrollers()
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;
@ -1289,7 +1289,7 @@ void MapLoader::SpawnScrollers()
auto itr = Level->GetSectorTagIterator(l->args[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++)
{
@ -1297,7 +1297,7 @@ void MapLoader::SpawnScrollers()
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]);
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++)
{
@ -1315,7 +1315,7 @@ void MapLoader::SpawnScrollers()
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)
{
if (s != (int)i)
Create<DScroller>(dx, dy, &Level->lines[s], control, accel);
Level->CreateThinker<DScroller>(dx, dy, &Level->lines[s], control, accel);
}
break;
}
@ -1337,32 +1337,32 @@ void MapLoader::SpawnScrollers()
case Scroll_Texture_Offsets:
// killough 3/2/98: scroll according to sidedef offsets
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]));
break;
case Scroll_Texture_Left:
l->special = special; // Restore the special, for compat_useblocking's benefit.
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;
case Scroll_Texture_Right:
l->special = special;
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;
case Scroll_Texture_Up:
l->special = special;
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;
case Scroll_Texture_Down:
l->special = special;
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;
case Scroll_Texture_Both:
@ -1370,7 +1370,7 @@ void MapLoader::SpawnScrollers()
if (l->args[0] == 0) {
dx = (l->args[1] - l->args[2]) / 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;
@ -1385,5 +1385,5 @@ void MapLoader::SpawnScrollers()
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
DACSThinker::DACSThinker ()
: DThinker(STAT_SCRIPTS)
{
Scripts = nullptr;
LastScript = nullptr;
@ -3880,7 +3879,7 @@ showme:
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;
}
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,
angle, distance, !!(flags & SDF_PERMANENT));
}
@ -9471,7 +9470,7 @@ scriptwait:
int secnum = Level->FindFirstSectorFromTag(STACK(8));
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));
}
@ -10234,7 +10233,7 @@ DLevelScript::DLevelScript (FLevelLocals *l, AActor *who, line_t *where, int num
{
Level = l;
if (Level->ACSThinker == nullptr)
Level->ACSThinker = Create<DACSThinker>();
Level->ACSThinker = Level->CreateThinker<DACSThinker>();
script = num;
assert(code->VarCount >= code->ArgCount);

View file

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

View file

@ -1835,7 +1835,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetBlend)
// if (color2.a == 0)
// 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),
float(tics)/TICRATE, self, true);
return 0;

View file

@ -244,7 +244,7 @@ bool FLevelLocals::CreateCeiling(sector_t *sec, DCeiling::ECeiling type, line_t
}
// 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;
switch (type)

View file

@ -480,7 +480,7 @@ bool FLevelLocals::EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
}
return false;
}
if (Create<DDoor> (sec, type, speed, delay, lightTag, topcountdown))
if (CreateThinker<DDoor> (sec, type, speed, delay, lightTag, topcountdown))
rtn = true;
}
else
@ -494,7 +494,7 @@ bool FLevelLocals::EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
if (sec->PlaneMoving(sector_t::ceiling))
continue;
if (Create<DDoor>(sec, type, speed, delay, lightTag, topcountdown))
if (CreateThinker<DDoor>(sec, type, speed, delay, lightTag, topcountdown))
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));
if (anim != NULL)
{
Create<DAnimatedDoor>(sec, line, speed, delay, anim, type);
CreateThinker<DAnimatedDoor>(sec, line, speed, delay, anim, type);
return true;
}
return false;
@ -798,7 +798,7 @@ bool FLevelLocals::EV_SlidingDoor (line_t *line, AActor *actor, int tag, int spe
if (anim != NULL)
{
rtn = true;
Create<DAnimatedDoor>(sec, line, speed, delay, anim, type);
CreateThinker<DAnimatedDoor>(sec, line, speed, delay, anim, type);
break;
}
}

View file

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

View file

@ -60,7 +60,6 @@ IMPLEMENT_CLASS(DLighting, false, false)
DLighting::DLighting (sector_t *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;
}
else
l = Create<DPhased> (sector, baselevel);
l = Level->CreateThinker<DPhased> (sector, baselevel);
int numsteps = PhaseHelper (sector->NextSpecialSector (
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)
: DLighting (sector)
{
m_BaseLevel = baselevel;
}
DPhased::DPhased (sector_t *sector)
: DLighting (sector)
void DPhased::Propagate()
{
validcount++;
PhaseHelper (sector, 0, 0, NULL);
PhaseHelper (m_Sector, 0, 0, nullptr);
}
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);
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)
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)
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)
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)
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)
// Sector_SetWind (tag, amount, angle)
@ -2235,7 +2234,7 @@ FUNC(LS_Sector_SetWind)
if (arg3)
return false;
AdjustPusher (arg0, arg1, arg2, true);
Level->AdjustPusher (arg0, arg1, arg2, true);
return true;
}
@ -2245,7 +2244,7 @@ FUNC(LS_Sector_SetCurrent)
if (arg3)
return false;
AdjustPusher (arg0, arg1, arg2, false);
Level->AdjustPusher (arg0, arg1, arg2, false);
return true;
}

View file

@ -4952,7 +4952,7 @@ void P_TraceBleed(int damage, const DVector3 &pos, AActor *actor, DAngle angle,
bloodcolor.a = 1;
}
DImpactDecal::StaticCreate(bloodType, bleedtrace.HitPos,
DImpactDecal::StaticCreate(actor->Level, bloodType, bleedtrace.HitPos,
bleedtrace.Line->sidedef[bleedtrace.Side], bleedtrace.ffloor, bloodcolor);
}
}
@ -6751,7 +6751,7 @@ void SpawnShootDecal(AActor *t1, const FTraceResults &trace)
}
if (decalbase != NULL)
{
DImpactDecal::StaticCreate(decalbase->GetDecal(),
DImpactDecal::StaticCreate(t1->Level, decalbase->GetDecal(),
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;
actor = static_cast<AActor *>(const_cast<PClassActor *>(type)->CreateNew ());
actor = static_cast<AActor *>(level.CreateThinker(type));
actor->SpawnTime = level.totaltime;
actor->SpawnOrder = level.spawnindex++;

View file

@ -234,7 +234,7 @@ bool FLevelLocals::EV_DoPillar (DPillar::EPillar type, line_t *line, int tag,
continue;
rtn = true;
Create<DPillar> (sec, type, speed, height, height2, crush, hexencrush);
CreateThinker<DPillar> (sec, type, speed, height, height2, crush, hexencrush);
}
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
rtn = true;
plat = Create<DPlat> (sec);
plat = CreateThinker<DPlat> (sec);
plat->m_Type = type;
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;
// Find pushers already attached to the sector, and change their parameters.
TArray<FThinkerCollection> Collection;
{
TThinkerIterator<DPusher> iterator;
auto iterator = GetThinkerIterator<DPusher>();
FThinkerCollection collect;
while ((collect.Obj = iterator.Next()))
@ -328,7 +328,7 @@ void AdjustPusher(int tag, int magnitude, int angle, bool wind)
}
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)
: DThinker (STAT_SCROLLER)
{
m_Type = type;
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)
: DThinker (STAT_SCROLLER)
{
double x = fabs(l->Delta().X), y = fabs(l->Delta().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())
{
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);
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();
memset(playerstarts, 0, sizeof(playerstarts));
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)
Level->sectors[secnum].ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING);
}
ChangeStatNum (STAT_LIGHTTRANSFER);
}
void DLightTransfer::Tick ()
@ -796,7 +795,6 @@ DWallLightTransfer::DWallLightTransfer (sector_t *srcSec, int target, uint8_t fl
Level->lines[linenum].sidedef[1]->Flags |= wallflags;
}
}
ChangeStatNum(STAT_LIGHTTRANSFER);
}
void DWallLightTransfer::Tick ()

View file

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

View file

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

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;
}

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.
break;
}
pe = Create<DRotatePoly>(poly);
pe = Level->CreateThinker<DRotatePoly>(poly);
poly->specialdata = pe;
poly->bBlocked = false;
if (byteAngle != 0)
@ -448,7 +448,7 @@ bool EV_MovePoly (FLevelLocals *Level, line_t *line, int polyNum, double speed,
{ // poly is already in motion
break;
}
pe = Create<DMovePoly>(poly);
pe = Level->CreateThinker<DMovePoly>(poly);
poly->specialdata = pe;
poly->bBlocked = false;
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
break;
}
pe = Create<DMovePolyTo>(poly);
pe = Level->CreateThinker<DMovePolyTo>(poly);
poly->specialdata = pe;
poly->bBlocked = false;
pe->m_Dist = distlen;
@ -681,7 +681,7 @@ bool EV_OpenPolyDoor(FLevelLocals *Level, line_t *line, int polyNum, double spee
break;
}
pd = Create<DPolyDoor>(poly, type);
pd = Level->CreateThinker<DPolyDoor>(poly, type);
poly->specialdata = pd;
if (type == PODOOR_SLIDE)
{
@ -1223,7 +1223,7 @@ void FPolyObj::LinkPolyobj ()
{
link = &Level->PolyBlockMap[j+i];
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)->next = nullptr;
(*link)->prev = nullptr;

View file

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