- Finished the framework for specifying all action functions externally,
including restricting them to particular classes. SVN r403 (trunk)
This commit is contained in:
parent
511e11e8b4
commit
24b5a0b110
14 changed files with 3410 additions and 3297 deletions
440
src/thingdef.cpp
440
src/thingdef.cpp
|
|
@ -413,336 +413,29 @@ void A_ChangeFlag(AActor * self)
|
|||
|
||||
struct AFuncDesc
|
||||
{
|
||||
const char * Name;
|
||||
const char *Name;
|
||||
actionf_p Function;
|
||||
const char * parameters;
|
||||
};
|
||||
|
||||
|
||||
// Prototype the code pointers
|
||||
#define WEAPON(x) void A_##x(AActor*);
|
||||
#define ACTOR(x) void A_##x(AActor*);
|
||||
ACTOR(MeleeAttack)
|
||||
ACTOR(MissileAttack)
|
||||
ACTOR(ComboAttack)
|
||||
ACTOR(BulletAttack)
|
||||
ACTOR(ScreamAndUnblock)
|
||||
ACTOR(ActiveAndUnblock)
|
||||
ACTOR(ActiveSound)
|
||||
ACTOR(FastChase)
|
||||
ACTOR(CentaurDefend)
|
||||
ACTOR(FreezeDeath)
|
||||
ACTOR(FreezeDeathChunks)
|
||||
ACTOR(GenericFreezeDeath)
|
||||
ACTOR(IceGuyDie)
|
||||
ACTOR(M_Saw)
|
||||
ACTOR(Wander)
|
||||
ACTOR(Look2)
|
||||
ACTOR(TossGib)
|
||||
ACTOR(SentinelBob)
|
||||
ACTOR(SentinelRefire)
|
||||
ACTOR(Tracer2)
|
||||
ACTOR(SetShadow)
|
||||
ACTOR(ClearShadow)
|
||||
ACTOR(GetHurt)
|
||||
ACTOR(TurretLook)
|
||||
ACTOR(KlaxonBlare)
|
||||
ACTOR(CheckTerrain)
|
||||
ACTOR(Countdown)
|
||||
ACTOR(AlertMonsters)
|
||||
ACTOR(ClearSoundTarget)
|
||||
ACTOR(FireAssaultGun)
|
||||
ACTOR(PlaySound)
|
||||
ACTOR(PlayWeaponSound)
|
||||
ACTOR(FLoopActiveSound)
|
||||
ACTOR(LoopActiveSound)
|
||||
ACTOR(StopSound)
|
||||
ACTOR(PlaySoundEx)
|
||||
ACTOR(StopSoundEx)
|
||||
ACTOR(SeekerMissile)
|
||||
ACTOR(Jump)
|
||||
ACTOR(ExplodeParms)
|
||||
ACTOR(CallSpecial)
|
||||
ACTOR(CustomMissile)
|
||||
ACTOR(CustomBulletAttack)
|
||||
ACTOR(JumpIfHealthLower)
|
||||
ACTOR(JumpIfCloser)
|
||||
ACTOR(JumpIfNoAmmo)
|
||||
ACTOR(JumpIfInventory)
|
||||
ACTOR(CustomPunch)
|
||||
ACTOR(FireBullets)
|
||||
ACTOR(FireCustomMissile)
|
||||
ACTOR(RailAttack)
|
||||
ACTOR(CustomRailgun)
|
||||
ACTOR(LightInverse)
|
||||
ACTOR(GiveInventory)
|
||||
ACTOR(TakeInventory)
|
||||
ACTOR(SpawnItem)
|
||||
ACTOR(SpawnItemEx)
|
||||
ACTOR(ThrowGrenade)
|
||||
ACTOR(Recoil)
|
||||
ACTOR(SelectWeapon)
|
||||
ACTOR(Print)
|
||||
ACTOR(SetTranslucent)
|
||||
ACTOR(FadeIn)
|
||||
ACTOR(FadeOut)
|
||||
ACTOR(SpawnDebris)
|
||||
ACTOR(SetSolid)
|
||||
ACTOR(UnsetSolid)
|
||||
ACTOR(SetFloat)
|
||||
ACTOR(UnsetFloat)
|
||||
ACTOR(BishopMissileWeave)
|
||||
ACTOR(CStaffMissileSlither)
|
||||
ACTOR(CheckSight)
|
||||
ACTOR(ExtChase)
|
||||
ACTOR(DropInventory)
|
||||
ACTOR(SetBlend)
|
||||
ACTOR(JumpIf)
|
||||
ACTOR(SetUserVar)
|
||||
ACTOR(SetUserVarRandom)
|
||||
ACTOR(KillMaster)
|
||||
ACTOR(KillChildren)
|
||||
ACTOR(DualPainAttack)
|
||||
ACTOR(GiveToTarget)
|
||||
ACTOR(TakeFromTarget)
|
||||
ACTOR(JumpIfInTargetInventory)
|
||||
ACTOR(CountdownArg)
|
||||
ACTOR(CustomMeleeAttack)
|
||||
ACTOR(CustomComboAttack)
|
||||
ACTOR(Light)
|
||||
ACTOR(Burst)
|
||||
ACTOR(SkullPop)
|
||||
ACTOR(CheckFloor)
|
||||
ACTOR(CheckPlayerDone)
|
||||
ACTOR(RadiusThrust)
|
||||
ACTOR(Stop)
|
||||
ACTOR(SPosAttackUseAtkSound)
|
||||
ACTOR(Respawn)
|
||||
ACTOR(BarrelDestroy)
|
||||
ACTOR(PlayerSkinCheck)
|
||||
ACTOR(QueueCorpse)
|
||||
|
||||
|
||||
#include "codepointers.h"
|
||||
#include "d_dehackedactions.h"
|
||||
void A_ComboAttack(AActor*);
|
||||
|
||||
/* What do the parameter letters mean?
|
||||
*
|
||||
* If the letter is uppercase, it is required. Lowercase letters are optional.
|
||||
* i = integer
|
||||
* f = fixed point
|
||||
* s = sound name
|
||||
* m = actor name
|
||||
* t = string
|
||||
* l = jump label
|
||||
* c = color
|
||||
* x = expression
|
||||
* y = expression
|
||||
* If the final character is a +, the previous parameter is repeated indefinitely,
|
||||
* and an "imaginary" first parameter is inserted containing the total number of
|
||||
* parameters passed.
|
||||
*/
|
||||
#define FUNC(name, parm) { #name, name, parm },
|
||||
// Declare the code pointer table
|
||||
AFuncDesc AFTable[]=
|
||||
AFuncDesc AFTable[] =
|
||||
{
|
||||
|
||||
// most of the functions available in Dehacked
|
||||
FUNC(A_MonsterRail, NULL)
|
||||
FUNC(A_BFGSpray, "mxx")
|
||||
FUNC(A_Pain, NULL)
|
||||
FUNC(A_NoBlocking, NULL)
|
||||
FUNC(A_XScream, NULL)
|
||||
FUNC(A_Look, NULL)
|
||||
FUNC(A_Chase, NULL)
|
||||
FUNC(A_FaceTarget, NULL)
|
||||
FUNC(A_PosAttack, NULL)
|
||||
FUNC(A_Scream, NULL)
|
||||
FUNC(A_SPosAttack, NULL)
|
||||
FUNC(A_SPosAttackUseAtkSound, NULL)
|
||||
FUNC(A_VileChase, NULL)
|
||||
FUNC(A_VileStart, NULL)
|
||||
FUNC(A_VileTarget, NULL)
|
||||
FUNC(A_VileAttack, NULL)
|
||||
FUNC(A_StartFire, NULL)
|
||||
FUNC(A_Fire, NULL)
|
||||
FUNC(A_FireCrackle, NULL)
|
||||
FUNC(A_Tracer, NULL)
|
||||
FUNC(A_SkelWhoosh, NULL)
|
||||
FUNC(A_SkelFist, NULL)
|
||||
FUNC(A_SkelMissile, NULL)
|
||||
FUNC(A_FatRaise, NULL)
|
||||
FUNC(A_FatAttack1, "m")
|
||||
FUNC(A_FatAttack2, "m")
|
||||
FUNC(A_FatAttack3, "m")
|
||||
FUNC(A_BossDeath, NULL)
|
||||
FUNC(A_CPosAttack, NULL)
|
||||
FUNC(A_CPosRefire, NULL)
|
||||
FUNC(A_TroopAttack, NULL)
|
||||
FUNC(A_SargAttack, NULL)
|
||||
FUNC(A_HeadAttack, NULL)
|
||||
FUNC(A_BruisAttack, NULL)
|
||||
FUNC(A_SkullAttack, NULL)
|
||||
FUNC(A_Metal, NULL)
|
||||
FUNC(A_SpidRefire, NULL)
|
||||
FUNC(A_BabyMetal, NULL)
|
||||
FUNC(A_BspiAttack, NULL)
|
||||
FUNC(A_Hoof, NULL)
|
||||
FUNC(A_CyberAttack, NULL)
|
||||
FUNC(A_PainAttack, "m")
|
||||
FUNC(A_DualPainAttack, "m")
|
||||
FUNC(A_PainDie, "m")
|
||||
FUNC(A_KeenDie, NULL)
|
||||
FUNC(A_BrainPain, NULL)
|
||||
FUNC(A_BrainScream, NULL)
|
||||
FUNC(A_BrainDie, NULL)
|
||||
FUNC(A_BrainAwake, NULL)
|
||||
FUNC(A_BrainSpit, NULL)
|
||||
FUNC(A_SpawnSound, NULL)
|
||||
FUNC(A_SpawnFly, NULL)
|
||||
FUNC(A_BrainExplode, NULL)
|
||||
FUNC(A_Die, NULL)
|
||||
FUNC(A_Detonate, NULL)
|
||||
FUNC(A_Mushroom, "mx")
|
||||
|
||||
FUNC(A_SetFloorClip, NULL)
|
||||
FUNC(A_UnSetFloorClip, NULL)
|
||||
FUNC(A_HideThing, NULL)
|
||||
FUNC(A_UnHideThing, NULL)
|
||||
FUNC(A_SetInvulnerable, NULL)
|
||||
FUNC(A_UnSetInvulnerable, NULL)
|
||||
FUNC(A_SetReflective, NULL)
|
||||
FUNC(A_UnSetReflective, NULL)
|
||||
FUNC(A_SetReflectiveInvulnerable, NULL)
|
||||
FUNC(A_UnSetReflectiveInvulnerable, NULL)
|
||||
FUNC(A_SetShootable, NULL)
|
||||
FUNC(A_UnSetShootable, NULL)
|
||||
FUNC(A_NoGravity, NULL)
|
||||
FUNC(A_Gravity, NULL)
|
||||
FUNC(A_LowGravity, NULL)
|
||||
{"A_Fall", A_NoBlocking, NULL}, // Allow Doom's old name, too, for this function
|
||||
FUNC(A_SetSolid, NULL)
|
||||
FUNC(A_UnsetSolid, NULL)
|
||||
FUNC(A_SetFloat, NULL)
|
||||
FUNC(A_UnsetFloat, NULL)
|
||||
|
||||
// For better chainsaw attacks
|
||||
FUNC(A_M_Saw, NULL)
|
||||
|
||||
// some functions from the old DECORATE parser
|
||||
FUNC(A_BulletAttack, NULL)
|
||||
FUNC(A_ScreamAndUnblock, NULL)
|
||||
FUNC(A_ActiveAndUnblock, NULL)
|
||||
FUNC(A_ActiveSound, NULL)
|
||||
|
||||
// useful functions from Hexen
|
||||
FUNC(A_FastChase, NULL)
|
||||
FUNC(A_FreezeDeath, NULL)
|
||||
FUNC(A_FreezeDeathChunks, NULL)
|
||||
FUNC(A_GenericFreezeDeath, NULL)
|
||||
FUNC(A_IceGuyDie, NULL) // useful for bursting a monster into ice chunks without delay
|
||||
FUNC(A_CentaurDefend, NULL)
|
||||
FUNC(A_BishopMissileWeave, NULL)
|
||||
FUNC(A_CStaffMissileSlither, NULL)
|
||||
FUNC(A_PlayerScream, NULL)
|
||||
FUNC(A_SkullPop, "m")
|
||||
FUNC(A_CheckPlayerDone, NULL)
|
||||
|
||||
// useful functions from Strife
|
||||
FUNC(A_Wander, NULL)
|
||||
FUNC(A_Look2, NULL)
|
||||
FUNC(A_TossGib, NULL)
|
||||
FUNC(A_SentinelBob, NULL)
|
||||
FUNC(A_SentinelRefire, NULL)
|
||||
FUNC(A_Tracer2, NULL)
|
||||
FUNC(A_SetShadow, NULL)
|
||||
FUNC(A_ClearShadow, NULL)
|
||||
FUNC(A_GetHurt, NULL)
|
||||
FUNC(A_TurretLook, NULL)
|
||||
FUNC(A_KlaxonBlare, NULL)
|
||||
FUNC(A_Countdown, NULL)
|
||||
FUNC(A_AlertMonsters, NULL)
|
||||
FUNC(A_ClearSoundTarget, NULL)
|
||||
FUNC(A_FireAssaultGun, NULL)
|
||||
FUNC(A_CheckTerrain, NULL )
|
||||
|
||||
// Only selected original weapon functions will be available.
|
||||
// All the attack pointers are somewhat tricky due to the way the flash state is handled
|
||||
FUNC(A_Light, "X")
|
||||
FUNC(A_Light0, NULL)
|
||||
FUNC(A_Light1, NULL)
|
||||
FUNC(A_Light2, NULL)
|
||||
FUNC(A_LightInverse, NULL)
|
||||
FUNC(A_WeaponReady, NULL)
|
||||
FUNC(A_Lower, NULL)
|
||||
FUNC(A_Raise, NULL)
|
||||
FUNC(A_ReFire, NULL)
|
||||
FUNC(A_Punch, NULL)
|
||||
FUNC(A_CheckReload, NULL)
|
||||
FUNC(A_GunFlash, NULL)
|
||||
FUNC(A_Saw, "ssxm")
|
||||
|
||||
// DECORATE specific functions
|
||||
FUNC(A_BulletAttack, NULL)
|
||||
FUNC(A_PlaySound, "S" )
|
||||
FUNC(A_PlayWeaponSound, "S" )
|
||||
FUNC(A_FLoopActiveSound, NULL )
|
||||
FUNC(A_LoopActiveSound, NULL )
|
||||
FUNC(A_StopSound, NULL )
|
||||
FUNC(A_PlaySoundEx, "STi" )
|
||||
FUNC(A_StopSoundEx, "T" )
|
||||
FUNC(A_SeekerMissile, "XX" )
|
||||
FUNC(A_Jump, "XL+" )
|
||||
FUNC(A_CustomMissile, "MXXxxx" )
|
||||
FUNC(A_CustomBulletAttack, "XXXXmx" )
|
||||
FUNC(A_CustomRailgun, "Xxccxxxm" )
|
||||
FUNC(A_JumpIfHealthLower, "XL" )
|
||||
FUNC(A_JumpIfCloser, "XL" )
|
||||
FUNC(A_JumpIfInventory, "MXL" )
|
||||
FUNC(A_GiveInventory, "Mx" )
|
||||
FUNC(A_TakeInventory, "Mx" )
|
||||
FUNC(A_SpawnItem, "Mxxyx" )
|
||||
FUNC(A_SpawnItemEx, "Mxxxxxxxxx" )
|
||||
FUNC(A_ThrowGrenade, "Mxxxy" )
|
||||
FUNC(A_SelectWeapon, "M")
|
||||
FUNC(A_Print, "Txt")
|
||||
FUNC(A_SetTranslucent, "Xx")
|
||||
FUNC(A_FadeIn, "x")
|
||||
FUNC(A_FadeOut, "x")
|
||||
FUNC(A_SpawnDebris, "Mx")
|
||||
FUNC(A_CheckSight, "L")
|
||||
FUNC(A_ExtChase, "XXyx")
|
||||
FUNC(A_DropInventory, "M")
|
||||
FUNC(A_SetBlend, "CXXc")
|
||||
FUNC(A_ChangeFlag, "TX")
|
||||
FUNC(A_JumpIf, "XL")
|
||||
FUNC(A_KillMaster, NULL)
|
||||
FUNC(A_KillChildren, NULL)
|
||||
FUNC(A_CheckFloor, "L")
|
||||
FUNC(A_PlayerSkinCheck, "L")
|
||||
{"A_BasicAttack", A_ComboAttack, "ISMF" },
|
||||
|
||||
// Weapon only functions
|
||||
FUNC(A_JumpIfNoAmmo, "L" )
|
||||
FUNC(A_CustomPunch, "Xxymx" )
|
||||
FUNC(A_FireBullets, "XXXXmyx" )
|
||||
FUNC(A_FireCustomMissile, "Mxyxxx" )
|
||||
FUNC(A_RailAttack, "Xxyccxxm" )
|
||||
FUNC(A_Recoil, "X")
|
||||
FUNC(A_JumpIfInTargetInventory, "MXL" )
|
||||
FUNC(A_GiveToTarget, "Mx" )
|
||||
FUNC(A_TakeFromTarget, "Mx" )
|
||||
FUNC(A_CountdownArg, "X")
|
||||
FUNC(A_CustomMeleeAttack, "Xssty" )
|
||||
FUNC(A_CustomComboAttack, "MXXsty" )
|
||||
FUNC(A_Burst, "M")
|
||||
FUNC(A_RadiusThrust, "xxy")
|
||||
{"A_Explode", A_ExplodeParms, "xxy" },
|
||||
FUNC(A_Stop, NULL)
|
||||
FUNC(A_Respawn, "y")
|
||||
FUNC(A_BarrelDestroy, NULL)
|
||||
FUNC(A_QueueCorpse, NULL)
|
||||
#define WEAPON(x) { "A_" #x, A_##x },
|
||||
#define ACTOR(x) { "A_" #x, A_##x },
|
||||
#include "codepointers.h"
|
||||
#include "d_dehackedactions.h"
|
||||
{ "A_Fall", A_NoBlocking },
|
||||
{ "A_BasicAttack", A_ComboAttack }
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Find a function by name using a binary search
|
||||
|
|
@ -753,7 +446,7 @@ static int STACK_ARGS funccmp(const void * a, const void * b)
|
|||
return stricmp( ((AFuncDesc*)a)->Name, ((AFuncDesc*)b)->Name);
|
||||
}
|
||||
|
||||
static AFuncDesc * FindFunction(char * string)
|
||||
static AFuncDesc * FindFunction(const char * string)
|
||||
{
|
||||
static bool funcsorted=false;
|
||||
|
||||
|
|
@ -1851,24 +1544,15 @@ do_stop:
|
|||
goto endofstate;
|
||||
}
|
||||
|
||||
//AFuncDesc * afd = FindFunction(sc_String);
|
||||
//PSymbolActionFunction *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 = afd->Arguments.Len();
|
||||
AFuncDesc * afd = FindFunction(sc_String);
|
||||
if (afd != NULL)
|
||||
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->parameters !=NULL)
|
||||
if (!afd->Arguments.IsEmpty())
|
||||
{
|
||||
const char * params = afd->parameters;
|
||||
int numparams = (int)strlen(params);
|
||||
const char *params = afd->Arguments.GetChars();
|
||||
int numparams = (int)afd->Arguments.Len();
|
||||
|
||||
int v;
|
||||
|
||||
|
|
@ -2582,7 +2266,9 @@ void ParseGlobalConst()
|
|||
//
|
||||
// ActorActionDef
|
||||
//
|
||||
// Parses an action function definition.
|
||||
// Parses an action function definition. A lot of this is essentially
|
||||
// documentation in the declaration for when I have a proper language
|
||||
// ready.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
|
@ -2592,11 +2278,18 @@ static void ActorActionDef (AActor *defaults, Baggage &bag)
|
|||
#define EVAL 2
|
||||
#define EVALNOT 4
|
||||
|
||||
AFuncDesc *afd;
|
||||
FName funcname;
|
||||
FString args;
|
||||
|
||||
SC_MustGetToken(TK_Native);
|
||||
SC_MustGetToken(TK_Identifier);
|
||||
funcname = sc_Name;
|
||||
afd = FindFunction(sc_String);
|
||||
if (afd == NULL)
|
||||
{
|
||||
SC_ScriptError ("The function '%s' has not been exported from the executable.", sc_String);
|
||||
}
|
||||
SC_MustGetToken('(');
|
||||
if (!SC_CheckToken(')'))
|
||||
{
|
||||
|
|
@ -2628,6 +2321,8 @@ static void ActorActionDef (AActor *defaults, Baggage &bag)
|
|||
break;
|
||||
}
|
||||
}
|
||||
// Read the variable type
|
||||
SC_MustGetAnyToken();
|
||||
switch (sc_TokenType)
|
||||
{
|
||||
case TK_Bool: type = 'i'; break;
|
||||
|
|
@ -2640,11 +2335,7 @@ static void ActorActionDef (AActor *defaults, Baggage &bag)
|
|||
case TK_Color: type = 'c'; break;
|
||||
case TK_Class:
|
||||
SC_MustGetToken('<');
|
||||
SC_MustGetToken(TK_Identifier);
|
||||
if (sc_Name != NAME_Actor)
|
||||
{
|
||||
SC_ScriptError ("Sorry, you can only use class<actor>");
|
||||
}
|
||||
SC_MustGetToken(TK_Identifier); // Skip class name, since the parser doesn't care
|
||||
SC_MustGetToken('>');
|
||||
type = 'm';
|
||||
break;
|
||||
|
|
@ -2657,6 +2348,16 @@ static void ActorActionDef (AActor *defaults, Baggage &bag)
|
|||
SC_ScriptError ("Unknown variable type %s", SC_TokenName(sc_TokenType, sc_String).GetChars());
|
||||
break;
|
||||
}
|
||||
// Read the optional variable name
|
||||
if (!SC_CheckToken(',') && !SC_CheckToken(')'))
|
||||
{
|
||||
SC_MustGetToken(TK_Identifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_UnGet();
|
||||
}
|
||||
// If eval or evalnot were a flag, hey the decorate parser doesn't actually care about the type.
|
||||
if (flags & EVALNOT)
|
||||
{
|
||||
type = 'y';
|
||||
|
|
@ -2665,10 +2366,9 @@ static void ActorActionDef (AActor *defaults, Baggage &bag)
|
|||
{
|
||||
type = 'x';
|
||||
}
|
||||
if (!(flags & OPTIONAL))
|
||||
if (!(flags & OPTIONAL) && type != '+')
|
||||
{
|
||||
type -= 'a' - 'A';
|
||||
break;
|
||||
}
|
||||
#undef OPTIONAL
|
||||
#undef EVAL
|
||||
|
|
@ -2686,7 +2386,7 @@ static void ActorActionDef (AActor *defaults, Baggage &bag)
|
|||
sym->SymbolName = funcname;
|
||||
sym->SymbolType = SYM_ActionFunction;
|
||||
sym->Arguments = args;
|
||||
sym->Function = NULL;
|
||||
sym->Function = afd->Function;
|
||||
if (bag.Info->Class->Symbols.AddSymbol (sym) == NULL)
|
||||
{
|
||||
delete sym;
|
||||
|
|
@ -4579,3 +4279,57 @@ void FinishThingdef()
|
|||
QuestItemClasses[i]=PClass::FindClass(fmt);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ParseClass
|
||||
//
|
||||
// A minimal placeholder so that I can assign properties to some native
|
||||
// classes. Please, no end users use this until it's finalized.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ParseClass()
|
||||
{
|
||||
Baggage bag;
|
||||
const PClass *cls;
|
||||
FName classname;
|
||||
FName supername;
|
||||
|
||||
SC_MustGetToken(TK_Identifier); // class name
|
||||
classname = sc_Name;
|
||||
SC_MustGetToken(TK_Extends); // because I'm not supporting Object
|
||||
SC_MustGetToken(TK_Identifier); // superclass name
|
||||
supername = sc_Name;
|
||||
SC_MustGetToken(TK_Native); // use actor definitions for your own stuff
|
||||
SC_MustGetToken('{');
|
||||
|
||||
cls = PClass::FindClass (classname);
|
||||
if (cls == NULL)
|
||||
{
|
||||
SC_ScriptError ("'%s' is not a native class", classname.GetChars());
|
||||
}
|
||||
if (cls->ParentClass == NULL || cls->ParentClass->TypeName != supername)
|
||||
{
|
||||
SC_ScriptError ("'%s' does not extend '%s'", classname.GetChars(), supername.GetChars());
|
||||
}
|
||||
bag.Info = cls->ActorInfo;
|
||||
|
||||
SC_MustGetAnyToken();
|
||||
while (sc_TokenType != '}')
|
||||
{
|
||||
if (sc_TokenType == TK_Action)
|
||||
{
|
||||
ActorActionDef (0, bag);
|
||||
}
|
||||
else if (sc_TokenType == TK_Const)
|
||||
{
|
||||
ActorConstDef (0, bag);
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_ScriptError ("Expected 'action' or 'const' but got %s", SC_TokenName(sc_TokenType, sc_String));
|
||||
}
|
||||
SC_MustGetAnyToken();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue