- Used the one unused byte in the state structure as a flag to tell what type
the NextState parameter is. The code did some rather unsafe checks with it to determine its type. - moved all state related code into a new file: p_states.cpp. - merged all FindState functions. All the different variations are now inlined and call the same function to do the real work. SVN r1243 (trunk)
This commit is contained in:
parent
b523ebd2a7
commit
954955c5a5
16 changed files with 1001 additions and 904 deletions
319
src/info.cpp
319
src/info.cpp
|
|
@ -51,122 +51,6 @@
|
|||
|
||||
extern void LoadDecorations ();
|
||||
|
||||
// Each state is owned by an actor. Actors can own any number of
|
||||
// states, but a single state cannot be owned by more than one
|
||||
// actor. States are archived by recording the actor they belong
|
||||
// to and the index into that actor's list of states.
|
||||
|
||||
// For NULL states, which aren't owned by any actor, the owner
|
||||
// is recorded as AActor with the following state. AActor should
|
||||
// never actually have this many states of its own, so this
|
||||
// is (relatively) safe.
|
||||
|
||||
#define NULL_STATE_INDEX 127
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FArchive &operator<< (FArchive &arc, FState *&state)
|
||||
{
|
||||
const PClass *info;
|
||||
|
||||
if (arc.IsStoring ())
|
||||
{
|
||||
if (state == NULL)
|
||||
{
|
||||
arc.UserWriteClass (RUNTIME_CLASS(AActor));
|
||||
arc.WriteCount (NULL_STATE_INDEX);
|
||||
return arc;
|
||||
}
|
||||
|
||||
info = FState::StaticFindStateOwner (state);
|
||||
|
||||
if (info != NULL)
|
||||
{
|
||||
arc.UserWriteClass (info);
|
||||
arc.WriteCount ((DWORD)(state - info->ActorInfo->OwnedStates));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this was never working as intended.
|
||||
I_Error ("Cannot find owner for state %p:\n"
|
||||
"%s %c%c %3d [%p] -> %p", state,
|
||||
sprites[state->sprite].name,
|
||||
state->GetFrame() + 'A',
|
||||
state->GetFullbright() ? '*' : ' ',
|
||||
state->GetTics(),
|
||||
state->GetAction(),
|
||||
state->GetNextState());
|
||||
*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const PClass *info;
|
||||
DWORD ofs;
|
||||
|
||||
arc.UserReadClass (info);
|
||||
ofs = arc.ReadCount ();
|
||||
if (ofs == NULL_STATE_INDEX && info == RUNTIME_CLASS(AActor))
|
||||
{
|
||||
state = NULL;
|
||||
}
|
||||
else if (info->ActorInfo != NULL)
|
||||
{
|
||||
state = info->ActorInfo->OwnedStates + ofs;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = NULL;
|
||||
}
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Find the actor that a state belongs to.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const PClass *FState::StaticFindStateOwner (const FState *state)
|
||||
{
|
||||
for (unsigned int i = 0; i < PClass::m_RuntimeActors.Size(); ++i)
|
||||
{
|
||||
FActorInfo *info = PClass::m_RuntimeActors[i]->ActorInfo;
|
||||
if (state >= info->OwnedStates &&
|
||||
state < info->OwnedStates + info->NumOwnedStates)
|
||||
{
|
||||
return info->Class;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Find the actor that a state belongs to, but restrict the search to
|
||||
// the specified type and its ancestors.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const PClass *FState::StaticFindStateOwner (const FState *state, const FActorInfo *info)
|
||||
{
|
||||
while (info != NULL)
|
||||
{
|
||||
if (state >= info->OwnedStates &&
|
||||
state < info->OwnedStates + info->NumOwnedStates)
|
||||
{
|
||||
return info->Class;
|
||||
}
|
||||
info = info->Class->ParentClass->ActorInfo;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
@ -344,209 +228,6 @@ void FActorInfo::SetPainChance(FName type, int chance)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FStateLabel *FStateLabels::FindLabel (FName label)
|
||||
{
|
||||
return const_cast<FStateLabel *>(BinarySearch<FStateLabel, FName> (Labels, NumLabels, &FStateLabel::Label, label));
|
||||
}
|
||||
|
||||
void FStateLabels::Destroy ()
|
||||
{
|
||||
for(int i=0; i<NumLabels;i++)
|
||||
{
|
||||
if (Labels[i].Children != NULL)
|
||||
{
|
||||
Labels[i].Children->Destroy();
|
||||
free (Labels[i].Children); // These are malloc'd, not new'd!
|
||||
Labels[i].Children=NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// HasStates
|
||||
//
|
||||
// Checks whether the actor has special death states.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool AActor::HasSpecialDeathStates () const
|
||||
{
|
||||
const FActorInfo *info = GetClass()->ActorInfo;
|
||||
|
||||
if (info->StateList != NULL)
|
||||
{
|
||||
FStateLabel *slabel = info->StateList->FindLabel (NAME_Death);
|
||||
if (slabel != NULL && slabel->Children != NULL)
|
||||
{
|
||||
for(int i=0;i<slabel->Children->NumLabels;i++)
|
||||
{
|
||||
if (slabel->Children->Labels[i].State != NULL) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
//
|
||||
// Finds a state that matches as many of the supplied names as possible.
|
||||
// A state with more names than those provided does not match.
|
||||
// A state with fewer names can match if there are no states with the exact
|
||||
// same number of names.
|
||||
//
|
||||
// The search proceeds like this. For the current class, keeping matching
|
||||
// names until there are no more. If both the argument list and the state
|
||||
// are out of names, it's an exact match, so return it. If the state still
|
||||
// has names, ignore it. If the argument list still has names, remember it.
|
||||
//
|
||||
//===========================================================================
|
||||
FState *FActorInfo::FindState (FName name) const
|
||||
{
|
||||
return FindState(1, &name);
|
||||
}
|
||||
|
||||
FState *FActorInfo::FindState (int numnames, FName *names, bool exact) const
|
||||
{
|
||||
FStateLabels *labels = StateList;
|
||||
FState *best = NULL;
|
||||
|
||||
if (labels != NULL)
|
||||
{
|
||||
int count = 0;
|
||||
FStateLabel *slabel = NULL;
|
||||
FName label;
|
||||
|
||||
// Find the best-matching label for this class.
|
||||
while (labels != NULL && count < numnames)
|
||||
{
|
||||
label = *names++;
|
||||
slabel = labels->FindLabel (label);
|
||||
|
||||
if (slabel != NULL)
|
||||
{
|
||||
count++;
|
||||
labels = slabel->Children;
|
||||
best = slabel->State;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (count < numnames && exact) return NULL;
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Creates a list of names from a string. Dots are used as separator
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void MakeStateNameList(const char * fname, TArray<FName> * out)
|
||||
{
|
||||
FName firstpart, secondpart;
|
||||
char * c;
|
||||
|
||||
// Handle the old names for the existing death states
|
||||
char * name = copystring(fname);
|
||||
firstpart = strtok(name, ".");
|
||||
switch (firstpart)
|
||||
{
|
||||
case NAME_Burn:
|
||||
firstpart = NAME_Death;
|
||||
secondpart = NAME_Fire;
|
||||
break;
|
||||
case NAME_Ice:
|
||||
firstpart = NAME_Death;
|
||||
secondpart = NAME_Ice;
|
||||
break;
|
||||
case NAME_Disintegrate:
|
||||
firstpart = NAME_Death;
|
||||
secondpart = NAME_Disintegrate;
|
||||
break;
|
||||
case NAME_XDeath:
|
||||
firstpart = NAME_Death;
|
||||
secondpart = NAME_Extreme;
|
||||
break;
|
||||
}
|
||||
|
||||
out->Clear();
|
||||
out->Push(firstpart);
|
||||
if (secondpart!=NAME_None) out->Push(secondpart);
|
||||
|
||||
while ((c = strtok(NULL, "."))!=NULL)
|
||||
{
|
||||
FName cc = c;
|
||||
out->Push(cc);
|
||||
}
|
||||
delete [] name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue