From 8323524014e306bf63cf2cfe8ad3509ae1c2c7f7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Jan 2019 01:49:20 +0100 Subject: [PATCH] - give thinkers a 'level' member and change linking to the chain to happen outside the constructor. --- src/b_bot.cpp | 1 - src/b_bot.h | 1 + src/b_game.cpp | 2 +- src/c_dispatch.cpp | 5 ++- src/decallib.cpp | 25 ++++++----- src/dsectoreffect.cpp | 7 ---- src/dsectoreffect.h | 3 +- src/dthinker.cpp | 27 +++++------- src/dthinker.h | 10 ++++- src/fragglescript/t_func.cpp | 2 +- src/fragglescript/t_load.cpp | 2 +- src/fragglescript/t_script.cpp | 1 - src/fragglescript/t_script.h | 2 +- src/g_level.cpp | 2 +- src/g_levellocals.h | 24 ++++++++++- src/g_shared/a_decals.cpp | 61 +++++++-------------------- src/g_shared/a_lightning.cpp | 11 +++-- src/g_shared/a_lightning.h | 1 + src/g_shared/a_quake.cpp | 16 +------ src/g_shared/a_sharedglobal.h | 20 ++++----- src/m_cheat.cpp | 2 +- src/maploader/specials.cpp | 70 +++++++++++++++---------------- src/p_acs.cpp | 9 ++-- src/p_acs.h | 1 + src/p_actionfunctions.cpp | 2 +- src/p_ceiling.cpp | 2 +- src/p_doors.cpp | 8 ++-- src/p_floor.cpp | 16 +++---- src/p_lights.cpp | 24 ++++------- src/p_lnspec.cpp | 5 +-- src/p_map.cpp | 4 +- src/p_mobj.cpp | 4 +- src/p_pillar.cpp | 2 +- src/p_plats.cpp | 2 +- src/p_pusher.cpp | 6 +-- src/p_scroll.cpp | 6 +-- src/p_setup.cpp | 2 +- src/p_spec.cpp | 2 - src/p_spec.h | 1 + src/p_spec_thinkers.h | 10 +++-- src/p_switch.cpp | 2 +- src/po_man.cpp | 10 ++--- src/scripting/backend/codegen.cpp | 16 ++++--- 43 files changed, 201 insertions(+), 228 deletions(-) diff --git a/src/b_bot.cpp b/src/b_bot.cpp index f02184282b..9bddac1ad0 100644 --- a/src/b_bot.cpp +++ b/src/b_bot.cpp @@ -64,7 +64,6 @@ IMPLEMENT_POINTERS_END DEFINE_FIELD(DBot, dest) DBot::DBot () -: DThinker(STAT_BOT) { Clear (); } diff --git a/src/b_bot.h b/src/b_bot.h index 393650cf46..0d28f796c8 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -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 (); diff --git a/src/b_game.cpp b/src/b_game.cpp index 516986e718..f8eca50a5e 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -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(); + players[bnum].Bot = level.CreateThinker(); players[bnum].Bot->player = &players[bnum]; players[bnum].Bot->skill = skill; playeringame[bnum] = true; diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index b046f44678..25ffc4b8a8 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -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 (com, beg); + currentUILevel->CreateThinker (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 (brkpt, tics, UnsafeExecutionContext); + currentUILevel->CreateThinker (brkpt, tics, UnsafeExecutionContext); } return; } diff --git a/src/decallib.cpp b/src/decallib.cpp index 945fc9a09f..9a3cd15cd6 100644 --- a/src/decallib.cpp +++ b/src/decallib.cpp @@ -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 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 (actor); + auto Level = actor->Level; + DDecalFader *fader = Level->CreateThinker (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 (actor); + auto Level = actor->Level; + DDecalStretcher *thinker = Level->CreateThinker (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 (actor); + auto Level = actor->Level; + DDecalSlider *thinker = Level->CreateThinker (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(actor); + auto Level = actor->Level; + DDecalColorer *Colorer = Level->CreateThinker(actor); - Colorer->TimeToStartDecay = level.maptime + DecayStart; + Colorer->TimeToStartDecay = Level->maptime + DecayStart; Colorer->TimeToEndDecay = Colorer->TimeToStartDecay + DecayTime; Colorer->StartColor = 0xff000000; Colorer->GoalColor = GoalColor; diff --git a/src/dsectoreffect.cpp b/src/dsectoreffect.cpp index c3711f3f74..7552531483 100644 --- a/src/dsectoreffect.cpp +++ b/src/dsectoreffect.cpp @@ -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; } diff --git a/src/dsectoreffect.h b/src/dsectoreffect.h index e583a85cdf..a3ccc718c9 100644 --- a/src/dsectoreffect.h +++ b/src/dsectoreffect.h @@ -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; }; diff --git a/src/dthinker.cpp b/src/dthinker.cpp index 439685438d..dc7ffdd6bc 100644 --- a/src/dthinker.cpp +++ b/src/dthinker.cpp @@ -70,8 +70,8 @@ void FThinkerList::AddTail(DThinker *thinker) assert(!(thinker->ObjectFlags & OF_EuthanizeMe)); if (Sentinel == NULL) { - Sentinel = Create(DThinker::NO_LINK); - Sentinel->ObjectFlags |= OF_Sentinel; + Sentinel = Create(); + 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); +} + //========================================================================== // // diff --git a/src/dthinker.h b/src/dthinker.h index 921a7fc4e2..548eb6bd0e 100644 --- a/src/dthinker.h +++ b/src/dthinker.h @@ -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 diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 00162b3a41..99be0b2b77 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -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(&Level->sectors[i],destlevel,speed); + if (!Level->sectors[i].lightingdata) Level->CreateThinker(&Level->sectors[i],destlevel,speed); } } } diff --git a/src/fragglescript/t_load.cpp b/src/fragglescript/t_load.cpp index 930c69682f..2bad1ddec5 100644 --- a/src/fragglescript/t_load.cpp +++ b/src/fragglescript/t_load.cpp @@ -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(); + auto th = Level->CreateThinker(); th->LevelScript->data = copystring(scriptsrc.GetChars()); Level->FraggleScriptThinker = th; diff --git a/src/fragglescript/t_script.cpp b/src/fragglescript/t_script.cpp index 3311184a75..b8caaaff1c 100644 --- a/src/fragglescript/t_script.cpp +++ b/src/fragglescript/t_script.cpp @@ -366,7 +366,6 @@ IMPLEMENT_POINTERS_END //========================================================================== DFraggleThinker::DFraggleThinker() -: DThinker(STAT_SCRIPTS) { GlobalScript = Create(); GC::WriteBarrier(this, GlobalScript); diff --git a/src/fragglescript/t_script.h b/src/fragglescript/t_script.h index 11c0c0ba49..7b21940bbb 100644 --- a/src/fragglescript/t_script.h +++ b/src/fragglescript/t_script.h @@ -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 GlobalScript; diff --git a/src/g_level.cpp b/src/g_level.cpp index c368233001..633096c540 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -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(); + level.CreateThinker(); } if (pnumerr > 0) { diff --git a/src/g_levellocals.h b/src/g_levellocals.h index feaa541285..8844cdba91 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -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 + T* CreateThinker(Args&&... args) + { + auto thinker = Create(std::forward(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(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 bodyque[BODYQUESIZE]; - TObjPtr automap; + TObjPtr automap = nullptr; int bodyqueslot; int NumMapSections; diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index e73788363c..e644d8c001 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -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(iz); + DBaseDecal *decal = Level->CreateThinker(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(pos.Z); + decal = Level->CreateThinker(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(iz); + DImpactDecal *decal = Level->CreateThinker(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(trace.HitPos.Z); + decal = Level->CreateThinker(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()); } diff --git a/src/g_shared/a_lightning.cpp b/src/g_shared/a_lightning.cpp index cebc3c8ef4..0c599a798d 100644 --- a/src/g_shared/a_lightning.cpp +++ b/src/g_shared/a_lightning.cpp @@ -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(); + level.CreateThinker(); } } void P_ForceLightning (int mode) { DLightningThinker *lightning = LocateLightning (); - if (lightning == NULL) + if (lightning == nullptr) { - lightning = Create(); + lightning = level.CreateThinker(); } - if (lightning != NULL) + if (lightning != nullptr) { lightning->ForceLightning (mode); } diff --git a/src/g_shared/a_lightning.h b/src/g_shared/a_lightning.h index 62a2604740..9375fb7acc 100644 --- a/src/g_shared/a_lightning.h +++ b/src/g_shared/a_lightning.h @@ -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); diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index a0c95c91a7..d2467a9251 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -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(activator, intensityX, intensityY, intensityZ, duration, damrad, tremrad, + level.CreateThinker(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(center, intensityX, intensityY, intensityZ, duration, damrad, tremrad, + level.CreateThinker(center, intensityX, intensityY, intensityZ, duration, damrad, tremrad, quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ, falloff, highpoint, rollIntensity, rollWave); } } diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index 327ff3d7ac..01823a051a 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -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__ diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 1ce0fac07b..0de6758d03 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -636,7 +636,7 @@ void cht_Suicide (player_t *plyr) // the initial tick. if (plyr->mo != NULL) { - DSuicider *suicide = Create(); + DSuicider *suicide = plyr->mo->Level->CreateThinker(); suicide->Pawn = plyr->mo; GC::WriteBarrier(suicide, suicide->Pawn); } diff --git a/src/maploader/specials.cpp b/src/maploader/specials.cpp index 4f42a017f5..7177de6557 100644 --- a/src/maploader/specials.cpp +++ b/src/maploader/specials.cpp @@ -514,7 +514,7 @@ void MapLoader::InitSectorSpecial(sector_t *sector, int special) break; case dSector_DoorCloseIn30: - Create(sector, DDoor::doorWaitClose, 2, 0, 0, 30 * TICRATE); + Level->CreateThinker(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 (sector, DDoor::doorWaitRaise, 2, TICRATE*30/7, 0, 5*60*TICRATE); + Level->CreateThinker (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 (line.frontsector, line.args[0], true); + Level->CreateThinker (line.frontsector, line.args[0], true); break; // killough 4/11/98: Add support for setting // ceiling lighting independently case Transfer_CeilingLight: - Create (line.frontsector, line.args[0], false); + Level->CreateThinker (line.frontsector, line.args[0], false); break; // [Graf Zahl] Add support for setting lighting // per wall independently case Transfer_WallLight: - Create (line.frontsector, line.args[0], line.args[1]); + Level->CreateThinker (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(sector, 48, 63 - (sector->lightlevel & 63)); + Level->CreateThinker(sector, 48, 63 - (sector->lightlevel & 63)); break; // [RH] Hexen-like phased lighting case LightSequenceStart: - Create(sector); + Level->CreateThinker(sector); break; case dLight_Flicker: - Create(sector); + Level->CreateThinker(sector); break; case dLight_StrobeFast: - Create(sector, STROBEBRIGHT, FASTDARK, false); + Level->CreateThinker(sector, STROBEBRIGHT, FASTDARK, false); break; case dLight_StrobeSlow: - Create(sector, STROBEBRIGHT, SLOWDARK, false); + Level->CreateThinker(sector, STROBEBRIGHT, SLOWDARK, false); break; case dLight_Strobe_Hurt: - Create(sector, STROBEBRIGHT, FASTDARK, false); + Level->CreateThinker(sector, STROBEBRIGHT, FASTDARK, false); break; case dLight_Glow: - Create(sector); + Level->CreateThinker(sector); break; case dLight_StrobeSlowSync: - Create(sector, STROBEBRIGHT, SLOWDARK, true); + Level->CreateThinker(sector, STROBEBRIGHT, SLOWDARK, true); break; case dLight_StrobeFastSync: - Create(sector, STROBEBRIGHT, FASTDARK, true); + Level->CreateThinker(sector, STROBEBRIGHT, FASTDARK, true); break; case dLight_FireFlicker: - Create(sector); + Level->CreateThinker(sector); break; case dScroll_EastLavaDamage: - Create(sector, STROBEBRIGHT, FASTDARK, false); + Level->CreateThinker(sector, STROBEBRIGHT, FASTDARK, false); break; case sLight_Strobe_Hurt: - Create(sector, STROBEBRIGHT, FASTDARK, false); + Level->CreateThinker(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::p_wind, l->args[3] ? l : nullptr, l->args[1], l->args[2], nullptr, s); + Level->CreateThinker(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::p_current, l->args[3] ? l : nullptr, l->args[1], l->args[2], nullptr, s); + Level->CreateThinker(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::p_push, l->args[3] ? l : NULL, l->args[2], + Level->CreateThinker(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::p_push, l->args[3] ? l : NULL, l->args[2], 0, thing, thing->Sector->Index()); + Level->CreateThinker(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(EScroll::sc_ceiling, -dx, dy, control, &Level->sectors[s], nullptr, accel); + Level->CreateThinker(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(EScroll::sc_ceiling, -dx, dy, control, line->frontsector, nullptr, accel); + Level->CreateThinker(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(EScroll::sc_floor, -dx, dy, control, &Level->sectors[s], nullptr, accel); + Level->CreateThinker(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(EScroll::sc_floor, -dx, dy, control, line->frontsector, nullptr, accel); + Level->CreateThinker(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(EScroll::sc_carry, dx, dy, control, &Level->sectors[s], nullptr, accel); + Level->CreateThinker(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(EScroll::sc_carry, dx, dy, control, line->frontsector, nullptr, accel); + Level->CreateThinker(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(dx, dy, &Level->lines[s], control, accel); + Level->CreateThinker(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(EScroll::sc_side, -side->GetTextureXOffset(side_t::mid), + Level->CreateThinker(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(EScroll::sc_side, l->args[0] / 64., 0, nullptr, nullptr, side, accel, SCROLLTYPE(l->args[1])); + Level->CreateThinker(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(EScroll::sc_side, -l->args[0] / 64., 0, nullptr, nullptr, side, accel, SCROLLTYPE(l->args[1])); + Level->CreateThinker(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(EScroll::sc_side, 0, l->args[0] / 64., nullptr, nullptr, side, accel, SCROLLTYPE(l->args[1])); + Level->CreateThinker(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(EScroll::sc_side, 0, -l->args[0] / 64., nullptr, nullptr, side, accel, SCROLLTYPE(l->args[1])); + Level->CreateThinker(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(EScroll::sc_side, dx, dy, nullptr, nullptr, side, accel); + Level->CreateThinker(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(type, dx, dy, nullptr, affectee, nullptr, accel, scrollpos); + Level->CreateThinker(type, dx, dy, nullptr, affectee, nullptr, accel, scrollpos); } diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 3f61326b64..6047ac87c0 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -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 (fr1, fg1, fb1, fa1, fr2, fg2, fb2, fa2, ftime, viewer->mo); + Level->CreateThinker (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(activator, activationline, backSide, pcd == PCD_SETCEILINGTRIGGER, &Level->sectors[secnum], + Level->CreateThinker(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(); + Level->ACSThinker = Level->CreateThinker(); script = num; assert(code->VarCount >= code->ArgCount); diff --git a/src/p_acs.h b/src/p_acs.h index 21cb61e62e..c209ca16d2 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -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(); diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index b9bf2603a4..6e7d3db8a3 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -1835,7 +1835,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetBlend) // if (color2.a == 0) // color2 = color; - Create(color.r/255.f, color.g/255.f, color.b/255.f, float(alpha), + self->Level->CreateThinker(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; diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index 99744de514..015fe58825 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -244,7 +244,7 @@ bool FLevelLocals::CreateCeiling(sector_t *sec, DCeiling::ECeiling type, line_t } // new door thinker - DCeiling *ceiling = Create (sec, speed, speed2, silent & ~4); + DCeiling *ceiling = CreateThinker (sec, speed, speed2, silent & ~4); vertex_t *spot = sec->Lines[0]->v1; switch (type) diff --git a/src/p_doors.cpp b/src/p_doors.cpp index b43ad17a79..e07e736a15 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -480,7 +480,7 @@ bool FLevelLocals::EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, } return false; } - if (Create (sec, type, speed, delay, lightTag, topcountdown)) + if (CreateThinker (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(sec, type, speed, delay, lightTag, topcountdown)) + if (CreateThinker(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(sec, line, speed, delay, anim, type); + CreateThinker(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(sec, line, speed, delay, anim, type); + CreateThinker(sec, line, speed, delay, anim, type); break; } } diff --git a/src/p_floor.cpp b/src/p_floor.cpp index c818670d30..8252822638 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -283,7 +283,7 @@ bool FLevelLocals::CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t * // new floor thinker rtn = true; - floor = Create(sec); + floor = CreateThinker(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 (sec); + floor = CreateThinker (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 (sec); + floor = CreateThinker (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 (s2); + floor = CreateThinker (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 (s1); + floor = CreateThinker (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 (sec); + elevator = CreateThinker (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 (sector); + waggle = CreateThinker (sector); waggle->m_OriginalDist = sector->ceilingplane.fD(); } else { - waggle = Create (sector); + waggle = CreateThinker (sector); waggle->m_OriginalDist = sector->floorplane.fD(); } waggle->m_Accumulator = offset; diff --git a/src/p_lights.cpp b/src/p_lights.cpp index 636bc4899c..96ef415c1e 100644 --- a/src/p_lights.cpp +++ b/src/p_lights.cpp @@ -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 (sector, baselevel); + l = Level->CreateThinker (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(§ors[secnum], upper, lower); + CreateThinker(§ors[secnum], upper, lower); } } @@ -599,7 +591,7 @@ void FLevelLocals::EV_StartLightStrobing(int tag, int upper, int lower, int utic if (sec->lightingdata) continue; - Create(sec, upper, lower, utics, ltics); + CreateThinker(sec, upper, lower, utics, ltics); } } @@ -613,7 +605,7 @@ void FLevelLocals::EV_StartLightStrobing(int tag, int utics, int ltics) if (sec->lightingdata) continue; - Create(sec, utics, ltics, false); + CreateThinker(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(sec, upper, lower, tics, false); + CreateThinker(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(sec, sec->lightlevel, value, tics, true); + CreateThinker(sec, sec->lightlevel, value, tics, true); } } } diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index a68bf9f341..a2e25d87e9 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -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; } diff --git a/src/p_map.cpp b/src/p_map.cpp index 9b52b897e1..9bfe404865 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -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); } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index e0f58fe73e..4283e0be01 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -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(const_cast(type)->CreateNew ()); + actor = static_cast(level.CreateThinker(type)); actor->SpawnTime = level.totaltime; actor->SpawnOrder = level.spawnindex++; diff --git a/src/p_pillar.cpp b/src/p_pillar.cpp index a681bee23a..ae29629f8e 100644 --- a/src/p_pillar.cpp +++ b/src/p_pillar.cpp @@ -234,7 +234,7 @@ bool FLevelLocals::EV_DoPillar (DPillar::EPillar type, line_t *line, int tag, continue; rtn = true; - Create (sec, type, speed, height, height2, crush, hexencrush); + CreateThinker (sec, type, speed, height, height2, crush, hexencrush); } return rtn; } diff --git a/src/p_plats.cpp b/src/p_plats.cpp index 2a39ef323c..993c5cbcbc 100644 --- a/src/p_plats.cpp +++ b/src/p_plats.cpp @@ -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 (sec); + plat = CreateThinker (sec); plat->m_Type = type; plat->m_Crush = -1; diff --git a/src/p_pusher.cpp b/src/p_pusher.cpp index 0ebb29351a..7b38aab3f2 100644 --- a/src/p_pusher.cpp +++ b/src/p_pusher.cpp @@ -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 Collection; { - TThinkerIterator iterator; + auto iterator = GetThinkerIterator(); 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(type, nullptr, magnitude, angle, nullptr, secnum); + CreateThinker(type, nullptr, magnitude, angle, nullptr, secnum); } } } diff --git a/src/p_scroll.cpp b/src/p_scroll.cpp index 649b8afe86..0923d8d601 100644 --- a/src/p_scroll.cpp +++ b/src/p_scroll.cpp @@ -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 (EScroll::sc_side, dx, dy, nullptr, nullptr, side, 0, Where); + Level->CreateThinker (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 (type, dx, dy, nullptr, &Level->sectors[i], nullptr, 0); + Level->CreateThinker (type, dx, dy, nullptr, &Level->sectors[i], nullptr, 0); } } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 6459065fb5..c4ddfa2be5 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -333,7 +333,7 @@ void FLevelLocals::ClearLevelData() AllPlayerStarts.Clear(); memset(playerstarts, 0, sizeof(playerstarts)); Scrolls.Clear(); - + if (automap) automap->Destroy(); } //========================================================================== diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 3d07180c13..71f1093fe4 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -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 () diff --git a/src/p_spec.h b/src/p_spec.h index 9de805f432..de9e291f56 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -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; diff --git a/src/p_spec_thinkers.h b/src/p_spec_thinkers.h index fe5ad9e075..3647a13144 100644 --- a/src/p_spec_thinkers.h +++ b/src/p_spec_thinkers.h @@ -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; diff --git a/src/p_switch.cpp b/src/p_switch.cpp index ec1d717ecc..3911c141d1 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -98,7 +98,7 @@ static bool P_StartButton (side_t *side, int Where, FSwitchDef *Switch, const DV } } - Create (side, Where, Switch, pos, useagain); + level.CreateThinker (side, Where, Switch, pos, useagain); return true; } diff --git a/src/po_man.cpp b/src/po_man.cpp index c4bdf717d1..44e451dc5b 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -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(poly); + pe = Level->CreateThinker(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(poly); + pe = Level->CreateThinker(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(poly); + pe = Level->CreateThinker(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(poly, type); + pd = Level->CreateThinker(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; diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index cb007c2f41..4beb56d674 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -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; }