fixed and completed the special field init code. Strings can now be used as class members, and so can structs which contain strings.

- made 'DamageMultiply' an actor property and moved the initialization of ConversationRoot to the property handler for the compiler to get this stuff out of the type classes.
- consolidate default initialization into one function which performs all the required setup. The original implementation did this when adding the fields but that cannot work because at that time no defaults have been created yet.
- fixed: When deriving a class the child class's defaults also must initialize the copied parent fields with special initialization. This part was completely missing.
- removed DECORATE code for parsing native classes because it's no longer needed.
This commit is contained in:
Christoph Oelckers 2016-11-11 14:40:32 +01:00
parent 15ddf70f58
commit 6529931281
9 changed files with 81 additions and 86 deletions

View file

@ -875,7 +875,7 @@ static void ParseActorProperty(FScanner &sc, Baggage &bag)
// Starts a new actor definition
//
//==========================================================================
PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName parentName, bool native)
PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName parentName)
{
PClassActor *replacee = NULL;
PClassActor *ti = NULL;
@ -908,36 +908,7 @@ PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName par
parent = RUNTIME_CLASS(AActor);
}
}
if (native)
{
ti = PClass::FindActor(typeName);
if (ti == NULL)
{
extern void DumpTypeTable();
DumpTypeTable();
sc.Message(MSG_ERROR, "Unknown native actor '%s'", typeName.GetChars());
goto create;
}
else if (ti != RUNTIME_CLASS(AActor) && ti->ParentClass->NativeClass() != parent->NativeClass())
{
sc.Message(MSG_ERROR, "Native class '%s' does not inherit from '%s'", typeName.GetChars(), parentName.GetChars());
parent = RUNTIME_CLASS(AActor);
goto create;
}
else if (ti->Defaults != NULL)
{
sc.Message(MSG_ERROR, "Redefinition of internal class '%s'", typeName.GetChars());
goto create;
}
ti->InitializeNativeDefaults();
ti->ParentClass->DeriveData(ti);
}
else
{
create:
ti = DecoDerivedClass(sc, parent, typeName);
}
ti = DecoDerivedClass(sc, parent, typeName);
ti->Replacee = ti->Replacement = NULL;
ti->DoomEdNum = -1;
@ -1025,12 +996,13 @@ static PClassActor *ParseActorHeader(FScanner &sc, Baggage *bag)
if (sc.CheckString("native"))
{
native = true;
sc.ScriptMessage("Cannot define native classes in DECORATE");
FScriptPosition::ErrorCounter++;
}
try
{
PClassActor *info = CreateNewActor(sc, typeName, parentName, native);
PClassActor *info = CreateNewActor(sc, typeName, parentName);
info->DoomEdNum = DoomEdNum > 0 ? DoomEdNum : -1;
info->SourceLumpName = Wads.GetLumpFullPath(sc.LumpNum);

View file

@ -164,8 +164,6 @@ void CreateDamageFunction(PClassActor *info, AActor *defaults, FxExpression *id,
//
//==========================================================================
PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName parentName, bool native);
void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *part2, int mod);
FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool constant);

View file

@ -652,6 +652,15 @@ DEFINE_PROPERTY(damage, X, Actor)
CreateDamageFunction(bag.Info, defaults, id, true);
}
//==========================================================================
//
//==========================================================================
DEFINE_PROPERTY(damagemultiply, F, Actor)
{
PROP_FLOAT_PARM(dmgm, 0);
defaults->DamageMultiply = dmgm;
}
//==========================================================================
//
//==========================================================================

View file

@ -1917,13 +1917,19 @@ void ZCCCompiler::InitDefaults()
if (ti->ParentClass->Defaults == DEFAULTS_VMEXPORT)
{
ti->ParentClass->Defaults = nullptr;
static_cast<PClassActor *>(ti->ParentClass)->InitializeNativeDefaults();
ti->ParentClass->InitializeDefaults();
ti->ParentClass->ParentClass->DeriveData(ti->ParentClass);
}
ti->InitializeNativeDefaults();
ti->InitializeDefaults();
ti->ParentClass->DeriveData(ti);
// We need special treatment for this one field in AActor's defaults which cannot be made visible to DECORATE as a property.
// It's better to do this here under controlled conditions than deeper down in the class type classes.
if (ti == RUNTIME_CLASS(AActor))
{
((AActor*)ti->Defaults)->ConversationRoot = 1;
}
Baggage bag;
#ifdef _DEBUG