mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-27 22:42:57 +00:00
- Fixed: deadthings.txt contained a superfluous ';' which created parsing errors
with my changed code. - Cleaned up DECORATE parser a little - moved the old style parsing code into its own file and rearranged a few things. - Made ProcessStates non-static so that it doesn't need to be passed as an argument to all functions in the DECORATE parser. - Moved DECORATE parser files into their own subdirectory. - Optimization: SC_GetToken no longer sets sc_name for identifiers. In most cases this creates needless overhead by adding a potentially unneeded name to the name table and looking up the name. In almost all cases where a name is needed it's as easy to assign sc_String to the name variable. - Added enum definitions to DECORATE. SVN r537 (trunk)
This commit is contained in:
parent
91241eb96e
commit
50f75b6e8a
28 changed files with 3341 additions and 3191 deletions
|
@ -1,3 +1,17 @@
|
|||
May 28, 2007 (Changes by Graf Zahl)
|
||||
- Fixed: deadthings.txt contained a superfluous ';' which created parsing errors
|
||||
with my changed code.
|
||||
- Cleaned up DECORATE parser a little - moved the old style parsing code into its
|
||||
own file and rearranged a few things.
|
||||
- Made ProcessStates non-static so that it doesn't need to be passed as an argument
|
||||
to all functions in the DECORATE parser.
|
||||
- Moved DECORATE parser files into their own subdirectory.
|
||||
- Optimization: SC_GetToken no longer sets sc_name for identifiers. In most cases
|
||||
this creates needless overhead by adding a potentially unneeded name to the name
|
||||
table and looking up the name. In almost all cases where a name is needed it's as
|
||||
easy to assign sc_String to the name variable.
|
||||
- Added enum definitions to DECORATE.
|
||||
|
||||
May 27, 2007 (Changes by Graf Zahl)
|
||||
- Fixed: Hirestex replacements for sprites didn't work properly due to some
|
||||
incorrect calculations in R_ProjectSprite.
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
#include "r_draw.h"
|
||||
#include "v_palette.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "thingdef.h"
|
||||
#include "thingdef/thingdef.h"
|
||||
#include "vectors.h"
|
||||
#include "dobject.h"
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "p_effect.h"
|
||||
#include "gi.h"
|
||||
#include "templates.h"
|
||||
#include "thingdef.h"
|
||||
#include "thingdef/thingdef.h"
|
||||
|
||||
static FRandom pr_punch ("Punch");
|
||||
static FRandom pr_saw ("Saw");
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "p_enemy.h"
|
||||
#include "gstrings.h"
|
||||
#include "a_action.h"
|
||||
#include "thingdef.h"
|
||||
#include "thingdef/thingdef.h"
|
||||
|
||||
//
|
||||
// Mancubus attack,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "p_local.h"
|
||||
#include "a_doomglobal.h"
|
||||
#include "a_action.h"
|
||||
#include "thingdef.h"
|
||||
#include "thingdef/thingdef.h"
|
||||
|
||||
void A_PainAttack (AActor *);
|
||||
void A_PainDie (AActor *);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "actor.h"
|
||||
#include "thingdef.h"
|
||||
#include "thingdef/thingdef.h"
|
||||
#include "p_conversation.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "a_action.h"
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#include "templates.h"
|
||||
#include "cmdlib.h"
|
||||
|
||||
extern void LoadDecorations (void (*process)(FState *, int));
|
||||
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
|
||||
|
@ -215,7 +215,7 @@ int GetSpriteIndex(const char * spritename)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ProcessStates (FState *states, int numstates)
|
||||
void ProcessStates (FState *states, int numstates)
|
||||
{
|
||||
int sprite = -1;
|
||||
|
||||
|
@ -278,7 +278,7 @@ void FActorInfo::StaticInit ()
|
|||
}
|
||||
|
||||
Printf ("LoadDecorations: Load external actors.\n");
|
||||
LoadDecorations (ProcessStates);
|
||||
LoadDecorations ();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -453,6 +453,7 @@ extern FDoomEdMap DoomEdMap;
|
|||
|
||||
int GetSpriteIndex(const char * spritename);
|
||||
void MakeStateNameList(const char * fname, TArray<FName> * out);
|
||||
void ProcessStates (FState *states, int numstates);
|
||||
|
||||
#include "infomacros.h"
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include "r_data.h"
|
||||
#include "w_wad.h"
|
||||
#include "a_strifeglobal.h"
|
||||
#include "thingdef.h"
|
||||
#include "thingdef/thingdef.h"
|
||||
|
||||
void FActorInfo::BuildDefaults ()
|
||||
{
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "a_sharedglobal.h"
|
||||
#include "a_doomglobal.h"
|
||||
#include "a_action.h"
|
||||
#include "thingdef.h"
|
||||
#include "thingdef/thingdef.h"
|
||||
|
||||
#include "gi.h"
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#include "a_action.h"
|
||||
#include "a_keys.h"
|
||||
#include "p_conversation.h"
|
||||
#include "thingdef.h"
|
||||
#include "thingdef/thingdef.h"
|
||||
#include "g_game.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "p_effect.h"
|
||||
#include "a_doomglobal.h"
|
||||
#include "templates.h"
|
||||
#include "thingdef.h"
|
||||
#include "thingdef/thingdef.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "tarray.h"
|
||||
#include "thingdef.h"
|
||||
#include "thingdef/thingdef.h"
|
||||
|
||||
static FRandom pr_skullpop ("SkullPop");
|
||||
|
||||
|
|
|
@ -1193,7 +1193,7 @@ void R_ProjectSprite (AActor *thing, int fakeside)
|
|||
if (thing == NULL ||
|
||||
(thing->renderflags & RF_INVISIBLE) ||
|
||||
thing->RenderStyle == STYLE_None ||
|
||||
(thing->RenderStyle >= STYLE_Translucent && thing->alpha <= 0))
|
||||
(thing->RenderStyle >= STYLE_Translucent && thing->alpha <= 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -390,7 +390,7 @@ bool SC_GetToken ()
|
|||
{
|
||||
if (SC_ScanString (true))
|
||||
{
|
||||
if (sc_TokenType == TK_Identifier || sc_TokenType == TK_NameConst)
|
||||
if (sc_TokenType == TK_NameConst)
|
||||
{
|
||||
sc_Name = FName(sc_String);
|
||||
}
|
||||
|
@ -854,6 +854,10 @@ FString SC_TokenName (int token, const char *string)
|
|||
"'stop'",
|
||||
"'eval'",
|
||||
"'evalnot'",
|
||||
"'pickup'",
|
||||
"'breakable'",
|
||||
"'projectile'",
|
||||
"'#include'",
|
||||
};
|
||||
|
||||
FString work;
|
||||
|
|
|
@ -145,6 +145,10 @@ enum
|
|||
TK_Stop,
|
||||
TK_Eval,
|
||||
TK_EvalNot,
|
||||
TK_Pickup,
|
||||
TK_Breakable,
|
||||
TK_Projectile,
|
||||
TK_Include,
|
||||
|
||||
TK_LastToken
|
||||
};
|
||||
|
|
5530
src/sc_man_scanner.h
5530
src/sc_man_scanner.h
File diff suppressed because it is too large
Load diff
|
@ -143,6 +143,12 @@ std2:
|
|||
'evalnot' { RET(TK_EvalNot); }
|
||||
'action' { RET(TK_Action); }
|
||||
|
||||
/* other DECORATE top level keywords */
|
||||
'#include' { RET(TK_Include); }
|
||||
'pickup' { RET(TK_Pickup); }
|
||||
'breakable' { RET(TK_Breakable); }
|
||||
'projectile' { RET(TK_Projectile); }
|
||||
|
||||
L (L|D)* { RET(TK_Identifier); }
|
||||
|
||||
("0" [xX] H+ IS?) | ("0" D+ IS?) | (D+ IS?)
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include "info.h"
|
||||
#include "sc_man.h"
|
||||
#include "tarray.h"
|
||||
#include "w_wad.h"
|
||||
#include "templates.h"
|
||||
#include "r_defs.h"
|
||||
#include "r_draw.h"
|
||||
|
@ -53,18 +52,8 @@
|
|||
#include "thingdef.h"
|
||||
#include "vectors.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
enum EDefinitionType
|
||||
{
|
||||
DEF_Decoration,
|
||||
DEF_BreakableDecoration,
|
||||
DEF_Pickup,
|
||||
DEF_Projectile,
|
||||
};
|
||||
|
||||
struct FExtraInfo
|
||||
{
|
||||
char DeathSprite[5];
|
||||
|
@ -111,14 +100,6 @@ IMPLEMENT_STATELESS_ACTOR (AFakeInventory, Any, -1, 0)
|
|||
PROP_Flags (MF_SPECIAL)
|
||||
END_DEFAULTS
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
void ProcessActor(void (*process)(FState *, int));
|
||||
void ParseClass();
|
||||
void ParseGlobalConst();
|
||||
void FinishThingdef();
|
||||
void InitDecorateTranslations();
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
void A_ScreamAndUnblock (AActor *);
|
||||
|
@ -127,17 +108,10 @@ void A_ActiveSound (AActor *);
|
|||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static void ParseDecorate (void (*process)(FState *, int));
|
||||
static void ParseInsideDecoration (FActorInfo *info, AActor *defaults,
|
||||
TArray<FState> &states, FExtraInfo &extra, EDefinitionType def);
|
||||
static void ParseSpriteFrames (FActorInfo *info, TArray<FState> &states);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
TArray<FActorInfo *> Decorations;
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static const char *RenderStyles[] =
|
||||
|
@ -248,332 +222,255 @@ static const char *FlagNames3[] =
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// LoadDecorations
|
||||
// ParseOldDecoration
|
||||
//
|
||||
// Called from FActor::StaticInit()
|
||||
// Reads an old style decoration object
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void LoadDecorations (void (*process)(FState *, int))
|
||||
{
|
||||
int lastlump, lump;
|
||||
|
||||
InitDecorateTranslations();
|
||||
lastlump = 0;
|
||||
while ((lump = Wads.FindLump ("DECORATE", &lastlump)) != -1)
|
||||
{
|
||||
SC_OpenLumpNum (lump, Wads.GetLumpFullName(lump));
|
||||
ParseDecorate (process);
|
||||
SC_Close ();
|
||||
}
|
||||
FinishThingdef();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ParseDecorate
|
||||
//
|
||||
// Parses a single DECORATE lump
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ParseDecorate (void (*process)(FState *, int))
|
||||
void ParseOldDecoration(EDefinitionType def)
|
||||
{
|
||||
TArray<FState> states;
|
||||
FExtraInfo extra;
|
||||
PClass *type;
|
||||
PClass *parent;
|
||||
EDefinitionType def;
|
||||
FActorInfo *info;
|
||||
FName typeName;
|
||||
int recursion=0;
|
||||
|
||||
// Get actor class name.
|
||||
while (true)
|
||||
if (def == DEF_Pickup) parent = RUNTIME_CLASS(AFakeInventory);
|
||||
else parent = RUNTIME_CLASS(AActor);
|
||||
|
||||
SC_MustGetString();
|
||||
typeName = FName(sc_String);
|
||||
type = parent->CreateDerivedClass (typeName, parent->Size);
|
||||
info = type->ActorInfo;
|
||||
info->GameFilter = 0x80;
|
||||
MakeStateDefines(parent->ActorInfo->StateList);
|
||||
|
||||
SC_MustGetString ();
|
||||
while (!SC_Compare ("{"))
|
||||
{
|
||||
if (!SC_GetString ())
|
||||
if (SC_Compare ("Doom"))
|
||||
{
|
||||
if (recursion==0) return;
|
||||
SC_Close();
|
||||
SC_RestoreScriptState();
|
||||
recursion--;
|
||||
continue;
|
||||
info->GameFilter |= GAME_Doom;
|
||||
}
|
||||
if (SC_Compare ("#include"))
|
||||
else if (SC_Compare ("Heretic"))
|
||||
{
|
||||
int lump;
|
||||
|
||||
SC_MustGetString();
|
||||
// This is not using SC_Open because it can print a more useful error message when done here
|
||||
lump = Wads.CheckNumForFullName(sc_String);
|
||||
if (lump==-1) lump = Wads.CheckNumForName(sc_String);
|
||||
if (lump==-1) SC_ScriptError("Lump '%s' not found", sc_String);
|
||||
SC_SaveScriptState();
|
||||
SC_OpenLumpNum(lump, sc_String);
|
||||
recursion++;
|
||||
continue;
|
||||
info->GameFilter |= GAME_Heretic;
|
||||
}
|
||||
if (SC_Compare ("Actor"))
|
||||
else if (SC_Compare ("Hexen"))
|
||||
{
|
||||
ProcessActor (process);
|
||||
continue;
|
||||
info->GameFilter |= GAME_Hexen;
|
||||
}
|
||||
if (SC_Compare ("Pickup"))
|
||||
else if (SC_Compare ("Raven"))
|
||||
{
|
||||
parent = RUNTIME_CLASS(AFakeInventory);
|
||||
def = DEF_Pickup;
|
||||
SC_MustGetString ();
|
||||
info->GameFilter |= GAME_Raven;
|
||||
}
|
||||
else if (SC_Compare ("Breakable"))
|
||||
else if (SC_Compare ("Strife"))
|
||||
{
|
||||
parent = RUNTIME_CLASS(AActor);
|
||||
def = DEF_BreakableDecoration;
|
||||
SC_MustGetString ();
|
||||
info->GameFilter |= GAME_Strife;
|
||||
}
|
||||
else if (SC_Compare ("Projectile"))
|
||||
{
|
||||
parent = RUNTIME_CLASS(AActor);
|
||||
def = DEF_Projectile;
|
||||
SC_MustGetString ();
|
||||
}
|
||||
else if (SC_Compare ("class"))
|
||||
{
|
||||
ParseClass();
|
||||
continue;
|
||||
}
|
||||
else if (SC_Compare ("Const"))
|
||||
{
|
||||
ParseGlobalConst();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent = RUNTIME_CLASS(AActor);
|
||||
def = DEF_Decoration;
|
||||
}
|
||||
|
||||
typeName = FName(sc_String);
|
||||
type = parent->CreateDerivedClass (typeName, parent->Size);
|
||||
info = type->ActorInfo;
|
||||
info->GameFilter = 0x80;
|
||||
Decorations.Push (info);
|
||||
MakeStateDefines(parent->ActorInfo->StateList);
|
||||
|
||||
SC_MustGetString ();
|
||||
while (!SC_Compare ("{"))
|
||||
{
|
||||
if (SC_Compare ("Doom"))
|
||||
{
|
||||
info->GameFilter |= GAME_Doom;
|
||||
}
|
||||
else if (SC_Compare ("Heretic"))
|
||||
{
|
||||
info->GameFilter |= GAME_Heretic;
|
||||
}
|
||||
else if (SC_Compare ("Hexen"))
|
||||
{
|
||||
info->GameFilter |= GAME_Hexen;
|
||||
}
|
||||
else if (SC_Compare ("Raven"))
|
||||
{
|
||||
info->GameFilter |= GAME_Raven;
|
||||
}
|
||||
else if (SC_Compare ("Strife"))
|
||||
{
|
||||
info->GameFilter |= GAME_Strife;
|
||||
}
|
||||
else if (SC_Compare ("Any"))
|
||||
{
|
||||
info->GameFilter = GAME_Any;
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_ScriptError ("Unknown game type %s", sc_String);
|
||||
}
|
||||
SC_MustGetString ();
|
||||
}
|
||||
if (info->GameFilter == 0x80)
|
||||
else if (SC_Compare ("Any"))
|
||||
{
|
||||
info->GameFilter = GAME_Any;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->GameFilter &= ~0x80;
|
||||
if (def != DEF_Decoration || info->GameFilter != 0x80)
|
||||
{
|
||||
SC_ScriptError ("Unknown game type %s in %s", sc_String, typeName.GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
// If this is a regular decoration (without preceding keyword) and no game
|
||||
// filters defined this is more likely a general syntax error so output a
|
||||
// more meaningful message.
|
||||
SC_ScriptError ("Syntax error: Unknown identifier '%s'", typeName.GetChars());
|
||||
}
|
||||
}
|
||||
SC_MustGetString ();
|
||||
}
|
||||
if (info->GameFilter == 0x80)
|
||||
{
|
||||
info->GameFilter = GAME_Any;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->GameFilter &= ~0x80;
|
||||
}
|
||||
|
||||
states.Clear ();
|
||||
memset (&extra, 0, sizeof(extra));
|
||||
ParseInsideDecoration (info, (AActor *)(type->Defaults), states, extra, def);
|
||||
states.Clear ();
|
||||
memset (&extra, 0, sizeof(extra));
|
||||
ParseInsideDecoration (info, (AActor *)(type->Defaults), states, extra, def);
|
||||
|
||||
info->NumOwnedStates = states.Size();
|
||||
if (info->NumOwnedStates == 0)
|
||||
{
|
||||
SC_ScriptError ("%s does not define any animation frames", typeName.GetChars() );
|
||||
}
|
||||
else if (extra.SpawnEnd == 0)
|
||||
{
|
||||
SC_ScriptError ("%s does not have a Frames definition", typeName.GetChars() );
|
||||
}
|
||||
else if (def == DEF_BreakableDecoration && extra.DeathEnd == 0)
|
||||
{
|
||||
SC_ScriptError ("%s does not have a DeathFrames definition", typeName.GetChars() );
|
||||
}
|
||||
else if (extra.IceDeathEnd != 0 && extra.bGenericIceDeath)
|
||||
{
|
||||
SC_ScriptError ("You cannot use IceDeathFrames and GenericIceDeath together");
|
||||
}
|
||||
info->NumOwnedStates = states.Size();
|
||||
if (info->NumOwnedStates == 0)
|
||||
{
|
||||
SC_ScriptError ("%s does not define any animation frames", typeName.GetChars() );
|
||||
}
|
||||
else if (extra.SpawnEnd == 0)
|
||||
{
|
||||
SC_ScriptError ("%s does not have a Frames definition", typeName.GetChars() );
|
||||
}
|
||||
else if (def == DEF_BreakableDecoration && extra.DeathEnd == 0)
|
||||
{
|
||||
SC_ScriptError ("%s does not have a DeathFrames definition", typeName.GetChars() );
|
||||
}
|
||||
else if (extra.IceDeathEnd != 0 && extra.bGenericIceDeath)
|
||||
{
|
||||
SC_ScriptError ("You cannot use IceDeathFrames and GenericIceDeath together");
|
||||
}
|
||||
|
||||
if (extra.IceDeathEnd != 0)
|
||||
{
|
||||
// Make a copy of the final frozen frame for A_FreezeDeathChunks
|
||||
FState icecopy = states[extra.IceDeathEnd-1];
|
||||
states.Push (icecopy);
|
||||
info->NumOwnedStates += 1;
|
||||
}
|
||||
if (extra.IceDeathEnd != 0)
|
||||
{
|
||||
// Make a copy of the final frozen frame for A_FreezeDeathChunks
|
||||
FState icecopy = states[extra.IceDeathEnd-1];
|
||||
states.Push (icecopy);
|
||||
info->NumOwnedStates += 1;
|
||||
}
|
||||
|
||||
info->OwnedStates = new FState[info->NumOwnedStates];
|
||||
memcpy (info->OwnedStates, &states[0], info->NumOwnedStates * sizeof(info->OwnedStates[0]));
|
||||
if (info->NumOwnedStates == 1)
|
||||
{
|
||||
info->OwnedStates->Tics = 0;
|
||||
info->OwnedStates->Misc1 = 0;
|
||||
info->OwnedStates->Frame &= ~SF_BIGTIC;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t i;
|
||||
info->OwnedStates = new FState[info->NumOwnedStates];
|
||||
memcpy (info->OwnedStates, &states[0], info->NumOwnedStates * sizeof(info->OwnedStates[0]));
|
||||
if (info->NumOwnedStates == 1)
|
||||
{
|
||||
info->OwnedStates->Tics = 0;
|
||||
info->OwnedStates->Misc1 = 0;
|
||||
info->OwnedStates->Frame &= ~SF_BIGTIC;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t i;
|
||||
|
||||
// Spawn states loop endlessly
|
||||
for (i = extra.SpawnStart; i < extra.SpawnEnd-1; ++i)
|
||||
// Spawn states loop endlessly
|
||||
for (i = extra.SpawnStart; i < extra.SpawnEnd-1; ++i)
|
||||
{
|
||||
info->OwnedStates[i].NextState = &info->OwnedStates[i+1];
|
||||
}
|
||||
info->OwnedStates[i].NextState = &info->OwnedStates[extra.SpawnStart];
|
||||
|
||||
// Death states are one-shot and freeze on the final state
|
||||
if (extra.DeathEnd != 0)
|
||||
{
|
||||
for (i = extra.DeathStart; i < extra.DeathEnd-1; ++i)
|
||||
{
|
||||
info->OwnedStates[i].NextState = &info->OwnedStates[i+1];
|
||||
}
|
||||
info->OwnedStates[i].NextState = &info->OwnedStates[extra.SpawnStart];
|
||||
|
||||
// Death states are one-shot and freeze on the final state
|
||||
if (extra.DeathEnd != 0)
|
||||
if (extra.bDiesAway || def == DEF_Projectile)
|
||||
{
|
||||
for (i = extra.DeathStart; i < extra.DeathEnd-1; ++i)
|
||||
{
|
||||
info->OwnedStates[i].NextState = &info->OwnedStates[i+1];
|
||||
}
|
||||
if (extra.bDiesAway || def == DEF_Projectile)
|
||||
{
|
||||
info->OwnedStates[i].NextState = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->OwnedStates[i].Tics = 0;
|
||||
info->OwnedStates[i].Misc1 = 0;
|
||||
info->OwnedStates[i].Frame &= ~SF_BIGTIC;
|
||||
}
|
||||
|
||||
if (def == DEF_Projectile)
|
||||
{
|
||||
if (extra.bExplosive)
|
||||
{
|
||||
info->OwnedStates[extra.DeathStart].Action = A_ExplodeParms;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The first frame plays the death sound and
|
||||
// the second frame makes it nonsolid.
|
||||
info->OwnedStates[extra.DeathStart].Action= A_Scream;
|
||||
if (extra.bSolidOnDeath)
|
||||
{
|
||||
}
|
||||
else if (extra.DeathStart + 1 < extra.DeathEnd)
|
||||
{
|
||||
info->OwnedStates[extra.DeathStart+1].Action = A_NoBlocking;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->OwnedStates[extra.DeathStart].Action = A_ScreamAndUnblock;
|
||||
}
|
||||
|
||||
if (extra.DeathHeight == 0) extra.DeathHeight = ((AActor*)(type->Defaults))->height;
|
||||
info->Class->Meta.SetMetaFixed (AMETA_DeathHeight, extra.DeathHeight);
|
||||
}
|
||||
AddState("Death", &info->OwnedStates[extra.DeathStart]);
|
||||
info->OwnedStates[i].NextState = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->OwnedStates[i].Tics = 0;
|
||||
info->OwnedStates[i].Misc1 = 0;
|
||||
info->OwnedStates[i].Frame &= ~SF_BIGTIC;
|
||||
}
|
||||
|
||||
// Burn states are the same as death states, except they can optionally terminate
|
||||
if (extra.FireDeathEnd != 0)
|
||||
if (def == DEF_Projectile)
|
||||
{
|
||||
for (i = extra.FireDeathStart; i < extra.FireDeathEnd-1; ++i)
|
||||
if (extra.bExplosive)
|
||||
{
|
||||
info->OwnedStates[i].NextState = &info->OwnedStates[i+1];
|
||||
info->OwnedStates[extra.DeathStart].Action = A_ExplodeParms;
|
||||
}
|
||||
if (extra.bBurnAway)
|
||||
{
|
||||
info->OwnedStates[i].NextState = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->OwnedStates[i].Tics = 0;
|
||||
info->OwnedStates[i].Misc1 = 0;
|
||||
info->OwnedStates[i].Frame &= ~SF_BIGTIC;
|
||||
}
|
||||
|
||||
// The first frame plays the burn sound and
|
||||
}
|
||||
else
|
||||
{
|
||||
// The first frame plays the death sound and
|
||||
// the second frame makes it nonsolid.
|
||||
info->OwnedStates[extra.FireDeathStart].Action = A_ActiveSound;
|
||||
if (extra.bSolidOnBurn)
|
||||
info->OwnedStates[extra.DeathStart].Action= A_Scream;
|
||||
if (extra.bSolidOnDeath)
|
||||
{
|
||||
}
|
||||
else if (extra.FireDeathStart + 1 < extra.FireDeathEnd)
|
||||
else if (extra.DeathStart + 1 < extra.DeathEnd)
|
||||
{
|
||||
info->OwnedStates[extra.FireDeathStart+1].Action = A_NoBlocking;
|
||||
info->OwnedStates[extra.DeathStart+1].Action = A_NoBlocking;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->OwnedStates[extra.FireDeathStart].Action = A_ActiveAndUnblock;
|
||||
info->OwnedStates[extra.DeathStart].Action = A_ScreamAndUnblock;
|
||||
}
|
||||
|
||||
if (extra.BurnHeight == 0) extra.BurnHeight = ((AActor*)(type->Defaults))->height;
|
||||
type->Meta.SetMetaFixed (AMETA_BurnHeight, extra.BurnHeight);
|
||||
|
||||
AddState("Burn", &info->OwnedStates[extra.FireDeathStart]);
|
||||
}
|
||||
|
||||
// Ice states are similar to burn and death, except their final frame enters
|
||||
// a loop that eventually causes them to bust to pieces.
|
||||
if (extra.IceDeathEnd != 0)
|
||||
{
|
||||
for (i = extra.IceDeathStart; i < extra.IceDeathEnd-1; ++i)
|
||||
{
|
||||
info->OwnedStates[i].NextState = &info->OwnedStates[i+1];
|
||||
}
|
||||
info->OwnedStates[i].NextState = &info->OwnedStates[info->NumOwnedStates-1];
|
||||
info->OwnedStates[i].Tics = 6;
|
||||
info->OwnedStates[i].Misc1 = 0;
|
||||
info->OwnedStates[i].Action = A_FreezeDeath;
|
||||
|
||||
i = info->NumOwnedStates - 1;
|
||||
info->OwnedStates[i].NextState = &info->OwnedStates[i];
|
||||
info->OwnedStates[i].Tics = 2;
|
||||
info->OwnedStates[i].Misc1 = 0;
|
||||
info->OwnedStates[i].Action = A_FreezeDeathChunks;
|
||||
AddState("Ice", &info->OwnedStates[extra.IceDeathStart]);
|
||||
}
|
||||
else if (extra.bGenericIceDeath)
|
||||
{
|
||||
AddState("Ice", &AActor::States[AActor::S_GENERICFREEZEDEATH]);
|
||||
if (extra.DeathHeight == 0) extra.DeathHeight = ((AActor*)(type->Defaults))->height;
|
||||
info->Class->Meta.SetMetaFixed (AMETA_DeathHeight, extra.DeathHeight);
|
||||
}
|
||||
AddState("Death", &info->OwnedStates[extra.DeathStart]);
|
||||
}
|
||||
if (def == DEF_BreakableDecoration)
|
||||
|
||||
// Burn states are the same as death states, except they can optionally terminate
|
||||
if (extra.FireDeathEnd != 0)
|
||||
{
|
||||
((AActor *)(type->Defaults))->flags |= MF_SHOOTABLE;
|
||||
for (i = extra.FireDeathStart; i < extra.FireDeathEnd-1; ++i)
|
||||
{
|
||||
info->OwnedStates[i].NextState = &info->OwnedStates[i+1];
|
||||
}
|
||||
if (extra.bBurnAway)
|
||||
{
|
||||
info->OwnedStates[i].NextState = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->OwnedStates[i].Tics = 0;
|
||||
info->OwnedStates[i].Misc1 = 0;
|
||||
info->OwnedStates[i].Frame &= ~SF_BIGTIC;
|
||||
}
|
||||
|
||||
// The first frame plays the burn sound and
|
||||
// the second frame makes it nonsolid.
|
||||
info->OwnedStates[extra.FireDeathStart].Action = A_ActiveSound;
|
||||
if (extra.bSolidOnBurn)
|
||||
{
|
||||
}
|
||||
else if (extra.FireDeathStart + 1 < extra.FireDeathEnd)
|
||||
{
|
||||
info->OwnedStates[extra.FireDeathStart+1].Action = A_NoBlocking;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->OwnedStates[extra.FireDeathStart].Action = A_ActiveAndUnblock;
|
||||
}
|
||||
|
||||
if (extra.BurnHeight == 0) extra.BurnHeight = ((AActor*)(type->Defaults))->height;
|
||||
type->Meta.SetMetaFixed (AMETA_BurnHeight, extra.BurnHeight);
|
||||
|
||||
AddState("Burn", &info->OwnedStates[extra.FireDeathStart]);
|
||||
}
|
||||
if (def == DEF_Projectile)
|
||||
|
||||
// Ice states are similar to burn and death, except their final frame enters
|
||||
// a loop that eventually causes them to bust to pieces.
|
||||
if (extra.IceDeathEnd != 0)
|
||||
{
|
||||
((AActor *)(type->Defaults))->flags |= MF_DROPOFF|MF_MISSILE;
|
||||
for (i = extra.IceDeathStart; i < extra.IceDeathEnd-1; ++i)
|
||||
{
|
||||
info->OwnedStates[i].NextState = &info->OwnedStates[i+1];
|
||||
}
|
||||
info->OwnedStates[i].NextState = &info->OwnedStates[info->NumOwnedStates-1];
|
||||
info->OwnedStates[i].Tics = 6;
|
||||
info->OwnedStates[i].Misc1 = 0;
|
||||
info->OwnedStates[i].Action = A_FreezeDeath;
|
||||
|
||||
i = info->NumOwnedStates - 1;
|
||||
info->OwnedStates[i].NextState = &info->OwnedStates[i];
|
||||
info->OwnedStates[i].Tics = 2;
|
||||
info->OwnedStates[i].Misc1 = 0;
|
||||
info->OwnedStates[i].Action = A_FreezeDeathChunks;
|
||||
AddState("Ice", &info->OwnedStates[extra.IceDeathStart]);
|
||||
}
|
||||
else if (extra.bGenericIceDeath)
|
||||
{
|
||||
AddState("Ice", &AActor::States[AActor::S_GENERICFREEZEDEATH]);
|
||||
}
|
||||
AddState("Spawn", &info->OwnedStates[extra.SpawnStart]);
|
||||
InstallStates(info, ((AActor *)(type->Defaults)));
|
||||
process (info->OwnedStates, info->NumOwnedStates);
|
||||
}
|
||||
if (def == DEF_BreakableDecoration)
|
||||
{
|
||||
((AActor *)(type->Defaults))->flags |= MF_SHOOTABLE;
|
||||
}
|
||||
if (def == DEF_Projectile)
|
||||
{
|
||||
((AActor *)(type->Defaults))->flags |= MF_DROPOFF|MF_MISSILE;
|
||||
}
|
||||
AddState("Spawn", &info->OwnedStates[extra.SpawnStart]);
|
||||
InstallStates (info, ((AActor *)(type->Defaults)));
|
||||
ProcessStates (info->OwnedStates, info->NumOwnedStates);
|
||||
}
|
||||
|
||||
//==========================================================================
|
|
@ -73,8 +73,6 @@
|
|||
const PClass *QuestItemClasses[31];
|
||||
|
||||
|
||||
extern TArray<FActorInfo *> Decorations;
|
||||
|
||||
// allow decal specifications in DECORATE. Decals are loaded after DECORATE so the names must be stored here.
|
||||
TArray<char*> DecalNames;
|
||||
// all state parameters
|
||||
|
@ -1169,7 +1167,6 @@ static FActorInfo * CreateNewActor(FActorInfo ** parentc, Baggage *bag)
|
|||
PClass * ti = parent->CreateDerivedClass (typeName, parent->Size);
|
||||
FActorInfo * info = ti->ActorInfo;
|
||||
|
||||
Decorations.Push (info);
|
||||
MakeStateDefines(parent->ActorInfo->StateList);
|
||||
|
||||
ResetBaggage (bag);
|
||||
|
@ -2150,7 +2147,7 @@ void ParseActorProperties (Baggage &bag)
|
|||
// Reads an actor definition
|
||||
//
|
||||
//==========================================================================
|
||||
void ProcessActor(void (*process)(FState *, int))
|
||||
void ProcessActor()
|
||||
{
|
||||
FActorInfo * info=NULL;
|
||||
AActor * defaults;
|
||||
|
@ -2169,8 +2166,8 @@ void ProcessActor(void (*process)(FState *, int))
|
|||
|
||||
ParseActorProperties (bag);
|
||||
FinishStates (info, defaults, bag);
|
||||
InstallStates(info, defaults);
|
||||
process(info->OwnedStates, info->NumOwnedStates);
|
||||
InstallStates (info, defaults);
|
||||
ProcessStates (info->OwnedStates, info->NumOwnedStates);
|
||||
if (bag.DropItemSet)
|
||||
{
|
||||
if (bag.DropItemList == NULL)
|
||||
|
@ -2252,7 +2249,7 @@ static void ActorConstDef (AActor *defaults, Baggage &bag)
|
|||
// (Maybe there will be other types later.)
|
||||
SC_MustGetToken(TK_Int);
|
||||
SC_MustGetToken(TK_Identifier);
|
||||
FName symname = sc_Name;
|
||||
FName symname = sc_String;
|
||||
SC_MustGetToken('=');
|
||||
int expr = ParseExpression (false, bag.Info->Class);
|
||||
SC_MustGetToken(';');
|
||||
|
@ -2270,6 +2267,46 @@ static void ActorConstDef (AActor *defaults, Baggage &bag)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ActorEnumDef
|
||||
//
|
||||
// Parses an enum definition.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ActorEnumDef (AActor *defaults, Baggage &bag)
|
||||
{
|
||||
int currvalue = 0;
|
||||
|
||||
SC_MustGetToken('{');
|
||||
while (!SC_CheckToken('}'))
|
||||
{
|
||||
SC_MustGetToken(TK_Identifier);
|
||||
FName symname = sc_String;
|
||||
if (SC_CheckToken('='))
|
||||
{
|
||||
int expr = ParseExpression(false, bag.Info->Class);
|
||||
currvalue = EvalExpressionI (expr, NULL, bag.Info->Class);
|
||||
}
|
||||
PSymbolConst *sym = new PSymbolConst;
|
||||
sym->SymbolName = symname;
|
||||
sym->SymbolType = SYM_Const;
|
||||
sym->Value = currvalue;
|
||||
if (bag.Info->Class->Symbols.AddSymbol (sym) == NULL)
|
||||
{
|
||||
delete sym;
|
||||
SC_ScriptError ("'%s' is already defined in class '%s'.",
|
||||
symname.GetChars(), bag.Info->Class->TypeName.GetChars());
|
||||
}
|
||||
// This allows a comma after the last value but doesn't enforce it.
|
||||
if (SC_CheckToken('}')) break;
|
||||
SC_MustGetToken(',');
|
||||
currvalue++;
|
||||
}
|
||||
SC_MustGetToken(';');
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ParseGlobalConst
|
||||
|
@ -2287,6 +2324,14 @@ void ParseGlobalConst()
|
|||
ActorConstDef(GetDefault<AActor>(), bag);
|
||||
}
|
||||
|
||||
void ParseGlobalEnum()
|
||||
{
|
||||
Baggage bag;
|
||||
|
||||
bag.Info = RUNTIME_CLASS(AActor)->ActorInfo;
|
||||
ActorEnumDef(GetDefault<AActor>(), bag);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ActorActionDef
|
||||
|
@ -2309,7 +2354,7 @@ static void ActorActionDef (AActor *defaults, Baggage &bag)
|
|||
|
||||
SC_MustGetToken(TK_Native);
|
||||
SC_MustGetToken(TK_Identifier);
|
||||
funcname = sc_Name;
|
||||
funcname = sc_String;
|
||||
afd = FindFunction(sc_String);
|
||||
if (afd == NULL)
|
||||
{
|
||||
|
@ -4177,6 +4222,7 @@ static const ActorProps props[] =
|
|||
{ "disintegrate", ActorDisintegrateState, RUNTIME_CLASS(AActor) },
|
||||
{ "donthurtshooter", ActorDontHurtShooter, RUNTIME_CLASS(AActor) },
|
||||
{ "dropitem", ActorDropItem, RUNTIME_CLASS(AActor) },
|
||||
{ "enum", ActorEnumDef, RUNTIME_CLASS(AActor) },
|
||||
{ "explosiondamage", ActorExplosionDamage, RUNTIME_CLASS(AActor) },
|
||||
{ "explosionradius", ActorExplosionRadius, RUNTIME_CLASS(AActor) },
|
||||
{ "fastspeed", ActorFastSpeed, RUNTIME_CLASS(AActor) },
|
||||
|
@ -4449,10 +4495,10 @@ void ParseClass()
|
|||
FName supername;
|
||||
|
||||
SC_MustGetToken(TK_Identifier); // class name
|
||||
classname = sc_Name;
|
||||
classname = sc_String;
|
||||
SC_MustGetToken(TK_Extends); // because I'm not supporting Object
|
||||
SC_MustGetToken(TK_Identifier); // superclass name
|
||||
supername = sc_Name;
|
||||
supername = sc_String;
|
||||
SC_MustGetToken(TK_Native); // use actor definitions for your own stuff
|
||||
SC_MustGetToken('{');
|
||||
|
||||
|
@ -4478,190 +4524,15 @@ void ParseClass()
|
|||
{
|
||||
ActorConstDef (0, bag);
|
||||
}
|
||||
else if (sc_TokenType == TK_Enum)
|
||||
{
|
||||
ActorEnumDef (0, bag);
|
||||
}
|
||||
else
|
||||
{
|
||||
FString tokname = SC_TokenName(sc_TokenType, sc_String);
|
||||
SC_ScriptError ("Expected 'action' or 'const' but got %s", tokname.GetChars());
|
||||
SC_ScriptError ("Expected 'action', 'const' or 'enum' but got %s", tokname.GetChars());
|
||||
}
|
||||
SC_MustGetAnyToken();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ParseFunctionCall(Baggage &bag, FState & state)
|
||||
{
|
||||
// Make the action name lowercase to satisfy the gperf hashers
|
||||
strlwr (sc_String);
|
||||
FString funcname = sc_String;
|
||||
|
||||
int minreq=0;
|
||||
memset(&state, 0, sizeof(state));
|
||||
if (DoSpecialFunctions(state, false, &minreq, bag))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
PSymbol *sym = bag.Info->Class->Symbols.FindSymbol (FName(sc_String, true), true);
|
||||
if (sym != NULL && sym->SymbolType == SYM_ActionFunction)
|
||||
{
|
||||
PSymbolActionFunction *afd = static_cast<PSymbolActionFunction *>(sym);
|
||||
state.Action = afd->Function;
|
||||
if (!afd->Arguments.IsEmpty())
|
||||
{
|
||||
const char *params = afd->Arguments.GetChars();
|
||||
int numparams = (int)afd->Arguments.Len();
|
||||
|
||||
int v;
|
||||
|
||||
if (!islower(*params))
|
||||
{
|
||||
SC_MustGetToken('(');
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!SC_CheckToken('('))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int paramindex = PrepareStateParameters(&state, numparams);
|
||||
int paramstart = paramindex;
|
||||
bool varargs = params[numparams - 1] == '+';
|
||||
|
||||
if (varargs)
|
||||
{
|
||||
StateParameters[paramindex++] = 0;
|
||||
}
|
||||
|
||||
while (*params)
|
||||
{
|
||||
switch(*params)
|
||||
{
|
||||
case 'I':
|
||||
case 'i': // Integer
|
||||
SC_MustGetNumber();
|
||||
v=sc_Number;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
case 'f': // Fixed point
|
||||
SC_MustGetFloat();
|
||||
v=fixed_t(sc_Float*FRACUNIT);
|
||||
break;
|
||||
|
||||
|
||||
case 'S':
|
||||
case 's': // Sound name
|
||||
SC_MustGetString();
|
||||
v=S_FindSound(sc_String);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
case 'm': // Actor name
|
||||
case 'T':
|
||||
case 't': // String
|
||||
SC_MustGetString();
|
||||
v = (int)(sc_String[0] ? FName(sc_String) : NAME_None);
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
case 'l': // Jump label
|
||||
|
||||
SC_ScriptError("You cannot use state jump calls in action functions (%s tries to call %s)\n",
|
||||
funcname.GetChars(), afd->SymbolName.GetChars());
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
case 'c': // Color
|
||||
SC_MustGetString ();
|
||||
if (SC_Compare("none"))
|
||||
{
|
||||
v = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int c = V_GetColor (NULL, sc_String);
|
||||
// 0 needs to be the default so we have to mark the color.
|
||||
v = MAKEARGB(1, RPART(c), GPART(c), BPART(c));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
case 'x':
|
||||
v = ParseExpression (false, bag.Info->Class);
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
case 'y':
|
||||
v = ParseExpression (true, bag.Info->Class);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
v = -1;
|
||||
break;
|
||||
}
|
||||
StateParameters[paramindex++] = v;
|
||||
params++;
|
||||
if (varargs)
|
||||
{
|
||||
StateParameters[paramstart]++;
|
||||
}
|
||||
if (*params)
|
||||
{
|
||||
if (*params == '+')
|
||||
{
|
||||
if (SC_CheckString(")"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
params--;
|
||||
v = 0;
|
||||
StateParameters.Push(v);
|
||||
}
|
||||
else if ((islower(*params) || *params=='!') && SC_CheckString(")"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
SC_MustGetStringName (",");
|
||||
}
|
||||
}
|
||||
SC_MustGetStringName(")");
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_MustGetString();
|
||||
if (SC_Compare("("))
|
||||
{
|
||||
SC_ScriptError("You cannot pass parameters to '%s'\n",funcname.GetChars());
|
||||
}
|
||||
SC_UnGet();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ParseActionFunction()
|
||||
{
|
||||
FState state;
|
||||
Baggage bag;
|
||||
bag.Info=RUNTIME_CLASS(AActor)->ActorInfo;
|
||||
|
||||
// for now only void functions with no parameters
|
||||
SC_MustGetToken(TK_Void);
|
||||
SC_MustGetString();
|
||||
FName funcname = sc_String;
|
||||
SC_MustGetToken('(');
|
||||
SC_MustGetToken(')');
|
||||
SC_MustGetToken('{');
|
||||
// All this can do for the moment is parse a list of simple function calls, nothing more
|
||||
while (SC_MustGetString(), sc_TokenType != '}');
|
||||
{
|
||||
ParseFunctionCall(bag, state);
|
||||
SC_MustGetToken(';');
|
||||
// Todo: Take the state's content and make a list of it.
|
||||
}
|
||||
|
||||
}
|
|
@ -71,5 +71,15 @@ enum
|
|||
int FindLineSpecialEx (const char *string, int *minargs, int *maxargs);
|
||||
|
||||
|
||||
// Types of old style decorations
|
||||
enum EDefinitionType
|
||||
{
|
||||
DEF_Decoration,
|
||||
DEF_BreakableDecoration,
|
||||
DEF_Pickup,
|
||||
DEF_Projectile,
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -696,7 +696,7 @@ static ExpData *ParseExpressionA (const PClass *cls)
|
|||
}
|
||||
SC_MustGetToken('.');
|
||||
SC_MustGetToken(TK_Identifier);
|
||||
PSymbol *sym = cls->Symbols.FindSymbol (sc_Name, true);
|
||||
PSymbol *sym = cls->Symbols.FindSymbol (sc_String, true);
|
||||
if (sym != NULL && sym->SymbolType == SYM_Const)
|
||||
{
|
||||
ExpData *data = new ExpData;
|
||||
|
@ -713,7 +713,7 @@ static ExpData *ParseExpressionA (const PClass *cls)
|
|||
}
|
||||
else if (SC_CheckToken(TK_Identifier))
|
||||
{
|
||||
switch (sc_Name)
|
||||
switch (FName(sc_String))
|
||||
{
|
||||
case NAME_Random:
|
||||
{
|
||||
|
@ -842,7 +842,7 @@ static ExpData *ParseExpressionA (const PClass *cls)
|
|||
// Check if this is a constant
|
||||
if (cls != NULL)
|
||||
{
|
||||
PSymbol *sym = cls->Symbols.FindSymbol (sc_Name, true);
|
||||
PSymbol *sym = cls->Symbols.FindSymbol (sc_String, true);
|
||||
if (sym != NULL && sym->SymbolType == SYM_Const)
|
||||
{
|
||||
ExpData *data = new ExpData;
|
||||
|
@ -855,9 +855,10 @@ static ExpData *ParseExpressionA (const PClass *cls)
|
|||
|
||||
// Check if it's a variable we understand
|
||||
int varid = -1;
|
||||
FName vname = sc_String;
|
||||
for (size_t i = 0; i < countof(ExpVars); i++)
|
||||
{
|
||||
if (sc_Name == ExpVars[i].name)
|
||||
if (vname == ExpVars[i].name)
|
||||
{
|
||||
varid = (int)i;
|
||||
break;
|
170
src/thingdef/thingdef_main.cpp
Normal file
170
src/thingdef/thingdef_main.cpp
Normal file
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
** decorations.cpp
|
||||
** Loads custom actors out of DECORATE lumps.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2002-2007 Randy Heit
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include "actor.h"
|
||||
#include "info.h"
|
||||
#include "sc_man.h"
|
||||
#include "tarray.h"
|
||||
#include "w_wad.h"
|
||||
#include "templates.h"
|
||||
#include "s_sound.h"
|
||||
#include "cmdlib.h"
|
||||
#include "thingdef.h"
|
||||
#include "vectors.h"
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
void ProcessActor();
|
||||
void ParseClass();
|
||||
void ParseGlobalConst();
|
||||
void ParseGlobalEnum();
|
||||
void FinishThingdef();
|
||||
void InitDecorateTranslations();
|
||||
void ParseOldDecoration(EDefinitionType def);
|
||||
|
||||
// STATIC FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ParseDecorate
|
||||
//
|
||||
// Parses a single DECORATE lump
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ParseDecorate ()
|
||||
{
|
||||
int recursion=0;
|
||||
int lump;
|
||||
|
||||
// Get actor class name.
|
||||
while (true)
|
||||
{
|
||||
SC_SavePos();
|
||||
if (!SC_GetToken ())
|
||||
{
|
||||
if (recursion==0) return;
|
||||
SC_Close();
|
||||
SC_RestoreScriptState();
|
||||
recursion--;
|
||||
continue;
|
||||
}
|
||||
switch (sc_TokenType)
|
||||
{
|
||||
case TK_Include:
|
||||
SC_MustGetString();
|
||||
// This is not using SC_Open because it can print a more useful error message when done here
|
||||
lump = Wads.CheckNumForFullName(sc_String);
|
||||
if (lump==-1) lump = Wads.CheckNumForName(sc_String);
|
||||
if (lump==-1) SC_ScriptError("Lump '%s' not found", sc_String);
|
||||
SC_SaveScriptState();
|
||||
SC_OpenLumpNum(lump, sc_String);
|
||||
recursion++;
|
||||
break;
|
||||
|
||||
case TK_Class:
|
||||
ParseClass();
|
||||
break;
|
||||
|
||||
case TK_Const:
|
||||
ParseGlobalConst();
|
||||
break;
|
||||
|
||||
case TK_Enum:
|
||||
ParseGlobalEnum();
|
||||
break;
|
||||
|
||||
case TK_Pickup:
|
||||
ParseOldDecoration(DEF_Pickup);
|
||||
break;
|
||||
|
||||
case TK_Breakable:
|
||||
ParseOldDecoration(DEF_BreakableDecoration);
|
||||
break;
|
||||
|
||||
case TK_Projectile:
|
||||
ParseOldDecoration(DEF_Projectile);
|
||||
break;
|
||||
|
||||
case ';':
|
||||
// ';' is the start of a comment in the non-cmode parser which
|
||||
// is used to parse parts of the DECORATE lump. If we don't add
|
||||
// a check here the user will only get weird non-informative
|
||||
// error messages if a semicolon is found.
|
||||
SC_ScriptError("Unexpected ';'");
|
||||
break;
|
||||
|
||||
case TK_Identifier:
|
||||
// 'ACTOR' cannot be a keyword because it is also needed as a class identifier
|
||||
// so let's do a special case for this.
|
||||
if (SC_Compare("ACTOR"))
|
||||
{
|
||||
ProcessActor ();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// Yuck! Too bad that there's no better way to check this properly
|
||||
SC_RestorePos();
|
||||
ParseOldDecoration(DEF_Decoration);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// LoadDecorations
|
||||
//
|
||||
// Called from FActor::StaticInit()
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void LoadDecorations ()
|
||||
{
|
||||
int lastlump, lump;
|
||||
|
||||
InitDecorateTranslations();
|
||||
lastlump = 0;
|
||||
while ((lump = Wads.FindLump ("DECORATE", &lastlump)) != -1)
|
||||
{
|
||||
SC_OpenLumpNum (lump, Wads.GetLumpFullName(lump));
|
||||
ParseDecorate ();
|
||||
SC_Close ();
|
||||
}
|
||||
FinishThingdef();
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
#include "vectors.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "a_doomglobal.h"
|
||||
#include "thingdef.h"
|
||||
#include "thingdef/thingdef.h"
|
||||
#include "v_video.h"
|
||||
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ actor DeadShotgunGuy : ShotgunGuy 19
|
|||
Spawn:
|
||||
Goto Super::Death+4
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Dead imp ----------------------------------------------------------------
|
||||
|
||||
|
|
16
zdoom.vcproj
16
zdoom.vcproj
|
@ -4283,15 +4283,15 @@
|
|||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\decorations.cpp"
|
||||
RelativePath=".\src\thingdef\olddecorations.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\thingdef.cpp"
|
||||
RelativePath=".\src\thingdef\thingdef.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\thingdef.h"
|
||||
RelativePath=".\src\thingdef\thingdef.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
|
@ -4299,7 +4299,15 @@
|
|||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\thingdef_exp.cpp"
|
||||
RelativePath=".\src\thingdef\thingdef_exp.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\thingdef\thingdef_main.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\thingdef\thingdef_specials.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
|
|
Loading…
Reference in a new issue