mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-14 16:40:56 +00:00
- resorted some of thingdef.cpp's contents into more appropriate files.
- split FinishActor into several functions. While DECORATE can, ZSCRIPT cannot do all this in one go. - split the state finalization into several class-specific virtual functions.
This commit is contained in:
parent
b1a83bfd26
commit
59ed26c0b6
10 changed files with 286 additions and 220 deletions
|
@ -65,6 +65,12 @@ void PClassInventory::ReplaceClassRef(PClass *oldclass, PClass *newclass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PClassInventory::Finalize(FStateDefinitions &statedef)
|
||||||
|
{
|
||||||
|
Super::Finalize(statedef);
|
||||||
|
((AActor*)Defaults)->flags |= MF_SPECIAL;
|
||||||
|
}
|
||||||
|
|
||||||
IMPLEMENT_CLASS(PClassAmmo)
|
IMPLEMENT_CLASS(PClassAmmo)
|
||||||
|
|
||||||
PClassAmmo::PClassAmmo()
|
PClassAmmo::PClassAmmo()
|
||||||
|
|
|
@ -139,6 +139,7 @@ public:
|
||||||
PClassInventory();
|
PClassInventory();
|
||||||
virtual void DeriveData(PClass *newclass);
|
virtual void DeriveData(PClass *newclass);
|
||||||
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
|
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
|
||||||
|
void Finalize(FStateDefinitions &statedef);
|
||||||
|
|
||||||
FString PickupMessage;
|
FString PickupMessage;
|
||||||
int GiveQuest; // Optionally give one of the quest items.
|
int GiveQuest; // Optionally give one of the quest items.
|
||||||
|
@ -274,6 +275,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
PClassWeapon();
|
PClassWeapon();
|
||||||
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
|
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
|
||||||
|
void Finalize(FStateDefinitions &statedef);
|
||||||
|
|
||||||
int SlotNumber;
|
int SlotNumber;
|
||||||
int SlotPriority;
|
int SlotPriority;
|
||||||
|
|
|
@ -67,6 +67,38 @@ void PClassWeapon::ReplaceClassRef(PClass *oldclass, PClass *newclass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PClassWeapon::Finalize(FStateDefinitions &statedef)
|
||||||
|
{
|
||||||
|
Super::Finalize(statedef);
|
||||||
|
FState *ready = FindState(NAME_Ready);
|
||||||
|
FState *select = FindState(NAME_Select);
|
||||||
|
FState *deselect = FindState(NAME_Deselect);
|
||||||
|
FState *fire = FindState(NAME_Fire);
|
||||||
|
|
||||||
|
// Consider any weapon without any valid state abstract and don't output a warning
|
||||||
|
// This is for creating base classes for weapon groups that only set up some properties.
|
||||||
|
if (ready || select || deselect || fire)
|
||||||
|
{
|
||||||
|
if (!ready)
|
||||||
|
{
|
||||||
|
I_Error("Weapon %s doesn't define a ready state.", TypeName.GetChars());
|
||||||
|
}
|
||||||
|
if (!select)
|
||||||
|
{
|
||||||
|
I_Error("Weapon %s doesn't define a select state.", TypeName.GetChars());
|
||||||
|
}
|
||||||
|
if (!deselect)
|
||||||
|
{
|
||||||
|
I_Error("Weapon %s doesn't define a deselect state.", TypeName.GetChars());
|
||||||
|
}
|
||||||
|
if (!fire)
|
||||||
|
{
|
||||||
|
I_Error("Weapon %s doesn't define a fire state.", TypeName.GetChars());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// AWeapon :: Serialize
|
// AWeapon :: Serialize
|
||||||
|
|
71
src/info.cpp
71
src/info.cpp
|
@ -53,7 +53,9 @@
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
|
#include "thingdef.h"
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
|
#include "doomerrors.h"
|
||||||
|
|
||||||
extern void LoadActors ();
|
extern void LoadActors ();
|
||||||
extern void InitBotStuff();
|
extern void InitBotStuff();
|
||||||
|
@ -380,6 +382,75 @@ void PClassActor::InitializeNativeDefaults()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// PClassActor :: SetReplacement
|
||||||
|
//
|
||||||
|
// Sets as a replacement class for another class.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
bool PClassActor::SetReplacement(FName replaceName)
|
||||||
|
{
|
||||||
|
// Check for "replaces"
|
||||||
|
if (replaceName != NAME_None)
|
||||||
|
{
|
||||||
|
// Get actor name
|
||||||
|
PClassActor *replacee = PClass::FindActor(replaceName);
|
||||||
|
|
||||||
|
if (replacee == nullptr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (replacee != nullptr)
|
||||||
|
{
|
||||||
|
replacee->Replacement = this;
|
||||||
|
Replacee = replacee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// PClassActor :: SetDropItems
|
||||||
|
//
|
||||||
|
// Sets a new drop item list
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void PClassActor::SetDropItems(DDropItem *drops)
|
||||||
|
{
|
||||||
|
DropItems = drops;
|
||||||
|
GC::WriteBarrier(this, DropItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// PClassActor :: Finalize
|
||||||
|
//
|
||||||
|
// Installs the parsed states and does some sanity checking
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void PClassActor::Finalize(FStateDefinitions &statedef)
|
||||||
|
{
|
||||||
|
AActor *defaults = (AActor*)Defaults;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
statedef.FinishStates(this, defaults);
|
||||||
|
}
|
||||||
|
catch (CRecoverableError &)
|
||||||
|
{
|
||||||
|
statedef.MakeStateDefines(NULL);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
statedef.InstallStates(this, defaults);
|
||||||
|
statedef.MakeStateDefines(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// PClassActor :: RegisterIDs
|
// PClassActor :: RegisterIDs
|
||||||
|
|
|
@ -53,6 +53,7 @@ struct Baggage;
|
||||||
class FScanner;
|
class FScanner;
|
||||||
struct FActorInfo;
|
struct FActorInfo;
|
||||||
class FIntCVar;
|
class FIntCVar;
|
||||||
|
class FStateDefinitions;
|
||||||
|
|
||||||
enum EStateDefineFlags
|
enum EStateDefineFlags
|
||||||
{
|
{
|
||||||
|
@ -234,6 +235,9 @@ public:
|
||||||
void SetPainChance(FName type, int chance);
|
void SetPainChance(FName type, int chance);
|
||||||
size_t PropagateMark();
|
size_t PropagateMark();
|
||||||
void InitializeNativeDefaults();
|
void InitializeNativeDefaults();
|
||||||
|
bool SetReplacement(FName replaceName);
|
||||||
|
void SetDropItems(DDropItem *drops);
|
||||||
|
virtual void Finalize(FStateDefinitions &statedef);
|
||||||
|
|
||||||
FState *FindState(int numnames, FName *names, bool exact=false) const;
|
FState *FindState(int numnames, FName *names, bool exact=false) const;
|
||||||
FState *FindStateByString(const char *name, bool exact=false);
|
FState *FindStateByString(const char *name, bool exact=false);
|
||||||
|
|
|
@ -57,6 +57,45 @@
|
||||||
#include "m_argv.h"
|
#include "m_argv.h"
|
||||||
|
|
||||||
void ParseOldDecoration(FScanner &sc, EDefinitionType def);
|
void ParseOldDecoration(FScanner &sc, EDefinitionType def);
|
||||||
|
EXTERN_CVAR(Bool, strictdecorate);
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// DecoDerivedClass
|
||||||
|
//
|
||||||
|
// Create a derived class and performs some additional sanity checks
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -1126,6 +1165,80 @@ static void ParseActionDef (FScanner &sc, PClassActor *cls)
|
||||||
ParseFunctionDef(sc, cls, funcname, rets, VARF_Method | VARF_Action);
|
ParseFunctionDef(sc, cls, funcname, rets, VARF_Method | VARF_Action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Starts a new actor definition
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName parentName, bool native)
|
||||||
|
{
|
||||||
|
PClassActor *replacee = NULL;
|
||||||
|
PClassActor *ti = NULL;
|
||||||
|
|
||||||
|
PClassActor *parent = RUNTIME_CLASS(AActor);
|
||||||
|
|
||||||
|
if (parentName != NAME_None)
|
||||||
|
{
|
||||||
|
parent = PClass::FindActor(parentName);
|
||||||
|
|
||||||
|
PClassActor *p = parent;
|
||||||
|
while (p != NULL)
|
||||||
|
{
|
||||||
|
if (p->TypeName == typeName)
|
||||||
|
{
|
||||||
|
sc.Message(MSG_ERROR, "'%s' inherits from a class with the same name", typeName.GetChars());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p = dyn_cast<PClassActor>(p->ParentClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent == NULL)
|
||||||
|
{
|
||||||
|
sc.Message(MSG_ERROR, "Parent type '%s' not found in %s", parentName.GetChars(), typeName.GetChars());
|
||||||
|
parent = RUNTIME_CLASS(AActor);
|
||||||
|
}
|
||||||
|
else if (!parent->IsDescendantOf(RUNTIME_CLASS(AActor)))
|
||||||
|
{
|
||||||
|
sc.Message(MSG_ERROR, "Parent type '%s' is not an actor in %s", parentName.GetChars(), typeName.GetChars());
|
||||||
|
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->Replacee = ti->Replacement = NULL;
|
||||||
|
ti->DoomEdNum = -1;
|
||||||
|
return ti;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Starts a new actor definition
|
// Starts a new actor definition
|
||||||
|
@ -1216,7 +1329,10 @@ static PClassActor *ParseActorHeader(FScanner &sc, Baggage *bag)
|
||||||
info->DoomEdNum = DoomEdNum > 0 ? DoomEdNum : -1;
|
info->DoomEdNum = DoomEdNum > 0 ? DoomEdNum : -1;
|
||||||
info->SourceLumpName = Wads.GetLumpFullPath(sc.LumpNum);
|
info->SourceLumpName = Wads.GetLumpFullPath(sc.LumpNum);
|
||||||
|
|
||||||
SetReplacement(sc, info, replaceName);
|
if (!info->SetReplacement(replaceName))
|
||||||
|
{
|
||||||
|
sc.ScriptMessage("Replaced type '%s' not found for %s", replaceName.GetChars(), info->TypeName.GetChars());
|
||||||
|
}
|
||||||
|
|
||||||
ResetBaggage (bag, info == RUNTIME_CLASS(AActor) ? NULL : static_cast<PClassActor *>(info->ParentClass));
|
ResetBaggage (bag, info == RUNTIME_CLASS(AActor) ? NULL : static_cast<PClassActor *>(info->ParentClass));
|
||||||
bag->Info = info;
|
bag->Info = info;
|
||||||
|
@ -1293,7 +1409,18 @@ static void ParseActor(FScanner &sc)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FinishActor(sc, info, bag);
|
if (bag.DropItemSet)
|
||||||
|
{
|
||||||
|
bag.Info->SetDropItems(bag.DropItemList);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
info->Finalize(bag.statedef);
|
||||||
|
}
|
||||||
|
catch (CRecoverableError &err)
|
||||||
|
{
|
||||||
|
sc.ScriptError("%s", err.GetMessage());
|
||||||
|
}
|
||||||
sc.SetCMode (false);
|
sc.SetCMode (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,202 +76,6 @@ void ParseDecorate(FScanner &ctx);
|
||||||
// STATIC FUNCTION PROTOTYPES --------------------------------------------
|
// STATIC FUNCTION PROTOTYPES --------------------------------------------
|
||||||
PClassActor *QuestItemClasses[31];
|
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
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName parentName, bool native)
|
|
||||||
{
|
|
||||||
PClassActor *replacee = NULL;
|
|
||||||
PClassActor *ti = NULL;
|
|
||||||
|
|
||||||
PClassActor *parent = RUNTIME_CLASS(AActor);
|
|
||||||
|
|
||||||
if (parentName != NAME_None)
|
|
||||||
{
|
|
||||||
parent = PClass::FindActor(parentName);
|
|
||||||
|
|
||||||
PClassActor *p = parent;
|
|
||||||
while (p != NULL)
|
|
||||||
{
|
|
||||||
if (p->TypeName == typeName)
|
|
||||||
{
|
|
||||||
sc.Message(MSG_ERROR, "'%s' inherits from a class with the same name", typeName.GetChars());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p = dyn_cast<PClassActor>(p->ParentClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parent == NULL)
|
|
||||||
{
|
|
||||||
sc.Message(MSG_ERROR, "Parent type '%s' not found in %s", parentName.GetChars(), typeName.GetChars());
|
|
||||||
parent = RUNTIME_CLASS(AActor);
|
|
||||||
}
|
|
||||||
else if (!parent->IsDescendantOf(RUNTIME_CLASS(AActor)))
|
|
||||||
{
|
|
||||||
sc.Message(MSG_ERROR, "Parent type '%s' is not an actor in %s", parentName.GetChars(), typeName.GetChars());
|
|
||||||
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->Replacee = ti->Replacement = NULL;
|
|
||||||
ti->DoomEdNum = -1;
|
|
||||||
return ti;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void SetReplacement(FScanner &sc, PClassActor *info, FName replaceName)
|
|
||||||
{
|
|
||||||
// Check for "replaces"
|
|
||||||
if (replaceName != NAME_None)
|
|
||||||
{
|
|
||||||
// Get actor name
|
|
||||||
PClassActor *replacee = PClass::FindActor(replaceName);
|
|
||||||
|
|
||||||
if (replacee == NULL)
|
|
||||||
{
|
|
||||||
sc.ScriptMessage("Replaced type '%s' not found for %s", replaceName.GetChars(), info->TypeName.GetChars());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (replacee != NULL)
|
|
||||||
{
|
|
||||||
replacee->Replacement = info;
|
|
||||||
info->Replacee = replacee;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// Finalizes an actor definition
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FinishActor(const FScriptPosition &sc, PClassActor *info, Baggage &bag)
|
|
||||||
{
|
|
||||||
AActor *defaults = (AActor*)info->Defaults;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
bag.statedef.FinishStates (info, defaults);
|
|
||||||
}
|
|
||||||
catch (CRecoverableError &err)
|
|
||||||
{
|
|
||||||
sc.Message(MSG_ERROR, "%s", err.GetMessage());
|
|
||||||
bag.statedef.MakeStateDefines(NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bag.statedef.InstallStates (info, defaults);
|
|
||||||
bag.statedef.MakeStateDefines(NULL);
|
|
||||||
if (bag.DropItemSet)
|
|
||||||
{
|
|
||||||
info->DropItems = bag.DropItemList;
|
|
||||||
GC::WriteBarrier(info, info->DropItems);
|
|
||||||
}
|
|
||||||
if (info->IsDescendantOf (RUNTIME_CLASS(AInventory)))
|
|
||||||
{
|
|
||||||
defaults->flags |= MF_SPECIAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Weapons must be checked for all relevant states. They may crash the game otherwise.
|
|
||||||
if (info->IsDescendantOf(RUNTIME_CLASS(AWeapon)))
|
|
||||||
{
|
|
||||||
FState *ready = info->FindState(NAME_Ready);
|
|
||||||
FState *select = info->FindState(NAME_Select);
|
|
||||||
FState *deselect = info->FindState(NAME_Deselect);
|
|
||||||
FState *fire = info->FindState(NAME_Fire);
|
|
||||||
|
|
||||||
// Consider any weapon without any valid state abstract and don't output a warning
|
|
||||||
// This is for creating base classes for weapon groups that only set up some properties.
|
|
||||||
if (ready || select || deselect || fire)
|
|
||||||
{
|
|
||||||
if (!ready)
|
|
||||||
{
|
|
||||||
sc.Message(MSG_ERROR, "Weapon %s doesn't define a ready state.\n", info->TypeName.GetChars());
|
|
||||||
}
|
|
||||||
if (!select)
|
|
||||||
{
|
|
||||||
sc.Message(MSG_ERROR, "Weapon %s doesn't define a select state.\n", info->TypeName.GetChars());
|
|
||||||
}
|
|
||||||
if (!deselect)
|
|
||||||
{
|
|
||||||
sc.Message(MSG_ERROR, "Weapon %s doesn't define a deselect state.\n", info->TypeName.GetChars());
|
|
||||||
}
|
|
||||||
if (!fire)
|
|
||||||
{
|
|
||||||
sc.Message(MSG_ERROR, "Weapon %s doesn't define a fire state.\n", info->TypeName.GetChars());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Do some postprocessing after everything has been defined
|
// Do some postprocessing after everything has been defined
|
||||||
|
@ -426,14 +230,6 @@ static void FinishThingdef()
|
||||||
|
|
||||||
ActorDamageFuncs.DeleteAndClear();
|
ActorDamageFuncs.DeleteAndClear();
|
||||||
StateTempCalls.DeleteAndClear();
|
StateTempCalls.DeleteAndClear();
|
||||||
|
|
||||||
// Since these are defined in DECORATE now the table has to be initialized here.
|
|
||||||
for(int i = 0; i < 31; i++)
|
|
||||||
{
|
|
||||||
char fmt[20];
|
|
||||||
mysnprintf(fmt, countof(fmt), "QuestItem%d", i+1);
|
|
||||||
QuestItemClasses[i] = PClass::FindActor(fmt);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -454,10 +250,11 @@ void LoadActors ()
|
||||||
|
|
||||||
timer.Reset(); timer.Clock();
|
timer.Reset(); timer.Clock();
|
||||||
ActorDamageFuncs.Clear();
|
ActorDamageFuncs.Clear();
|
||||||
FScriptPosition::ResetErrorCounter();
|
|
||||||
InitThingdef();
|
InitThingdef();
|
||||||
lastlump = 0;
|
lastlump = 0;
|
||||||
ParseScripts();
|
ParseScripts();
|
||||||
|
|
||||||
|
FScriptPosition::ResetErrorCounter();
|
||||||
while ((lump = Wads.FindLump ("DECORATE", &lastlump)) != -1)
|
while ((lump = Wads.FindLump ("DECORATE", &lastlump)) != -1)
|
||||||
{
|
{
|
||||||
FScanner sc(lump);
|
FScanner sc(lump);
|
||||||
|
@ -471,4 +268,12 @@ void LoadActors ()
|
||||||
timer.Unclock();
|
timer.Unclock();
|
||||||
if (!batchrun) Printf("DECORATE parsing took %.2f ms\n", timer.TimeMS());
|
if (!batchrun) Printf("DECORATE parsing took %.2f ms\n", timer.TimeMS());
|
||||||
// Base time: ~52 ms
|
// Base time: ~52 ms
|
||||||
|
|
||||||
|
// Since these are defined in DECORATE now the table has to be initialized here.
|
||||||
|
for (int i = 0; i < 31; i++)
|
||||||
|
{
|
||||||
|
char fmt[20];
|
||||||
|
mysnprintf(fmt, countof(fmt), "QuestItem%d", i + 1);
|
||||||
|
QuestItemClasses[i] = PClass::FindActor(fmt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,10 +178,8 @@ void SetImplicitArgs(TArray<PType *> *args, TArray<DWORD> *argflags, PClass *cls
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName parentName, bool native);
|
PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName parentName, bool native);
|
||||||
void SetReplacement(FScanner &sc, PClassActor *info, FName replaceName);
|
|
||||||
|
|
||||||
void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *part2, int mod);
|
void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *part2, int mod);
|
||||||
void FinishActor(const FScriptPosition &sc, PClassActor *info, Baggage &bag);
|
|
||||||
FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool constant);
|
FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool constant);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,10 @@ void ZCCCompiler::ProcessClass(ZCC_Class *cnode, PSymbolTreeNode *treenode)
|
||||||
name << "nodes - " << FName(cnode->NodeName);
|
name << "nodes - " << FName(cnode->NodeName);
|
||||||
cls->TreeNodes.SetName(name);
|
cls->TreeNodes.SetName(name);
|
||||||
|
|
||||||
|
if (!static_cast<PClassActor *>(cnode->Type)->SetReplacement(cnode->Replaces->Id))
|
||||||
|
{
|
||||||
|
Warn(cnode, "Replaced type '%s' not found for %s", FName(cnode->Replaces->Id).GetChars(), cnode->Type->TypeName.GetChars());
|
||||||
|
}
|
||||||
|
|
||||||
// Need to check if the class actually has a body.
|
// Need to check if the class actually has a body.
|
||||||
if (node != nullptr) do
|
if (node != nullptr) do
|
||||||
|
@ -1836,6 +1840,10 @@ void ZCCCompiler::InitDefaults()
|
||||||
content = static_cast<decltype(content)>(content->SiblingNext);
|
content = static_cast<decltype(content)>(content->SiblingNext);
|
||||||
} while (content != d->Content);
|
} while (content != d->Content);
|
||||||
}
|
}
|
||||||
|
if (bag.DropItemSet)
|
||||||
|
{
|
||||||
|
bag.Info->SetDropItems(bag.DropItemList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2239,5 +2247,13 @@ void ZCCCompiler::CompileStates()
|
||||||
st = static_cast<decltype(st)>(st->SiblingNext);
|
st = static_cast<decltype(st)>(st->SiblingNext);
|
||||||
} while (st != s->Body);
|
} while (st != s->Body);
|
||||||
}
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
static_cast<PClassActor *>(c->Type())->Finalize(statedef);
|
||||||
|
}
|
||||||
|
catch (CRecoverableError &err)
|
||||||
|
{
|
||||||
|
Error(c->cls, "%s", err.GetMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -371,25 +371,30 @@ class Actor : Thinker native
|
||||||
native int ACS_NamedExecuteWithResult(name script, int arg1=0, int arg2=0, int arg3=0, int arg4=0);
|
native int ACS_NamedExecuteWithResult(name script, int arg1=0, int arg2=0, int arg3=0, int arg4=0);
|
||||||
native void ACS_NamedExecuteAlways(name script, int mapnum=0, int arg1=0, int arg2=0, int arg3=0);
|
native void ACS_NamedExecuteAlways(name script, int mapnum=0, int arg1=0, int arg2=0, int arg3=0);
|
||||||
|
|
||||||
/*
|
|
||||||
States
|
States
|
||||||
{
|
{
|
||||||
Spawn:
|
Spawn:
|
||||||
TNT1 A -1
|
TNT1 A -1;
|
||||||
Stop
|
Stop;
|
||||||
Null:
|
Null:
|
||||||
TNT1 A 1
|
TNT1 A 1;
|
||||||
Stop
|
Stop;
|
||||||
GenericFreezeDeath:
|
GenericFreezeDeath:
|
||||||
// Generic freeze death frames. Woo!
|
// Generic freeze death frames. Woo!
|
||||||
"####" "#" 5 A_GenericFreezeDeath
|
#### # 5 A_GenericFreezeDeath;
|
||||||
"----" A 1 A_FreezeDeathChunks
|
---- A 1 A_FreezeDeathChunks;
|
||||||
Wait
|
Wait;
|
||||||
GenericCrush:
|
GenericCrush:
|
||||||
POL5 A -1
|
POL5 A -1;
|
||||||
Stop
|
Stop;
|
||||||
|
Test.State:
|
||||||
|
&&&& A[\] 5 offset(4,4*2);
|
||||||
|
&&&& A[\] DEFAULT_HEALTH;
|
||||||
|
abcd efgh random(3, 6);
|
||||||
|
lght blahblah 5*3 light("furz", "bläh", "rülps");
|
||||||
|
lght blahblah 5 light("boing");
|
||||||
|
goto Actor::Spawn+1;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// Internal functions
|
// Internal functions
|
||||||
deprecated private native state __decorate_internal_state__(state s);
|
deprecated private native state __decorate_internal_state__(state s);
|
||||||
|
|
Loading…
Reference in a new issue