- 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
commit 693bf96cb3
11 changed files with 89 additions and 126 deletions

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;