- did some code cleanup and reorganization in thingdef.cpp.

- Replaced the translation parser for TEXTURES with FRemapTable::AddToTranslation.


SVN r1241 (trunk)
This commit is contained in:
Christoph Oelckers 2008-09-21 22:25:23 +00:00
parent 6227906072
commit 8a79985f46
7 changed files with 267 additions and 367 deletions

View file

@ -1,4 +1,6 @@
September 21, 2008 (Changes by Graf Zahl)
- did some code cleanup and reorganization in thingdef.cpp.
- Replaced the translation parser for TEXTURES with FRemapTable::AddToTranslation.
- To get the game name the screenshot code might as well use the globally
available GameNames array instead of creating its own list.
- Moved backpack names for cheat into gameinfo.

View file

@ -953,16 +953,11 @@ void FTextureManager::AddTexturesLumps (int lump1, int lump2, int patcheslump)
}
static bool Check(char *& range, char c)
{
while (isspace(*range)) range++;
if (*range==c)
{
range++;
return true;
}
return false;
}
//==========================================================================
//
//
//
//==========================================================================
void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part)
{
@ -1056,46 +1051,7 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part)
do
{
sc.MustGetString();
char *range = sc.String;
int start,end;
start=strtol(range, &range, 10);
if (!Check(range, ':')) return;
end=strtol(range, &range, 10);
if (!Check(range, '=')) return;
if (!Check(range, '['))
{
int pal1,pal2;
pal1=strtol(range, &range, 10);
if (!Check(range, ':')) return;
pal2=strtol(range, &range, 10);
part.Translation->AddIndexRange(start, end, pal1, pal2);
}
else
{
// translation using RGB values
int r1,g1,b1,r2,g2,b2;
r1=strtol(range, &range, 10);
if (!Check(range, ',')) return;
g1=strtol(range, &range, 10);
if (!Check(range, ',')) return;
b1=strtol(range, &range, 10);
if (!Check(range, ']')) return;
if (!Check(range, ':')) return;
if (!Check(range, '[')) return;
r2=strtol(range, &range, 10);
if (!Check(range, ',')) return;
g2=strtol(range, &range, 10);
if (!Check(range, ',')) return;
b2=strtol(range, &range, 10);
if (!Check(range, ']')) return;
part.Translation->AddColorRange(start, end, r1, g1, b1, r2, g2, b2);
}
part.Translation->AddToTranslation(sc.String);
}
while (sc.CheckString(","));
}
@ -1161,6 +1117,11 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part)
}
}
//==========================================================================
//
// Constructor for text based multipatch definitions
//
//==========================================================================
FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype)
: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false)

View file

@ -353,123 +353,64 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
// Starts a new actor definition
//
//==========================================================================
static FActorInfo *CreateNewActor(FScanner &sc, FActorInfo **parentc, Baggage *bag)
static FActorInfo *CreateNewActor(FName typeName, FName parentName, FName replaceName,
int DoomEdNum, bool native)
{
FName typeName;
const PClass *replacee = NULL;
int DoomEdNum = -1;
PClass *ti = NULL;
FActorInfo *info = NULL;
// Get actor name
sc.MustGetString();
char *colon = strchr(sc.String, ':');
if (colon != NULL)
{
*colon++ = 0;
}
/*
if (PClass::FindClass (sc.String) != NULL)
{
sc.ScriptError ("Actor %s is already defined.", sc.String);
}
*/
typeName = sc.String;
PClass *parent = RUNTIME_CLASS(AActor);
if (parentc)
{
*parentc = NULL;
// Do some tweaking so that a definition like 'Actor:Parent' which is read as a single token is recognized as well
// without having resort to C-mode (which disallows periods in actor names.)
if (colon == NULL)
{
sc.MustGetString ();
if (sc.String[0]==':')
{
colon = sc.String + 1;
}
}
if (colon != NULL)
{
if (colon[0] == 0)
{
sc.MustGetString ();
colon = sc.String;
}
}
if (colon != NULL)
{
parent = const_cast<PClass *> (PClass::FindClass (colon));
if (parent == NULL)
{
sc.ScriptError ("Parent type '%s' not found", colon);
}
else if (!parent->IsDescendantOf(RUNTIME_CLASS(AActor)))
{
sc.ScriptError ("Parent type '%s' is not an actor", colon);
}
else if (parent->ActorInfo == NULL)
{
sc.ScriptError ("uninitialized parent type '%s'", colon);
}
else
{
*parentc = parent->ActorInfo;
}
if (parentName != NAME_None)
{
parent = const_cast<PClass *> (PClass::FindClass (parentName));
if (parent == NULL)
{
I_Error ("Parent type '%s' not found in %s", parentName.GetChars(), typeName.GetChars());
}
else if (!parent->IsDescendantOf(RUNTIME_CLASS(AActor)))
{
I_Error ("Parent type '%s' is not an actor in %s", parentName.GetChars(), typeName.GetChars());
}
else if (parent->ActorInfo == NULL)
{
I_Error ("uninitialized parent type '%s' in %s", parentName.GetChars(), typeName.GetChars());
}
else sc.UnGet();
}
// Check for "replaces"
if (sc.CheckString ("replaces"))
if (replaceName != NAME_None)
{
// Get actor name
sc.MustGetString ();
replacee = PClass::FindClass (sc.String);
replacee = PClass::FindClass (replaceName);
if (replacee == NULL)
{
sc.ScriptError ("Replaced type '%s' not found", sc.String);
I_Error ("Replaced type '%s' not found in %s", replaceName.GetChars(), typeName.GetChars());
}
else if (replacee->ActorInfo == NULL)
{
sc.ScriptError ("Replaced type '%s' is not an actor", sc.String);
I_Error ("Replaced type '%s' is not an actor in %s", replaceName.GetChars(), typeName.GetChars());
}
}
// Now, after the actor names have been parsed, it is time to switch to C-mode
// for the rest of the actor definition.
sc.SetCMode (true);
if (sc.CheckNumber())
{
if (sc.Number>=-1 && sc.Number<32768) DoomEdNum = sc.Number;
else sc.ScriptError ("DoomEdNum must be in the range [-1,32767]");
}
if (sc.CheckString("native"))
Printf("Defining %s\n", typeName.GetChars());
if (native)
{
ti = (PClass*)PClass::FindClass(typeName);
if (ti == NULL)
{
sc.ScriptError("Unknown native class '%s'", typeName.GetChars());
I_Error("Unknown native class '%s'", typeName.GetChars());
}
else if (ti != RUNTIME_CLASS(AActor) && ti->ParentClass->NativeClass() != parent->NativeClass())
{
sc.ScriptError("Native class '%s' does not inherit from '%s'",
typeName.GetChars(),parent->TypeName.GetChars());
I_Error("Native class '%s' does not inherit from '%s'", typeName.GetChars(), parentName.GetChars());
}
else if (ti->ActorInfo != NULL)
{
sc.ScriptMessage("Redefinition of internal class '%s'", typeName.GetChars());
I_Error("Redefinition of internal class '%s'", typeName.GetChars());
}
ti->InitializeActorInfo();
info = ti->ActorInfo;
@ -482,10 +423,6 @@ static FActorInfo *CreateNewActor(FScanner &sc, FActorInfo **parentc, Baggage *b
MakeStateDefines(parent->ActorInfo->StateList);
ResetBaggage (bag);
bag->Info = info;
bag->Lumpnum = sc.LumpNum;
info->DoomEdNum = -1;
if (parent->ActorInfo->DamageFactors != NULL)
{
@ -506,10 +443,98 @@ static FActorInfo *CreateNewActor(FScanner &sc, FActorInfo **parentc, Baggage *b
ti->ActorInfo->Replacee = replacee->ActorInfo;
}
info->DoomEdNum = DoomEdNum;
if (DoomEdNum > 0) info->DoomEdNum = DoomEdNum;
return info;
}
//==========================================================================
//
// Starts a new actor definition
//
//==========================================================================
static FActorInfo *ParseActorHeader(FScanner &sc, Baggage *bag)
{
FName typeName;
FName parentName;
FName replaceName;
bool native = false;
int DoomEdNum = -1;
// Get actor name
sc.MustGetString();
char *colon = strchr(sc.String, ':');
if (colon != NULL)
{
*colon++ = 0;
}
typeName = sc.String;
// Do some tweaking so that a definition like 'Actor:Parent' which is read as a single token is recognized as well
// without having resort to C-mode (which disallows periods in actor names.)
if (colon == NULL)
{
sc.MustGetString ();
if (sc.String[0]==':')
{
colon = sc.String + 1;
}
}
if (colon != NULL)
{
if (colon[0] == 0)
{
sc.MustGetString ();
colon = sc.String;
}
}
if (colon == NULL)
{
sc.UnGet();
}
parentName = colon;
// Check for "replaces"
if (sc.CheckString ("replaces"))
{
// Get actor name
sc.MustGetString ();
replaceName = sc.String;
}
// Now, after the actor names have been parsed, it is time to switch to C-mode
// for the rest of the actor definition.
sc.SetCMode (true);
if (sc.CheckNumber())
{
if (sc.Number>=-1 && sc.Number<32768) DoomEdNum = sc.Number;
else sc.ScriptError ("DoomEdNum must be in the range [-1,32767]");
}
if (sc.CheckString("native"))
{
native = true;
}
try
{
FActorInfo *info = CreateNewActor(typeName, parentName, replaceName, DoomEdNum, native);
ResetBaggage (bag);
bag->Info = info;
bag->Lumpnum = sc.LumpNum;
return info;
}
catch (CRecoverableError &err)
{
sc.ScriptError("%s", err.GetMessage());
return NULL;
}
}
//==========================================================================
//
// Reads an actor definition
@ -520,64 +545,41 @@ void ParseActor(FScanner &sc)
FActorInfo * info=NULL;
Baggage bag;
try
info = ParseActorHeader(sc, &bag);
sc.MustGetToken('{');
while (sc.MustGetAnyToken(), sc.TokenType != '}')
{
FActorInfo * parent;
info = CreateNewActor(sc, &parent, &bag);
sc.MustGetToken('{');
while (sc.MustGetAnyToken(), sc.TokenType != '}')
switch (sc.TokenType)
{
switch (sc.TokenType)
{
case TK_Action:
ParseActionDef (sc, info->Class);
break;
case TK_Action:
ParseActionDef (sc, info->Class);
break;
case TK_Const:
ParseConstant (sc, &info->Class->Symbols, info->Class);
break;
case TK_Const:
ParseConstant (sc, &info->Class->Symbols, info->Class);
break;
case TK_Enum:
ParseEnum (sc, &info->Class->Symbols, info->Class);
break;
case TK_Enum:
ParseEnum (sc, &info->Class->Symbols, info->Class);
break;
case TK_Identifier:
// other identifier related checks here
case TK_Projectile: // special case: both keyword and property name
ParseActorProperty(sc, bag);
break;
case TK_Identifier:
// other identifier related checks here
case TK_Projectile: // special case: both keyword and property name
ParseActorProperty(sc, bag);
break;
case '+':
case '-':
ParseActorFlag(sc, bag, sc.TokenType);
break;
default:
sc.ScriptError("Unexpected '%s' in definition of '%s'", sc.String, bag.Info->Class->TypeName.GetChars());
break;
}
case '+':
case '-':
ParseActorFlag(sc, bag, sc.TokenType);
break;
default:
sc.ScriptError("Unexpected '%s' in definition of '%s'", sc.String, bag.Info->Class->TypeName.GetChars());
break;
}
FinishActor(sc, info, bag);
}
catch(CRecoverableError & e)
{
throw e;
}
// I think this is better than a crash log.
#ifndef _DEBUG
catch (...)
{
if (info)
sc.ScriptError("Unexpected error during parsing of actor %s", info->Class->TypeName.GetChars());
else
sc.ScriptError("Unexpected error during parsing of actor definitions");
}
#endif
sc.SetCMode (false);
}
@ -589,10 +591,33 @@ void ParseActor(FScanner &sc)
//
//==========================================================================
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;
}
void FinishThingdef()
{
unsigned int i;
bool isRuntimeActor=false;
int errorcount=0;
for (i = 0;i < PClass::m_Types.Size(); i++)
@ -602,13 +627,6 @@ void FinishThingdef()
// Skip non-actors
if (!ti->IsDescendantOf(RUNTIME_CLASS(AActor))) continue;
// Everything coming after the first runtime actor is also a runtime actor
// so this check is sufficient
if (ti == PClass::m_RuntimeActors[0])
{
isRuntimeActor=true;
}
AActor *def = GetDefaultByType(ti);
if (!def)
@ -627,21 +645,7 @@ void FinishThingdef()
if (ti->IsDescendantOf(RUNTIME_CLASS(AInventory)))
{
AInventory * defaults=(AInventory *)def;
fuglyname v;
v = defaults->PickupFlash;
if (v != NAME_None && v.IsValidName())
{
defaults->PickupFlash = PClass::FindClass(v);
if (isRuntimeActor)
{
if (!defaults->PickupFlash)
{
Printf("Unknown pickup flash '%s' in '%s'\n", v.GetChars(), ti->TypeName.GetChars());
errorcount++;
}
}
}
errorcount += ResolvePointer(&defaults->PickupFlash, ti, RUNTIME_CLASS(AActor), "pickup flash");
}
if (ti->IsDescendantOf(RUNTIME_CLASS(APowerupGiver)) && ti != RUNTIME_CLASS(APowerupGiver))
@ -683,122 +687,47 @@ void FinishThingdef()
if (ti->IsDescendantOf(RUNTIME_CLASS(AWeapon)))
{
AWeapon * defaults=(AWeapon *)def;
fuglyname v;
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");
v = defaults->AmmoType1;
if (v != NAME_None && v.IsValidName())
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)
{
defaults->AmmoType1 = PClass::FindClass(v);
if (isRuntimeActor)
// Do some consistency checks. If these states are undefined the weapon cannot work!
if (!ready)
{
if (!defaults->AmmoType1)
{
Printf("Unknown ammo type '%s' in '%s'\n", v.GetChars(), ti->TypeName.GetChars());
errorcount++;
}
else if (defaults->AmmoType1->ParentClass != RUNTIME_CLASS(AAmmo))
{
Printf("Invalid ammo type '%s' in '%s'\n", v.GetChars(), ti->TypeName.GetChars());
errorcount++;
}
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++;
}
}
v = defaults->AmmoType2;
if (v != NAME_None && v.IsValidName())
{
defaults->AmmoType2 = PClass::FindClass(v);
if (isRuntimeActor)
{
if (!defaults->AmmoType2)
{
Printf("Unknown ammo type '%s' in '%s'\n", v.GetChars(), ti->TypeName.GetChars());
errorcount++;
}
else if (defaults->AmmoType2->ParentClass != RUNTIME_CLASS(AAmmo))
{
Printf("Invalid ammo type '%s' in '%s'\n", v.GetChars(), ti->TypeName.GetChars());
errorcount++;
}
}
}
v = defaults->SisterWeaponType;
if (v != NAME_None && v.IsValidName())
{
defaults->SisterWeaponType = PClass::FindClass(v);
if (isRuntimeActor)
{
if (!defaults->SisterWeaponType)
{
Printf("Unknown sister weapon type '%s' in '%s'\n", v.GetChars(), ti->TypeName.GetChars());
errorcount++;
}
else if (!defaults->SisterWeaponType->IsDescendantOf(RUNTIME_CLASS(AWeapon)))
{
Printf("Invalid sister weapon type '%s' in '%s'\n", v.GetChars(), ti->TypeName.GetChars());
errorcount++;
}
}
}
if (isRuntimeActor)
{
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;
fuglyname v;
v = defaults->WeaponClass;
if (v != NAME_None && v.IsValidName())
{
defaults->WeaponClass = PClass::FindClass(v);
if (!defaults->WeaponClass)
{
Printf("Unknown weapon type '%s' in '%s'\n", v.GetChars(), ti->TypeName.GetChars());
errorcount++;
}
else if (!defaults->WeaponClass->IsDescendantOf(RUNTIME_CLASS(AWeapon)))
{
Printf("Invalid weapon type '%s' in '%s'\n", v.GetChars(), ti->TypeName.GetChars());
errorcount++;
}
}
errorcount += ResolvePointer(&defaults->WeaponClass, ti, RUNTIME_CLASS(AWeapon), "weapon type");
}
}
if (errorcount > 0)

View file

@ -106,7 +106,7 @@ void InstallStates(FActorInfo *info, AActor *defaults);
void MakeStateDefines(const FStateLabels *list);
void AddStateDefines(const FStateLabels *list);
FState *P_GetState(AActor *self, FState *CallingState, int offset);
int FinishStates (FScanner &sc, FActorInfo *actor, AActor *defaults, Baggage &bag);
int FinishStates (FActorInfo *actor, AActor *defaults);
int ParseStates(FScanner &sc, FActorInfo *actor, AActor *defaults, Baggage &bag);
FState *CheckState(FScanner &sc, PClass *type);

View file

@ -526,7 +526,14 @@ void FinishActor(FScanner &sc, FActorInfo *info, Baggage &bag)
{
AActor *defaults = (AActor*)info->Class->Defaults;
FinishStates (sc, info, defaults, bag);
try
{
FinishStates (info, defaults);
}
catch (CRecoverableError &err)
{
sc.ScriptError(err.GetMessage());
}
InstallStates (info, defaults);
if (bag.DropItemSet)
{

View file

@ -2013,7 +2013,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, startitem, S_i, PlayerPawn)
di->amount = 1;
if (PROP_PARM_COUNT > 1)
{
PROP_INT_PARM(amt, 0);
PROP_INT_PARM(amt, 1);
di->amount = amt;
}
di->Next = bag.DropItemList;

View file

@ -387,6 +387,40 @@ void AddStateDefines(const FStateLabels *list)
//==========================================================================
//
// RetargetState(Pointer)s
//
// These functions are used when a goto follows one or more labels.
// Because multiple labels are permitted to occur consecutively with no
// intervening states, it is not enough to remember the last label defined
// and adjust it. So these functions search for all labels that point to
// the current position in the state array and give them a copy of the
// target string instead.
//
//==========================================================================
static void RetargetStatePointers (intptr_t count, const char *target, TArray<FStateDefine> & statelist)
{
for(unsigned i = 0;i<statelist.Size(); i++)
{
if (statelist[i].State == (FState*)count)
{
statelist[i].State = target == NULL ? NULL : (FState *)copystring (target);
}
if (statelist[i].Children.Size() > 0)
{
RetargetStatePointers(count, target, statelist[i].Children);
}
}
}
static void RetargetStates (intptr_t count, const char *target)
{
RetargetStatePointers(count, target, StateLabels);
}
//==========================================================================
//***
// PrepareStateParameters
// creates an empty parameter list for a parameterized function call
//
@ -403,7 +437,7 @@ int PrepareStateParameters(FState * state, int numparams)
}
//==========================================================================
//
//***
// DoActionSpecials
// handles action specials as code pointers
//
@ -457,40 +491,7 @@ bool DoActionSpecials(FScanner &sc, FState & state, bool multistate, int * state
}
//==========================================================================
//
// RetargetState(Pointer)s
//
// These functions are used when a goto follows one or more labels.
// Because multiple labels are permitted to occur consecutively with no
// intervening states, it is not enough to remember the last label defined
// and adjust it. So these functions search for all labels that point to
// the current position in the state array and give them a copy of the
// target string instead.
//
//==========================================================================
static void RetargetStatePointers (intptr_t count, const char *target, TArray<FStateDefine> & statelist)
{
for(unsigned i = 0;i<statelist.Size(); i++)
{
if (statelist[i].State == (FState*)count)
{
statelist[i].State = target == NULL ? NULL : (FState *)copystring (target);
}
if (statelist[i].Children.Size() > 0)
{
RetargetStatePointers(count, target, statelist[i].Children);
}
}
}
static void RetargetStates (intptr_t count, const char *target)
{
RetargetStatePointers(count, target, StateLabels);
}
//==========================================================================
//
//***
// Reads a state label that may contain '.'s.
// processes a state block
//
@ -515,7 +516,7 @@ static FString ParseStateString(FScanner &sc)
}
//==========================================================================
//
//***
// ParseStates
// parses a state block
//
@ -821,7 +822,7 @@ endofstate:
//
//==========================================================================
static FState *ResolveGotoLabel (FScanner &sc, AActor *actor, const PClass *mytype, char *name)
static FState *ResolveGotoLabel (AActor *actor, const PClass *mytype, char *name)
{
const PClass *type=mytype;
FState *state;
@ -849,15 +850,15 @@ static FState *ResolveGotoLabel (FScanner &sc, AActor *actor, const PClass *myty
const PClass *stype = PClass::FindClass (classname);
if (stype == NULL)
{
sc.ScriptError ("%s is an unknown class.", classname);
I_Error ("%s is an unknown class.", classname);
}
if (!stype->IsDescendantOf (RUNTIME_CLASS(AActor)))
{
sc.ScriptError ("%s is not an actor class, so it has no states.", stype->TypeName.GetChars());
I_Error ("%s is not an actor class, so it has no states.", stype->TypeName.GetChars());
}
if (!stype->IsAncestorOf (type))
{
sc.ScriptError ("%s is not derived from %s so cannot access its states.",
I_Error ("%s is not derived from %s so cannot access its states.",
type->TypeName.GetChars(), stype->TypeName.GetChars());
}
if (type != stype)
@ -887,7 +888,7 @@ static FState *ResolveGotoLabel (FScanner &sc, AActor *actor, const PClass *myty
}
else if (v != 0)
{
sc.ScriptError ("Attempt to get invalid state %s from actor %s.", label, type->TypeName.GetChars());
I_Error ("Attempt to get invalid state %s from actor %s.", label, type->TypeName.GetChars());
}
delete[] namestart; // free the allocated string buffer
return state;
@ -922,15 +923,15 @@ static void FixStatePointers (FActorInfo *actor, TArray<FStateDefine> & list)
//
//==========================================================================
static void FixStatePointersAgain (FScanner &sc, FActorInfo *actor, AActor *defaults, TArray<FStateDefine> & list)
static void FixStatePointersAgain (FActorInfo *actor, AActor *defaults, TArray<FStateDefine> & list)
{
for(unsigned i=0;i<list.Size(); i++)
{
if (list[i].State != NULL && FState::StaticFindStateOwner (list[i].State, actor) == NULL)
{ // It's not a valid state, so it must be a label string. Resolve it.
list[i].State = ResolveGotoLabel (sc, defaults, actor->Class, (char *)list[i].State);
list[i].State = ResolveGotoLabel (defaults, actor->Class, (char *)list[i].State);
}
if (list[i].Children.Size() > 0) FixStatePointersAgain(sc, actor, defaults, list[i].Children);
if (list[i].Children.Size() > 0) FixStatePointersAgain(actor, defaults, list[i].Children);
}
}
@ -942,7 +943,7 @@ static void FixStatePointersAgain (FScanner &sc, FActorInfo *actor, AActor *defa
//
//==========================================================================
int FinishStates (FScanner &sc, FActorInfo *actor, AActor *defaults, Baggage &bag)
int FinishStates (FActorInfo *actor, AActor *defaults)
{
static int c=0;
int count = StateArray.Size();
@ -985,7 +986,7 @@ int FinishStates (FScanner &sc, FActorInfo *actor, AActor *defaults, Baggage &ba
}
else // goto
{
realstates[i].NextState = ResolveGotoLabel (sc, defaults, bag.Info->Class, (char *)realstates[i].NextState);
realstates[i].NextState = ResolveGotoLabel (defaults, actor->Class, (char *)realstates[i].NextState);
}
}
}
@ -993,7 +994,7 @@ int FinishStates (FScanner &sc, FActorInfo *actor, AActor *defaults, Baggage &ba
StateArray.Clear ();
// Fix state pointers that are gotos
FixStatePointersAgain (sc, actor, defaults, StateLabels);
FixStatePointersAgain (actor, defaults, StateLabels);
return count;
}