- Merged FActorInfo::FindStateExact and FActorInfo::FindState into one function

because the differences are only minimal.
- Removed all the varargs FindState functions because they aren't really needed.
  The engine itself never explicitly checks for more than 2 labels and for the 
  rest a function that gets passed a FName array is more suitable anyway.


SVN r414 (trunk)
This commit is contained in:
Christoph Oelckers 2006-12-16 14:06:21 +00:00
parent 979dfdf4cf
commit 693bf96cb3
11 changed files with 103 additions and 140 deletions

View file

@ -1,4 +1,9 @@
December 16, 2006 (Changes by Graf Zahl)
- Merged FActorInfo::FindStateExact and FActorInfo::FindState into one function
because the differences are only minimal.
- Removed all the varargs FindState functions because they aren't really needed.
The engine itself never explicitly checks for more than 2 labels and for the
rest a function that gets passed a FName array is more suitable anyway.
- Changed state label storage so that each actor owns all the state labels itself
and doesn't have to traverse parent lists to find them. This is required for
Dehacked actors that inherit states (e.g. NonsolidMeat and Spectre) but it also

View file

@ -749,8 +749,7 @@ public:
bool UpdateWaterLevel (fixed_t oldz);
FState *FindState (FName label) const;
FState *FindState (int numnames, int first, ...) const;
FState *FindState (int numnames, va_list arglist) const;
FState *FindState (FName label, FName sublabel, bool exact = false) const;
bool HasSpecialDeathStates () const;
static FState States[];

View file

@ -2499,7 +2499,7 @@ static bool LoadDehSupp ()
StateMap[i].State = def->SpawnState;
break;
case DeathState:
StateMap[i].State = type->ActorInfo->FindStateExact(1, NAME_Death);
StateMap[i].State = type->ActorInfo->FindState(NAME_Death);
break;
}
StateMap[i].StateSpan = supp[6+i*4+3];

View file

@ -715,7 +715,7 @@ bool F_CastResponder (event_t* ev)
// go into death frame
castdeath = true;
caststate = castorder[castnum].Class->ActorInfo->FindState(1, NAME_Death);
caststate = castorder[castnum].Class->ActorInfo->FindState(NAME_Death);
if (caststate != NULL)
{
casttics = caststate->GetTics();

View file

@ -421,29 +421,6 @@ void FStateLabels::Destroy ()
}
//===========================================================================
//
// FindState (one name version)
//
// Finds a state with the exact specified name.
//
//===========================================================================
FState *AActor::FindState (FName label) const
{
const FActorInfo *info = GetClass()->ActorInfo;
if (info->StateList != NULL)
{
FStateLabel *slabel = info->StateList->FindLabel (label);
if (slabel != NULL)
{
return slabel->State;
}
}
return NULL;
}
//===========================================================================
//
// HasStates
@ -470,6 +447,58 @@ bool AActor::HasSpecialDeathStates () const
return false;
}
//===========================================================================
//
// FindState (one name version)
//
// Finds a state with the exact specified name.
//
//===========================================================================
FState *AActor::FindState (FName label) const
{
const FActorInfo *info = GetClass()->ActorInfo;
if (info->StateList != NULL)
{
FStateLabel *slabel = info->StateList->FindLabel (label);
if (slabel != NULL)
{
return slabel->State;
}
}
return NULL;
}
//===========================================================================
//
// FindState (two name version)
//
//===========================================================================
FState *AActor::FindState (FName label, FName sublabel, bool exact) const
{
const FActorInfo *info = GetClass()->ActorInfo;
if (info->StateList != NULL)
{
FStateLabel *slabel = info->StateList->FindLabel (label);
if (slabel != NULL)
{
if (slabel->Children != NULL)
{
FStateLabel *slabel2 = slabel->Children->FindLabel(sublabel);
if (slabel2 != NULL)
{
return slabel2->State;
}
}
if (!exact) return slabel->State;
}
}
return NULL;
}
//===========================================================================
//
// FindState (multiple names version)
@ -485,37 +514,18 @@ bool AActor::HasSpecialDeathStates () const
// has names, ignore it. If the argument list still has names, remember it.
//
//===========================================================================
FState *AActor::FindState (int numnames, int first, ...) const // The 'first' parameter is only here to
// disambiguate from the single parameter version
// Please note that this code does *NOT* compile
// properly with VC++ when 'first' is removed!
FState *FActorInfo::FindState (FName name) const
{
va_list arglist;
va_start (arglist, numnames);
return FindState (numnames, arglist);
return FindState(1, &name);
}
FState *FActorInfo::FindState (int numnames, ...) const
{
va_list arglist;
va_start (arglist, numnames);
return FindState (numnames, arglist);
}
FState *AActor::FindState (int numnames, va_list arglist) const
{
return GetClass()->ActorInfo->FindState (numnames, arglist);
}
FState *FActorInfo::FindState (int numnames, va_list arglist) const
FState *FActorInfo::FindState (int numnames, FName *names, bool exact) const
{
FStateLabels *labels = StateList;
FState *best = NULL;
if (labels != NULL)
{
va_list names = arglist;
int count = 0;
FStateLabel *slabel = NULL;
FName label;
@ -523,7 +533,7 @@ FState *FActorInfo::FindState (int numnames, va_list arglist) const
// Find the best-matching label for this class.
while (labels != NULL && count < numnames)
{
label = ENamedName(va_arg (names, int));
label = *names++;
slabel = labels->FindLabel (label);
if (slabel != NULL)
@ -537,62 +547,11 @@ FState *FActorInfo::FindState (int numnames, va_list arglist) const
break;
}
}
if (count < numnames && exact) return NULL;
}
return best;
}
//===========================================================================
//
// FindStateExact
//
// This is like FindState, except it will only return states whose labels
// match the requested one exactly.
//
//===========================================================================
FState *FActorInfo::FindStateExact (int numnames, ...) const
{
va_list arglist;
va_start (arglist, numnames);
return FindStateExact (numnames, arglist);
}
FState *FActorInfo::FindStateExact (int numnames, va_list arglist) const
{
FStateLabels *labels = StateList;
if (labels != NULL)
{
va_list names = arglist;
int count = 0;
FStateLabel *slabel = NULL;
FName label;
// Look for a matching label for this class.
while (labels != NULL && count < numnames)
{
label = ENamedName(va_arg (names, int));
slabel = labels->FindLabel (label);
if (slabel != NULL)
{
count++;
labels = slabel->Children;
}
else
{
break;
}
}
// Only exact matches count.
if (slabel != NULL && count == numnames)
{
return slabel->State;
}
}
return NULL;
}
//===========================================================================
//
// Changes a single state

View file

@ -384,12 +384,11 @@ struct FActorInfo
void ApplyDefaults (BYTE *defaults);
void RegisterIDs ();
FState *FindState (int numnames, ...) const;
FState *FindState (int numnames, va_list arglist) const;
FState *FindState (FName name) const;
FState *FindState (int numnames, FName *names, bool exact=false) const;
void ChangeState (FName label, FState * newstate) const;
FState *FindStateExact (int numnames, ...) const;
FState *FindStateExact (int numnames, va_list arglist) const;
FActorInfo *GetReplacement ();
FActorInfo *GetReplacee ();

View file

@ -613,7 +613,7 @@ void AActor::Die (AActor *source, AActor *inflictor)
if (DamageType != NAME_None)
{
diestate = GetClass()->ActorInfo->FindStateExact (2, NAME_Death, int(DamageType));
diestate = FindState (NAME_Death, DamageType, true);
if (diestate == NULL)
{
if (DamageType == NAME_Ice)
@ -641,7 +641,7 @@ void AActor::Die (AActor *source, AActor *inflictor)
if ((health<gibhealth || flags4 & MF4_EXTREMEDEATH) && !(flags4 & MF4_NOEXTREMEDEATH))
{ // Extreme death
diestate = GetClass()->ActorInfo->FindStateExact (2, NAME_Death, NAME_Extreme);
diestate = FindState (NAME_Death, NAME_Extreme, true);
// if a non-player mark as extremely dead for the crash state.
if (diestate != NULL && player == NULL && health >= gibhealth) health = gibhealth-1;
}
@ -1086,7 +1086,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
return;
}
FState * woundstate = target->FindState(2,NAME_Wound, (int)mod);
FState * woundstate = target->FindState(NAME_Wound, mod);
if (woundstate != NULL)
{
int woundhealth = RUNTIME_TYPE(target)->Meta.GetMetaInt (AMETA_WoundHealth, 6);
@ -1104,7 +1104,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
if (pr_lightning() < 96)
{
target->flags |= MF_JUSTHIT; // fight back!
FState * painstate = target->FindState(2,NAME_Pain, (int)mod);
FState * painstate = target->FindState(NAME_Pain, mod);
if (painstate != NULL) target->SetState (painstate);
}
else
@ -1119,7 +1119,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
else
{
target->flags |= MF_JUSTHIT; // fight back!
FState * painstate = target->FindState(2,NAME_Pain, (int)mod);
FState * painstate = target->FindState(NAME_Pain, mod);
if (painstate != NULL) target->SetState (painstate);
if (inflictor && inflictor->IsKindOf (RUNTIME_CLASS(APoisonCloud)))
{
@ -1311,7 +1311,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage,
}
if (!(level.time&63) && playPainSound)
{
FState * painstate = target->FindState(2,NAME_Pain, (int)target->DamageType);
FState * painstate = target->FindState(NAME_Pain, target->DamageType);
if (painstate != NULL) target->SetState (painstate);
}
/*

View file

@ -1014,7 +1014,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
if (target != NULL && target->flags & (MF_SHOOTABLE|MF_CORPSE))
{
if (target->flags & MF_NOBLOOD) nextstate = mo->FindState(NAME_Crash);
if (nextstate == NULL) nextstate = mo->FindState(2, NAME_Death, NAME_Extreme);
if (nextstate == NULL) nextstate = mo->FindState(NAME_Death, NAME_Extreme);
}
if (nextstate == NULL) nextstate = mo->FindState(NAME_Death);
mo->SetState (nextstate);
@ -4711,7 +4711,7 @@ int AActor::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FN
target = source;
if (pr_takedamage() < PainChance)
{
FState * painstate = FindState(2,NAME_Pain, (int)damagetype);
FState * painstate = FindState(NAME_Pain, damagetype);
if (painstate != NULL) SetState (painstate);
}
return -1;
@ -4729,7 +4729,7 @@ int AActor::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FN
}
if (damagetype == NAME_Ice)
{
death = GetClass()->ActorInfo->FindStateExact (2, NAME_Death, NAME_Ice);
death = FindState (NAME_Death, NAME_Ice, true);
if (death == NULL && !deh.NoAutofreeze && !(flags4 & MF4_NOICEDEATH) &&
(player || (flags3 & MF3_ISMONSTER)))
{
@ -4738,7 +4738,7 @@ int AActor::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FN
}
else
{
death = FindState (2, NAME_Death, int(damagetype));
death = FindState (NAME_Death, damagetype);
}
return (death == NULL) ? -1 : damage;
}
@ -4753,7 +4753,7 @@ void AActor::Crash()
if (DamageType != NAME_None)
{
crashstate = GetClass()->ActorInfo->FindStateExact(2, NAME_Crash, int(DamageType));
crashstate = FindState(NAME_Crash, DamageType, true);
}
if (crashstate == NULL)
{
@ -4762,7 +4762,7 @@ void AActor::Crash()
if (health<gibhealth)
{ // Extreme death
crashstate = FindState (2, NAME_Crash, NAME_Extreme);
crashstate = FindState (NAME_Crash, NAME_Extreme);
}
else
{ // Normal death

View file

@ -79,7 +79,7 @@ extern TArray<FActorInfo *> Decorations;
TArray<char*> DecalNames;
// all state parameters
TArray<int> StateParameters;
TArray<int> JumpParameters;
TArray<FName> JumpParameters;
//==========================================================================
//
@ -917,7 +917,7 @@ FState * FindStateInClass(AActor * actor, const PClass * type, const char * name
MakeStateNameList(name, &namelist);
FActorInfo * info = type->ActorInfo;
if (info) return info->FindStateExact(namelist.Size(), (va_list)&namelist[0]);
if (info) return info->FindState(namelist.Size(), &namelist[0], true);
return NULL;
}
@ -1014,12 +1014,12 @@ void InstallStates(FActorInfo *info, AActor *defaults)
info->StateList = CreateStateLabelList(StateLabels);
// Cache these states as member veriables.
defaults->SpawnState = info->FindStateExact(1,NAME_Spawn);
defaults->SeeState = info->FindStateExact(1,NAME_See);
defaults->SpawnState = info->FindState(NAME_Spawn);
defaults->SeeState = info->FindState(NAME_See);
// Melee and Missile states are manipulated by the scripted marines so they
// have to be stored locally
defaults->MeleeState = info->FindStateExact(1,NAME_Melee);
defaults->MissileState = info->FindStateExact(1,NAME_Missile);
defaults->MeleeState = info->FindState(NAME_Melee);
defaults->MissileState = info->FindState(NAME_Missile);
}
@ -1637,7 +1637,7 @@ do_stop:
}
else
{
if (JumpParameters.Size()==0) JumpParameters.Push(0);
if (JumpParameters.Size()==0) JumpParameters.Push(NAME_None);
v = -(int)JumpParameters.Size();
FString statestring = ParseStateString();
@ -1675,20 +1675,20 @@ do_stop:
// labels in subclasses.
// It also means that the validity of the given state cannot
// be checked here.
JumpParameters.Push(0);
JumpParameters.Push(NAME_None);
}
TArray<FName> names;
MakeStateNameList(statestring, &names);
if (stype != NULL)
{
if (!stype->ActorInfo->FindState(names.Size(), (va_list)&names[0]))
if (!stype->ActorInfo->FindState(names.Size(), &names[0]))
{
SC_ScriptError("Jump to unknown state '%s' in class '%s'",
statestring.GetChars(), stype->TypeName.GetChars());
}
}
JumpParameters.Push(names.Size());
JumpParameters.Push((ENamedName)names.Size());
for(unsigned i=0;i<names.Size();i++)
{
JumpParameters.Push(names[i]);
@ -2003,7 +2003,7 @@ static FState *CheckState(PClass *type)
if (info != NULL)
{
state = info->FindStateExact(1, (int)FName(sc_String));
state = info->FindState(FName(sc_String));
}
if (SC_GetString ())
@ -4249,10 +4249,10 @@ void FinishThingdef()
if (isRuntimeActor)
{
// Do some consistency checks. If these states are undefined the weapon cannot work!
if (!ti->ActorInfo->FindState(1, NAME_Ready)) I_Error("Weapon %s doesn't define a ready state.\n", ti->TypeName.GetChars());
if (!ti->ActorInfo->FindState(1, NAME_Select)) I_Error("Weapon %s doesn't define a select state.\n", ti->TypeName.GetChars());
if (!ti->ActorInfo->FindState(1, NAME_Deselect)) I_Error("Weapon %s doesn't define a deselect state.\n", ti->TypeName.GetChars());
if (!ti->ActorInfo->FindState(1, NAME_Fire)) I_Error("Weapon %s doesn't define a fire state.\n", ti->TypeName.GetChars());
if (!ti->ActorInfo->FindState(NAME_Ready)) I_Error("Weapon %s doesn't define a ready state.\n", ti->TypeName.GetChars());
if (!ti->ActorInfo->FindState(NAME_Select)) I_Error("Weapon %s doesn't define a select state.\n", ti->TypeName.GetChars());
if (!ti->ActorInfo->FindState(NAME_Deselect)) I_Error("Weapon %s doesn't define a deselect state.\n", ti->TypeName.GetChars());
if (!ti->ActorInfo->FindState(NAME_Fire)) I_Error("Weapon %s doesn't define a fire state.\n", ti->TypeName.GetChars());
}
}

View file

@ -23,7 +23,7 @@ public:
// All state parameters are stored in this array now.
extern TArray<int> StateParameters;
extern TArray<int> JumpParameters;
extern TArray<FName> JumpParameters;
int ParseExpression (bool _not, PClass *cls);

View file

@ -391,20 +391,21 @@ static void DoJump(AActor * self, FState * CallingState, int offset)
{
offset = -offset;
int classname = JumpParameters[offset];
FName classname = JumpParameters[offset];
const PClass *cls;
cls = classname==NAME_None? RUNTIME_TYPE(self) : PClass::FindClass((ENamedName)classname);
cls = classname==NAME_None? RUNTIME_TYPE(self) : PClass::FindClass(classname);
if (cls==NULL || cls->ActorInfo==NULL) return; // shouldn't happen
jumpto = cls->ActorInfo->FindState(JumpParameters[offset+1], (va_list)&JumpParameters[offset+2]);
int numnames = (int)JumpParameters[offset+1];
jumpto = cls->ActorInfo->FindState(numnames, &JumpParameters[offset+2]);
if (jumpto == NULL)
{
char * dot="";
Printf("Jump target '");
if (classname != NAME_None) Printf("%s::", ((FName)(ENamedName)classname).GetChars());
for (int i=0;i<JumpParameters[offset+1];i++)
if (classname != NAME_None) Printf("%s::", classname.GetChars());
for (int i=0;i<numnames;i++)
{
Printf("%s%s", dot, ((FName)(ENamedName)JumpParameters[offset+2+i]).GetChars());
Printf("%s%s", dot, JumpParameters[offset+2+i].GetChars());
}
Printf("not found in %s\n", self->GetClass()->TypeName.GetChars());
return;