This commit is contained in:
Rachael Alexanderson 2017-04-14 23:09:21 -04:00
commit 997a62de36
92 changed files with 623 additions and 449 deletions

View file

@ -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

View file

@ -613,7 +613,7 @@ public:
FActorInfo *GetInfo() const
{
return ((PClassActor*)GetClass())->ActorInfo();
return static_cast<PClassActor*>(GetClass())->ActorInfo();
}
@ -739,7 +739,7 @@ public:
AInventory *FindInventory (FName type, bool subclass = false);
template<class T> T *FindInventory ()
{
return static_cast<T *> (FindInventory (RUNTIME_TEMPLATE_CLASS(T)));
return static_cast<T *> (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<T *>(actor);
}
};
@ -1563,12 +1563,12 @@ inline AActor *Spawn(FName type, const DVector3 &pos, replace_t allowreplacement
template<class T> inline T *Spawn(const DVector3 &pos, replace_t allowreplacement)
{
return static_cast<T *>(AActor::StaticSpawn(RUNTIME_TEMPLATE_CLASS(T), pos, allowreplacement));
return static_cast<T *>(AActor::StaticSpawn(RUNTIME_CLASS(T), pos, allowreplacement));
}
template<class T> inline T *Spawn() // for inventory items we do not need coordinates and replacement info.
{
return static_cast<T *>(AActor::StaticSpawn(RUNTIME_TEMPLATE_CLASS(T), DVector3(0, 0, 0), NO_REPLACE));
return static_cast<T *>(AActor::StaticSpawn(RUNTIME_CLASS(T), DVector3(0, 0, 0), NO_REPLACE));
}
inline PClassActor *PClass::FindActor(FName name)

View file

@ -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<DBot>();
players[bnum].Bot->player = &players[bnum];
players[bnum].Bot->skill = skill;
playeringame[bnum] = true;

View file

@ -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<PClassActor*>(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)/* ||

View file

@ -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<DHUDMessage>(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<DHUDMessage> (font, msg, 1.5f, 0.375f, 0, 0,
(EColorRange)PrintColors[PRINTLEVELS+1], con_midtime), MAKE_ID('C','N','T','R'));
}
else

View file

@ -636,7 +636,7 @@ void C_DoCommand (const char *cmd, int keynum)
}
else
{
new DStoredCommand (com, beg);
Create<DStoredCommand> (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<DWaitingCommand> (brkpt, tics);
}
return;
}

View file

@ -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<FString> 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;

View file

@ -1201,7 +1201,7 @@ void DDecalFader::Tick ()
DThinker *FDecalFaderAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const
{
DDecalFader *fader = new DDecalFader (actor);
DDecalFader *fader = Create<DDecalFader> (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<DDecalStretcher> (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<DDecalSlider> (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<DDecalColorer>(actor);
Colorer->TimeToStartDecay = level.maptime + DecayStart;
Colorer->TimeToEndDecay = Colorer->TimeToStartDecay + DecayTime;

View file

@ -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());

View file

@ -35,6 +35,7 @@
#define __DOBJECT_H__
#include <stdlib.h>
#include <type_traits>
#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<DObject *>(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<typename T, typename... Args>
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<typename T, typename... Args>
T* Create(Args&&... args)
{
DObject::nonew nono;
T *object = new(nono) T(std::forward<Args>(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

View file

@ -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<DSectorMarker>();
}
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<DObject>();
SoftRoots->ObjectFlags |= OF_Fixed;
probe = &Root;
while (*probe != NULL)

View file

@ -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<DObject>();
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();

View file

@ -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>(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<DThinkerIterator>(type, statnum));
}
DEFINE_ACTION_FUNCTION(DThinkerIterator, Next)

View file

@ -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 T> 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)

View file

@ -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<DLightLevel>(&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<DRunningScript>(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<DRunningScript>(Script->trigger, script, 0);
// hook into chain at start
th->AddRunningScript(runscr);
}

View file

@ -315,7 +315,7 @@ bool FScriptLoader::ParseInfo(MapData * map)
}
if (HasScripts)
{
new DFraggleThinker;
Create<DFraggleThinker>();
DFraggleThinker::ActiveThinker->LevelScript->data = copystring(scriptsrc.GetChars());
if (drownflag==-1) drownflag = (level.maptype != MAPTYPE_DOOM || fsglobal);

View file

@ -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<DFsSection>();
newsec->start_index = MakeIndex(brace);
newsec->next = sections[n];

View file

@ -406,8 +406,8 @@ DFraggleThinker::DFraggleThinker()
else
{
ActiveThinker = this;
RunningScripts = new DRunningScript;
LevelScript = new DFsScript;
RunningScripts = Create<DRunningScript>();
LevelScript = Create<DFsScript>();
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<DRunningScript>(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<DFsScript>();
GC::AddSoftRoot(global_script);
init_functions();
}

View file

@ -417,7 +417,7 @@ void FParser::spec_script()
return;
}
newscript = new DFsScript;
newscript = Create<DFsScript>();
// add to scripts list of parent
Script->children[scriptnum] = newscript;

View file

@ -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<DFsVariable>(name);
newvar->type = vtype;
int n = variable_hash(name);

View file

@ -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<DHUDMessageFadeOut>(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<DHUDMessageFadeOut>(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<DHUDMessageFadeOut> (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<DHUDMessageFadeOut> (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;

View file

@ -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<DAutosaver>();
}
}

View file

@ -181,7 +181,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_QueueCorpse)
if (sv_corpsequeuesize > 0)
{
new DCorpsePointer (self);
Create<DCorpsePointer> (self);
}
return 0;
}

View file

@ -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<DBaseDecal>(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<DImpactDecal>(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<DImpactDecal>(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<DBaseDecal>(trace.HitPos.Z);
wall = trace.Line->sidedef[trace.Side];
decal->StickToWall(wall, trace.HitPos.X, trace.HitPos.Y, trace.ffloor);
tpl->ApplyToDecal(decal, wall);

View file

@ -184,7 +184,7 @@ void P_StartLightning ()
DLightningThinker *lightning = LocateLightning ();
if (lightning == NULL)
{
new DLightningThinker ();
Create<DLightningThinker>();
}
}
@ -193,7 +193,7 @@ void P_ForceLightning (int mode)
DLightningThinker *lightning = LocateLightning ();
if (lightning == NULL)
{
lightning = new DLightningThinker ();
lightning = Create<DLightningThinker>();
}
if (lightning != NULL)
{

View file

@ -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<DEarthquake>(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<DEarthquake>(center, intensityX, intensityY, intensityZ, duration, damrad, tremrad,
quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ, falloff, highpoint, rollIntensity, rollWave);
}
}

View file

@ -11,7 +11,7 @@ struct F3DFloor;
class DBaseDecal;
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
{

View file

@ -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<DSpotState>();
return SpotState;
}

View file

@ -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<DHUDMessageFadeOut> (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<DHUDFont>(fnt, spac, mono, sy, sy));
}
DEFINE_FIELD(DHUDFont, mFont);

View file

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

View file

@ -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 ();

View file

@ -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")

View file

@ -152,6 +152,7 @@ struct gameinfo_t
int statusbarfile = -1;
FName statusbarclass;
int statusbarclassfile = -1;
FName MessageBoxClass;
FName backpacktype;
FString intermissionMusic;
int intermissionOrder;

View file

@ -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();

View file

@ -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<DIntermissionController>(desc, deleteme, state);
GC::WriteBarrier(DIntermissionController::CurrentIntermission);
}

View file

@ -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<FString> 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);
}

View file

@ -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<FString> Argv;
};
extern DArgs *Args;
extern FArgs *Args;
#endif //__M_ARGV_H__

View file

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

View file

@ -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)
{

View file

@ -543,7 +543,7 @@ static void ParseListMenu(FScanner &sc)
{
sc.MustGetString();
DListMenuDescriptor *desc = new DListMenuDescriptor;
DListMenuDescriptor *desc = Create<DListMenuDescriptor>();
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<DOptionMenuDescriptor>();
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<DListMenuDescriptor>();
DefaultOptionMenuSettings = Create<DOptionMenuDescriptor>();
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<DOptionMenuDescriptor>();
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<DOptionMenuDescriptor>();
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<DOptionMenuDescriptor>();
MenuDescriptors[NAME_Skillmenu] = od;
od->mMenuName = NAME_Skillmenu;
od->mTitle = "$MNU_CHOOSESKILL";

View file

@ -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<void*>(handler) };
auto f = dyn_cast<PFunction>(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<void*>(handler) };
VMCall(func, params, countof(params), nullptr, 0);
return (DMenu*)p;
}
return nullptr;
}
//=============================================================================

View file

@ -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)

View file

@ -3659,7 +3659,7 @@ DLevelScript::DLevelScript ()
{
next = prev = NULL;
if (DACSThinker::ActiveThinker == NULL)
new DACSThinker;
Create<DACSThinker>();
activefont = SmallFont;
}
@ -4071,7 +4071,7 @@ showme:
fa1 = viewer->BlendA;
}
}
new DFlashFader (fr1, fg1, fb1, fa1, fr2, fg2, fb2, fa2, ftime, viewer->mo);
Create<DFlashFader> (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<DHUDMessage> (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<DHUDMessageFadeOut> (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<DHUDMessageTypeOnFadeOut> (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<DHUDMessageFadeInOut> (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<DPlaneWatcher> (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<DPlaneWatcher> (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<DLevelScript> (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<DACSThinker>();
script = num;
assert(code->VarCount >= code->ArgCount);

View file

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

View file

@ -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<DCeiling> (sec, speed, speed2, silent & ~4);
vertex_t *spot = sec->Lines[0]->v1;
switch (type)

View file

@ -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<DHUDMessageFadeOut>(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
{

View file

@ -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<DDoor> (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<DDoor>(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<DAnimatedDoor>(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<DAnimatedDoor>(sec, line, speed, delay, anim, type);
break;
}
}

View file

@ -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<DFloor>(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<DFloor> (sec);
floor->m_Direction = (type == DFloor::buildUp) ? 1 : -1;
stairstep = stairsize * floor->m_Direction;
floor->m_Type = DFloor::buildStair; //jff 3/31/98 do not leave uninited
@ -734,7 +734,7 @@ bool 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<DFloor> (sec);
floor->StartFloorSound ();
floor->m_Direction = (type == DFloor::buildUp) ? 1 : -1;
floor->m_FloorDestDist = sec->floorplane.PointToDist (DVector2(0, 0), height);
@ -813,7 +813,7 @@ bool EV_DoDonut (int tag, line_t *line, double pillarspeed, double slimespeed)
s3 = ln->backsector;
// Spawn rising slime
floor = new DFloor (s2);
floor = Create<DFloor> (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<DFloor> (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<DElevator> (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<DCeilingWaggle> (sector);
waggle->m_OriginalDist = sector->ceilingplane.fD();
}
else
{
waggle = new DFloorWaggle (sector);
waggle = Create<DFloorWaggle> (sector);
waggle->m_OriginalDist = sector->floorplane.fD();
}
waggle->m_Accumulator = offset;

View file

@ -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<DHUDMessageFadeOut>(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<DHUDMessageFadeOut> (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<DHUDMessageFadeOut> (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<DHUDMessageFadeOut> (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;

View file

@ -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<DFlicker> (&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<DStrobe> (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<DStrobe> (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<DGlow2> (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<DGlow2> (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<DPhased> (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<DPhased>(sector, 48, 63 - (sector->lightlevel & 63));
break;
// [RH] Hexen-like phased lighting
case LightSequenceStart:
new DPhased(sector);
Create<DPhased>(sector);
break;
case dLight_Flicker:
new DLightFlash(sector);
Create<DLightFlash>(sector);
break;
case dLight_StrobeFast:
new DStrobe(sector, STROBEBRIGHT, FASTDARK, false);
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
break;
case dLight_StrobeSlow:
new DStrobe(sector, STROBEBRIGHT, SLOWDARK, false);
Create<DStrobe>(sector, STROBEBRIGHT, SLOWDARK, false);
break;
case dLight_Strobe_Hurt:
new DStrobe(sector, STROBEBRIGHT, FASTDARK, false);
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
break;
case dLight_Glow:
new DGlow(sector);
Create<DGlow>(sector);
break;
case dLight_StrobeSlowSync:
new DStrobe(sector, STROBEBRIGHT, SLOWDARK, true);
Create<DStrobe>(sector, STROBEBRIGHT, SLOWDARK, true);
break;
case dLight_StrobeFastSync:
new DStrobe(sector, STROBEBRIGHT, FASTDARK, true);
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, true);
break;
case dLight_FireFlicker:
new DFireFlicker(sector);
Create<DFireFlicker>(sector);
break;
case dScroll_EastLavaDamage:
new DStrobe(sector, STROBEBRIGHT, FASTDARK, false);
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
break;
case sLight_Strobe_Hurt:
new DStrobe(sector, STROBEBRIGHT, FASTDARK, false);
Create<DStrobe>(sector, STROBEBRIGHT, FASTDARK, false);
break;
default:

View file

@ -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<DBlockLinesIterator>(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<DBlockLinesIterator>(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<DBlockThingsIterator>(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<DBlockThingsIterator>(x, y, z, h, radius, ignore, nullptr));
}
DEFINE_ACTION_FUNCTION(DBlockThingsIterator, Next)

View file

@ -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<APlayerPawn*>(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<DActorIterator>(type, tid));
}
DEFINE_ACTION_FUNCTION(DActorIterator, Next)

View file

@ -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<DPillar> (sec, type, speed, height, height2, crush, hexencrush);
}
return rtn;
}

View file

@ -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<DPlat> (sec);
plat->m_Type = type;
plat->m_Crush = -1;

View file

@ -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<DPSprite>(this, newcaller, layer);
}
else
{
@ -1263,7 +1263,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Overlay)
}
DPSprite *pspr;
pspr = new DPSprite(player, stateowner, layer);
pspr = Create<DPSprite>(player, stateowner, layer);
pspr->SetState(state);
ACTION_RETURN_BOOL(true);
}

View file

@ -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>(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>(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> (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> (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<DPusher> (type, nullptr, magnitude, angle, nullptr, secnum);
}
}
}

View file

@ -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);

View file

@ -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<DScroller>(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<DScroller>(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<DScroller> (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<DScroller>(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<DScroller> (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<DScroller> (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<DScroller>(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<DScroller> (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<DScroller> (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<DScroller> (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<DScroller> (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<DScroller> (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<DScroller> (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<DScroller> (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<DScroller> (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<DScroller>(type, dx, dy, control, affectee, accel, scrollpos);
}

View file

@ -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<DDoor>(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<DDoor> (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<DLightTransfer> (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<DLightTransfer> (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<DWallLightTransfer> (line.frontsector, line.args[0], line.args[1]);
break;
case Sector_Attach3dMidtex:

View file

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

View file

@ -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<DActiveButton> (side, Where, Switch, pos, useagain);
return true;
}

View file

@ -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<DSectorTagIterator>(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<DLineIdIterator>(tag));
}
DEFINE_ACTION_FUNCTION(DLineIdIterator, Next)

View file

@ -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<DRotatePoly>(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<DMovePoly>(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<DMovePolyTo>(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<DPolyDoor>(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();

View file

@ -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:

View file

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

View file

@ -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:

View file

@ -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<DWallScrollInterpolation>(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<DSectorPlaneInterpolation>(this, true, attach);
break;
case sector_t::FloorMove:
interp = new DSectorPlaneInterpolation(this, false, attach);
interp = Create<DSectorPlaneInterpolation>(this, false, attach);
break;
case sector_t::CeilingScroll:
interp = new DSectorScrollInterpolation(this, true);
interp = Create<DSectorScrollInterpolation>(this, true);
break;
case sector_t::FloorScroll:
interp = new DSectorScrollInterpolation(this, false);
interp = Create<DSectorScrollInterpolation>(this, false);
break;
default:
@ -981,7 +981,7 @@ DInterpolation *FPolyObj::SetInterpolation()
}
else
{
interpolation = new DPolyobjInterpolation(this);
interpolation = Create<DPolyobjInterpolation>(this);
interpolation->AddRef();
}
GC::WriteBarrier(interpolation);

View file

@ -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));
}
//----------------------------------------------------------------------------
//
//

View file

@ -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<DSeqActorNode> (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<DSeqSectorNode>(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<DSeqPolyNode>(poly, sequence, modenum);
}
return NULL;
}

View file

@ -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<PSymbolVMFunction>(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<PField>(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<PField> 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<FxMemberBase *>(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<PField>(NAME_None, membervar->Type, FScopeBarrier::ChangeSideInFlags(membervar->Flags | parentfield->Flags, BarrierSide), membervar->Offset + parentfield->Offset);
newfield->BitValue = membervar->BitValue;
static_cast<FxMemberBase *>(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<PField> 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<FxMemberBase *>(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<PField> 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<FxMemberBase *>(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<PField>(NAME_None, elementtype, parentfield->Flags, indexval * arraytype->ElementSize + parentfield->Offset);
static_cast<FxMemberBase *>(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<PField>(NAME_None, TypeUInt32, ismeta? VARF_Meta : 0, SizeAddr);
static_cast<FxMemberBase *>(Array)->membervar = f;
static_cast<FxMemberBase *>(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<FxMemberBase*>(Self);
auto newfield = new PField(NAME_None, backingtype, 0, member->membervar->Offset);
auto newfield = Create<PField>(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<FxMemberBase*>(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<PField>(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<VMValue> &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<PClass *>(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<PClass *>(cls));
}
else ret->SetPointer(nullptr);
return 1;
ACTION_RETURN_POINTER(cls);
}
ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build)

View file

@ -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

View file

@ -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()

View file

@ -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<PSymbolConstNumeric>(symname, TypeSInt32);
sym->Value = val.GetInt();
}
else
{
sym = new PSymbolConstNumeric(symname, TypeFloat64);
sym = Create<PSymbolConstNumeric>(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<PSymbolConstNumeric>(symname, TypeSInt32);
sym->Value = currvalue;
if (symt->AddSymbol (sym) == NULL)
{

View file

@ -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<PField>(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<PField>(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<PField>(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.

View file

@ -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<PFunction>(containingclass, NAME_None); // anonymous functions do not have names.
sym->AddVariant(NewPrototype(rets, args), argflags, argnames, nullptr, fflags, flags);
return sym;
}

View file

@ -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<PField>(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<PSymbolType>(NAME_sByte, TypeSInt8));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Byte, TypeUInt8));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Short, TypeSInt16));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_uShort, TypeUInt16));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Int, TypeSInt32));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_uInt, TypeUInt32));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Bool, TypeBool));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Float, TypeFloat64));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Double, TypeFloat64));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Float32, TypeFloat32));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Float64, TypeFloat64));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_String, TypeString));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Name, TypeName));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Sound, TypeSound));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Color, TypeColor));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_State, TypeState));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Vector2, TypeVector2));
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(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<PSymbolConstNumeric>(NAME_Min, this, minval));
Symbols.AddSymbol(Create<PSymbolConstNumeric>(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<PSymbolConstNumeric>(NAME_Min, this, 0u));
Symbols.AddSymbol(Create<PSymbolConstNumeric>(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<PSymbolConstNumeric>(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<PSymbolConstNumeric>(sym[i].Name, this, sym[i].Value));
}
}

View file

@ -329,7 +329,7 @@ ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols,
case AST_Enum:
zenumType = static_cast<ZCC_Enum *>(node);
enumType = NewEnum(zenumType->NodeName, OutNamespace);
OutNamespace->Symbols.AddSymbol(new PSymbolType(zenumType->NodeName, enumType));
OutNamespace->Symbols.AddSymbol(Create<PSymbolType>(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<PSymbolTreeNode>(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<PSymbolType>(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<PSymbolType>(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<PSymbolType>(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<PSymbolType>(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<PSymbolType>(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<PSymbolType>(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<ZCC_ExprConstant *>(val);
if (cval->Type == TypeString)
{
def->Symbol = new PSymbolConstString(def->NodeName, *(cval->StringVal));
def->Symbol = Create<PSymbolConstString>(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<PSymbolConstNumeric>(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<PSymbolConstNumeric>(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<PSymbolConstString>(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<PSymbolConstNumeric>(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<PSymbolConstNumeric>(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<PSymbolConstNumeric>(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<PField>(sas->Id, NewArray(ztype, values.Size()), VARF_Static | VARF_ReadOnly, (size_t)destmem));
}
}
@ -1337,7 +1337,7 @@ bool ZCCCompiler::CompileFields(PContainerType *type, TArray<ZCC_VarDeclarator *
{
// This is a global variable.
if (fd->BitValue != 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<PField>(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<ZCC_Property *> &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<PProperty>(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<PFunction>(c->Type(), f->Name);
sym->AddVariant(NewPrototype(rets, args), argflags, argnames, afd == nullptr ? nullptr : *(afd->VMPointer), varflags, useflags);
c->Type()->Symbols.ReplaceSymbol(sym);

View file

@ -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)

View file

@ -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<DBrokenLines>(broken, count));
}

View file

@ -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<DInterBackground>(wbst));
}
//====================================================================

View file

@ -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"});

View file

@ -69,6 +69,7 @@ gameinfo
statscreen_coop = "CoopStatusScreen"
statscreen_dm = "DeathmatchStatusScreen"
statscreen_single = "DoomStatusScreen"
messageboxclass = "MessageBoxMenu"
}
DoomEdNums

View file

@ -70,6 +70,7 @@ gameinfo
statscreen_coop = "CoopStatusScreen"
statscreen_dm = "DeathmatchStatusScreen"
statscreen_single = "DoomStatusScreen"
messageboxclass = "MessageBoxMenu"
}
spawnnums

View file

@ -68,6 +68,7 @@ gameinfo
statscreen_coop = "CoopStatusScreen"
statscreen_dm = "DeathmatchStatusScreen"
statscreen_single = "RavenStatusScreen"
messageboxclass = "MessageBoxMenu"
}
DoomEdNums

View file

@ -66,6 +66,7 @@ gameinfo
statscreen_coop = "CoopStatusScreen"
statscreen_dm = "DeathmatchStatusScreen"
statscreen_single = "RavenStatusScreen"
messageboxclass = "MessageBoxMenu"
}
DoomEdNums

View file

@ -54,6 +54,7 @@ gameinfo
statscreen_mapnamefont = "BigFont"
statscreen_finishedpatch = "WIF"
statscreen_enteringpatch = "WIENTER"
messageboxclass = "MessageBoxMenu"
}
DoomEdNums

View file

@ -68,6 +68,7 @@ gameinfo
statscreen_dm = "DeathmatchStatusScreen"
statscreen_single = "RavenStatusScreen"
statusbarclass = "StrifeStatusBar"
messageboxclass = "MessageBoxMenu"
}
DoomEdNums

View file

@ -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);

View file

@ -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.

View file

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

View file

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

View file

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