diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index 2965357dd..421b27fb1 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -51,6 +51,8 @@ #include "codegeneration/codegen.h" #include "vmbuilder.h" +#define DEFAULTS_VMEXPORT ((BYTE *)(void *)1) + //========================================================================== // // ZCCCompiler :: ProcessClass @@ -498,6 +500,26 @@ void ZCCCompiler::CreateClassTypes() } else { + // The parent was the last native class in the inheritance tree. + // There is probably a better place for this somewhere else + // TODO: Do this somewhere else or find a less hackish way to do it + if (!parent->bRuntimeClass) + { + //assert(parent->VMExported != nullptr); // Ideally the macro would be used on all inheritable-native classes + /**/ if (parent->VMExported != nullptr) { /**/ // remove the if condition when all done + + parent = parent->VMExported; + assert(parent->bRuntimeClass == false); + + if (parent->Defaults == nullptr) + { + // We have to manually do that since zscript knows nothing about these + parent->Defaults = DEFAULTS_VMEXPORT; + } + + /**/ } /**/ + } + // We will never get here if the name is a duplicate, so we can just do the assignment. c->cls->Type = parent->FindClassTentative(c->NodeName()); } @@ -1887,6 +1909,16 @@ void ZCCCompiler::InitDefaults() { // Copy the parent's defaults and meta data. auto ti = static_cast(c->Type()); + + // Hack for the DVMObjects as they weren't in the list originally + // TODO: process them in a non hackish way obviously + if (ti->ParentClass->Defaults == DEFAULTS_VMEXPORT) + { + ti->ParentClass->Defaults = nullptr; + static_cast(ti->ParentClass)->InitializeNativeDefaults(); + ti->ParentClass->ParentClass->DeriveData(ti->ParentClass); + } + ti->InitializeNativeDefaults(); ti->ParentClass->DeriveData(ti); @@ -2239,6 +2271,20 @@ void ZCCCompiler::CompileStates() if (c->States.Size()) Error(c->cls, "%s: States can only be defined for actors.", c->Type()->TypeName.GetChars()); continue; } + + // Same here, hack in the DVMObject as they weren't in the list originally + // TODO: process them in a non hackish way obviously + if (c->Type()->bRuntimeClass == true && c->Type()->ParentClass->bRuntimeClass == false) + { + auto vmtype = static_cast(c->Type()->ParentClass); + if (vmtype->StateList == nullptr) + { + FStateDefinitions vmstates; + vmstates.MakeStateDefines(dyn_cast(vmtype->ParentClass)); + vmtype->Finalize(vmstates); + } + } + FString statename; // The state builder wants the label as one complete string, not separated into tokens. FStateDefinitions statedef; statedef.MakeStateDefines(dyn_cast(c->Type()->ParentClass));