diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a6dcfd766a..da79cd4086 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -111,6 +111,7 @@ if( WIN32 ) ( MSVC15 AND NOT CMAKE_GENERATOR_TOOLSET STREQUAL "v150_xp" ) ) # For VS 2017. # for modern Windows SDKs the DirectX headers should be available by default. set( DX_dinput8_LIBRARY dinput8 ) + set( DX_dxguid_LIBRARY dxguid ) else() find_path( D3D_INCLUDE_DIR d3d9.h diff --git a/src/actor.h b/src/actor.h index 666ca67f80..bc65144da6 100644 --- a/src/actor.h +++ b/src/actor.h @@ -613,7 +613,7 @@ public: FActorInfo *GetInfo() const { - return ((PClassActor*)GetClass())->ActorInfo(); + return static_cast(GetClass())->ActorInfo(); } @@ -739,7 +739,7 @@ public: AInventory *FindInventory (FName type, bool subclass = false); template T *FindInventory () { - return static_cast (FindInventory (RUNTIME_TEMPLATE_CLASS(T))); + return static_cast (FindInventory (RUNTIME_CLASS(T))); } // Adds one item of a particular type. Returns NULL if it could not be added. @@ -1512,7 +1512,7 @@ public: do { actor = FActorIterator::Next (); - } while (actor && !actor->IsKindOf (RUNTIME_TEMPLATE_CLASS(T))); + } while (actor && !actor->IsKindOf (RUNTIME_CLASS(T))); return static_cast(actor); } }; @@ -1563,12 +1563,12 @@ inline AActor *Spawn(FName type, const DVector3 &pos, replace_t allowreplacement template inline T *Spawn(const DVector3 &pos, replace_t allowreplacement) { - return static_cast(AActor::StaticSpawn(RUNTIME_TEMPLATE_CLASS(T), pos, allowreplacement)); + return static_cast(AActor::StaticSpawn(RUNTIME_CLASS(T), pos, allowreplacement)); } template inline T *Spawn() // for inventory items we do not need coordinates and replacement info. { - return static_cast(AActor::StaticSpawn(RUNTIME_TEMPLATE_CLASS(T), DVector3(0, 0, 0), NO_REPLACE)); + return static_cast(AActor::StaticSpawn(RUNTIME_CLASS(T), DVector3(0, 0, 0), NO_REPLACE)); } inline PClassActor *PClass::FindActor(FName name) diff --git a/src/b_game.cpp b/src/b_game.cpp index ea80030ffd..9a78110953 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -375,7 +375,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 = new DBot; + players[bnum].Bot = Create(); players[bnum].Bot->player = &players[bnum]; players[bnum].Bot->skill = skill; playeringame[bnum] = true; diff --git a/src/b_think.cpp b/src/b_think.cpp index 25932f390e..116e70c4f4 100644 --- a/src/b_think.cpp +++ b/src/b_think.cpp @@ -313,12 +313,13 @@ void DBot::ThinkForMove (ticcmd_t *cmd) old = player->mo->Pos(); } +int P_GetRealMaxHealth(APlayerPawn *actor, int max); + //BOT_WhatToGet // //Determines if the bot will roam after an item or not. void DBot::WhatToGet (AActor *item) { -#define typeis(x) item->IsKindOf (PClass::FindClass (#x)) if ((item->renderflags & RF_INVISIBLE) //Under respawn and away. || item == prev) { @@ -350,17 +351,24 @@ void DBot::WhatToGet (AActor *item) { auto ac = PClass::FindActor(NAME_Ammo); auto parent = item->GetClass(); - while (parent->ParentClass != ac) parent = (PClassActor*)(parent->ParentClass); + while (parent->ParentClass != ac) parent = static_cast(parent->ParentClass); AInventory *holdingammo = player->mo->FindInventory(parent); if (holdingammo != NULL && holdingammo->Amount >= holdingammo->MaxAmount) { return; } } - else if ((typeis (Megasphere) || typeis (Soulsphere) || typeis (HealthBonus)) && player->mo->health >= deh.MaxSoulsphere) - return; - else if (item->IsKindOf (PClass::FindActor(NAME_Health)) && player->mo->health >= player->mo->GetMaxHealth(true)) - return; + else if (item->GetClass()->TypeName == NAME_Megasphere || item->IsKindOf(NAME_Health)) + { + // do the test with the health item that's actually given. + if (item->GetClass()->TypeName == NAME_Megasphere) item = GetDefaultByName("MegasphereHealth"); + if (item != nullptr) + { + int maxhealth = P_GetRealMaxHealth(player->mo, item->IntVar(NAME_MaxAmount)); + if (player->mo->health >= maxhealth) + return; + } + } if ((dest == NULL || !(dest->flags & MF_SPECIAL)/* || diff --git a/src/c_console.cpp b/src/c_console.cpp index f401ed0e5b..ff3f86b20c 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -1822,7 +1822,7 @@ void C_MidPrint (FFont *font, const char *msg) AddToConsole (-1, msg); AddToConsole (-1, bar3); - StatusBar->AttachMessage (new DHUDMessage (font, msg, 1.5f, 0.375f, 0, 0, + StatusBar->AttachMessage (Create(font, msg, 1.5f, 0.375f, 0, 0, (EColorRange)PrintColors[PRINTLEVELS], con_midtime), MAKE_ID('C','N','T','R')); } else @@ -1839,7 +1839,7 @@ void C_MidPrintBold (FFont *font, const char *msg) AddToConsole (-1, msg); AddToConsole (-1, bar3); - StatusBar->AttachMessage (new DHUDMessage (font, msg, 1.5f, 0.375f, 0, 0, + StatusBar->AttachMessage (Create (font, msg, 1.5f, 0.375f, 0, 0, (EColorRange)PrintColors[PRINTLEVELS+1], con_midtime), MAKE_ID('C','N','T','R')); } else diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 464ed4495a..996872a669 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -636,7 +636,7 @@ void C_DoCommand (const char *cmd, int keynum) } else { - new DStoredCommand (com, beg); + Create (com, beg); } } } @@ -730,7 +730,7 @@ void AddCommandString (char *cmd, int keynum) // Note that deferred commands lose track of which key // (if any) they were pressed from. *brkpt = ';'; - new DWaitingCommand (brkpt, tics); + Create (brkpt, tics); } return; } diff --git a/src/d_main.cpp b/src/d_main.cpp index b03ca3e504..b6a67c06b0 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1770,7 +1770,7 @@ bool ConsiderPatches (const char *arg) // //========================================================================== -FExecList *D_MultiExec (DArgs *list, FExecList *exec) +FExecList *D_MultiExec (FArgs *list, FExecList *exec) { for (int i = 0; i < list->NumArgs(); ++i) { @@ -1980,7 +1980,8 @@ static void SetMapxxFlag() static void FinalGC() { - Args = NULL; + delete Args; + Args = nullptr; GC::FinalGC = true; GC::FullGC(); GC::DelSoftRootHead(); // the soft root head will not be collected by a GC so we have to do it explicitly @@ -2264,7 +2265,6 @@ void D_DoomMain (void) int p; const char *v; const char *wad; - DArgs *execFiles; TArray pwads; FString *args; int argcount; @@ -2372,13 +2372,15 @@ void D_DoomMain (void) // Process automatically executed files FExecList *exec; - execFiles = new DArgs; + FArgs *execFiles = new FArgs; GameConfig->AddAutoexec(execFiles, gameinfo.ConfigName); exec = D_MultiExec(execFiles, NULL); + delete execFiles; // Process .cfg files at the start of the command line. execFiles = Args->GatherFiles ("-exec"); exec = D_MultiExec(execFiles, exec); + delete execFiles; // [RH] process all + commands on the command line exec = C_ParseCmdLineParams(exec); @@ -2747,10 +2749,7 @@ void D_DoomMain (void) GC::FullGC(); // perform one final garbage collection after shutdown - for (DObject *obj = GC::Root; obj; obj = obj->ObjNext) - { - obj->ClearClass(); // Delete the Class pointer because the data it points to has been deleted. This will automatically be reset if needed. - } + assert(GC::Root == nullptr); restart++; PClass::bShutdown = false; diff --git a/src/decallib.cpp b/src/decallib.cpp index d9f22499eb..aa6fa38b47 100644 --- a/src/decallib.cpp +++ b/src/decallib.cpp @@ -1201,7 +1201,7 @@ void DDecalFader::Tick () DThinker *FDecalFaderAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const { - DDecalFader *fader = new DDecalFader (actor); + DDecalFader *fader = Create (actor); fader->TimeToStartDecay = level.maptime + DecayStart; fader->TimeToEndDecay = fader->TimeToStartDecay + DecayTime; @@ -1227,7 +1227,7 @@ void DDecalStretcher::Serialize(FSerializer &arc) DThinker *FDecalStretcherAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const { - DDecalStretcher *thinker = new DDecalStretcher (actor); + DDecalStretcher *thinker = Create (actor); thinker->TimeToStart = level.maptime + StretchStart; thinker->TimeToStop = thinker->TimeToStart + StretchTime; @@ -1313,7 +1313,7 @@ void DDecalSlider::Serialize(FSerializer &arc) DThinker *FDecalSliderAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const { - DDecalSlider *thinker = new DDecalSlider (actor); + DDecalSlider *thinker = Create (actor); thinker->TimeToStart = level.maptime + SlideStart; thinker->TimeToStop = thinker->TimeToStart + SlideTime; @@ -1432,7 +1432,7 @@ void DDecalColorer::Tick () DThinker *FDecalColorerAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const { - DDecalColorer *Colorer = new DDecalColorer (actor); + DDecalColorer *Colorer = Create(actor); Colorer->TimeToStartDecay = level.maptime + DecayStart; Colorer->TimeToEndDecay = Colorer->TimeToStartDecay + DecayTime; diff --git a/src/dobject.cpp b/src/dobject.cpp index 687e76f850..39c55f2b57 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -612,12 +612,6 @@ void DObject::CheckIfSerialized () const } -DEFINE_ACTION_FUNCTION(DObject, GetClassName) -{ - PARAM_SELF_PROLOGUE(DObject); - ACTION_RETURN_INT(self->GetClass()->TypeName); -} - DEFINE_ACTION_FUNCTION(DObject, MSTime) { ACTION_RETURN_INT(I_MSTime()); diff --git a/src/dobject.h b/src/dobject.h index 0108e1378f..d043dfada4 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -35,6 +35,7 @@ #define __DOBJECT_H__ #include +#include #include "doomtype.h" #include "i_system.h" @@ -45,8 +46,6 @@ class FSoundID; class DObject; /* -class DArgs; -class DCanvas; class DConsoleCommand; class DConsoleAlias; class DSeqNode; @@ -85,8 +84,7 @@ class DPillar; class PClassActor; #define RUNTIME_CLASS_CASTLESS(cls) (cls::RegistrationInfo.MyClass) // Passed a native class name, returns a PClass representing that class -#define RUNTIME_CLASS(cls) ((cls::MetaClass *)RUNTIME_CLASS_CASTLESS(cls)) // Like above, but returns the true type of the meta object -#define RUNTIME_TEMPLATE_CLASS(cls) ((typename cls::MetaClass *)RUNTIME_CLASS_CASTLESS(cls)) // RUNTIME_CLASS, but works with templated parameters on GCC +#define RUNTIME_CLASS(cls) ((typename cls::MetaClass *)RUNTIME_CLASS_CASTLESS(cls)) // Like above, but returns the true type of the meta object #define NATIVE_TYPE(object) (object->StaticType()) // Passed an object, returns the type of the C++ class representing the object // Enumerations for the meta classes created by ClassReg::RegisterClass() @@ -231,11 +229,6 @@ public: void SerializeUserVars(FSerializer &arc); virtual void Serialize(FSerializer &arc); - void ClearClass() - { - Class = NULL; - } - // Releases the object from the GC, letting the caller care of any maintenance. void Release(); @@ -264,12 +257,7 @@ public: PClass *GetClass() const { - if (Class == NULL) - { - // Save a little time the next time somebody wants this object's type - // by recording it now. - const_cast(this)->Class = StaticType(); - } + assert(Class != nullptr); return Class; } @@ -278,10 +266,21 @@ public: Class = inClass; } - void *operator new(size_t len) +private: + struct nonew + { + }; + + void *operator new(size_t len, nonew&) { return M_Malloc(len); } +public: + + void operator delete (void *mem, nonew&) + { + M_Free(mem); + } void operator delete (void *mem) { @@ -354,8 +353,28 @@ protected: { M_Free (mem); } + + template + friend T* Create(Args&&... args); + }; +// This is the only method aside from calling CreateNew that should be used for creating DObjects +// to ensure that the Class pointer is always set. +template +T* Create(Args&&... args) +{ + DObject::nonew nono; + T *object = new(nono) T(std::forward(args)...); + if (object != nullptr) + { + object->SetClass(RUNTIME_CLASS(T)); + assert(object->GetClass() != nullptr); // beware of objects that get created before the type system is up. + } + return object; +} + + class AInventory;// // When you write to a pointer to an Object, you must call this for diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index 03a7153291..3631c36ed1 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -323,7 +323,6 @@ static void MarkRoot() int i; Gray = NULL; - Mark(Args); Mark(StatusBar); M_MarkMenus(); Mark(DIntermissionController::CurrentIntermission); @@ -351,7 +350,7 @@ static void MarkRoot() // Mark sectors. if (SectorMarker == nullptr && level.sectors.Size() > 0) { - SectorMarker = new DSectorMarker; + SectorMarker = Create(); } else if (level.sectors.Size() == 0) { @@ -592,7 +591,7 @@ void AddSoftRoot(DObject *obj) // Create a new object to root the soft roots off of, and stick // it at the end of the object list, so we know that anything // before it is not a soft root. - SoftRoots = new DObject; + SoftRoots = Create(); SoftRoots->ObjectFlags |= OF_Fixed; probe = &Root; while (*probe != NULL) diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 3d27b3a0dd..bf41d3cdea 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -226,7 +226,7 @@ void PClass::StaticInit () // WP_NOCHANGE must point to a valid object, although it does not need to be a weapon. // A simple DObject is enough to give the GC the ability to deal with it, if subjected to it. - WP_NOCHANGE = (AWeapon*)new DObject; + WP_NOCHANGE = (AWeapon*)Create(); WP_NOCHANGE->Release(); } @@ -267,6 +267,7 @@ void PClass::StaticShutdown () { p.PendingWeapon = nullptr; } + Namespaces.ReleaseSymbols(); // This must be done in two steps because the native classes are not ordered by inheritance, // so all meta data must be gone before deleting the actual class objects. @@ -275,7 +276,6 @@ void PClass::StaticShutdown () // Unless something went wrong, anything left here should be class and type objects only, which do not own any scripts. bShutdown = true; TypeTable.Clear(); - Namespaces.ReleaseSymbols(); ClassDataAllocator.FreeAllBlocks(); AllClasses.Clear(); PClassActor::AllActorClasses.Clear(); diff --git a/src/dthinker.cpp b/src/dthinker.cpp index 35dd6505c6..5e53606512 100644 --- a/src/dthinker.cpp +++ b/src/dthinker.cpp @@ -69,7 +69,7 @@ void FThinkerList::AddTail(DThinker *thinker) assert(!(thinker->ObjectFlags & OF_EuthanizeMe)); if (Sentinel == NULL) { - Sentinel = new DThinker(DThinker::NO_LINK); + Sentinel = Create(DThinker::NO_LINK); Sentinel->ObjectFlags |= OF_Sentinel; Sentinel->NextThinker = Sentinel; Sentinel->PrevThinker = Sentinel; @@ -179,37 +179,41 @@ void DThinker::SerializeThinkers(FSerializer &arc, bool hubLoad) { for (i = 0; i <= MAX_STATNUM; i++) { + if (arc.BeginArray(nullptr)) { - int size = arc.ArraySize(); - for (int j = 0; j < size; j++) + if (!hubLoad || i != STAT_STATIC) // do not load static thinkers in a hub transition because they'd just duplicate the active ones. { - DThinker *thinker = nullptr; - arc(nullptr, thinker); - if (thinker != nullptr) + int size = arc.ArraySize(); + for (int j = 0; j < size; j++) { - // This may be a player stored in their ancillary list. Remove - // them first before inserting them into the new list. - if (thinker->NextThinker != nullptr) + DThinker *thinker = nullptr; + arc(nullptr, thinker); + if (thinker != nullptr) { - thinker->Remove(); - } - // Thinkers with the OF_JustSpawned flag set go in the FreshThinkers - // list. Anything else goes in the regular Thinkers list. - if (thinker->ObjectFlags & OF_EuthanizeMe) - { - // This thinker was destroyed during the loading process. Do - // not link it into any list. - } - else if (thinker->ObjectFlags & OF_JustSpawned) - { - FreshThinkers[i].AddTail(thinker); - thinker->PostSerialize(); - } - else - { - Thinkers[i].AddTail(thinker); - thinker->PostSerialize(); + // This may be a player stored in their ancillary list. Remove + // them first before inserting them into the new list. + if (thinker->NextThinker != nullptr) + { + thinker->Remove(); + } + // Thinkers with the OF_JustSpawned flag set go in the FreshThinkers + // list. Anything else goes in the regular Thinkers list. + if (thinker->ObjectFlags & OF_EuthanizeMe) + { + // This thinker was destroyed during the loading process. Do + // not link it into any list. + } + else if (thinker->ObjectFlags & OF_JustSpawned) + { + FreshThinkers[i].AddTail(thinker); + thinker->PostSerialize(); + } + else + { + Thinkers[i].AddTail(thinker); + thinker->PostSerialize(); + } } } } @@ -727,7 +731,7 @@ DEFINE_ACTION_FUNCTION(DThinkerIterator, Create) PARAM_PROLOGUE; PARAM_CLASS_DEF(type, DThinker); PARAM_INT_DEF(statnum); - ACTION_RETURN_OBJECT(new DThinkerIterator(type, statnum)); + ACTION_RETURN_OBJECT(Create(type, statnum)); } DEFINE_ACTION_FUNCTION(DThinkerIterator, Next) diff --git a/src/dthinker.h b/src/dthinker.h index a8c374bb75..da7eced7d3 100644 --- a/src/dthinker.h +++ b/src/dthinker.h @@ -91,9 +91,10 @@ public: static DThinker *FirstThinker (int statnum); static bool bSerialOverride; -private: + // only used internally but Create needs access. enum no_link_type { NO_LINK }; DThinker(no_link_type) throw(); +private: static void DestroyThinkersInList (FThinkerList &list); static int TickThinkers (FThinkerList *list, FThinkerList *dest); // Returns: # of thinkers ticked static void SaveList(FSerializer &arc, DThinker *node); @@ -133,10 +134,10 @@ protected: template class TThinkerIterator : public FThinkerIterator { public: - TThinkerIterator (int statnum=MAX_STATNUM+1) : FThinkerIterator (RUNTIME_TEMPLATE_CLASS(T), statnum) + TThinkerIterator (int statnum=MAX_STATNUM+1) : FThinkerIterator (RUNTIME_CLASS(T), statnum) { } - TThinkerIterator (int statnum, DThinker *prev) : FThinkerIterator (RUNTIME_TEMPLATE_CLASS(T), statnum, prev) + TThinkerIterator (int statnum, DThinker *prev) : FThinkerIterator (RUNTIME_CLASS(T), statnum, prev) { } TThinkerIterator (const PClass *subclass, int statnum=MAX_STATNUM+1) : FThinkerIterator(subclass, statnum) diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 9e1d95ffde..181d20d30d 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -1873,7 +1873,7 @@ void FParser::SF_FadeLight(void) FSectorTagIterator it(sectag); while ((i = it.Next()) >= 0) { - if (!level.sectors[i].lightingdata) new DLightLevel(&level.sectors[i],destlevel,speed); + if (!level.sectors[i].lightingdata) Create(&level.sectors[i],destlevel,speed); } } } @@ -4036,7 +4036,7 @@ DRunningScript *FParser::SaveCurrentScript() DFraggleThinker *th = DFraggleThinker::ActiveThinker; if (th) { - DRunningScript *runscr = new DRunningScript(Script->trigger, Script, Script->MakeIndex(Rover)); + DRunningScript *runscr = Create(Script->trigger, Script, Script->MakeIndex(Rover)); // hook into chain at start th->AddRunningScript(runscr); @@ -4170,7 +4170,7 @@ void FParser::SF_StartScript() script_error("script %i not defined\n", snum); } - DRunningScript *runscr = new DRunningScript(Script->trigger, script, 0); + DRunningScript *runscr = Create(Script->trigger, script, 0); // hook into chain at start th->AddRunningScript(runscr); } diff --git a/src/fragglescript/t_load.cpp b/src/fragglescript/t_load.cpp index 99818a53d7..e277354251 100644 --- a/src/fragglescript/t_load.cpp +++ b/src/fragglescript/t_load.cpp @@ -315,7 +315,7 @@ bool FScriptLoader::ParseInfo(MapData * map) } if (HasScripts) { - new DFraggleThinker; + Create(); DFraggleThinker::ActiveThinker->LevelScript->data = copystring(scriptsrc.GetChars()); if (drownflag==-1) drownflag = (level.maptype != MAPTYPE_DOOM || fsglobal); diff --git a/src/fragglescript/t_prepro.cpp b/src/fragglescript/t_prepro.cpp index 4128e6661d..c770e94af6 100644 --- a/src/fragglescript/t_prepro.cpp +++ b/src/fragglescript/t_prepro.cpp @@ -156,7 +156,7 @@ void DFsScript::ClearSections() DFsSection *DFsScript::NewSection(const char *brace) { int n = section_hash(brace); - DFsSection *newsec = new DFsSection; + DFsSection *newsec = Create(); newsec->start_index = MakeIndex(brace); newsec->next = sections[n]; diff --git a/src/fragglescript/t_script.cpp b/src/fragglescript/t_script.cpp index 9dc1533106..47447d9888 100644 --- a/src/fragglescript/t_script.cpp +++ b/src/fragglescript/t_script.cpp @@ -406,8 +406,8 @@ DFraggleThinker::DFraggleThinker() else { ActiveThinker = this; - RunningScripts = new DRunningScript; - LevelScript = new DFsScript; + RunningScripts = Create(); + LevelScript = Create(); LevelScript->parent = global_script; GC::WriteBarrier(this, RunningScripts); GC::WriteBarrier(this, LevelScript); @@ -669,7 +669,7 @@ bool T_RunScript(int snum, AActor * t_trigger) DFsScript *script = th->LevelScript->children[snum]; if(!script) return false; - DRunningScript *runscr = new DRunningScript(t_trigger, script, 0); + DRunningScript *runscr = Create(t_trigger, script, 0); // hook into chain at start th->AddRunningScript(runscr); return true; @@ -699,7 +699,7 @@ void T_Init() if (global_script == NULL) { - global_script = new DFsScript; + global_script = Create(); GC::AddSoftRoot(global_script); init_functions(); } diff --git a/src/fragglescript/t_spec.cpp b/src/fragglescript/t_spec.cpp index d2f0922e27..7703398ed9 100644 --- a/src/fragglescript/t_spec.cpp +++ b/src/fragglescript/t_spec.cpp @@ -417,7 +417,7 @@ void FParser::spec_script() return; } - newscript = new DFsScript; + newscript = Create(); // add to scripts list of parent Script->children[scriptnum] = newscript; diff --git a/src/fragglescript/t_variable.cpp b/src/fragglescript/t_variable.cpp index a87d2c1e60..d0a0c8b9fc 100644 --- a/src/fragglescript/t_variable.cpp +++ b/src/fragglescript/t_variable.cpp @@ -334,7 +334,7 @@ void DFsVariable::Serialize(FSerializer & ar) DFsVariable *DFsScript::NewVariable(const char *name, int vtype) { - DFsVariable *newvar = new DFsVariable(name); + DFsVariable *newvar = Create(name); newvar->type = vtype; int n = variable_hash(name); diff --git a/src/g_game.cpp b/src/g_game.cpp index 26e9d5c9c3..201d07e865 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -343,7 +343,7 @@ CCMD (weapnext) // [BC] Option to display the name of the weapon being cycled to. if ((displaynametags & 2) && StatusBar && SmallFont && SendItemUse) { - StatusBar->AttachMessage(new DHUDMessageFadeOut(SmallFont, SendItemUse->GetTag(), + StatusBar->AttachMessage(Create(SmallFont, SendItemUse->GetTag(), 1.5f, 0.90f, 0, 0, (EColorRange)*nametagcolor, 2.f, 0.35f), MAKE_ID( 'W', 'E', 'P', 'N' )); } if (SendItemUse != players[consoleplayer].ReadyWeapon) @@ -358,7 +358,7 @@ CCMD (weapprev) // [BC] Option to display the name of the weapon being cycled to. if ((displaynametags & 2) && StatusBar && SmallFont && SendItemUse) { - StatusBar->AttachMessage(new DHUDMessageFadeOut(SmallFont, SendItemUse->GetTag(), + StatusBar->AttachMessage(Create(SmallFont, SendItemUse->GetTag(), 1.5f, 0.90f, 0, 0, (EColorRange)*nametagcolor, 2.f, 0.35f), MAKE_ID( 'W', 'E', 'P', 'N' )); } if (SendItemUse != players[consoleplayer].ReadyWeapon) @@ -394,7 +394,7 @@ CCMD (invnext) } } if ((displaynametags & 1) && StatusBar && SmallFont && who->InvSel) - StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, who->InvSel->GetTag(), + StatusBar->AttachMessage (Create (SmallFont, who->InvSel->GetTag(), 1.5f, 0.80f, 0, 0, (EColorRange)*nametagcolor, 2.f, 0.35f), MAKE_ID('S','I','N','V')); } who->player->inventorytics = 5*TICRATE; @@ -429,7 +429,7 @@ CCMD (invprev) who->InvSel = item; } if ((displaynametags & 1) && StatusBar && SmallFont && who->InvSel) - StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, who->InvSel->GetTag(), + StatusBar->AttachMessage (Create (SmallFont, who->InvSel->GetTag(), 1.5f, 0.80f, 0, 0, (EColorRange)*nametagcolor, 2.f, 0.35f), MAKE_ID('S','I','N','V')); } who->player->inventorytics = 5*TICRATE; diff --git a/src/g_level.cpp b/src/g_level.cpp index 46248deca6..ad83a2a05b 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1059,7 +1059,7 @@ void G_DoLoadLevel (int position, bool autosave) // [RH] Always save the game when entering a new level. if (autosave && !savegamerestore && disableautosave < 1) { - DAutosaver GCCNOWARN *dummy = new DAutosaver; + DAutosaver GCCNOWARN *dummy = Create(); } } diff --git a/src/g_shared/a_action.cpp b/src/g_shared/a_action.cpp index 71f796a89b..627c7323de 100644 --- a/src/g_shared/a_action.cpp +++ b/src/g_shared/a_action.cpp @@ -181,7 +181,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_QueueCorpse) if (sv_corpsequeuesize > 0) { - new DCorpsePointer (self); + Create (self); } return 0; } diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index 9c31256ecd..edc170294a 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -522,7 +522,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 = new DBaseDecal(iz); + DBaseDecal *decal = Create(iz); if (decal != NULL) { if (decal->StickToWall (wall, ix, iy, ffloor).isValid()) @@ -615,7 +615,7 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, const DVect StaticCreate (tpl_low, pos, wall, ffloor, lowercolor); } DImpactDecal::CheckMax(); - decal = new DImpactDecal (pos.Z); + decal = Create(pos.Z); if (decal == NULL) { return NULL; @@ -651,7 +651,7 @@ DBaseDecal *DImpactDecal::CloneSelf (const FDecalTemplate *tpl, double ix, doubl } DImpactDecal::CheckMax(); - DImpactDecal *decal = new DImpactDecal(iz); + DImpactDecal *decal = Create(iz); if (decal != NULL) { if (decal->StickToWall (wall, ix, iy, ffloor).isValid()) @@ -704,7 +704,7 @@ CCMD (spray) Net_WriteString (argv[1]); } -void SprayDecal(AActor *shooter, const char *name) +void SprayDecal(AActor *shooter, const char *name, double distance) { FTraceResults trace; @@ -713,7 +713,7 @@ void SprayDecal(AActor *shooter, const char *name) double c = pitch.Cos(); DVector3 vec(c * ang.Cos(), c * ang.Sin(), -pitch.Sin()); - if (Trace(shooter->PosPlusZ(shooter->Height / 2), shooter->Sector, vec, 172., 0, ML_BLOCKEVERYTHING, shooter, trace, TRACE_NoSky)) + if (Trace(shooter->PosPlusZ(shooter->Height / 2), shooter->Sector, vec, distance, 0, ML_BLOCKEVERYTHING, shooter, trace, TRACE_NoSky)) { if (trace.HitType == TRACE_HitWall) { @@ -739,7 +739,7 @@ DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t * { if (permanent) { - decal = new DBaseDecal(trace.HitPos.Z); + decal = Create(trace.HitPos.Z); wall = trace.Line->sidedef[trace.Side]; decal->StickToWall(wall, trace.HitPos.X, trace.HitPos.Y, trace.ffloor); tpl->ApplyToDecal(decal, wall); diff --git a/src/g_shared/a_lightning.cpp b/src/g_shared/a_lightning.cpp index cec7c18002..28cdeceea9 100644 --- a/src/g_shared/a_lightning.cpp +++ b/src/g_shared/a_lightning.cpp @@ -184,7 +184,7 @@ void P_StartLightning () DLightningThinker *lightning = LocateLightning (); if (lightning == NULL) { - new DLightningThinker (); + Create(); } } @@ -193,7 +193,7 @@ void P_ForceLightning (int mode) DLightningThinker *lightning = LocateLightning (); if (lightning == NULL) { - lightning = new DLightningThinker (); + lightning = Create(); } if (lightning != NULL) { diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index feb7e62560..6c8e0f2da2 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -374,7 +374,7 @@ bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, { if (activator != NULL) { - new DEarthquake(activator, intensityX, intensityY, intensityZ, duration, damrad, tremrad, + Create(activator, intensityX, intensityY, intensityZ, duration, damrad, tremrad, quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ, falloff, highpoint, rollIntensity, rollWave); return true; } @@ -385,7 +385,7 @@ bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, while ( (center = iterator.Next ()) ) { res = true; - new DEarthquake(center, intensityX, intensityY, intensityZ, duration, damrad, tremrad, + Create(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 f45cd9d0e2..626985f937 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -11,7 +11,7 @@ struct F3DFloor; class DBaseDecal; class DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *sec, double x, double y, double z, DAngle angle, double tracedist, bool permanent); -void SprayDecal(AActor *shooter, const char *name); +void SprayDecal(AActor *shooter, const char *name,double distance = 172.); class DBaseDecal : public DThinker { diff --git a/src/g_shared/a_specialspot.cpp b/src/g_shared/a_specialspot.cpp index 5c0919820a..dc6829d2dd 100644 --- a/src/g_shared/a_specialspot.cpp +++ b/src/g_shared/a_specialspot.cpp @@ -248,7 +248,7 @@ void DSpotState::Tick () DSpotState *DSpotState::GetSpotState(bool create) { - if (SpotState == NULL && create) SpotState = new DSpotState; + if (SpotState == NULL && create) SpotState = Create(); return SpotState; } diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 1afe8d46df..4b2b1e727b 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -771,7 +771,7 @@ void DBaseStatusBar::ShowPlayerName () EColorRange color; color = (CPlayer == &players[consoleplayer]) ? CR_GOLD : CR_GREEN; - AttachMessage (new DHUDMessageFadeOut (SmallFont, CPlayer->userinfo.GetName(), + AttachMessage (Create (SmallFont, CPlayer->userinfo.GetName(), 1.5f, 0.92f, 0, 0, color, 2.f, 0.35f), MAKE_ID('P','N','A','M')); } @@ -1664,7 +1664,7 @@ DEFINE_ACTION_FUNCTION(DHUDFont, Create) PARAM_BOOL_DEF(mono); PARAM_INT_DEF(sx); PARAM_INT_DEF(sy); - ACTION_RETURN_POINTER(new DHUDFont(fnt, spac, mono, sy, sy)); + ACTION_RETURN_POINTER(Create(fnt, spac, mono, sy, sy)); } DEFINE_FIELD(DHUDFont, mFont); diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index b3fc0b7126..ad9a87b208 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -643,7 +643,7 @@ void FGameConfigFile::CreateStandardAutoExec(const char *section, bool start) } } -void FGameConfigFile::AddAutoexec (DArgs *list, const char *game) +void FGameConfigFile::AddAutoexec (FArgs *list, const char *game) { char section[64]; const char *key; diff --git a/src/gameconfigfile.h b/src/gameconfigfile.h index faeec2e517..1ba066d058 100644 --- a/src/gameconfigfile.h +++ b/src/gameconfigfile.h @@ -37,7 +37,7 @@ #include "doomtype.h" #include "configfile.h" -class DArgs; +class FArgs; class FIWadManager; class FGameConfigFile : public FConfigFile @@ -53,7 +53,7 @@ public: void DoModSetup (const char *gamename); void ArchiveGlobalData (); void ArchiveGameData (const char *gamename); - void AddAutoexec (DArgs *list, const char *gamename); + void AddAutoexec (FArgs *list, const char *gamename); FString GetConfigPath (bool tryProg); void ReadNetVars (); diff --git a/src/gi.cpp b/src/gi.cpp index 6be40f7018..ecc3016241 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -371,6 +371,7 @@ void FMapInfoParser::ParseGameInfo() GAMEINFOKEY_STRING_STAMPED(statusbarclass, "statusbarclass", statusbarclassfile) GAMEINFOKEY_MUSIC(intermissionMusic, intermissionOrder, "intermissionMusic") GAMEINFOKEY_STRING(CursorPic, "CursorPic") + GAMEINFOKEY_STRING(MessageBoxClass, "MessageBoxClass") GAMEINFOKEY_BOOL(noloopfinalemusic, "noloopfinalemusic") GAMEINFOKEY_BOOL(drawreadthis, "drawreadthis") GAMEINFOKEY_BOOL(swapmenu, "swapmenu") diff --git a/src/gi.h b/src/gi.h index 52fdaf49c1..be46aabfa9 100644 --- a/src/gi.h +++ b/src/gi.h @@ -152,6 +152,7 @@ struct gameinfo_t int statusbarfile = -1; FName statusbarclass; int statusbarclassfile = -1; + FName MessageBoxClass; FName backpacktype; FString intermissionMusic; int intermissionOrder; diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 24e6ee6264..a684f4c4cc 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -120,7 +120,10 @@ void OpenGLFrameBuffer::InitializeState() if (first) { - ogl_LoadFunctions(); + if (ogl_LoadFunctions() == ogl_LOAD_FAILED) + { + I_FatalError("Failed to load OpenGL functions."); + } } gl_LoadExtensions(); diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 916d1c24d5..650f03f875 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -897,7 +897,7 @@ void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t s if (state == FSTATE_InLevel) wipegamestate = GS_FINALE; // don't wipe when within a level. viewactive = false; automapactive = false; - DIntermissionController::CurrentIntermission = new DIntermissionController(desc, deleteme, state); + DIntermissionController::CurrentIntermission = Create(desc, deleteme, state); GC::WriteBarrier(DIntermissionController::CurrentIntermission); } diff --git a/src/m_argv.cpp b/src/m_argv.cpp index 3958859860..aac5771d63 100644 --- a/src/m_argv.cpp +++ b/src/m_argv.cpp @@ -37,47 +37,45 @@ #include "cmdlib.h" #include "i_system.h" -IMPLEMENT_CLASS(DArgs, false, false) - //=========================================================================== // -// DArgs Default Constructor +// FArgs Default Constructor // //=========================================================================== -DArgs::DArgs() +FArgs::FArgs() { } //=========================================================================== // -// DArgs Copy Constructor +// FArgs Copy Constructor // //=========================================================================== -DArgs::DArgs(const DArgs &other) -: DObject(), Argv(other.Argv) +FArgs::FArgs(const FArgs &other) +: Argv(other.Argv) { } //=========================================================================== // -// DArgs Argv Constructor +// FArgs Argv Constructor // //=========================================================================== -DArgs::DArgs(int argc, char **argv) +FArgs::FArgs(int argc, char **argv) { SetArgs(argc, argv); } //=========================================================================== // -// DArgs String Argv Constructor +// FArgs String Argv Constructor // //=========================================================================== -DArgs::DArgs(int argc, FString *argv) +FArgs::FArgs(int argc, FString *argv) { AppendArgs(argc, argv); } @@ -86,11 +84,11 @@ DArgs::DArgs(int argc, FString *argv) //=========================================================================== // -// DArgs Copy Operator +// FArgs Copy Operator // //=========================================================================== -DArgs &DArgs::operator=(const DArgs &other) +FArgs &FArgs::operator=(const FArgs &other) { Argv = other.Argv; return *this; @@ -98,11 +96,11 @@ DArgs &DArgs::operator=(const DArgs &other) //=========================================================================== // -// DArgs :: SetArgs +// FArgs :: SetArgs // //=========================================================================== -void DArgs::SetArgs(int argc, char **argv) +void FArgs::SetArgs(int argc, char **argv) { Argv.Resize(argc); for (int i = 0; i < argc; ++i) @@ -113,25 +111,25 @@ void DArgs::SetArgs(int argc, char **argv) //=========================================================================== // -// DArgs :: FlushArgs +// FArgs :: FlushArgs // //=========================================================================== -void DArgs::FlushArgs() +void FArgs::FlushArgs() { Argv.Clear(); } //=========================================================================== // -// DArgs :: CheckParm +// FArgs :: CheckParm // // Checks for the given parameter in the program's command line arguments. // Returns the argument number (1 to argc-1) or 0 if not present // //=========================================================================== -int DArgs::CheckParm(const char *check, int start) const +int FArgs::CheckParm(const char *check, int start) const { for (unsigned i = start; i < Argv.Size(); ++i) { @@ -145,14 +143,14 @@ int DArgs::CheckParm(const char *check, int start) const //=========================================================================== // -// DArgs :: CheckParmList +// FArgs :: CheckParmList // // Returns the number of arguments after the parameter (if found) and also // returns a pointer to the first argument. // //=========================================================================== -int DArgs::CheckParmList(const char *check, FString **strings, int start) const +int FArgs::CheckParmList(const char *check, FString **strings, int start) const { unsigned int i, parmat = CheckParm(check, start); @@ -180,14 +178,14 @@ int DArgs::CheckParmList(const char *check, FString **strings, int start) const //=========================================================================== // -// DArgs :: CheckValue +// FArgs :: CheckValue // // Like CheckParm, but it also checks that the parameter has a value after // it and returns that or NULL if not present. // //=========================================================================== -const char *DArgs::CheckValue(const char *check) const +const char *FArgs::CheckValue(const char *check) const { int i = CheckParm(check); @@ -204,14 +202,14 @@ const char *DArgs::CheckValue(const char *check) const //=========================================================================== // -// DArgs :: TakeValue +// FArgs :: TakeValue // // Like CheckValue, except it also removes the parameter and its argument // (if present) from argv. // //=========================================================================== -FString DArgs::TakeValue(const char *check) +FString FArgs::TakeValue(const char *check) { int i = CheckParm(check); FString out; @@ -233,11 +231,11 @@ FString DArgs::TakeValue(const char *check) //=========================================================================== // -// DArgs :: RemoveArg +// FArgs :: RemoveArg // //=========================================================================== -void DArgs::RemoveArgs(const char *check) +void FArgs::RemoveArgs(const char *check) { int i = CheckParm(check); @@ -253,64 +251,64 @@ void DArgs::RemoveArgs(const char *check) //=========================================================================== // -// DArgs :: GetArg +// FArgs :: GetArg // // Gets the argument at a particular position. // //=========================================================================== -const char *DArgs::GetArg(int arg) const +const char *FArgs::GetArg(int arg) const { return ((unsigned)arg < Argv.Size()) ? Argv[arg].GetChars() : NULL; } //=========================================================================== // -// DArgs :: GetArgList +// FArgs :: GetArgList // // Returns a pointer to the FString at a particular position. // //=========================================================================== -FString *DArgs::GetArgList(int arg) const +FString *FArgs::GetArgList(int arg) const { return ((unsigned)arg < Argv.Size()) ? &Argv[arg] : NULL; } //=========================================================================== // -// DArgs :: NumArgs +// FArgs :: NumArgs // //=========================================================================== -int DArgs::NumArgs() const +int FArgs::NumArgs() const { return (int)Argv.Size(); } //=========================================================================== // -// DArgs :: AppendArg +// FArgs :: AppendArg // // Adds another argument to argv. Invalidates any previous results from // GetArgList(). // //=========================================================================== -void DArgs::AppendArg(FString arg) +void FArgs::AppendArg(FString arg) { Argv.Push(arg); } //=========================================================================== // -// DArgs :: AppendArgs +// FArgs :: AppendArgs // // Adds an array of FStrings to argv. // //=========================================================================== -void DArgs::AppendArgs(int argc, const FString *argv) +void FArgs::AppendArgs(int argc, const FString *argv) { if (argv != NULL && argc > 0) { @@ -324,20 +322,20 @@ void DArgs::AppendArgs(int argc, const FString *argv) //=========================================================================== // -// DArgs :: RemoveArg +// FArgs :: RemoveArg // // Removes a single argument from argv. // //=========================================================================== -void DArgs::RemoveArg(int argindex) +void FArgs::RemoveArg(int argindex) { Argv.Delete(argindex); } //=========================================================================== // -// DArgs :: CollectFiles +// FArgs :: CollectFiles // // Takes all arguments after any instance of -param and any arguments before // all switches that end in .extension and combines them into a single @@ -346,7 +344,7 @@ void DArgs::RemoveArg(int argindex) // //=========================================================================== -void DArgs::CollectFiles(const char *param, const char *extension) +void FArgs::CollectFiles(const char *param, const char *extension) { TArray work; unsigned int i; @@ -407,7 +405,7 @@ void DArgs::CollectFiles(const char *param, const char *extension) //=========================================================================== // -// DArgs :: GatherFiles +// FArgs :: GatherFiles // // Returns all the arguments after the first instance of -param. If you want // to combine more than one or get switchless stuff included, you need to @@ -415,11 +413,11 @@ void DArgs::CollectFiles(const char *param, const char *extension) // //=========================================================================== -DArgs *DArgs::GatherFiles(const char *param) const +FArgs *FArgs::GatherFiles(const char *param) const { FString *files; int filecount; filecount = CheckParmList(param, &files); - return new DArgs(filecount, files); + return new FArgs(filecount, files); } diff --git a/src/m_argv.h b/src/m_argv.h index c317256f77..31df56ad8e 100644 --- a/src/m_argv.h +++ b/src/m_argv.h @@ -40,16 +40,15 @@ // // MISC // -class DArgs : public DObject +class FArgs { - DECLARE_CLASS(DArgs, DObject) public: - DArgs(); - DArgs(const DArgs &args); - DArgs(int argc, char **argv); - DArgs(int argc, FString *argv); + FArgs(); + FArgs(const FArgs &args); + FArgs(int argc, char **argv); + FArgs(int argc, FString *argv); - DArgs &operator=(const DArgs &other); + FArgs &operator=(const FArgs &other); void AppendArg(FString arg); void AppendArgs(int argc, const FString *argv); @@ -57,7 +56,7 @@ public: void RemoveArgs(const char *check); void SetArgs(int argc, char **argv); void CollectFiles(const char *param, const char *extension); - DArgs *GatherFiles(const char *param) const; + FArgs *GatherFiles(const char *param) const; void SetArg(int argnum, const char *arg); int CheckParm(const char *check, int start=1) const; // Returns the position of the given parameter in the arg list (0 if not found). @@ -73,6 +72,6 @@ private: TArray Argv; }; -extern DArgs *Args; +extern FArgs *Args; #endif //__M_ARGV_H__ diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index b667415a87..cba490a0c7 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -666,7 +666,7 @@ void cht_Suicide (player_t *plyr) // the initial tick. if (plyr->mo != NULL) { - DSuicider *suicide = new DSuicider; + DSuicider *suicide = Create(); suicide->Pawn = plyr->mo; GC::WriteBarrier(suicide, suicide->Pawn); } diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 229835405b..a118638aa9 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -231,7 +231,7 @@ void M_FindResponseFile (void) ParseCommandLine (file, NULL, argv); // Create a new argument vector - DArgs *newargs = new DArgs; + FArgs *newargs = new FArgs; // Copy parameters before response file. for (index = 0; index < i; ++index) @@ -246,6 +246,7 @@ void M_FindResponseFile (void) newargs->AppendArg(Args->GetArg(index)); // Use the new argument vector as the global Args object. + delete Args; Args = newargs; if (++added_stuff == limit) { diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 8c80325c08..a14ac25b32 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -543,7 +543,7 @@ static void ParseListMenu(FScanner &sc) { sc.MustGetString(); - DListMenuDescriptor *desc = new DListMenuDescriptor; + DListMenuDescriptor *desc = Create(); desc->mMenuName = sc.String; desc->mSelectedItem = -1; desc->mAutoselect = -1; @@ -867,7 +867,7 @@ static void ParseOptionMenu(FScanner &sc) { sc.MustGetString(); - DOptionMenuDescriptor *desc = new DOptionMenuDescriptor; + DOptionMenuDescriptor *desc = Create(); desc->mMenuName = sc.String; desc->mSelectedItem = -1; desc->mScrollPos = 0; @@ -919,8 +919,8 @@ void M_ParseMenuDefs() OptionSettings.mFontColorHighlight = V_FindFontColor(gameinfo.mFontColorHighlight); OptionSettings.mFontColorSelection = V_FindFontColor(gameinfo.mFontColorSelection); // these are supposed to get GC'd after parsing is complete. - DefaultListMenuSettings = new DListMenuDescriptor; - DefaultOptionMenuSettings = new DOptionMenuDescriptor; + DefaultListMenuSettings = Create(); + DefaultOptionMenuSettings = Create(); DefaultListMenuSettings->Reset(); DefaultOptionMenuSettings->Reset(); @@ -1066,7 +1066,7 @@ static void BuildEpisodeMenu() { // Couldn't create the episode menu, either because there's too many episodes or some error occured // Create an option menu for episode selection instead. - DOptionMenuDescriptor *od = new DOptionMenuDescriptor; + DOptionMenuDescriptor *od = Create(); MenuDescriptors[NAME_Episodemenu] = od; od->mMenuName = NAME_Episodemenu; od->mTitle = "$MNU_EPISODE"; @@ -1199,7 +1199,7 @@ static void BuildPlayerclassMenu() { // Couldn't create the playerclass menu, either because there's too many episodes or some error occured // Create an option menu for class selection instead. - DOptionMenuDescriptor *od = new DOptionMenuDescriptor; + DOptionMenuDescriptor *od = Create(); MenuDescriptors[NAME_Playerclassmenu] = od; od->mMenuName = NAME_Playerclassmenu; od->mTitle = "$MNU_CHOOSECLASS"; @@ -1505,7 +1505,7 @@ fail: DOptionMenuDescriptor *od; if (desc == nullptr) { - od = new DOptionMenuDescriptor; + od = Create(); MenuDescriptors[NAME_Skillmenu] = od; od->mMenuName = NAME_Skillmenu; od->mTitle = "$MNU_CHOOSESKILL"; diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index 3684209646..3531cf2f62 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -66,14 +66,18 @@ DEFINE_ACTION_FUNCTION(DMessageBoxMenu, CallHandler) DMenu *CreateMessageBoxMenu(DMenu *parent, const char *message, int messagemode, bool playsound, FName action = NAME_None, hfunc handler = nullptr) { - auto c = PClass::FindClass("MessageBoxMenu"); + auto c = PClass::FindClass(gameinfo.MessageBoxClass); + if (!c->IsDescendantOf(NAME_MessageBoxMenu)) c = PClass::FindClass(NAME_MessageBoxMenu); auto p = c->CreateNew(); FString namestr = message; - VMValue params[] = { p, parent, &namestr, messagemode, playsound, action.GetIndex(), reinterpret_cast(handler) }; - auto f = dyn_cast(c->FindSymbol("Init", false)); - VMCall(f->Variants[0].Implementation, params, countof(params), nullptr, 0); - return (DMenu*)p; + IFVIRTUALPTRNAME(p, NAME_MessageBoxMenu, Init) + { + VMValue params[] = { p, parent, &namestr, messagemode, playsound, action.GetIndex(), reinterpret_cast(handler) }; + VMCall(func, params, countof(params), nullptr, 0); + return (DMenu*)p; + } + return nullptr; } //============================================================================= diff --git a/src/namedef.h b/src/namedef.h index 18075976d7..ad29da9ba7 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -111,10 +111,8 @@ xx(Ironlich) xx(Minotaur) xx(Sorcerer2) -// P_SpawnMapThing checks for these as health items (I smell a FIXME) -xx(Berserk) -xx(Soulsphere) -xx(Megasphere) // also counts as armor for P_SpawnMapThing +// Bots check this +xx(Megasphere) // Standard player classes xx(DoomPlayer) @@ -337,6 +335,7 @@ xx(RandomPick) xx(FRandomPick) xx(GetClass) xx(GetParentClass) +xx(GetClassName) xx(GetDefaultByType) xx(Exp) xx(Log10) @@ -912,3 +911,5 @@ xx(Enum) xx(StaticArray) xx(DynArray) xx(Struct) +xx(ReflectType) +xx(MessageBoxMenu) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index dd75f90697..58288d9e13 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3659,7 +3659,7 @@ DLevelScript::DLevelScript () { next = prev = NULL; if (DACSThinker::ActiveThinker == NULL) - new DACSThinker; + Create(); activefont = SmallFont; } @@ -4071,7 +4071,7 @@ showme: fa1 = viewer->BlendA; } } - new DFlashFader (fr1, fg1, fb1, fa1, fr2, fg2, fb2, fa2, ftime, viewer->mo); + Create (fr1, fg1, fb1, fa1, fr2, fg2, fb2, fa2, ftime, viewer->mo); } } } @@ -8819,13 +8819,13 @@ scriptwait: { default: // normal alpha = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 1.f; - msg = new DHUDMessage (activefont, work, x, y, hudwidth, hudheight, color, holdTime); + msg = Create (activefont, work, x, y, hudwidth, hudheight, color, holdTime); break; case 1: // fade out { float fadeTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.5f; alpha = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 1.f; - msg = new DHUDMessageFadeOut (activefont, work, x, y, hudwidth, hudheight, color, holdTime, fadeTime); + msg = Create (activefont, work, x, y, hudwidth, hudheight, color, holdTime, fadeTime); } break; case 2: // type on, then fade out @@ -8833,7 +8833,7 @@ scriptwait: float typeTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.05f; float fadeTime = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 0.5f; alpha = (optstart < sp-2) ? ACSToFloat(Stack[optstart+2]) : 1.f; - msg = new DHUDMessageTypeOnFadeOut (activefont, work, x, y, hudwidth, hudheight, color, typeTime, holdTime, fadeTime); + msg = Create (activefont, work, x, y, hudwidth, hudheight, color, typeTime, holdTime, fadeTime); } break; case 3: // fade in, then fade out @@ -8841,7 +8841,7 @@ scriptwait: float inTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.5f; float outTime = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 0.5f; alpha = (optstart < sp-2) ? ACSToFloat(Stack[optstart + 2]) : 1.f; - msg = new DHUDMessageFadeInOut (activefont, work, x, y, hudwidth, hudheight, color, holdTime, inTime, outTime); + msg = Create (activefont, work, x, y, hudwidth, hudheight, color, holdTime, inTime, outTime); } break; } @@ -9630,13 +9630,13 @@ scriptwait: break; case PCD_SETFLOORTRIGGER: - new DPlaneWatcher (activator, activationline, backSide, false, STACK(8), + Create (activator, activationline, backSide, false, STACK(8), STACK(7), STACK(6), STACK(5), STACK(4), STACK(3), STACK(2), STACK(1)); sp -= 8; break; case PCD_SETCEILINGTRIGGER: - new DPlaneWatcher (activator, activationline, backSide, true, STACK(8), + Create (activator, activationline, backSide, true, STACK(8), STACK(7), STACK(6), STACK(5), STACK(4), STACK(3), STACK(2), STACK(1)); sp -= 8; break; @@ -10513,7 +10513,7 @@ static DLevelScript *P_GetScriptGoing (AActor *who, line_t *where, int num, cons return NULL; } - return new DLevelScript (who, where, num, code, module, args, argcount, flags); + return Create (who, where, num, code, module, args, argcount, flags); } DLevelScript::DLevelScript (AActor *who, line_t *where, int num, const ScriptPtr *code, FBehavior *module, @@ -10521,7 +10521,7 @@ DLevelScript::DLevelScript (AActor *who, line_t *where, int num, const ScriptPtr : activeBehavior (module) { if (DACSThinker::ActiveThinker == NULL) - new DACSThinker; + Create(); script = num; assert(code->VarCount >= code->ArgCount); diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index 19cafed238..838c885e60 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -3574,8 +3574,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetBlend) if (color2.a == 0) color2 = color; - new 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, 0, + Create(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, 0.f, float(tics)/TICRATE, self); return 0; } @@ -6813,7 +6813,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SprayDecal) { PARAM_SELF_PROLOGUE(AActor); PARAM_STRING(name); - SprayDecal(self, name); + PARAM_FLOAT_DEF(dist); + SprayDecal(self, name, dist); return 0; } diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index c7bc715f2e..40b0094ab4 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -244,7 +244,7 @@ bool P_CreateCeiling(sector_t *sec, DCeiling::ECeiling type, line_t *line, int t } // new door thinker - DCeiling *ceiling = new DCeiling (sec, speed, speed2, silent & ~4); + DCeiling *ceiling = Create (sec, speed, speed2, silent & ~4); vertex_t *spot = sec->Lines[0]->v1; switch (type) diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index bbd9281b77..a715f6a491 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -1170,9 +1170,9 @@ static void TerminalResponse (const char *str) // merchants can tell you something like this but continue to show // their dialogue screen. I think most other conversations use this // only as a response for terminating the dialogue. - StatusBar->AttachMessage(new DHUDMessageFadeOut(SmallFont, str, + StatusBar->AttachMessage(Create(SmallFont, str, float(CleanWidth/2) + 0.4f, float(ConversationMenuY - 110 + CleanHeight/2), CleanWidth, -CleanHeight, - CR_UNTRANSLATED, 3, 1), MAKE_ID('T','A','L','K')); + CR_UNTRANSLATED, 3.f, 1.f), MAKE_ID('T','A','L','K')); } else { diff --git a/src/p_doors.cpp b/src/p_doors.cpp index f09fd7f9bf..13c5447f13 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -485,7 +485,7 @@ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, } return false; } - if (new DDoor (sec, type, speed, delay, lightTag, topcountdown)) + if (Create (sec, type, speed, delay, lightTag, topcountdown)) rtn = true; } else @@ -499,7 +499,7 @@ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, if (sec->PlaneMoving(sector_t::ceiling)) continue; - if (new DDoor (sec, type, speed, delay, lightTag, topcountdown)) + if (Create(sec, type, speed, delay, lightTag, topcountdown)) rtn = true; } @@ -779,7 +779,7 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay, FDoorAnimation *anim = TexMan.FindAnimatedDoor (line->sidedef[0]->GetTexture(side_t::top)); if (anim != NULL) { - new DAnimatedDoor (sec, line, speed, delay, anim, type); + Create(sec, line, speed, delay, anim, type); return true; } return false; @@ -804,7 +804,7 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay, if (anim != NULL) { rtn = true; - new DAnimatedDoor (sec, line, speed, delay, anim, type); + Create(sec, line, speed, delay, anim, type); break; } } diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 918419fbea..580726155b 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -282,7 +282,7 @@ bool P_CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line, // new floor thinker rtn = true; - floor = new DFloor(sec); + floor = Create(sec); floor->m_Type = floortype; floor->m_Crush = crush; floor->m_Hexencrush = hexencrush; @@ -631,7 +631,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, // new floor thinker rtn = true; - floor = new DFloor (sec); + floor = Create (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 EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, secnum = newsecnum; // create and initialize a thinker for the next step - floor = new DFloor (sec); + floor = Create (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 EV_DoDonut (int tag, line_t *line, double pillarspeed, double slimespeed) s3 = ln->backsector; // Spawn rising slime - floor = new DFloor (s2); + floor = Create (s2); floor->m_Type = DFloor::donutRaise; floor->m_Crush = -1; floor->m_Hexencrush = false; @@ -828,7 +828,7 @@ bool EV_DoDonut (int tag, line_t *line, double pillarspeed, double slimespeed) floor->StartFloorSound (); // Spawn lowering donut-hole - floor = new DFloor (s1); + floor = Create (s1); floor->m_Type = DFloor::floorLowerToNearest; floor->m_Crush = -1; floor->m_Hexencrush = false; @@ -1017,7 +1017,7 @@ bool EV_DoElevator (line_t *line, DElevator::EElevator elevtype, // create and initialize new elevator thinker rtn = true; - elevator = new DElevator (sec); + elevator = Create (sec); elevator->m_Type = elevtype; elevator->m_Speed = speed; elevator->StartFloorSound (); @@ -1327,12 +1327,12 @@ bool EV_StartWaggle (int tag, line_t *line, int height, int speed, int offset, retCode = true; if (ceiling) { - waggle = new DCeilingWaggle (sector); + waggle = Create (sector); waggle->m_OriginalDist = sector->ceilingplane.fD(); } else { - waggle = new DFloorWaggle (sector); + waggle = Create (sector); waggle->m_OriginalDist = sector->floorplane.fD(); } waggle->m_Accumulator = offset; diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 6de00eb378..59a22fa762 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -408,7 +408,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) SexMessage (GStrings("SPREEKILLSELF"), buff, player->userinfo.GetGender(), player->userinfo.GetName(), player->userinfo.GetName()); - StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, buff, + StatusBar->AttachMessage (Create(SmallFont, buff, 1.5f, 0.2f, 0, 0, CR_WHITE, 3.f, 0.5f), MAKE_ID('K','S','P','R')); } } @@ -465,7 +465,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) { SexMessage (GStrings("SPREEOVER"), buff, player->userinfo.GetGender(), player->userinfo.GetName(), source->player->userinfo.GetName()); - StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, buff, + StatusBar->AttachMessage (Create (SmallFont, buff, 1.5f, 0.2f, 0, 0, CR_WHITE, 3.f, 0.5f), MAKE_ID('K','S','P','R')); } } @@ -475,7 +475,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) { SexMessage (spreemsg, buff, player->userinfo.GetGender(), player->userinfo.GetName(), source->player->userinfo.GetName()); - StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, buff, + StatusBar->AttachMessage (Create (SmallFont, buff, 1.5f, 0.2f, 0, 0, CR_WHITE, 3.f, 0.5f), MAKE_ID('K','S','P','R')); } } @@ -525,7 +525,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) { SexMessage (multimsg, buff, player->userinfo.GetGender(), player->userinfo.GetName(), source->player->userinfo.GetName()); - StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, buff, + StatusBar->AttachMessage (Create (SmallFont, buff, 1.5f, 0.8f, 0, 0, CR_RED, 3.f, 0.5f), MAKE_ID('M','K','I','L')); } } @@ -1122,20 +1122,27 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da { int reflectdamage = 0; + bool reflecttype = false; for (auto p = target->player->mo->Inventory; p != nullptr; p = p->Inventory) { // This picks the reflection item with the maximum efficiency for the given damage type. if (p->IsKindOf(NAME_PowerReflection)) { - int mydamage = p->ApplyDamageFactor(mod, damage); - if (mydamage > reflectdamage) reflectdamage = mydamage; + double alwaysreflect = p->FloatVar(NAME_Strength); + int alwaysdamage = clamp(int(damage * alwaysreflect), 0, damage); + int mydamage = alwaysdamage + p->ApplyDamageFactor(mod, damage - alwaysdamage); + if (mydamage > reflectdamage) + { + reflectdamage = mydamage; + reflecttype = p->BoolVar(NAME_ReflectType); + } } } if (reflectdamage > 0) { // use the reflect item's damage factors to get the final value here. - P_DamageMobj(source, nullptr, target, reflectdamage, NAME_Reflection ); + P_DamageMobj(source, nullptr, target, reflectdamage, reflecttype? mod : NAME_Reflection ); // Reset means of death flag. MeansOfDeath = mod; diff --git a/src/p_lights.cpp b/src/p_lights.cpp index d680bfc46b..c3a69f0527 100644 --- a/src/p_lights.cpp +++ b/src/p_lights.cpp @@ -152,14 +152,16 @@ class DPhased : public DLighting public: DPhased(sector_t *sector); DPhased(sector_t *sector, int baselevel, int phase); + // These are for internal use only but the Create template needs access to them. + DPhased(); + DPhased(sector_t *sector, int baselevel); + void Serialize(FSerializer &arc); void Tick(); protected: uint8_t m_BaseLevel; uint8_t m_Phase; private: - DPhased(); - DPhased(sector_t *sector, int baselevel); int PhaseHelper(sector_t *sector, int index, int light, sector_t *prev); }; @@ -325,7 +327,7 @@ void EV_StartLightFlickering (int tag, int upper, int lower) FSectorTagIterator it(tag); while ((secnum = it.Next()) >= 0) { - new DFlicker (&level.sectors[secnum], upper, lower); + Create (&level.sectors[secnum], upper, lower); } } @@ -506,7 +508,7 @@ void EV_StartLightStrobing (int tag, int upper, int lower, int utics, int ltics) if (sec->lightingdata) continue; - new DStrobe (sec, upper, lower, utics, ltics); + Create (sec, upper, lower, utics, ltics); } } @@ -520,7 +522,7 @@ void EV_StartLightStrobing (int tag, int utics, int ltics) if (sec->lightingdata) continue; - new DStrobe (sec, utics, ltics, false); + Create (sec, utics, ltics, false); } } @@ -826,7 +828,7 @@ void EV_StartLightGlowing (int tag, int upper, int lower, int tics) if (sec->lightingdata) continue; - new DGlow2 (sec, upper, lower, tics, false); + Create (sec, upper, lower, tics, false); } } @@ -856,7 +858,7 @@ void EV_StartLightFading (int tag, int value, int tics) if (sec->lightlevel == value) continue; - new DGlow2 (sec, sec->lightlevel, value, tics, true); + Create (sec, sec->lightlevel, value, tics, true); } } } @@ -930,7 +932,7 @@ int DPhased::PhaseHelper (sector_t *sector, int index, int light, sector_t *prev m_BaseLevel = baselevel; } else - l = new DPhased (sector, baselevel); + l = Create (sector, baselevel); int numsteps = PhaseHelper (sector->NextSpecialSector ( sector->special == LightSequenceSpecial1 ? @@ -998,52 +1000,52 @@ void P_SpawnLights(sector_t *sector) switch (sector->special) { case Light_Phased: - new DPhased(sector, 48, 63 - (sector->lightlevel & 63)); + Create(sector, 48, 63 - (sector->lightlevel & 63)); break; // [RH] Hexen-like phased lighting case LightSequenceStart: - new DPhased(sector); + Create(sector); break; case dLight_Flicker: - new DLightFlash(sector); + Create(sector); break; case dLight_StrobeFast: - new DStrobe(sector, STROBEBRIGHT, FASTDARK, false); + Create(sector, STROBEBRIGHT, FASTDARK, false); break; case dLight_StrobeSlow: - new DStrobe(sector, STROBEBRIGHT, SLOWDARK, false); + Create(sector, STROBEBRIGHT, SLOWDARK, false); break; case dLight_Strobe_Hurt: - new DStrobe(sector, STROBEBRIGHT, FASTDARK, false); + Create(sector, STROBEBRIGHT, FASTDARK, false); break; case dLight_Glow: - new DGlow(sector); + Create(sector); break; case dLight_StrobeSlowSync: - new DStrobe(sector, STROBEBRIGHT, SLOWDARK, true); + Create(sector, STROBEBRIGHT, SLOWDARK, true); break; case dLight_StrobeFastSync: - new DStrobe(sector, STROBEBRIGHT, FASTDARK, true); + Create(sector, STROBEBRIGHT, FASTDARK, true); break; case dLight_FireFlicker: - new DFireFlicker(sector); + Create(sector); break; case dScroll_EastLavaDamage: - new DStrobe(sector, STROBEBRIGHT, FASTDARK, false); + Create(sector, STROBEBRIGHT, FASTDARK, false); break; case sLight_Strobe_Hurt: - new DStrobe(sector, STROBEBRIGHT, FASTDARK, false); + Create(sector, STROBEBRIGHT, FASTDARK, false); break; default: diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 21ed99c619..5e7dfa2187 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -938,7 +938,7 @@ DEFINE_ACTION_FUNCTION(DBlockLinesIterator, Create) PARAM_PROLOGUE; PARAM_OBJECT_NOT_NULL(origin, AActor); PARAM_FLOAT_DEF(radius); - ACTION_RETURN_OBJECT(new DBlockLinesIterator(origin, radius)); + ACTION_RETURN_OBJECT(Create(origin, radius)); } DEFINE_ACTION_FUNCTION(DBlockLinesIterator, CreateFromPos) @@ -950,7 +950,7 @@ DEFINE_ACTION_FUNCTION(DBlockLinesIterator, CreateFromPos) PARAM_FLOAT(h); PARAM_FLOAT(radius); PARAM_POINTER_DEF(sec, sector_t); - ACTION_RETURN_OBJECT(new DBlockLinesIterator(x, y, z, h, radius, sec)); + ACTION_RETURN_OBJECT(Create(x, y, z, h, radius, sec)); } DEFINE_ACTION_FUNCTION(DBlockLinesIterator, Next) @@ -1277,7 +1277,7 @@ DEFINE_ACTION_FUNCTION(DBlockThingsIterator, Create) PARAM_OBJECT_NOT_NULL(origin, AActor); PARAM_FLOAT_DEF(radius); PARAM_BOOL_DEF(ignore); - ACTION_RETURN_OBJECT(new DBlockThingsIterator(origin, radius, ignore)); + ACTION_RETURN_OBJECT(Create(origin, radius, ignore)); } DEFINE_ACTION_FUNCTION(DBlockThingsIterator, CreateFromPos) @@ -1289,7 +1289,7 @@ DEFINE_ACTION_FUNCTION(DBlockThingsIterator, CreateFromPos) PARAM_FLOAT(h); PARAM_FLOAT(radius); PARAM_BOOL(ignore); - ACTION_RETURN_OBJECT(new DBlockThingsIterator(x, y, z, h, radius, ignore, nullptr)); + ACTION_RETURN_OBJECT(Create(x, y, z, h, radius, ignore, nullptr)); } DEFINE_ACTION_FUNCTION(DBlockThingsIterator, Next) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 4df7bdd7bb..c0098490ad 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1380,6 +1380,54 @@ DEFINE_ACTION_FUNCTION(AActor, ObtainInventory) return 0; } +//--------------------------------------------------------------------------- +// +// FUNC P_GetRealMaxHealth +// +// Taken out of P_GiveBody so that the bot code can also use it to decide +// whether to pick up an item or not. +// +//--------------------------------------------------------------------------- + +int P_GetRealMaxHealth(APlayerPawn *actor, int max) +{ + // Max is 0 by default, preserving default behavior for P_GiveBody() + // calls while supporting health pickups. + auto player = actor->player; + if (max <= 0) + { + max = actor->GetMaxHealth(true); + // [MH] First step in predictable generic morph effects + if (player->morphTics) + { + if (player->MorphStyle & MORPH_FULLHEALTH) + { + if (!(player->MorphStyle & MORPH_ADDSTAMINA)) + { + max -= actor->stamina + actor->BonusHealth; + } + } + else // old health behaviour + { + max = MAXMORPHHEALTH; + if (player->MorphStyle & MORPH_ADDSTAMINA) + { + max += actor->stamina + actor->BonusHealth; + } + } + } + } + else + { + // Bonus health should be added on top of the item's limit. + if (player->morphTics == 0 || (player->MorphStyle & MORPH_ADDSTAMINA)) + { + max += actor->BonusHealth; + } + } + return max; +} + //--------------------------------------------------------------------------- // // FUNC P_GiveBody @@ -1400,33 +1448,8 @@ bool P_GiveBody(AActor *actor, int num, int max) num = clamp(num, -65536, 65536); // prevent overflows for bad values if (player != NULL) { - // Max is 0 by default, preserving default behavior for P_GiveBody() - // calls while supporting health pickups. - if (max <= 0) - { - max = static_cast(actor)->GetMaxHealth(true); - // [MH] First step in predictable generic morph effects - if (player->morphTics) - { - if (player->MorphStyle & MORPH_FULLHEALTH) - { - if (!(player->MorphStyle & MORPH_ADDSTAMINA)) - { - max -= player->mo->stamina + player->mo->BonusHealth; - } - } - else // old health behaviour - { - max = MAXMORPHHEALTH; - if (player->MorphStyle & MORPH_ADDSTAMINA) - { - max += player->mo->stamina + player->mo->BonusHealth; - } - } - } - } - // [RH] For Strife: A negative body sets you up with a percentage - // of your full health. + max = P_GetRealMaxHealth(player->mo, max); // do not pass voodoo dolls in here. + // [RH] For Strife: A negative value sets you up with a percentage of your full health. if (num < 0) { num = max * -num / 100; @@ -7952,7 +7975,7 @@ DEFINE_ACTION_FUNCTION(DActorIterator, Create) PARAM_PROLOGUE; PARAM_INT(tid); PARAM_CLASS_DEF(type, AActor); - ACTION_RETURN_OBJECT(new DActorIterator(type, tid)); + ACTION_RETURN_OBJECT(Create(type, tid)); } DEFINE_ACTION_FUNCTION(DActorIterator, Next) diff --git a/src/p_pillar.cpp b/src/p_pillar.cpp index 77316ad2c5..0f383b43f7 100644 --- a/src/p_pillar.cpp +++ b/src/p_pillar.cpp @@ -238,7 +238,7 @@ bool EV_DoPillar (DPillar::EPillar type, line_t *line, int tag, continue; rtn = true; - new DPillar (sec, type, speed, height, height2, crush, hexencrush); + Create (sec, type, speed, height, height2, crush, hexencrush); } return rtn; } diff --git a/src/p_plats.cpp b/src/p_plats.cpp index 8dd82c024a..320597ddcc 100644 --- a/src/p_plats.cpp +++ b/src/p_plats.cpp @@ -253,7 +253,7 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, double height, // Find lowest & highest floors around sector rtn = true; - plat = new DPlat (sec); + plat = Create (sec); plat->m_Type = type; plat->m_Crush = -1; diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 45c4d36d73..cb89305d87 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -255,7 +255,7 @@ DPSprite *player_t::GetPSprite(PSPLayers layer) DPSprite *pspr = FindPSprite(layer); if (pspr == nullptr) { - pspr = new DPSprite(this, newcaller, layer); + pspr = Create(this, newcaller, layer); } else { @@ -1263,7 +1263,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Overlay) } DPSprite *pspr; - pspr = new DPSprite(player, stateowner, layer); + pspr = Create(player, stateowner, layer); pspr->SetState(state); ACTION_RETURN_BOOL(true); } diff --git a/src/p_pusher.cpp b/src/p_pusher.cpp index 0b08b4f65b..c4b38c582b 100644 --- a/src/p_pusher.cpp +++ b/src/p_pusher.cpp @@ -371,7 +371,7 @@ void P_SpawnPushers () { FSectorTagIterator itr(l->args[0]); while ((s = itr.Next()) >= 0) - new DPusher(DPusher::p_wind, l->args[3] ? l : NULL, l->args[1], l->args[2], NULL, s); + Create(DPusher::p_wind, l->args[3] ? l : nullptr, l->args[1], l->args[2], nullptr, s); l->special = 0; break; } @@ -380,7 +380,7 @@ void P_SpawnPushers () { FSectorTagIterator itr(l->args[0]); while ((s = itr.Next()) >= 0) - new DPusher(DPusher::p_current, l->args[3] ? l : NULL, l->args[1], l->args[2], NULL, s); + Create(DPusher::p_current, l->args[3] ? l : nullptr, l->args[1], l->args[2], nullptr, s); l->special = 0; break; } @@ -394,7 +394,7 @@ void P_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) - new DPusher (DPusher::p_push, l->args[3] ? l : NULL, l->args[2], + Create (DPusher::p_push, l->args[3] ? l : NULL, l->args[2], 0, thing, s); } } @@ -407,7 +407,7 @@ void P_SpawnPushers () if (thing->GetClass()->TypeName == NAME_PointPusher || thing->GetClass()->TypeName == NAME_PointPuller) { - new DPusher (DPusher::p_push, l->args[3] ? l : NULL, l->args[2], 0, thing, thing->Sector->Index()); + Create (DPusher::p_push, l->args[3] ? l : NULL, l->args[2], 0, thing, thing->Sector->Index()); } } } @@ -452,7 +452,7 @@ void AdjustPusher (int tag, int magnitude, int angle, bool wind) } if (i == numcollected) { - new DPusher (type, NULL, magnitude, angle, NULL, secnum); + Create (type, nullptr, magnitude, angle, nullptr, secnum); } } } diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index b20e9af099..6c8d29973f 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -996,7 +996,7 @@ void G_SerializeLevel(FSerializer &arc, bool hubload) // [ZZ] serialize events E_SerializeEvents(arc); - DThinker::SerializeThinkers(arc, !hubload); + DThinker::SerializeThinkers(arc, hubload); arc.Array("polyobjs", polyobjs, po_NumPolyobjs); SerializeSubsectors(arc, "subsectors"); StatusBar->SerializeMessages(arc); diff --git a/src/p_scroll.cpp b/src/p_scroll.cpp index d74c6273f2..59b18f1cee 100644 --- a/src/p_scroll.cpp +++ b/src/p_scroll.cpp @@ -470,7 +470,7 @@ void P_SpawnScrollers(void) FSectorTagIterator itr(l->args[0]); while ((s = itr.Next()) >= 0) { - new DScroller(EScroll::sc_ceiling, -dx, dy, control, s, accel); + Create(EScroll::sc_ceiling, -dx, dy, control, s, accel); } for (unsigned j = 0; j < copyscrollers.Size(); j++) { @@ -478,7 +478,7 @@ void P_SpawnScrollers(void) if (line->args[0] == l->args[0] && (line->args[1] & 1)) { - new DScroller(EScroll::sc_ceiling, -dx, dy, control, line->frontsector->Index(), accel); + Create(EScroll::sc_ceiling, -dx, dy, control, line->frontsector->Index(), accel); } } break; @@ -490,7 +490,7 @@ void P_SpawnScrollers(void) FSectorTagIterator itr(l->args[0]); while ((s = itr.Next()) >= 0) { - new DScroller (EScroll::sc_floor, -dx, dy, control, s, accel); + Create (EScroll::sc_floor, -dx, dy, control, s, accel); } for(unsigned j = 0;j < copyscrollers.Size(); j++) { @@ -498,7 +498,7 @@ void P_SpawnScrollers(void) if (line->args[0] == l->args[0] && (line->args[1] & 2)) { - new DScroller(EScroll::sc_floor, -dx, dy, control, line->frontsector->Index(), accel); + Create(EScroll::sc_floor, -dx, dy, control, line->frontsector->Index(), accel); } } } @@ -508,7 +508,7 @@ void P_SpawnScrollers(void) FSectorTagIterator itr(l->args[0]); while ((s = itr.Next()) >= 0) { - new DScroller (EScroll::sc_carry, dx, dy, control, s, accel); + Create (EScroll::sc_carry, dx, dy, control, s, accel); } for(unsigned j = 0;j < copyscrollers.Size(); j++) { @@ -516,7 +516,7 @@ void P_SpawnScrollers(void) if (line->args[0] == l->args[0] && (line->args[1] & 4)) { - new DScroller (EScroll::sc_carry, dx, dy, control, line->frontsector->Index(), accel); + Create (EScroll::sc_carry, dx, dy, control, line->frontsector->Index(), accel); } } } @@ -530,7 +530,7 @@ void P_SpawnScrollers(void) while ((s = itr.Next()) >= 0) { if (s != (int)i) - new DScroller(dx, dy, &level.lines[s], control, accel); + Create(dx, dy, &level.lines[s], control, accel); } break; } @@ -538,35 +538,35 @@ void P_SpawnScrollers(void) case Scroll_Texture_Offsets: // killough 3/2/98: scroll according to sidedef offsets s = level.lines[i].sidedef[0]->Index(); - new DScroller (EScroll::sc_side, -level.sides[s].GetTextureXOffset(side_t::mid), + Create (EScroll::sc_side, -level.sides[s].GetTextureXOffset(side_t::mid), level.sides[s].GetTextureYOffset(side_t::mid), -1, s, accel, SCROLLTYPE(l->args[0])); break; case Scroll_Texture_Left: l->special = special; // Restore the special, for compat_useblocking's benefit. s = level.lines[i].sidedef[0]->Index(); - new DScroller (EScroll::sc_side, l->args[0] / 64., 0, + Create (EScroll::sc_side, l->args[0] / 64., 0, -1, s, accel, SCROLLTYPE(l->args[1])); break; case Scroll_Texture_Right: l->special = special; s = level.lines[i].sidedef[0]->Index(); - new DScroller (EScroll::sc_side, -l->args[0] / 64., 0, + Create (EScroll::sc_side, -l->args[0] / 64., 0, -1, s, accel, SCROLLTYPE(l->args[1])); break; case Scroll_Texture_Up: l->special = special; s = level.lines[i].sidedef[0]->Index(); - new DScroller (EScroll::sc_side, 0, l->args[0] / 64., + Create (EScroll::sc_side, 0, l->args[0] / 64., -1, s, accel, SCROLLTYPE(l->args[1])); break; case Scroll_Texture_Down: l->special = special; s = level.lines[i].sidedef[0]->Index(); - new DScroller (EScroll::sc_side, 0, -l->args[0] / 64., + Create (EScroll::sc_side, 0, -l->args[0] / 64., -1, s, accel, SCROLLTYPE(l->args[1])); break; @@ -575,7 +575,7 @@ void P_SpawnScrollers(void) if (l->args[0] == 0) { dx = (l->args[1] - l->args[2]) / 64.; dy = (l->args[4] - l->args[3]) / 64.; - new DScroller (EScroll::sc_side, dx, dy, -1, s, accel); + Create (EScroll::sc_side, dx, dy, -1, s, accel); } break; @@ -656,7 +656,7 @@ void SetWallScroller (int id, int sidechoice, double dx, double dy, EScrollPos W } if (i == numcollected) { - new DScroller (EScroll::sc_side, dx, dy, -1, sidenum, 0, Where); + Create (EScroll::sc_side, dx, dy, -1, sidenum, 0, Where); } } } @@ -696,11 +696,11 @@ void SetScroller (int tag, EScroll type, double dx, double dy) FSectorTagIterator itr(tag); while ((i = itr.Next()) >= 0) { - new DScroller (type, dx, dy, -1, i, 0); + Create (type, dx, dy, -1, i, 0); } } void P_CreateScroller(EScroll type, double dx, double dy, int control, int affectee, int accel, EScrollPos scrollpos) { - new DScroller(type, dx, dy, control, affectee, accel, scrollpos); + Create(type, dx, dy, control, affectee, accel, scrollpos); } diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 43c094e25f..7c128eb1d2 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1133,7 +1133,7 @@ void P_InitSectorSpecial(sector_t *sector, int special) break; case dSector_DoorCloseIn30: - new DDoor(sector, DDoor::doorWaitClose, 2, 0, 0, 30 * TICRATE); + Create(sector, DDoor::doorWaitClose, 2, 0, 0, 30 * TICRATE); break; case dDamage_End: @@ -1141,7 +1141,7 @@ void P_InitSectorSpecial(sector_t *sector, int special) break; case dSector_DoorRaiseIn5Mins: - new DDoor (sector, DDoor::doorWaitRaise, 2, TICRATE*30/7, 0, 5*60*TICRATE); + Create (sector, DDoor::doorWaitRaise, 2, TICRATE*30/7, 0, 5*60*TICRATE); break; case dFriction_Low: @@ -1322,19 +1322,19 @@ void P_SpawnSpecials (void) // killough 3/16/98: Add support for setting // floor lighting independently (e.g. lava) case Transfer_FloorLight: - new DLightTransfer (line.frontsector, line.args[0], true); + Create (line.frontsector, line.args[0], true); break; // killough 4/11/98: Add support for setting // ceiling lighting independently case Transfer_CeilingLight: - new DLightTransfer (line.frontsector, line.args[0], false); + Create (line.frontsector, line.args[0], false); break; // [Graf Zahl] Add support for setting lighting // per wall independently case Transfer_WallLight: - new DWallLightTransfer (line.frontsector, line.args[0], line.args[1]); + Create (line.frontsector, line.args[0], line.args[1]); break; case Sector_Attach3dMidtex: diff --git a/src/p_spec.h b/src/p_spec.h index 48535d0b03..5c8130a532 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -190,9 +190,9 @@ public: void Tick (); bool IsLift() const { return m_Type == platDownWaitUpStay || m_Type == platDownWaitUpStayStone; } + DPlat(sector_t *sector); protected: - DPlat (sector_t *sector); double m_Speed; double m_Low; diff --git a/src/p_switch.cpp b/src/p_switch.cpp index d23e30ea22..3563f96b80 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -103,7 +103,7 @@ static bool P_StartButton (side_t *side, int Where, FSwitchDef *Switch, const DV } } - new DActiveButton (side, Where, Switch, pos, useagain); + Create (side, Where, Switch, pos, useagain); return true; } diff --git a/src/p_tags.cpp b/src/p_tags.cpp index 6fe06ed0fc..74bcafbd78 100644 --- a/src/p_tags.cpp +++ b/src/p_tags.cpp @@ -382,7 +382,7 @@ DEFINE_ACTION_FUNCTION(DSectorTagIterator, Create) PARAM_PROLOGUE; PARAM_INT(tag); PARAM_POINTER_DEF(line, line_t); - ACTION_RETURN_POINTER(new DSectorTagIterator(tag, line)); + ACTION_RETURN_POINTER(Create(tag, line)); } DEFINE_ACTION_FUNCTION(DSectorTagIterator, Next) @@ -416,7 +416,7 @@ DEFINE_ACTION_FUNCTION(DLineIdIterator, Create) { PARAM_PROLOGUE; PARAM_INT(tag); - ACTION_RETURN_POINTER(new DLineIdIterator(tag)); + ACTION_RETURN_POINTER(Create(tag)); } DEFINE_ACTION_FUNCTION(DLineIdIterator, Next) diff --git a/src/po_man.cpp b/src/po_man.cpp index 0a8948b232..09c42211cf 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -34,6 +34,7 @@ #include "p_blockmap.h" #include "g_levellocals.h" #include "actorinlines.h" +#include "v_text.h" // MACROS ------------------------------------------------------------------ @@ -390,7 +391,7 @@ bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, // cannot do rotations on linked polyportals. break; } - pe = new DRotatePoly(poly->tag); + pe = Create(poly->tag); poly->specialdata = pe; poly->bBlocked = false; if (byteAngle != 0) @@ -472,7 +473,7 @@ bool EV_MovePoly (line_t *line, int polyNum, double speed, DAngle angle, { // poly is already in motion break; } - pe = new DMovePoly(poly->tag); + pe = Create(poly->tag); poly->specialdata = pe; poly->bBlocked = false; pe->m_Dist = dist; // Distance @@ -554,7 +555,7 @@ bool EV_MovePolyTo(line_t *line, int polyNum, double speed, const DVector2 &targ { // poly is already in motion break; } - pe = new DMovePolyTo(poly->tag); + pe = Create(poly->tag); poly->specialdata = pe; poly->bBlocked = false; pe->m_Dist = distlen; @@ -709,7 +710,7 @@ bool EV_OpenPolyDoor(line_t *line, int polyNum, double speed, DAngle angle, int break; } - pd = new DPolyDoor(poly->tag, type); + pd = Create(poly->tag, type); poly->specialdata = pd; if (type == PODOOR_SLIDE) { @@ -1536,19 +1537,23 @@ static void SpawnPolyobj (int index, int tag, int type) { if (po->Sidedefs.Size() > 0) { - I_Error ("SpawnPolyobj: Polyobj %d already spawned.\n", tag); + Printf (TEXTCOLOR_RED "SpawnPolyobj: Polyobj %d already spawned.\n", tag); + return; } - sd->linedef->special = 0; - sd->linedef->args[0] = 0; - IterFindPolySides(&polyobjs[index], sd); - po->MirrorNum = sd->linedef->args[1]; - po->crush = (type != SMT_PolySpawn) ? 3 : 0; - po->bHurtOnTouch = (type == SMT_PolySpawnHurt); - po->tag = tag; - po->seqType = sd->linedef->args[2]; - if (po->seqType < 0 || po->seqType > 63) + else { - po->seqType = 0; + sd->linedef->special = 0; + sd->linedef->args[0] = 0; + IterFindPolySides(&polyobjs[index], sd); + po->MirrorNum = sd->linedef->args[1]; + po->crush = (type != SMT_PolySpawn) ? 3 : 0; + po->bHurtOnTouch = (type == SMT_PolySpawnHurt); + po->tag = tag; + po->seqType = sd->linedef->args[2]; + if (po->seqType < 0 || po->seqType > 63) + { + po->seqType = 0; + } } break; } @@ -1570,9 +1575,13 @@ static void SpawnPolyobj (int index, int tag, int type) { if (!level.sides[i].linedef->args[1]) { - I_Error("SpawnPolyobj: Explicit line missing order number in poly %d, linedef %d.\n", tag, level.sides[i].linedef->Index()); + Printf(TEXTCOLOR_RED "SpawnPolyobj: Explicit line missing order number in poly %d, linedef %d.\n", tag, level.sides[i].linedef->Index()); + return; + } + else + { + po->Sidedefs.Push(&level.sides[i]); } - po->Sidedefs.Push (&level.sides[i]); } } qsort(&po->Sidedefs[0], po->Sidedefs.Size(), sizeof(po->Sidedefs[0]), posicmp); @@ -1585,7 +1594,10 @@ static void SpawnPolyobj (int index, int tag, int type) po->MirrorNum = po->Sidedefs[0]->linedef->args[2]; } else - I_Error ("SpawnPolyobj: Poly %d does not exist\n", tag); + { + Printf(TEXTCOLOR_RED "SpawnPolyobj: Poly %d does not exist\n", tag); + return; + } } validcount++; @@ -1648,11 +1660,13 @@ static void TranslateToStartSpot (int tag, const DVector2 &origin) } if (po == NULL) { // didn't match the tag with a polyobj tag - I_Error("TranslateToStartSpot: Unable to match polyobj tag: %d\n", tag); + Printf(TEXTCOLOR_RED "TranslateToStartSpot: Unable to match polyobj tag: %d\n", tag); + return; } if (po->Sidedefs.Size() == 0) { - I_Error ("TranslateToStartSpot: Anchor point located without a StartSpot point: %d\n", tag); + Printf(TEXTCOLOR_RED "TranslateToStartSpot: Anchor point located without a StartSpot point: %d\n", tag); + return; } po->OriginalPts.Resize(po->Sidedefs.Size()); po->PrevPts.Resize(po->Sidedefs.Size()); @@ -1738,8 +1752,7 @@ void PO_Init (void) { if (polyobjs[polyIndex].OriginalPts.Size() == 0) { - I_Error ("PO_Init: StartSpot located without an Anchor point: %d\n", - polyobjs[polyIndex].tag); + Printf (TEXTCOLOR_RED "PO_Init: StartSpot located without an Anchor point: %d\n", polyobjs[polyIndex].tag); } } InitBlockMap(); diff --git a/src/posix/cocoa/i_main.mm b/src/posix/cocoa/i_main.mm index 0d426caaa0..d8fef49324 100644 --- a/src/posix/cocoa/i_main.mm +++ b/src/posix/cocoa/i_main.mm @@ -179,7 +179,7 @@ static void I_DetectOS() } -DArgs* Args; // command line arguments +FArgs* Args; // command line arguments // Newer versions of GCC than 4.2 have a bug with C++ exceptions in Objective-C++ code. @@ -188,7 +188,7 @@ DArgs* Args; // command line arguments void OriginalMainExcept(int argc, char** argv); void OriginalMainTry(int argc, char** argv) { - Args = new DArgs(argc, argv); + Args = new FArgs(argc, argv); /* killough 1/98: diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index 298aee3a30..afeddf10dd 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -888,7 +888,10 @@ CocoaFrameBuffer::CocoaFrameBuffer(int width, int height, bool bgra, bool fullsc if (!isOpenGLInitialized) { - ogl_LoadFunctions(); + if (ogl_LoadFunctions() == ogl_LOAD_FAILED) + { + I_FatalError("Failed to load OpenGL functions."); + } isOpenGLInitialized = true; } diff --git a/src/posix/sdl/i_main.cpp b/src/posix/sdl/i_main.cpp index 7fe5aeb083..21f58e71e9 100644 --- a/src/posix/sdl/i_main.cpp +++ b/src/posix/sdl/i_main.cpp @@ -82,7 +82,7 @@ void Mac_I_FatalError(const char* errortext); // PUBLIC DATA DEFINITIONS ------------------------------------------------- // The command line arguments. -DArgs *Args; +FArgs *Args; // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -218,7 +218,7 @@ int main (int argc, char **argv) try { - Args = new DArgs(argc, argv); + Args = new FArgs(argc, argv); /* killough 1/98: diff --git a/src/r_data/r_interpolate.cpp b/src/r_data/r_interpolate.cpp index 2c7197a441..8f8fc3f800 100644 --- a/src/r_data/r_interpolate.cpp +++ b/src/r_data/r_interpolate.cpp @@ -907,7 +907,7 @@ DInterpolation *side_t::SetInterpolation(int position) { if (textures[position].interpolation == NULL) { - textures[position].interpolation = new DWallScrollInterpolation(this, position); + textures[position].interpolation = Create(this, position); } textures[position].interpolation->AddRef(); GC::WriteBarrier(textures[position].interpolation); @@ -942,19 +942,19 @@ DInterpolation *sector_t::SetInterpolation(int position, bool attach) switch (position) { case sector_t::CeilingMove: - interp = new DSectorPlaneInterpolation(this, true, attach); + interp = Create(this, true, attach); break; case sector_t::FloorMove: - interp = new DSectorPlaneInterpolation(this, false, attach); + interp = Create(this, false, attach); break; case sector_t::CeilingScroll: - interp = new DSectorScrollInterpolation(this, true); + interp = Create(this, true); break; case sector_t::FloorScroll: - interp = new DSectorScrollInterpolation(this, false); + interp = Create(this, false); break; default: @@ -981,7 +981,7 @@ DInterpolation *FPolyObj::SetInterpolation() } else { - interpolation = new DPolyobjInterpolation(this); + interpolation = Create(this); interpolation->AddRef(); } GC::WriteBarrier(interpolation); diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index 3c61ec4ac7..b069aa9f36 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -1356,6 +1356,13 @@ int R_FindCustomTranslation(FName name) return (t != nullptr)? *t : -1; } +DEFINE_ACTION_FUNCTION(_Translation, GetID) +{ + PARAM_PROLOGUE; + PARAM_NAME(t); + ACTION_RETURN_INT(R_FindCustomTranslation(t)); +} + //---------------------------------------------------------------------------- // // diff --git a/src/s_sndseq.cpp b/src/s_sndseq.cpp index 8d4652d2bc..589dcc0530 100644 --- a/src/s_sndseq.cpp +++ b/src/s_sndseq.cpp @@ -881,7 +881,7 @@ DSeqNode *SN_StartSequence (AActor *actor, int sequence, seqtype_t type, int mod } if (TwiddleSeqNum (sequence, type)) { - return new DSeqActorNode (actor, sequence, modenum); + return Create (actor, sequence, modenum); } return NULL; } @@ -904,7 +904,7 @@ DSeqNode *SN_StartSequence (sector_t *sector, int chan, int sequence, seqtype_t } if (TwiddleSeqNum (sequence, type)) { - return new DSeqSectorNode (sector, chan, sequence, modenum); + return Create(sector, chan, sequence, modenum); } return NULL; } @@ -928,7 +928,7 @@ DSeqNode *SN_StartSequence (FPolyObj *poly, int sequence, seqtype_t type, int mo } if (TwiddleSeqNum (sequence, type)) { - return new DSeqPolyNode (poly, sequence, modenum); + return Create(poly, sequence, modenum); } return NULL; } diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index 5b7fcddc9d..737bb3c310 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -274,7 +274,7 @@ static PSymbol *FindBuiltinFunction(FName funcname, VMNativeFunction::NativeCall PSymbol *sym = Namespaces.GlobalNamespace->Symbols.FindSymbol(funcname, false); if (sym == nullptr) { - PSymbolVMFunction *symfunc = new PSymbolVMFunction(funcname); + PSymbolVMFunction *symfunc = Create(funcname); VMNativeFunction *calldec = new VMNativeFunction(func, funcname); calldec->PrintableName = funcname.GetChars(); symfunc->Function = calldec; @@ -6809,7 +6809,7 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build) //========================================================================== FxStackVariable::FxStackVariable(PType *type, int offset, const FScriptPosition &pos) - : FxMemberBase(EFX_StackVariable, new PField(NAME_None, type, 0, offset), pos) + : FxMemberBase(EFX_StackVariable, Create(NAME_None, type, 0, offset), pos) { } @@ -7030,13 +7030,13 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx) } else if (classx->ValueType->isStruct()) { - // if this is a struct within a class or another struct we can simplify the expression by creating a new PField with a cumulative offset. + // if this is a struct within a class or another struct we can simplify the expression by creating a Create with a cumulative offset. if (classx->ExprType == EFX_ClassMember || classx->ExprType == EFX_StructMember || classx->ExprType == EFX_GlobalVariable || classx->ExprType == EFX_StackVariable) { auto parentfield = static_cast(classx)->membervar; // PFields are garbage collected so this will be automatically taken care of later. // [ZZ] call ChangeSideInFlags to ensure that we don't get ui+play - auto newfield = new PField(NAME_None, membervar->Type, FScopeBarrier::ChangeSideInFlags(membervar->Flags | parentfield->Flags, BarrierSide), membervar->Offset + parentfield->Offset); + auto newfield = Create(NAME_None, membervar->Type, FScopeBarrier::ChangeSideInFlags(membervar->Flags | parentfield->Flags, BarrierSide), membervar->Offset + parentfield->Offset); newfield->BitValue = membervar->BitValue; static_cast(classx)->membervar = newfield; classx->isresolved = false; // re-resolve the parent so it can also check if it can be optimized away. @@ -7259,7 +7259,7 @@ FxExpression *FxArrayElement::Resolve(FCompileContext &ctx) if (Array->isStaticArray()) { - // if this is an array within a class or another struct we can simplify the expression by creating a new PField with a cumulative offset. + // if this is an array within a class or another struct we can simplify the expression by creating a Create with a cumulative offset. if (Array->ExprType == EFX_ClassMember || Array->ExprType == EFX_StructMember || Array->ExprType == EFX_GlobalVariable || Array->ExprType == EFX_StackVariable) { auto parentfield = static_cast(Array)->membervar; @@ -7283,12 +7283,12 @@ FxExpression *FxArrayElement::Resolve(FCompileContext &ctx) return nullptr; } - // if this is an array within a class or another struct we can simplify the expression by creating a new PField with a cumulative offset. + // if this is an array within a class or another struct we can simplify the expression by creating a Create with a cumulative offset. if (Array->ExprType == EFX_ClassMember || Array->ExprType == EFX_StructMember || Array->ExprType == EFX_GlobalVariable || Array->ExprType == EFX_StackVariable) { auto parentfield = static_cast(Array)->membervar; // PFields are garbage collected so this will be automatically taken care of later. - auto newfield = new PField(NAME_None, elementtype, parentfield->Flags, indexval * arraytype->ElementSize + parentfield->Offset); + auto newfield = Create(NAME_None, elementtype, parentfield->Flags, indexval * arraytype->ElementSize + parentfield->Offset); static_cast(Array)->membervar = newfield; Array->isresolved = false; // re-resolve the parent so it can also check if it can be optimized away. auto x = Array->Resolve(ctx); @@ -7337,7 +7337,7 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build) start = ExpEmit(build, REGT_POINTER); build->Emit(OP_LP, start.RegNum, arrayvar.RegNum, build->GetConstantInt(0)); - auto f = new PField(NAME_None, TypeUInt32, ismeta? VARF_Meta : 0, SizeAddr); + auto f = Create(NAME_None, TypeUInt32, ismeta? VARF_Meta : 0, SizeAddr); static_cast(Array)->membervar = f; static_cast(Array)->AddressRequested = false; Array->ValueType = TypeUInt32; @@ -7775,6 +7775,13 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx) } break; + case NAME_GetClassName: + if (CheckArgSize(NAME_GetClassName, ArgList, 0, 0, ScriptPosition)) + { + func = new FxGetClassName(new FxSelf(ScriptPosition)); + } + break; + case NAME_GetDefaultByType: if (CheckArgSize(NAME_GetDefaultByType, ArgList, 1, 1, ScriptPosition)) { @@ -8149,7 +8156,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) if (Self->ExprType == EFX_StructMember || Self->ExprType == EFX_ClassMember || Self->ExprType == EFX_StackVariable) { auto member = static_cast(Self); - auto newfield = new PField(NAME_None, backingtype, 0, member->membervar->Offset); + auto newfield = Create(NAME_None, backingtype, 0, member->membervar->Offset); member->membervar = newfield; } } @@ -8193,7 +8200,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) if (Self->ExprType == EFX_StructMember || Self->ExprType == EFX_ClassMember || Self->ExprType == EFX_GlobalVariable) { auto member = static_cast(Self); - auto newfield = new PField(NAME_None, TypeUInt32, VARF_ReadOnly, member->membervar->Offset + sizeof(void*)); // the size is stored right behind the pointer. + auto newfield = Create(NAME_None, TypeUInt32, VARF_ReadOnly, member->membervar->Offset + sizeof(void*)); // the size is stored right behind the pointer. member->membervar = newfield; Self = nullptr; delete this; @@ -8215,14 +8222,20 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) if (MethodName == NAME_GetParentClass && (Self->IsObject() || Self->ValueType->isClassPointer())) { - if (ArgList.Size() > 0) + if (CheckArgSize(NAME_GetParentClass, ArgList, 0, 0, ScriptPosition)) { - ScriptPosition.Message(MSG_ERROR, "too many parameters in call to %s", MethodName.GetChars()); - delete this; - return nullptr; + auto x = new FxGetParentClass(Self); + return x->Resolve(ctx); + } + } + if (MethodName == NAME_GetClassName && + (Self->IsObject() || Self->ValueType->isClassPointer())) + { + if (CheckArgSize(NAME_GetClassName, ArgList, 0, 0, ScriptPosition)) + { + auto x = new FxGetClassName(Self); + return x->Resolve(ctx); } - auto x = new FxGetParentClass(Self); - return x->Resolve(ctx); } if (Self->ValueType->isRealPointer()) @@ -9336,11 +9349,11 @@ FxExpression *FxGetParentClass::Resolve(FCompileContext &ctx) if (!Self->ValueType->isClassPointer() && !Self->IsObject()) { - ScriptPosition.Message(MSG_ERROR, "GetClass() requires an object"); + ScriptPosition.Message(MSG_ERROR, "GetParentClass() requires an object"); delete this; return nullptr; } - ValueType = NewClassPointer(RUNTIME_CLASS(DObject)); // + ValueType = NewClassPointer(RUNTIME_CLASS(DObject)); return this; } @@ -9365,6 +9378,52 @@ ExpEmit FxGetParentClass::Emit(VMFunctionBuilder *build) // //========================================================================== +FxGetClassName::FxGetClassName(FxExpression *self) + :FxExpression(EFX_GetClassName, self->ScriptPosition) +{ + Self = self; +} + +FxGetClassName::~FxGetClassName() +{ + SAFE_DELETE(Self); +} + +FxExpression *FxGetClassName::Resolve(FCompileContext &ctx) +{ + SAFE_RESOLVE(Self, ctx); + + if (!Self->ValueType->isClassPointer() && !Self->IsObject()) + { + ScriptPosition.Message(MSG_ERROR, "GetClassName() requires an object"); + delete this; + return nullptr; + } + ValueType = TypeName; + return this; +} + +ExpEmit FxGetClassName::Emit(VMFunctionBuilder *build) +{ + ExpEmit op = Self->Emit(build); + op.Free(build); + if (Self->IsObject()) + { + ExpEmit to(build, REGT_POINTER); + build->Emit(OP_CLSS, to.RegNum, op.RegNum); + op = to; + op.Free(build); + } + ExpEmit to(build, REGT_INT); + build->Emit(OP_LW, to.RegNum, op.RegNum, build->GetConstantInt(myoffsetof(PClass, TypeName))); + return to; +} + +//========================================================================== +// +// +//========================================================================== + FxGetDefaultByType::FxGetDefaultByType(FxExpression *self) :FxExpression(EFX_GetDefaultByType, self->ScriptPosition) { @@ -10680,27 +10739,21 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx) int BuiltinNameToClass(VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret) { - assert(numparam == 2); - assert(numret == 1); - assert(param[0].Type == REGT_INT); - assert(param[1].Type == REGT_POINTER); - assert(ret->RegType == REGT_POINTER); + PARAM_PROLOGUE; + PARAM_NAME(clsname); + PARAM_CLASS(desttype, DObject); - FName clsname = ENamedName(param[0].i); + PClass *cls = nullptr; if (clsname != NAME_None) { - const PClass *cls = PClass::FindClass(clsname); - const PClass *desttype = reinterpret_cast(param[1].a); - - if (cls->VMType == nullptr || !cls->IsDescendantOf(desttype)) + cls = PClass::FindClass(clsname); + if (cls != nullptr && (cls->VMType == nullptr || !cls->IsDescendantOf(desttype))) { - // Let the caller check this. Making this an error with a message is only taking away options from the user. + // does not match required parameters or is invalid. cls = nullptr; } - ret->SetPointer(const_cast(cls)); } - else ret->SetPointer(nullptr); - return 1; + ACTION_RETURN_POINTER(cls); } ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build) diff --git a/src/scripting/backend/codegen.h b/src/scripting/backend/codegen.h index aa2e06910d..004b1f2289 100644 --- a/src/scripting/backend/codegen.h +++ b/src/scripting/backend/codegen.h @@ -296,6 +296,7 @@ enum EFxType EFX_NamedNode, EFX_GetClass, EFX_GetParentClass, + EFX_GetClassName, EFX_StrLen, EFX_ColorLiteral, EFX_GetDefaultByType, @@ -1660,6 +1661,24 @@ public: ExpEmit Emit(VMFunctionBuilder *build); }; +//========================================================================== +// +// FxGetClass +// +//========================================================================== + +class FxGetClassName : public FxExpression +{ + FxExpression *Self; + +public: + + FxGetClassName(FxExpression *self); + ~FxGetClassName(); + FxExpression *Resolve(FCompileContext&); + ExpEmit Emit(VMFunctionBuilder *build); +}; + //========================================================================== // // FxGetDefaultByType diff --git a/src/scripting/backend/scopebarrier.cpp b/src/scripting/backend/scopebarrier.cpp index 65740ec180..4fe0f646d5 100644 --- a/src/scripting/backend/scopebarrier.cpp +++ b/src/scripting/backend/scopebarrier.cpp @@ -93,7 +93,7 @@ EScopeFlags FScopeBarrier::ChangeSideInObjectFlags(EScopeFlags flags, int side) int f = int(flags); f &= ~(Scope_UI | Scope_Play); f |= ObjectFlagsFromSide(side); - return (EScopeFlags)flags; + return (EScopeFlags)f; } FScopeBarrier::FScopeBarrier() diff --git a/src/scripting/decorate/thingdef_parse.cpp b/src/scripting/decorate/thingdef_parse.cpp index 0a0b2fa3d1..c2cc3ecbeb 100644 --- a/src/scripting/decorate/thingdef_parse.cpp +++ b/src/scripting/decorate/thingdef_parse.cpp @@ -255,12 +255,12 @@ static void ParseConstant (FScanner &sc, PSymbolTable *symt, PClassActor *cls, P PSymbolConstNumeric *sym; if (type == TK_Int) { - sym = new PSymbolConstNumeric(symname, TypeSInt32); + sym = Create(symname, TypeSInt32); sym->Value = val.GetInt(); } else { - sym = new PSymbolConstNumeric(symname, TypeFloat64); + sym = Create(symname, TypeFloat64); sym->Float = val.GetFloat(); } if (symt->AddSymbol (sym) == NULL) @@ -318,7 +318,7 @@ static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClassActor *cls, PName FScriptPosition::ErrorCounter++; } } - PSymbolConstNumeric *sym = new PSymbolConstNumeric(symname, TypeSInt32); + PSymbolConstNumeric *sym = Create(symname, TypeSInt32); sym->Value = currvalue; if (symt->AddSymbol (sym) == NULL) { diff --git a/src/scripting/symbols.cpp b/src/scripting/symbols.cpp index 057b6ef290..9fcefd6039 100644 --- a/src/scripting/symbols.cpp +++ b/src/scripting/symbols.cpp @@ -311,7 +311,7 @@ PSymbol *PSymbolTable::AddSymbol (PSymbol *sym) PField *PSymbolTable::AddField(FName name, PType *type, uint32_t flags, unsigned &Size, unsigned *Align) { - PField *field = new PField(name, type, flags); + PField *field = Create(name, type, flags); // The new field is added to the end of this struct, alignment permitting. field->Offset = (Size + (type->Align - 1)) & ~(type->Align - 1); @@ -345,7 +345,7 @@ PField *PSymbolTable::AddField(FName name, PType *type, uint32_t flags, unsigned PField *PSymbolTable::AddNativeField(FName name, PType *type, size_t address, uint32_t flags, int bitvalue) { - PField *field = new PField(name, type, flags | VARF_Native | VARF_Transient, address, bitvalue); + PField *field = Create(name, type, flags | VARF_Native | VARF_Transient, address, bitvalue); if (AddSymbol(field) == nullptr) { // name is already in use @@ -370,7 +370,7 @@ void PSymbolTable::WriteFields(FSerializer &ar, const void *addr, const void *de { const PField *field = dyn_cast(pair->Value); // Skip fields without or with native serialization - if (field && !(field->Flags & (VARF_Transient | VARF_Meta))) + if (field && !(field->Flags & (VARF_Transient | VARF_Meta | VARF_Static))) { // todo: handle defaults in WriteValue //auto defp = def == nullptr ? nullptr : (const uint8_t *)def + field->Offset; @@ -512,13 +512,16 @@ PNamespace *FNamespaceManager::NewNamespace(int filenum) //========================================================================== // -// +// Deallocate the entire namespace manager. // //========================================================================== void FNamespaceManager::ReleaseSymbols() { - RemoveSymbols(); + for (auto ns : AllNamespaces) + { + delete ns; + } GlobalNamespace = nullptr; AllNamespaces.Clear(); } @@ -537,7 +540,7 @@ int FNamespaceManager::RemoveSymbols() for (auto ns : AllNamespaces) { count += ns->Symbols.Symbols.CountUsed(); - delete ns; + ns->Symbols.ReleaseSymbols(); } return count; } @@ -550,7 +553,6 @@ int FNamespaceManager::RemoveSymbols() void RemoveUnusedSymbols() { - // Global symbols are not needed anymore after running the compiler. int count = Namespaces.RemoveSymbols(); // We do not need any non-field and non-function symbols in structs and classes anymore. diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp index a76fdd5fb9..aa8db34fdc 100644 --- a/src/scripting/thingdef.cpp +++ b/src/scripting/thingdef.cpp @@ -171,7 +171,7 @@ PFunction *CreateAnonymousFunction(PContainerType *containingclass, PType *retur rets[0] = returntype != nullptr? returntype : TypeError; // Use TypeError as placeholder if we do not know the return type yet. SetImplicitArgs(&args, &argflags, &argnames, containingclass, fflags, flags); - PFunction *sym = new PFunction(containingclass, NAME_None); // anonymous functions do not have names. + PFunction *sym = Create(containingclass, NAME_None); // anonymous functions do not have names. sym->AddVariant(NewPrototype(rets, args), argflags, argnames, nullptr, fflags, flags); return sym; } diff --git a/src/scripting/types.cpp b/src/scripting/types.cpp index 4649777afe..5a8581812f 100644 --- a/src/scripting/types.cpp +++ b/src/scripting/types.cpp @@ -337,7 +337,7 @@ void PType::StaticInit() TypeVector3->AddField(NAME_Y, TypeFloat64); TypeVector3->AddField(NAME_Z, TypeFloat64); // allow accessing xy as a vector2. This is not supposed to be serialized so it's marked transient - TypeVector3->Symbols.AddSymbol(new PField(NAME_XY, TypeVector2, VARF_Transient, 0)); + TypeVector3->Symbols.AddSymbol(Create(NAME_XY, TypeVector2, VARF_Transient, 0)); TypeTable.AddType(TypeVector3, NAME_Struct); TypeVector3->loadOp = OP_LV3; TypeVector3->storeOp = OP_SV3; @@ -347,24 +347,24 @@ void PType::StaticInit() - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_sByte, TypeSInt8)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Byte, TypeUInt8)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Short, TypeSInt16)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_uShort, TypeUInt16)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Int, TypeSInt32)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_uInt, TypeUInt32)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Bool, TypeBool)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Float, TypeFloat64)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Double, TypeFloat64)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Float32, TypeFloat32)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Float64, TypeFloat64)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_String, TypeString)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Name, TypeName)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Sound, TypeSound)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Color, TypeColor)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_State, TypeState)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Vector2, TypeVector2)); - Namespaces.GlobalNamespace->Symbols.AddSymbol(new PSymbolType(NAME_Vector3, TypeVector3)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_sByte, TypeSInt8)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Byte, TypeUInt8)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Short, TypeSInt16)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_uShort, TypeUInt16)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Int, TypeSInt32)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_uInt, TypeUInt32)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Bool, TypeBool)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Float, TypeFloat64)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Double, TypeFloat64)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Float32, TypeFloat32)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Float64, TypeFloat64)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_String, TypeString)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Name, TypeName)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Sound, TypeSound)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Color, TypeColor)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_State, TypeState)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Vector2, TypeVector2)); + Namespaces.GlobalNamespace->Symbols.AddSymbol(Create(NAME_Vector3, TypeVector3)); } @@ -444,13 +444,13 @@ PInt::PInt(unsigned int size, bool unsign, bool compatible) { int maxval = (1u << ((8 * size) - 1)) - 1; // compute as unsigned to prevent overflow before -1 int minval = -maxval - 1; - Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Min, this, minval)); - Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Max, this, maxval)); + Symbols.AddSymbol(Create(NAME_Min, this, minval)); + Symbols.AddSymbol(Create(NAME_Max, this, maxval)); } else { - Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Min, this, 0u)); - Symbols.AddSymbol(new PSymbolConstNumeric(NAME_Max, this, (1u << ((8 * size) - 1)))); + Symbols.AddSymbol(Create(NAME_Min, this, 0u)); + Symbols.AddSymbol(Create(NAME_Max, this, (1u << ((8 * size) - 1)))); } SetOps(); } @@ -799,7 +799,7 @@ void PFloat::SetSymbols(const PFloat::SymbolInitF *sym, size_t count) { for (size_t i = 0; i < count; ++i) { - Symbols.AddSymbol(new PSymbolConstNumeric(sym[i].Name, this, sym[i].Value)); + Symbols.AddSymbol(Create(sym[i].Name, this, sym[i].Value)); } } @@ -807,7 +807,7 @@ void PFloat::SetSymbols(const PFloat::SymbolInitI *sym, size_t count) { for (size_t i = 0; i < count; ++i) { - Symbols.AddSymbol(new PSymbolConstNumeric(sym[i].Name, this, sym[i].Value)); + Symbols.AddSymbol(Create(sym[i].Name, this, sym[i].Value)); } } diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index c6f65dc983..9f6c1fdce2 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -329,7 +329,7 @@ ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols, case AST_Enum: zenumType = static_cast(node); enumType = NewEnum(zenumType->NodeName, OutNamespace); - OutNamespace->Symbols.AddSymbol(new PSymbolType(zenumType->NodeName, enumType)); + OutNamespace->Symbols.AddSymbol(Create(zenumType->NodeName, enumType)); break; case AST_Class: @@ -399,7 +399,7 @@ PSymbolTreeNode *ZCCCompiler::AddTreeNode(FName name, ZCC_TreeNode *node, PSymbo } else { - auto sy = new PSymbolTreeNode(name, node); + auto sy = Create(name, node); FString name; treenodes->AddSymbol(sy); return sy; @@ -549,13 +549,13 @@ void ZCCCompiler::CreateStructTypes() // old versions force 'play'. sf = FScopeBarrier::ChangeSideInObjectFlags(sf, FScopeBarrier::Side_Play); } - s->strct->Symbol = new PSymbolType(s->NodeName(), s->Type()); + s->strct->Symbol = Create(s->NodeName(), s->Type()); syms->AddSymbol(s->strct->Symbol); for (auto e : s->Enums) { auto etype = NewEnum(e->NodeName, s->Type()); - s->Type()->Symbols.AddSymbol(new PSymbolType(e->NodeName, etype)); + s->Type()->Symbols.AddSymbol(Create(e->NodeName, etype)); } } } @@ -701,7 +701,7 @@ void ZCCCompiler::CreateClassTypes() c->Type()->ScopeFlags = FScopeBarrier::ChangeSideInObjectFlags(c->Type()->ScopeFlags, FScopeBarrier::Side_Play); } - c->cls->Symbol = new PSymbolType(c->NodeName(), c->Type()); + c->cls->Symbol = Create(c->NodeName(), c->Type()); OutNamespace->Symbols.AddSymbol(c->cls->Symbol); Classes.Push(c); OrigClasses.Delete(i--); @@ -725,7 +725,7 @@ void ZCCCompiler::CreateClassTypes() Error(c->cls, "Class %s has unknown base class %s", c->NodeName().GetChars(), FName(c->cls->ParentName->Id).GetChars()); // create a placeholder so that the compiler can continue looking for errors. c->cls->Type = NewClassType(RUNTIME_CLASS(DObject)->FindClassTentative(c->NodeName())); - c->cls->Symbol = new PSymbolType(c->NodeName(), c->Type()); + c->cls->Symbol = Create(c->NodeName(), c->Type()); OutNamespace->Symbols.AddSymbol(c->cls->Symbol); Classes.Push(c); OrigClasses.Delete(i--); @@ -741,7 +741,7 @@ void ZCCCompiler::CreateClassTypes() { Error(c->cls, "Class %s has circular inheritance", FName(c->NodeName()).GetChars()); c->cls->Type = NewClassType(RUNTIME_CLASS(DObject)->FindClassTentative(c->NodeName())); - c->cls->Symbol = new PSymbolType(c->NodeName(), c->Type()); + c->cls->Symbol = Create(c->NodeName(), c->Type()); OutNamespace->Symbols.AddSymbol(c->cls->Symbol); Classes.Push(c); } @@ -752,7 +752,7 @@ void ZCCCompiler::CreateClassTypes() for (auto e : cd->Enums) { auto etype = NewEnum(e->NodeName, cd->Type()); - cd->Type()->Symbols.AddSymbol(new PSymbolType(e->NodeName, etype)); + cd->Type()->Symbols.AddSymbol(Create(e->NodeName, etype)); } // Link the tree node tables. We only can do this after we know the class relations. for (auto cc : Classes) @@ -872,13 +872,13 @@ void ZCCCompiler::AddConstant(ZCC_ConstantWork &constant) ZCC_ExprConstant *cval = static_cast(val); if (cval->Type == TypeString) { - def->Symbol = new PSymbolConstString(def->NodeName, *(cval->StringVal)); + def->Symbol = Create(def->NodeName, *(cval->StringVal)); } else if (cval->Type->isInt()) { // How do we get an Enum type in here without screwing everything up??? //auto type = def->Type != nullptr ? def->Type : cval->Type; - def->Symbol = new PSymbolConstNumeric(def->NodeName, cval->Type, cval->IntVal); + def->Symbol = Create(def->NodeName, cval->Type, cval->IntVal); } else if (cval->Type->isFloat()) { @@ -886,7 +886,7 @@ void ZCCCompiler::AddConstant(ZCC_ConstantWork &constant) { Error(def, "Enum members must be integer values"); } - def->Symbol = new PSymbolConstNumeric(def->NodeName, cval->Type, cval->DoubleVal); + def->Symbol = Create(def->NodeName, cval->Type, cval->DoubleVal); } else { @@ -898,13 +898,13 @@ void ZCCCompiler::AddConstant(ZCC_ConstantWork &constant) { if (c.Type == TypeString) { - def->Symbol = new PSymbolConstString(def->NodeName, c.GetString()); + def->Symbol = Create(def->NodeName, c.GetString()); } else if (c.Type->isInt()) { // How do we get an Enum type in here without screwing everything up??? //auto type = def->Type != nullptr ? def->Type : cval->Type; - def->Symbol = new PSymbolConstNumeric(def->NodeName, c.Type, c.GetInt()); + def->Symbol = Create(def->NodeName, c.Type, c.GetInt()); } else if (c.Type->isFloat()) { @@ -912,7 +912,7 @@ void ZCCCompiler::AddConstant(ZCC_ConstantWork &constant) { Error(def, "Enum members must be integer values"); } - def->Symbol = new PSymbolConstNumeric(def->NodeName, c.Type, c.GetFloat()); + def->Symbol = Create(def->NodeName, c.Type, c.GetFloat()); } else { @@ -924,7 +924,7 @@ void ZCCCompiler::AddConstant(ZCC_ConstantWork &constant) if (def->Symbol == nullptr) { // Create a dummy constant so we don't make any undefined value warnings. - def->Symbol = new PSymbolConstNumeric(def->NodeName, TypeError, 0); + def->Symbol = Create(def->NodeName, TypeError, 0); } constant.Outputtable->ReplaceSymbol(def->Symbol); } @@ -1025,7 +1025,7 @@ void ZCCCompiler::CompileArrays(ZCC_StructWork *work) copyp += ztype->Align; } } - work->Type()->Symbols.AddSymbol(new PField(sas->Id, NewArray(ztype, values.Size()), VARF_Static | VARF_ReadOnly, (size_t)destmem)); + work->Type()->Symbols.AddSymbol(Create(sas->Id, NewArray(ztype, values.Size()), VARF_Static | VARF_ReadOnly, (size_t)destmem)); } } @@ -1337,7 +1337,7 @@ bool ZCCCompiler::CompileFields(PContainerType *type, TArrayBitValue != 0) thisfieldtype = fd->FieldSize == 1 ? TypeUInt8 : fd->FieldSize == 2 ? TypeUInt16 : TypeUInt32; - PField *field = new PField(name->Name, thisfieldtype, varflags | VARF_Native | VARF_Static, fd->FieldOffset, fd->BitValue); + PField *field = Create(name->Name, thisfieldtype, varflags | VARF_Native | VARF_Static, fd->FieldOffset, fd->BitValue); if (OutNamespace->Symbols.AddSymbol(field) == nullptr) { // name is already in use @@ -1428,7 +1428,7 @@ bool ZCCCompiler::CompileProperties(PClass *type, TArray &Proper else qualifiedname.Format("@property@%s.%s", prefix.GetChars(), name.GetChars()); fields.ShrinkToFit(); - if (!type->VMType->Symbols.AddSymbol(new PProperty(qualifiedname, fields))) + if (!type->VMType->Symbols.AddSymbol(Create(qualifiedname, fields))) { Error(id, "Unable to add property %s to class %s", FName(p->NodeName).GetChars(), type->TypeName.GetChars()); } @@ -2607,7 +2607,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool } while (p != f->Params); } - PFunction *sym = new PFunction(c->Type(), f->Name); + PFunction *sym = Create(c->Type(), f->Name); sym->AddVariant(NewPrototype(rets, args), argflags, argnames, afd == nullptr ? nullptr : *(afd->VMPointer), varflags, useflags); c->Type()->Symbols.ReplaceSymbol(sym); diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 314a0fb9af..ea589cbfcd 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -186,9 +186,9 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms) void DCanvas::SetClipRect(int x, int y, int w, int h) { clipleft = clamp(x, 0, GetWidth()); - clipwidth = clamp(w, 0, GetWidth() - x); + clipwidth = clamp(w, -1, GetWidth() - x); cliptop = clamp(y, 0, GetHeight()); - clipheight = clamp(h, 0, GetHeight() - y); + clipheight = clamp(h, -1, GetHeight() - y); } DEFINE_ACTION_FUNCTION(_Screen, SetClipRect) diff --git a/src/v_text.cpp b/src/v_text.cpp index 3c31312b3f..cf8ce8cc7b 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -454,5 +454,5 @@ DEFINE_ACTION_FUNCTION(FFont, BreakLines) unsigned int count; FBrokenLines *broken = V_BreakLines(self, maxwidth, text, true, &count); - ACTION_RETURN_OBJECT(new DBrokenLines(broken, count)); + ACTION_RETURN_OBJECT(Create(broken, count)); } diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index dc915a0119..113253f953 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -251,7 +251,7 @@ DEFINE_ACTION_FUNCTION(DInterBackground, Create) { PARAM_PROLOGUE; PARAM_POINTER(wbst, wbstartstruct_t); - ACTION_RETURN_POINTER(new DInterBackground(wbst)); + ACTION_RETURN_POINTER(Create(wbst)); } //==================================================================== diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index 99706c9a96..bf16a87085 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -124,7 +124,7 @@ extern UINT TimerPeriod; // PUBLIC DATA DEFINITIONS ------------------------------------------------- // The command line arguments. -DArgs *Args; +FArgs *Args; HINSTANCE g_hInst; DWORD SessionID; @@ -840,7 +840,7 @@ void DoMain (HINSTANCE hInstance) _set_new_handler (NewFailure); #endif - Args = new DArgs(__argc, __argv); + Args = new FArgs(__argc, __argv); // Load Win32 modules Kernel32Module.Load({"kernel32.dll"}); diff --git a/wadsrc/static/mapinfo/chex.txt b/wadsrc/static/mapinfo/chex.txt index f35a5f2cdc..4d234b351c 100644 --- a/wadsrc/static/mapinfo/chex.txt +++ b/wadsrc/static/mapinfo/chex.txt @@ -69,6 +69,7 @@ gameinfo statscreen_coop = "CoopStatusScreen" statscreen_dm = "DeathmatchStatusScreen" statscreen_single = "DoomStatusScreen" + messageboxclass = "MessageBoxMenu" } DoomEdNums diff --git a/wadsrc/static/mapinfo/doomcommon.txt b/wadsrc/static/mapinfo/doomcommon.txt index 8dd21dbad0..bca27b5279 100644 --- a/wadsrc/static/mapinfo/doomcommon.txt +++ b/wadsrc/static/mapinfo/doomcommon.txt @@ -70,6 +70,7 @@ gameinfo statscreen_coop = "CoopStatusScreen" statscreen_dm = "DeathmatchStatusScreen" statscreen_single = "DoomStatusScreen" + messageboxclass = "MessageBoxMenu" } spawnnums diff --git a/wadsrc/static/mapinfo/heretic.txt b/wadsrc/static/mapinfo/heretic.txt index 2418537936..ebb538afde 100644 --- a/wadsrc/static/mapinfo/heretic.txt +++ b/wadsrc/static/mapinfo/heretic.txt @@ -68,6 +68,7 @@ gameinfo statscreen_coop = "CoopStatusScreen" statscreen_dm = "DeathmatchStatusScreen" statscreen_single = "RavenStatusScreen" + messageboxclass = "MessageBoxMenu" } DoomEdNums diff --git a/wadsrc/static/mapinfo/hexen.txt b/wadsrc/static/mapinfo/hexen.txt index 09d3254641..7fd6dbba25 100644 --- a/wadsrc/static/mapinfo/hexen.txt +++ b/wadsrc/static/mapinfo/hexen.txt @@ -66,6 +66,7 @@ gameinfo statscreen_coop = "CoopStatusScreen" statscreen_dm = "DeathmatchStatusScreen" statscreen_single = "RavenStatusScreen" + messageboxclass = "MessageBoxMenu" } DoomEdNums diff --git a/wadsrc/static/mapinfo/mindefaults.txt b/wadsrc/static/mapinfo/mindefaults.txt index f02ff78d02..4199a0a6f4 100644 --- a/wadsrc/static/mapinfo/mindefaults.txt +++ b/wadsrc/static/mapinfo/mindefaults.txt @@ -54,6 +54,7 @@ gameinfo statscreen_mapnamefont = "BigFont" statscreen_finishedpatch = "WIF" statscreen_enteringpatch = "WIENTER" + messageboxclass = "MessageBoxMenu" } DoomEdNums diff --git a/wadsrc/static/mapinfo/strife.txt b/wadsrc/static/mapinfo/strife.txt index 73f7c45724..0d17586bf3 100644 --- a/wadsrc/static/mapinfo/strife.txt +++ b/wadsrc/static/mapinfo/strife.txt @@ -68,6 +68,7 @@ gameinfo statscreen_dm = "DeathmatchStatusScreen" statscreen_single = "RavenStatusScreen" statusbarclass = "StrifeStatusBar" + messageboxclass = "MessageBoxMenu" } DoomEdNums diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index fb883f846c..9b7836d171 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -1092,7 +1092,7 @@ class Actor : Thinker native native bool A_SetVisibleRotation(double anglestart = 0, double angleend = 0, double pitchstart = 0, double pitchend = 0, int flags = 0, int ptr = AAPTR_DEFAULT); native void A_SetTranslation(name transname); native bool A_SetSize(double newradius, double newheight = -1, bool testpos = false); - native void A_SprayDecal(String name); + native void A_SprayDecal(String name, double dist = 172); native void A_SetMugshotState(String name); native void A_RearrangePointers(int newtarget, int newmaster = AAPTR_DEFAULT, int newtracer = AAPTR_DEFAULT, int flags=0); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index c834dff946..bb941b4148 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -258,6 +258,7 @@ struct Translation version("2.4") native int AddTranslation(); native static bool SetPlayerTranslation(int group, int num, int plrnum, PlayerClass pclass); + native static int GetID(Name transname); static int MakeID(int group, int num) { return (group << 16) + num; @@ -342,7 +343,6 @@ class Object native native static uint MSTime(); native vararg static void ThrowAbortException(String fmt, ...); - native Name GetClassName(); native virtualscope void Destroy(); // This does not call into the native method of the same name to avoid problems with objects that get garbage collected late on shutdown. diff --git a/wadsrc/static/zscript/inventory/powerups.txt b/wadsrc/static/zscript/inventory/powerups.txt index 0453316726..8402588c57 100644 --- a/wadsrc/static/zscript/inventory/powerups.txt +++ b/wadsrc/static/zscript/inventory/powerups.txt @@ -1861,6 +1861,10 @@ class PowerInfiniteAmmo : Powerup class PowerReflection : Powerup { + // if 1, reflects the damage type as well. + bool ReflectType; + property ReflectType : ReflectType; + Default { Powerup.Duration -60; diff --git a/wadsrc/static/zscript/menu/messagebox.txt b/wadsrc/static/zscript/menu/messagebox.txt index 48d9949a39..86796d3011 100644 --- a/wadsrc/static/zscript/menu/messagebox.txt +++ b/wadsrc/static/zscript/menu/messagebox.txt @@ -50,7 +50,7 @@ class MessageBoxMenu : Menu // //============================================================================= - void Init(Menu parent, String message, int messagemode, bool playsound = false, Name cmd = 'None', voidptr native_handler = null) + virtual void Init(Menu parent, String message, int messagemode, bool playsound = false, Name cmd = 'None', voidptr native_handler = null) { Super.Init(parent); mAction = cmd; diff --git a/wadsrc/static/zscript/shared/camera.txt b/wadsrc/static/zscript/shared/camera.txt index abb394745e..f19d90d253 100644 --- a/wadsrc/static/zscript/shared/camera.txt +++ b/wadsrc/static/zscript/shared/camera.txt @@ -36,7 +36,8 @@ class SecurityCamera : Actor if (args[1]) Delta /= 2; Acc = 0.; - Pitch = clamp(args[0], -89, 89); + int arg = (args[0] << 24) >> 24; // make sure the value has the intended sign. + Pitch = clamp(arg, -89, 89); Range = args[1]; }