- changed handling of duplicate classes in DECORATE.

Instead of replacing the original, the second class will get renamed now, using the originating file as an identifier. In the vast majority of cases this should do exactly what is needed: Create an unconflicting second class that can coexist with the original. Unless the class is used by name this should eliminate all problems with this, but so far I haven't seen anything that used them by name.

This is choosing the lesser of two evils. While some mod out there may get broken, the old setup meant that the first class of a given name could not be written out to a savegame because it was not retrievable when loading it back.
This commit is contained in:
Christoph Oelckers 2016-10-07 15:28:25 +02:00
commit d819aafcf3
4 changed files with 72 additions and 16 deletions

View file

@ -68,13 +68,44 @@
TDeletingArray<class FxExpression *> ActorDamageFuncs;
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
void InitThingdef();
void ParseDecorate (FScanner &sc);
void ParseDecorate(FScanner &ctx);
// STATIC FUNCTION PROTOTYPES --------------------------------------------
PClassActor *QuestItemClasses[31];
EXTERN_CVAR(Bool, strictdecorate);
PClassActor *DecoDerivedClass(const FScriptPosition &sc, PClassActor *parent, FName typeName)
{
PClassActor *type = static_cast<PClassActor *>(parent->CreateDerivedClass(typeName, parent->Size));
if (type == nullptr)
{
FString newname = typeName.GetChars();
FString sourcefile = sc.FileName;
sourcefile.Substitute(":", "@");
newname << '@' << sourcefile;
if (strictdecorate)
{
sc.Message(MSG_ERROR, "Tried to define class '%s' more than once.", typeName.GetChars());
}
else
{
// Due to backwards compatibility issues this cannot be an unconditional error.
sc.Message(MSG_WARNING, "Tried to define class '%s' more than once. Renaming class to '%s'", typeName.GetChars(), newname.GetChars());
}
type = static_cast<PClassActor *>(parent->CreateDerivedClass(newname, parent->Size));
if (type == nullptr)
{
// This we cannot handle cleanly anymore. Let's just abort and forget about the odd mod out that was this careless.
sc.Message(MSG_FATAL, "Tried to define class '%s' more than twice in the same file.", typeName.GetChars());
}
}
return type;
}
//==========================================================================
//
// Starts a new actor definition
@ -141,7 +172,7 @@ PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName par
else
{
create:
ti = static_cast<PClassActor *>(parent->CreateDerivedClass (typeName, parent->Size));
ti = DecoDerivedClass(sc, parent, typeName);
}
ti->Replacee = ti->Replacement = NULL;
@ -428,6 +459,16 @@ void LoadActors ()
while ((lump = Wads.FindLump ("DECORATE", &lastlump)) != -1)
{
FScanner sc(lump);
if (Wads.GetLumpFile(lump) == 0)
{
// define namespace 'zdoom'
}
else
{
// use namespace 'zdoom'
}
ParseDecorate (sc);
}
FinishThingdef();