mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- Made several DECORATE errors which do not involve parsing non-fatal.
- Added a static error counter to FScriptPosition class. - Changed initialization of actor class type properties: fuglyname is gone as is the postprocessing in FinishThingdef. Instead an empty placeholder class is now created when a class is first referenced and this placeholder is later filled in. - Added option to replace backslash with '^' in state frame definitions because the backslash is just causing too many problems because it's also an escape character. SVN r1334 (trunk)
This commit is contained in:
parent
8f686a5e02
commit
f8c38e5f54
12 changed files with 211 additions and 186 deletions
|
@ -1,3 +1,14 @@
|
|||
December 30, 2008 (Changes by Graf Zahl)
|
||||
- Made several DECORATE errors which do not involve parsing non-fatal.
|
||||
- Added a static error counter to FScriptPosition class.
|
||||
- Changed initialization of actor class type properties: fuglyname is gone as
|
||||
is the postprocessing in FinishThingdef. Instead an empty placeholder class
|
||||
is now created when a class is first referenced and this placeholder is later
|
||||
filled in.
|
||||
- Added option to replace backslash with '^' in state frame definitions because
|
||||
the backslash is just causing too many problems because it's also an escape
|
||||
character.
|
||||
|
||||
December 28, 2008 (Changes by Graf Zahl)
|
||||
- Added Karate Chris's new DMFlags submission.
|
||||
|
||||
|
|
|
@ -216,7 +216,7 @@ const PClass *PClass::FindClass (FName zaname)
|
|||
}
|
||||
else if (lexx == 0)
|
||||
{
|
||||
return cls;
|
||||
return cls->Size<0? NULL : cls;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -247,15 +247,34 @@ DObject *PClass::CreateNew () const
|
|||
PClass *PClass::CreateDerivedClass (FName name, unsigned int size)
|
||||
{
|
||||
assert (size >= Size);
|
||||
PClass *type;
|
||||
bool notnew;
|
||||
|
||||
PClass *type = new PClass;
|
||||
const PClass *existclass = FindClass(name);
|
||||
|
||||
// This is a placeholder so fill it in
|
||||
if (existclass != NULL && existclass->Size == -1)
|
||||
{
|
||||
type = const_cast<PClass*>(existclass);
|
||||
if (!IsDescendantOf(type->ParentClass))
|
||||
{
|
||||
I_Error("%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars());
|
||||
}
|
||||
Printf("Defining placeholder class %s\n", name.GetChars());
|
||||
notnew = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = new PClass;
|
||||
notnew = false;
|
||||
}
|
||||
|
||||
type->TypeName = name;
|
||||
type->ParentClass = this;
|
||||
type->Size = size;
|
||||
type->Pointers = NULL;
|
||||
type->ConstructNative = ConstructNative;
|
||||
type->ClassIndex = m_Types.Push (type);
|
||||
if (!notnew) type->ClassIndex = m_Types.Push (type);
|
||||
type->Meta = Meta;
|
||||
type->Defaults = new BYTE[size];
|
||||
memcpy (type->Defaults, Defaults, Size);
|
||||
|
@ -267,7 +286,7 @@ PClass *PClass::CreateDerivedClass (FName name, unsigned int size)
|
|||
type->bRuntimeClass = true;
|
||||
type->ActorInfo = NULL;
|
||||
type->Symbols.SetParentTable (&this->Symbols);
|
||||
type->InsertIntoHash();
|
||||
if (!notnew) type->InsertIntoHash();
|
||||
|
||||
// If this class has an actor info, then any classes derived from it
|
||||
// also need an actor info.
|
||||
|
@ -290,6 +309,51 @@ PClass *PClass::CreateDerivedClass (FName name, unsigned int size)
|
|||
return type;
|
||||
}
|
||||
|
||||
// Like FindClass but creates a placeholder if no class
|
||||
// is found. CreateDerivedClass will automatcally fill in
|
||||
// the placeholder when the actual class is defined.
|
||||
const PClass *PClass::FindClassTentative (FName name)
|
||||
{
|
||||
if (name == NAME_None)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PClass *cls = TypeHash[name % HASH_SIZE];
|
||||
|
||||
while (cls != 0)
|
||||
{
|
||||
int lexx = int(name) - int(cls->TypeName);
|
||||
if (lexx > 0)
|
||||
{
|
||||
cls = cls->HashNext;
|
||||
}
|
||||
else if (lexx == 0)
|
||||
{
|
||||
return cls;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
PClass *type = new PClass;
|
||||
Printf("Creating placeholder class %s : %s\n", name.GetChars(), TypeName.GetChars());
|
||||
|
||||
type->TypeName = name;
|
||||
type->ParentClass = this;
|
||||
type->Size = -1;
|
||||
type->Pointers = NULL;
|
||||
type->ConstructNative = NULL;
|
||||
type->ClassIndex = m_Types.Push (type);
|
||||
type->Defaults = NULL;
|
||||
type->FlatPointers = NULL;
|
||||
type->bRuntimeClass = true;
|
||||
type->ActorInfo = NULL;
|
||||
type->InsertIntoHash();
|
||||
return type;
|
||||
}
|
||||
|
||||
// This is used by DECORATE to assign ActorInfos to internal classes
|
||||
void PClass::InitializeActorInfo ()
|
||||
{
|
||||
|
|
|
@ -169,6 +169,7 @@ struct PClass
|
|||
static const PClass *FindClass (const FString &name) { return FindClass (FName (name, true)); }
|
||||
static const PClass *FindClass (ENamedName name) { return FindClass (FName (name)); }
|
||||
static const PClass *FindClass (FName name);
|
||||
const PClass *FindClassTentative (FName name); // not static!
|
||||
|
||||
static TArray<PClass *> m_Types;
|
||||
static TArray<PClass *> m_RuntimeActors;
|
||||
|
|
|
@ -826,8 +826,14 @@ bool FStateDefinitions::AddStates(FState *state, const char *framechars)
|
|||
bool error = false;
|
||||
while (*framechars)
|
||||
{
|
||||
int frame=((*framechars++)&223)-'A';
|
||||
int frame;
|
||||
|
||||
if (*framechars == '^')
|
||||
frame = '\\'-'A';
|
||||
else
|
||||
frame = ((*framechars)&223)-'A';
|
||||
|
||||
framechars++;
|
||||
if (frame<0 || frame>28)
|
||||
{
|
||||
frame = 0;
|
||||
|
|
|
@ -1030,6 +1030,7 @@ void FScanner::CheckOpen()
|
|||
// a class that remembers a parser position
|
||||
//
|
||||
//==========================================================================
|
||||
int FScriptPosition::ErrorCounter;
|
||||
|
||||
FScriptPosition::FScriptPosition(const FScriptPosition &other)
|
||||
{
|
||||
|
@ -1092,6 +1093,7 @@ void STACK_ARGS FScriptPosition::Message (int severity, const char *message, ...
|
|||
break;
|
||||
|
||||
case MSG_ERROR:
|
||||
ErrorCounter++;
|
||||
type = "error";
|
||||
break;
|
||||
|
||||
|
|
|
@ -238,6 +238,7 @@ enum
|
|||
|
||||
struct FScriptPosition
|
||||
{
|
||||
static int ErrorCounter;
|
||||
FString FileName;
|
||||
int ScriptLine;
|
||||
|
||||
|
@ -250,6 +251,10 @@ struct FScriptPosition
|
|||
FScriptPosition(FScanner &sc);
|
||||
FScriptPosition &operator=(const FScriptPosition &other);
|
||||
void Message(int severity, const char *message,...) const;
|
||||
static void ResetErrorCounter()
|
||||
{
|
||||
ErrorCounter = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -184,7 +184,8 @@ void SetReplacement(FActorInfo *info, FName replaceName)
|
|||
|
||||
void FinishActor(const FScriptPosition &sc, FActorInfo *info, Baggage &bag)
|
||||
{
|
||||
AActor *defaults = (AActor*)info->Class->Defaults;
|
||||
PClass *ti = info->Class;
|
||||
AActor *defaults = (AActor*)ti->Defaults;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -192,7 +193,9 @@ void FinishActor(const FScriptPosition &sc, FActorInfo *info, Baggage &bag)
|
|||
}
|
||||
catch (CRecoverableError &err)
|
||||
{
|
||||
sc.Message(MSG_FATAL, "%s", err.GetMessage());
|
||||
sc.Message(MSG_ERROR, "%s", err.GetMessage());
|
||||
bag.statedef.MakeStateDefines(NULL);
|
||||
return;
|
||||
}
|
||||
bag.statedef.InstallStates (info, defaults);
|
||||
bag.statedef.MakeStateDefines(NULL);
|
||||
|
@ -200,69 +203,78 @@ void FinishActor(const FScriptPosition &sc, FActorInfo *info, Baggage &bag)
|
|||
{
|
||||
if (bag.DropItemList == NULL)
|
||||
{
|
||||
if (info->Class->Meta.GetMetaInt (ACMETA_DropItems) != 0)
|
||||
if (ti->Meta.GetMetaInt (ACMETA_DropItems) != 0)
|
||||
{
|
||||
info->Class->Meta.SetMetaInt (ACMETA_DropItems, 0);
|
||||
ti->Meta.SetMetaInt (ACMETA_DropItems, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info->Class->Meta.SetMetaInt (ACMETA_DropItems,
|
||||
ti->Meta.SetMetaInt (ACMETA_DropItems,
|
||||
StoreDropItemChain(bag.DropItemList));
|
||||
}
|
||||
}
|
||||
if (info->Class->IsDescendantOf (RUNTIME_CLASS(AInventory)))
|
||||
if (ti->IsDescendantOf (RUNTIME_CLASS(AInventory)))
|
||||
{
|
||||
defaults->flags |= MF_SPECIAL;
|
||||
}
|
||||
|
||||
// Weapons must be checked for all relevant states. They may crash the game otherwise.
|
||||
if (ti->IsDescendantOf(RUNTIME_CLASS(AWeapon)))
|
||||
{
|
||||
FState * ready = ti->ActorInfo->FindState(NAME_Ready);
|
||||
FState * select = ti->ActorInfo->FindState(NAME_Select);
|
||||
FState * deselect = ti->ActorInfo->FindState(NAME_Deselect);
|
||||
FState * fire = ti->ActorInfo->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", ti->TypeName.GetChars());
|
||||
}
|
||||
if (!select)
|
||||
{
|
||||
sc.Message(MSG_ERROR, "Weapon %s doesn't define a select state.\n", ti->TypeName.GetChars());
|
||||
}
|
||||
if (!deselect)
|
||||
{
|
||||
sc.Message(MSG_ERROR, "Weapon %s doesn't define a deselect state.\n", ti->TypeName.GetChars());
|
||||
}
|
||||
if (!fire)
|
||||
{
|
||||
sc.Message(MSG_ERROR, "Weapon %s doesn't define a fire state.\n", ti->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Do some postprocessing after everything has been defined
|
||||
// This also processes all the internal actors to adjust the type
|
||||
// fields in the weapons
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static int ResolvePointer(const PClass **pPtr, const PClass *owner, const PClass *destclass, const char *description)
|
||||
{
|
||||
fuglyname v;
|
||||
|
||||
v = *pPtr;
|
||||
if (v != NAME_None && v.IsValidName())
|
||||
{
|
||||
*pPtr = PClass::FindClass(v);
|
||||
if (!*pPtr)
|
||||
{
|
||||
Printf("Unknown %s '%s' in '%s'\n", description, v.GetChars(), owner->TypeName.GetChars());
|
||||
return 1;
|
||||
}
|
||||
else if (!(*pPtr)->IsDescendantOf(destclass))
|
||||
{
|
||||
*pPtr = NULL;
|
||||
Printf("Invalid %s '%s' in '%s'\n", description, v.GetChars(), owner->TypeName.GetChars());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void FinishThingdef()
|
||||
{
|
||||
unsigned int i;
|
||||
int errorcount;
|
||||
int errorcount = StateParams.ResolveAll();
|
||||
|
||||
errorcount = StateParams.ResolveAll();
|
||||
|
||||
for (i = 0;i < PClass::m_Types.Size(); i++)
|
||||
for (unsigned i = 0;i < PClass::m_Types.Size(); i++)
|
||||
{
|
||||
PClass * ti = PClass::m_Types[i];
|
||||
|
||||
// Skip non-actors
|
||||
if (!ti->IsDescendantOf(RUNTIME_CLASS(AActor))) continue;
|
||||
|
||||
if (ti->Size == -1)
|
||||
{
|
||||
Printf("Class %s referenced but not defined\n", ti->TypeName.GetChars());
|
||||
errorcount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
AActor *def = GetDefaultByType(ti);
|
||||
|
||||
if (!def)
|
||||
|
@ -271,100 +283,6 @@ static void FinishThingdef()
|
|||
errorcount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Friendlies never count as kills!
|
||||
if (def->flags & MF_FRIENDLY)
|
||||
{
|
||||
def->flags &=~MF_COUNTKILL;
|
||||
}
|
||||
|
||||
if (ti->IsDescendantOf(RUNTIME_CLASS(AInventory)))
|
||||
{
|
||||
AInventory * defaults=(AInventory *)def;
|
||||
errorcount += ResolvePointer(&defaults->PickupFlash, ti, RUNTIME_CLASS(AActor), "pickup flash");
|
||||
}
|
||||
|
||||
if (ti->IsDescendantOf(RUNTIME_CLASS(APowerupGiver)) && ti != RUNTIME_CLASS(APowerupGiver))
|
||||
{
|
||||
FString typestr;
|
||||
APowerupGiver * defaults=(APowerupGiver *)def;
|
||||
fuglyname v;
|
||||
|
||||
v = defaults->PowerupType;
|
||||
if (v != NAME_None && v.IsValidName())
|
||||
{
|
||||
typestr.Format ("Power%s", v.GetChars());
|
||||
const PClass * powertype=PClass::FindClass(typestr);
|
||||
if (!powertype) powertype=PClass::FindClass(v.GetChars());
|
||||
|
||||
if (!powertype)
|
||||
{
|
||||
Printf("Unknown powerup type '%s' in '%s'\n", v.GetChars(), ti->TypeName.GetChars());
|
||||
errorcount++;
|
||||
}
|
||||
else if (!powertype->IsDescendantOf(RUNTIME_CLASS(APowerup)))
|
||||
{
|
||||
Printf("Invalid powerup type '%s' in '%s'\n", v.GetChars(), ti->TypeName.GetChars());
|
||||
errorcount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
defaults->PowerupType=powertype;
|
||||
}
|
||||
}
|
||||
else if (v == NAME_None)
|
||||
{
|
||||
Printf("No powerup type specified in '%s'\n", ti->TypeName.GetChars());
|
||||
errorcount++;
|
||||
}
|
||||
}
|
||||
|
||||
// the typeinfo properties of weapons have to be fixed here after all actors have been declared
|
||||
if (ti->IsDescendantOf(RUNTIME_CLASS(AWeapon)))
|
||||
{
|
||||
AWeapon * defaults=(AWeapon *)def;
|
||||
errorcount += ResolvePointer(&defaults->AmmoType1, ti, RUNTIME_CLASS(AAmmo), "ammo type");
|
||||
errorcount += ResolvePointer(&defaults->AmmoType2, ti, RUNTIME_CLASS(AAmmo), "ammo type");
|
||||
errorcount += ResolvePointer(&defaults->SisterWeaponType, ti, RUNTIME_CLASS(AWeapon), "sister weapon type");
|
||||
|
||||
FState * ready = ti->ActorInfo->FindState(NAME_Ready);
|
||||
FState * select = ti->ActorInfo->FindState(NAME_Select);
|
||||
FState * deselect = ti->ActorInfo->FindState(NAME_Deselect);
|
||||
FState * fire = ti->ActorInfo->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)
|
||||
{
|
||||
// Do some consistency checks. If these states are undefined the weapon cannot work!
|
||||
if (!ready)
|
||||
{
|
||||
Printf("Weapon %s doesn't define a ready state.\n", ti->TypeName.GetChars());
|
||||
errorcount++;
|
||||
}
|
||||
if (!select)
|
||||
{
|
||||
Printf("Weapon %s doesn't define a select state.\n", ti->TypeName.GetChars());
|
||||
errorcount++;
|
||||
}
|
||||
if (!deselect)
|
||||
{
|
||||
Printf("Weapon %s doesn't define a deselect state.\n", ti->TypeName.GetChars());
|
||||
errorcount++;
|
||||
}
|
||||
if (!fire)
|
||||
{
|
||||
Printf("Weapon %s doesn't define a fire state.\n", ti->TypeName.GetChars());
|
||||
errorcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// same for the weapon type of weapon pieces.
|
||||
else if (ti->IsDescendantOf(RUNTIME_CLASS(AWeaponPiece)))
|
||||
{
|
||||
AWeaponPiece * defaults=(AWeaponPiece *)def;
|
||||
errorcount += ResolvePointer(&defaults->WeaponClass, ti, RUNTIME_CLASS(AWeapon), "weapon type");
|
||||
}
|
||||
}
|
||||
if (errorcount > 0)
|
||||
{
|
||||
|
@ -378,7 +296,6 @@ static void FinishThingdef()
|
|||
mysnprintf(fmt, countof(fmt), "QuestItem%d", i+1);
|
||||
QuestItemClasses[i] = PClass::FindClass(fmt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -395,6 +312,7 @@ void LoadActors ()
|
|||
{
|
||||
int lastlump, lump;
|
||||
|
||||
FScriptPosition::ResetErrorCounter();
|
||||
InitThingdef();
|
||||
lastlump = 0;
|
||||
while ((lump = Wads.FindLump ("DECORATE", &lastlump)) != -1)
|
||||
|
@ -402,6 +320,10 @@ void LoadActors ()
|
|||
FScanner sc(lump);
|
||||
ParseDecorate (sc);
|
||||
}
|
||||
if (FScriptPosition::ErrorCounter > 0)
|
||||
{
|
||||
I_Error("%d errors while parsing DECORATE scripts", FScriptPosition::ErrorCounter);
|
||||
}
|
||||
FinishThingdef();
|
||||
}
|
||||
|
||||
|
|
|
@ -27,31 +27,6 @@ FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2);
|
|||
void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int index);
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// This class is for storing a name inside a const PClass* field without
|
||||
// generating compiler warnings. It does not manipulate data in any other
|
||||
// way.
|
||||
//
|
||||
//==========================================================================
|
||||
class fuglyname : public FName
|
||||
{
|
||||
public:
|
||||
fuglyname() : FName() {}
|
||||
fuglyname(const char *foo) : FName(foo) {}
|
||||
operator const PClass *()
|
||||
{
|
||||
return reinterpret_cast<const PClass *>(size_t(int(*this)));
|
||||
}
|
||||
fuglyname &operator= (const PClass *foo)
|
||||
{
|
||||
FName *p = this;
|
||||
*p = ENamedName(reinterpret_cast<size_t>(foo));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// State parser
|
||||
|
|
|
@ -62,6 +62,12 @@ struct FCompileContext
|
|||
bool lax;
|
||||
bool isconst;
|
||||
|
||||
FCompileContext(const PClass *_cls = NULL, bool _lax = false, bool _isconst = false)
|
||||
{
|
||||
cls = _cls;
|
||||
lax = _lax;
|
||||
isconst = _isconst;
|
||||
}
|
||||
|
||||
PSymbol *FindInClass(FName identifier)
|
||||
{
|
||||
|
|
|
@ -232,7 +232,7 @@ static ExpVal GetVariableValue (void *address, FExpressionType &type)
|
|||
|
||||
ExpVal FxExpression::EvalExpression (AActor *self)
|
||||
{
|
||||
I_Error("Unresolved expression found");
|
||||
ScriptPosition.Message(MSG_ERROR, "Unresolved expression found");
|
||||
ExpVal val;
|
||||
|
||||
val.Type = VAL_Int;
|
||||
|
@ -2635,23 +2635,27 @@ FxExpression *FxMultiNameState::Resolve(FCompileContext &ctx)
|
|||
}
|
||||
if (scope != NULL)
|
||||
{
|
||||
FState *destination = NULL;
|
||||
// If the label is class specific we can resolve it right here
|
||||
if (scope->ActorInfo == NULL)
|
||||
if (names[1] != NAME_None)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "'%s' has no actorinfo", names[0].GetChars());
|
||||
delete this;
|
||||
return NULL;
|
||||
}
|
||||
FState *destination = scope->ActorInfo->FindState(names.Size()-1, &names[1], false);
|
||||
if (destination == NULL)
|
||||
{
|
||||
ScriptPosition.Message(ctx.lax? MSG_WARNING:MSG_ERROR, "Unknown state jump destination");
|
||||
if (!ctx.lax)
|
||||
if (scope->ActorInfo == NULL)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "'%s' has no actorinfo", names[0].GetChars());
|
||||
delete this;
|
||||
return NULL;
|
||||
}
|
||||
return this;
|
||||
destination = scope->ActorInfo->FindState(names.Size()-1, &names[1], false);
|
||||
if (destination == NULL)
|
||||
{
|
||||
ScriptPosition.Message(ctx.lax? MSG_WARNING:MSG_ERROR, "Unknown state jump destination");
|
||||
if (!ctx.lax)
|
||||
{
|
||||
delete this;
|
||||
return NULL;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
FxExpression *x = new FxConstant(destination, ScriptPosition);
|
||||
delete this;
|
||||
|
@ -2707,7 +2711,7 @@ FStateExpressions StateParams;
|
|||
|
||||
FStateExpressions::~FStateExpressions()
|
||||
{
|
||||
for(int i=0; i<Size(); i++)
|
||||
for(unsigned i=0; i<Size(); i++)
|
||||
{
|
||||
if (expressions[i].expr != NULL && !expressions[i].cloned)
|
||||
{
|
||||
|
@ -2797,7 +2801,7 @@ int FStateExpressions::ResolveAll()
|
|||
|
||||
FCompileContext ctx;
|
||||
ctx.lax = true;
|
||||
for(int i=0; i<Size(); i++)
|
||||
for(unsigned i=0; i<Size(); i++)
|
||||
{
|
||||
if (expressions[i].cloned)
|
||||
{
|
||||
|
@ -2822,7 +2826,7 @@ int FStateExpressions::ResolveAll()
|
|||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<Size(); i++)
|
||||
for(unsigned i=0; i<Size(); i++)
|
||||
{
|
||||
if (expressions[i].expr != NULL)
|
||||
{
|
||||
|
|
|
@ -69,6 +69,25 @@
|
|||
#include "colormatcher.h"
|
||||
#include "autosegs.h"
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Gets a class pointer and performs an error check for correct type
|
||||
//
|
||||
//==========================================================================
|
||||
static const PClass *FindClassTentative(const char *name, const char *ancestor)
|
||||
{
|
||||
const PClass *anc = PClass::FindClass(ancestor);
|
||||
assert(anc != NULL); // parent classes used here should always be natively defined
|
||||
const PClass *cls = const_cast<PClass*>(anc)->FindClassTentative(name);
|
||||
assert (cls != NULL); // cls can not ne NULL here
|
||||
if (!cls->IsDescendantOf(anc))
|
||||
{
|
||||
I_Error("%s does not inherit from %s\n", name, ancestor);
|
||||
}
|
||||
return cls;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// HandleDeprecatedFlags
|
||||
|
@ -107,7 +126,7 @@ void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int ind
|
|||
case DEPF_PICKUPFLASH:
|
||||
if (set)
|
||||
{
|
||||
static_cast<AInventory*>(defaults)->PickupFlash = fuglyname("PickupFlash");
|
||||
static_cast<AInventory*>(defaults)->PickupFlash = FindClassTentative("PickupFlash", "Actor");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1160,7 +1179,7 @@ DEFINE_CLASS_PROPERTY(defmaxamount, 0, Inventory)
|
|||
DEFINE_CLASS_PROPERTY(pickupflash, S, Inventory)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
defaults->PickupFlash = fuglyname(str);
|
||||
defaults->PickupFlash = FindClassTentative(str, "Actor");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1270,7 +1289,7 @@ DEFINE_CLASS_PROPERTY(ammogive2, I, Weapon)
|
|||
DEFINE_CLASS_PROPERTY(ammotype, S, Weapon)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
defaults->AmmoType1 = fuglyname(str);
|
||||
defaults->AmmoType1 = FindClassTentative(str, "Ammo");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1279,7 +1298,7 @@ DEFINE_CLASS_PROPERTY(ammotype, S, Weapon)
|
|||
DEFINE_CLASS_PROPERTY(ammotype1, S, Weapon)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
defaults->AmmoType1 = fuglyname(str);
|
||||
defaults->AmmoType1 = FindClassTentative(str, "Ammo");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1288,7 +1307,7 @@ DEFINE_CLASS_PROPERTY(ammotype1, S, Weapon)
|
|||
DEFINE_CLASS_PROPERTY(ammotype2, S, Weapon)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
defaults->AmmoType2 = fuglyname(str);
|
||||
defaults->AmmoType2 = FindClassTentative(str, "Ammo");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1359,7 +1378,7 @@ DEFINE_CLASS_PROPERTY(selectionorder, I, Weapon)
|
|||
DEFINE_CLASS_PROPERTY(sisterweapon, S, Weapon)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
defaults->SisterWeaponType = fuglyname(str);
|
||||
defaults->SisterWeaponType = FindClassTentative(str, "Weapon");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1395,7 +1414,7 @@ DEFINE_CLASS_PROPERTY(number, I, WeaponPiece)
|
|||
DEFINE_CLASS_PROPERTY(weapon, S, WeaponPiece)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
defaults->WeaponClass = fuglyname(str);
|
||||
defaults->WeaponClass = FindClassTentative(str, "Weapon");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1505,7 +1524,18 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, mode, S, PowerupGiver)
|
|||
DEFINE_CLASS_PROPERTY_PREFIX(powerup, type, S, PowerupGiver)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
defaults->PowerupType = fuglyname(str);
|
||||
|
||||
// Yuck! What was I thinking when I decided to prepend "Power" to the name?
|
||||
// Now it's too late to change it...
|
||||
const PClass *cls = PClass::FindClass(str);
|
||||
if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(APowerupGiver)))
|
||||
{
|
||||
FString st;
|
||||
st.Format("%s%s", strnicmp(str, "power", 5)? "Power" : "", str);
|
||||
cls = FindClassTentative(st, "Powerup");
|
||||
}
|
||||
|
||||
defaults->PowerupType = cls;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -17,7 +17,6 @@ enum ExpValType
|
|||
VAL_Pointer, // Dereferenced variable (only used for addressing arrays for now.)
|
||||
VAL_Sound, // Sound identifier. Internally it's an int.
|
||||
VAL_Name, // A Name
|
||||
VAL_MultiName, // Multiple names for multi-label states
|
||||
VAL_Color, // A color.
|
||||
VAL_State, // A State pointer
|
||||
|
||||
|
|
Loading…
Reference in a new issue