- Fixed: The global WeaponSection string was never freed. It has been replaced
with an FString now. - Fixed: The music strings in the default level info were never freed and caused memory leaks when used repeatedly. - Fixed: The intermusic string in the level info was never freed. - Fixed: The default fire obituary should only be printed if the damage came from the environment. If it comes from a monster the monster specific obituary should be used instead. - Added custom damage types from the floating point test release. - Changed Pain Elemental's massacre check. Now A_PainDie checks for the damage type and doesn't spawn anything if it is NAME_Massacre. A_PainDie can also be used by other actors so a more generalized approach is needed than hard coding it into the Pain Elemental. - Converted a few of Doom's monsters to DECORATE because I couldn't test the first version of the custom state code with the corpses inheriting from them. - Added custom states from last year's floating point test release and fixed some bugs I found in that code. Unfortunately it wasn't all salvageable and it was easier to recreate some parts from scratch. SVN r368 (trunk)
This commit is contained in:
parent
3b2c2efcb1
commit
063c85b157
118 changed files with 2103 additions and 1818 deletions
322
src/info.cpp
322
src/info.cpp
|
|
@ -49,6 +49,7 @@
|
|||
#include "r_state.h"
|
||||
#include "i_system.h"
|
||||
#include "p_local.h"
|
||||
#include "templates.h"
|
||||
|
||||
extern void LoadDecorations (void (*process)(FState *, int));
|
||||
|
||||
|
|
@ -64,6 +65,11 @@ extern void LoadDecorations (void (*process)(FState *, int));
|
|||
|
||||
#define NULL_STATE_INDEX 127
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FArchive &operator<< (FArchive &arc, FState *&state)
|
||||
{
|
||||
const PClass *info;
|
||||
|
|
@ -119,7 +125,12 @@ FArchive &operator<< (FArchive &arc, FState *&state)
|
|||
return arc;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Find the actor that a state belongs to.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const PClass *FState::StaticFindStateOwner (const FState *state)
|
||||
{
|
||||
const FActorInfo *info = RUNTIME_CLASS(AActor)->ActorInfo;
|
||||
|
|
@ -153,8 +164,13 @@ const PClass *FState::StaticFindStateOwner (const FState *state)
|
|||
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)
|
||||
|
|
@ -169,6 +185,11 @@ const PClass *FState::StaticFindStateOwner (const FState *state, const FActorInf
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int GetSpriteIndex(const char * spritename)
|
||||
{
|
||||
for (unsigned i = 0; i < sprites.Size (); ++i)
|
||||
|
|
@ -187,7 +208,12 @@ int GetSpriteIndex(const char * spritename)
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Change sprite names to indices
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ProcessStates (FState *states, int numstates)
|
||||
{
|
||||
int sprite = -1;
|
||||
|
|
@ -205,6 +231,12 @@ static void ProcessStates (FState *states, int numstates)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FActorInfo::StaticInit ()
|
||||
{
|
||||
TAutoSegIterator<FActorInfo *, &ARegHead, &ARegTail> reg;
|
||||
|
|
@ -247,7 +279,12 @@ void FActorInfo::StaticInit ()
|
|||
LoadDecorations (ProcessStates);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Called after the IWAD has been identified
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FActorInfo::StaticGameSet ()
|
||||
{
|
||||
// Run every AT_GAME_SET function
|
||||
|
|
@ -258,7 +295,12 @@ void FActorInfo::StaticGameSet ()
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Called after Dehacked patches are applied
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FActorInfo::StaticSetActorNums ()
|
||||
{
|
||||
memset (SpawnableThings, 0, sizeof(SpawnableThings));
|
||||
|
|
@ -278,6 +320,11 @@ void FActorInfo::StaticSetActorNums ()
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FActorInfo::RegisterIDs ()
|
||||
{
|
||||
if (GameFilter == GAME_Any || (GameFilter & gameinfo.gametype))
|
||||
|
|
@ -293,8 +340,12 @@ void FActorInfo::RegisterIDs ()
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Called when a new game is started, but only if the game
|
||||
// speed has changed.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FActorInfo::StaticSpeedSet ()
|
||||
{
|
||||
|
|
@ -305,6 +356,11 @@ void FActorInfo::StaticSpeedSet ()
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FActorInfo *FActorInfo::GetReplacement ()
|
||||
{
|
||||
if (Replacement == NULL)
|
||||
|
|
@ -320,6 +376,11 @@ FActorInfo *FActorInfo::GetReplacement ()
|
|||
return rep;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FActorInfo *FActorInfo::GetReplacee ()
|
||||
{
|
||||
if (Replacee == NULL)
|
||||
|
|
@ -335,6 +396,267 @@ FActorInfo *FActorInfo::GetReplacee ()
|
|||
return rep;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FindState (one name version)
|
||||
//
|
||||
// Finds a state with the exact specified name.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FState *AActor::FindState (FName label) const
|
||||
{
|
||||
const FActorInfo *info = GetClass()->ActorInfo;
|
||||
FStateLabel *slabel;
|
||||
|
||||
while (info != NULL)
|
||||
{
|
||||
if (info->StateList != NULL)
|
||||
{
|
||||
slabel = info->StateList->FindLabel (label);
|
||||
if (slabel != NULL && slabel->valid)
|
||||
{
|
||||
return slabel->State;
|
||||
}
|
||||
}
|
||||
info = info->Class->ParentClass->ActorInfo;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// HasStates
|
||||
//
|
||||
// Checks whether the actor has substates for the given name.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool AActor::HasStates (FName label) const
|
||||
{
|
||||
const FActorInfo *info = GetClass()->ActorInfo;
|
||||
FStateLabel *slabel;
|
||||
|
||||
while (info != NULL)
|
||||
{
|
||||
if (info->StateList != NULL)
|
||||
{
|
||||
slabel = info->StateList->FindLabel (label);
|
||||
if (slabel != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
info = info->Class->ParentClass->ActorInfo;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// 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.
|
||||
// Repeat with each successive ancestor class. The state with the longest
|
||||
// match not exceeding the supplied number of names is returned.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FState *AActor::FindState (int numnames, int first, ...) const // The 'first' parameter is only here to
|
||||
// disambiguate from the single parameter version
|
||||
{
|
||||
va_list arglist;
|
||||
va_start (arglist, numnames);
|
||||
return FindState (numnames, arglist);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
const FActorInfo *info = this;
|
||||
FState *best = NULL;
|
||||
int bestcount = 0;
|
||||
|
||||
// Search this actor's class, plus all its ancestors for a match.
|
||||
while (info != NULL && bestcount < numnames)
|
||||
{
|
||||
FStateLabels *labels = info->StateList;
|
||||
|
||||
if (labels != NULL)
|
||||
{
|
||||
va_list names = arglist;
|
||||
int count = 0;
|
||||
FStateLabel *slabel = NULL;
|
||||
FName label;
|
||||
|
||||
// Find the best-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;
|
||||
|
||||
// Labels that are more specific than what we want do not match.
|
||||
// Less specific labels do match.
|
||||
if (slabel->valid && count > bestcount)
|
||||
{
|
||||
if (count == numnames)
|
||||
{
|
||||
return slabel->State;
|
||||
}
|
||||
bestcount = count;
|
||||
best = slabel->State;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Walk up the class hierarchy and repeat.
|
||||
info = info->Class->ParentClass->ActorInfo;
|
||||
}
|
||||
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
|
||||
{
|
||||
const FActorInfo *info = this;
|
||||
|
||||
// Search this actor's class, plus all its ancestors for a match.
|
||||
while (info != NULL)
|
||||
{
|
||||
FStateLabels *labels = info->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 && slabel->valid && count == numnames)
|
||||
{
|
||||
return slabel->State;
|
||||
}
|
||||
}
|
||||
// Walk up the class hierarchy and repeat.
|
||||
info = info->Class->ParentClass->ActorInfo;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Changes a single state
|
||||
//
|
||||
// If the given state does not exist it won't be changed
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FActorInfo::ChangeState (FName label, FState * newstate) const
|
||||
{
|
||||
FStateLabel *slabel;
|
||||
|
||||
if (StateList != NULL)
|
||||
{
|
||||
slabel = StateList->FindLabel (label);
|
||||
if (slabel != NULL)
|
||||
{
|
||||
slabel->State = newstate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FDoomEdMap DoomEdMap;
|
||||
|
||||
FDoomEdMap::FDoomEdEntry *FDoomEdMap::DoomEdHash[DOOMED_HASHSIZE];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue