- Restructured the action function interface to remove the dependence on

the global CallingState variable.


SVN r1163 (trunk)
This commit is contained in:
Christoph Oelckers 2008-08-12 14:30:07 +00:00
parent b1d36182c4
commit 1957659b1b
34 changed files with 408 additions and 425 deletions

View file

@ -1,4 +1,6 @@
August 12, 2008 (Changes by Graf Zahl)
- Restructured the action function interface to remove the dependence on
the global CallingState variable.
- Changed handling of AUTOPAGE texture so that it is properly inserted into
the texture manager even if it is from Raven's IWADs.
- Removed code related to internal ActorInfo definitions from dobjtype.cpp.

View file

@ -1457,24 +1457,20 @@ static void SetPointer(FState *state, PSymbol *sym)
{
if (sym==NULL)
{
state->Action = NULL;
state->ParameterIndex=0;
state->SetAction(NULL);
}
else switch (sym->SymbolType)
{
case SYM_ActionFunction:
state->Action = static_cast<PSymbolActionFunction*>(sym)->Function;
state->ParameterIndex=0; // No parameters for patched code pointers
state->SetAction(static_cast<PSymbolActionFunction*>(sym));
break;
/*
case SYM_ExternalFunction:
state->Action = A_CallExtFunction;
state->ParameterIndex = static_cast<PSymbolExternalFunction*>(sym->Data);
break;
*/
default:
state->Action = NULL;
state->ParameterIndex=0;
state->SetAction(NULL);
}
}
@ -1498,7 +1494,7 @@ static int PatchPointer (int ptrNum)
{
int index = atoi(Line2);
if ((unsigned)(index) >= (unsigned)NumActions)
state->Action = NULL;
state->SetAction(NULL);
else
{
SetPointer(state, CodePtrSymbols[ActionList[index]]);
@ -1800,7 +1796,7 @@ static int PatchCodePtrs (int dummy)
if (name == -1)
{
state->Action = NULL;
state->SetAction(NULL);
Printf ("Frame %d: Unknown code pointer: %s\n", frame, Line2);
}
else
@ -1821,7 +1817,7 @@ static int PatchCodePtrs (int dummy)
}
if (min > max)
{
state->Action = NULL;
state->SetAction(NULL);
Printf ("Frame %d: Unknown code pointer: %s\n", frame, Line2);
}
else

View file

@ -46,11 +46,14 @@ struct PSymbolConst : public PSymbol
// 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.
struct FState;
typedef void (*actionf_p)(AActor *self, FState *state, int parameters);
struct PSymbolActionFunction : public PSymbol
{
FString Arguments;
void (*Function)(AActor*);
actionf_p Function;
int defaultparameterindex;
};
// A symbol table -----------------------------------------------------------

View file

@ -40,8 +40,7 @@
class AActor;
class player_t;
struct pspdef_s;
typedef void (*actionf_p)( AActor* );
struct FState;
class FThinkerIterator;

View file

@ -76,7 +76,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainDie)
G_ExitLevel (0, false);
}
DEFINE_ACTION_FUNCTION(AActor, A_BrainSpit)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit)
{
DSpotState *state = DSpotState::GetSpotState();
AActor *targ;
@ -88,7 +88,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainSpit)
if (targ != NULL)
{
const PClass *spawntype = NULL;
int index = CheckIndex (1, NULL);
int index = CheckIndex (1);
if (index >= 0) spawntype = PClass::FindClass ((ENamedName)StateParameters[index]);
if (spawntype == NULL) spawntype = PClass::FindClass("SpawnShot");
@ -129,7 +129,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainSpit)
}
}
DEFINE_ACTION_FUNCTION(AActor, A_SpawnFly)
static void SpawnFly(AActor *self, const PClass *spawntype, FSoundID sound)
{
AActor *newmobj;
AActor *fog;
@ -143,22 +143,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnFly)
targ = self->target;
const PClass *spawntype = NULL;
int index = CheckIndex (1, NULL);
// First spawn teleport fire.
if (index >= 0)
{
spawntype = PClass::FindClass ((ENamedName)StateParameters[index]);
if (spawntype != NULL)
{
fog = Spawn (spawntype, targ->x, targ->y, targ->z, ALLOW_REPLACE);
if (fog != NULL) S_Sound (fog, CHAN_BODY, fog->SeeSound, 1, ATTN_NORM);
}
}
else
{
fog = Spawn("SpawnFire", targ->x, targ->y, targ->z, ALLOW_REPLACE);
if (fog != NULL) S_Sound (fog, CHAN_BODY, "brain/spawn", 1, ATTN_NORM);
if (fog != NULL) S_Sound (fog, CHAN_BODY, sound, 1, ATTN_NORM);
}
FName SpawnName;
@ -245,9 +233,29 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnFly)
self->Destroy ();
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnFly)
{
const PClass *spawntype = NULL;
FSoundID sound;
int index = CheckIndex (1);
// First spawn teleport fire.
if (index >= 0)
{
spawntype = PClass::FindClass ((ENamedName)StateParameters[index]);
if (spawntype != NULL) sound = GetDefaultByType(spawntype)->SeeSound;
}
else
{
spawntype = PClass::FindClass ("SpawnFire");
sound = "brain/spawn";
}
SpawnFly(self, spawntype, sound);
}
// travelling cube sound
DEFINE_ACTION_FUNCTION(AActor, A_SpawnSound)
{
S_Sound (self, CHAN_BODY, "brain/cube", 1, ATTN_IDLE);
CALL_ACTION(A_SpawnFly, self);
SpawnFly(self, PClass::FindClass("SpawnFire"), "brain/spawn");
}

View file

@ -96,7 +96,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePistol)
//
// A_Saw
//
DEFINE_ACTION_FUNCTION(AActor, A_Saw)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
{
angle_t angle;
int damage=0;
@ -119,7 +119,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Saw)
return;
}
int index = CheckIndex (4, NULL);
int index = CheckIndex (4);
if (index >= 0)
{
fullsound = FSoundID(StateParameters[index]);
@ -487,7 +487,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBFG)
// A_BFGSpray
// Spawn a BFG explosion on every monster in view
//
DEFINE_ACTION_FUNCTION(AActor, A_BFGSpray)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
{
int i;
int j;
@ -499,7 +499,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BFGSpray)
int damagecnt = 15;
AActor *linetarget;
int index = CheckIndex (3, NULL);
int index = CheckIndex (3);
if (index >= 0)
{
spraytype = PClass::FindClass ((ENamedName)StateParameters[index]);

View file

@ -21,7 +21,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FatRaise)
S_Sound (self, CHAN_WEAPON, "fatso/raiseguns", 1, ATTN_NORM);
}
DEFINE_ACTION_FUNCTION(AActor, A_FatAttack1)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1)
{
AActor *missile;
angle_t an;
@ -30,7 +30,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FatAttack1)
return;
const PClass *spawntype = NULL;
int index = CheckIndex (1, NULL);
int index = CheckIndex (1);
if (index >= 0) spawntype = PClass::FindClass ((ENamedName)StateParameters[index]);
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
@ -49,7 +49,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FatAttack1)
}
}
DEFINE_ACTION_FUNCTION(AActor, A_FatAttack2)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2)
{
AActor *missile;
angle_t an;
@ -58,7 +58,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FatAttack2)
return;
const PClass *spawntype = NULL;
int index = CheckIndex (1, NULL);
int index = CheckIndex (1);
if (index >= 0) spawntype = PClass::FindClass ((ENamedName)StateParameters[index]);
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
@ -77,7 +77,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FatAttack2)
}
}
DEFINE_ACTION_FUNCTION(AActor, A_FatAttack3)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3)
{
AActor *missile;
angle_t an;
@ -86,7 +86,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FatAttack3)
return;
const PClass *spawntype = NULL;
int index = CheckIndex (1, NULL);
int index = CheckIndex (1);
if (index >= 0) spawntype = PClass::FindClass ((ENamedName)StateParameters[index]);
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
@ -116,12 +116,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FatAttack3)
// Original idea: Linguica
//
DEFINE_ACTION_FUNCTION(AActor, A_Mushroom)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom)
{
int i, j, n = self->GetMissileDamage (0, 1);
const PClass *spawntype = NULL;
int index = CheckIndex (2, NULL);
int index = CheckIndex (2);
if (index >= 0)
{
spawntype = PClass::FindClass((ENamedName)StateParameters[index]);

View file

@ -19,40 +19,45 @@
//
#define SKULLSPEED (20*FRACUNIT)
DEFINE_ACTION_FUNCTION(AActor, A_SkullAttack)
void A_SkullAttack(AActor *self, fixed_t speed)
{
AActor *dest;
angle_t an;
int dist;
int n;
if (!self->target)
return;
int index = CheckIndex (1, NULL);
if (index >= 0)
{
n = FLOAT2FIXED(EvalExpressionF (StateParameters[index], self));
if (n == 0) n = SKULLSPEED;
}
else n = SKULLSPEED;
dest = self->target;
self->flags |= MF_SKULLFLY;
S_Sound (self, CHAN_VOICE, self->AttackSound, 1, ATTN_NORM);
A_FaceTarget (self);
an = self->angle >> ANGLETOFINESHIFT;
self->momx = FixedMul (n, finecosine[an]);
self->momy = FixedMul (n, finesine[an]);
self->momx = FixedMul (speed, finecosine[an]);
self->momy = FixedMul (speed, finesine[an]);
dist = P_AproxDistance (dest->x - self->x, dest->y - self->y);
dist = dist / n;
dist = dist / speed;
if (dist < 1)
dist = 1;
self->momz = (dest->z+(dest->height>>1) - self->z) / dist;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullAttack)
{
int n;
int index = CheckIndex (1);
if (index >= 0)
{
n = FLOAT2FIXED(EvalExpressionF (StateParameters[index], self));
if (n == 0) n = SKULLSPEED;
}
else n = SKULLSPEED;
A_SkullAttack(self, n);
}
//==========================================================================
//
// CVAR transsouls

View file

@ -10,10 +10,10 @@
DECLARE_ACTION(A_SkullAttack)
static const PClass *GetSpawnType()
static const PClass *GetSpawnType(DECLARE_PARAMINFO)
{
const PClass *spawntype = NULL;
int index=CheckIndex(1, NULL);
int index=CheckIndex(1);
if (index>=0)
{
spawntype = PClass::FindClass((ENamedName)StateParameters[index]);
@ -23,6 +23,9 @@ static const PClass *GetSpawnType()
}
#define SKULLSPEED (20*FRACUNIT)
void A_SkullAttack(AActor *self, fixed_t speed);
//
// A_PainShootSkull
// Spawn a lost soul and launch it at the target
@ -127,7 +130,7 @@ void A_PainShootSkull (AActor *self, angle_t angle, const PClass *spawntype)
// [RH] Lost souls hate the same things as their pain elementals
other->CopyFriendliness (self, true);
CALL_ACTION(A_SkullAttack, other);
A_SkullAttack(other, SKULLSPEED);
}
@ -135,34 +138,34 @@ void A_PainShootSkull (AActor *self, angle_t angle, const PClass *spawntype)
// A_PainAttack
// Spawn a lost soul and launch it at the target
//
DEFINE_ACTION_FUNCTION(AActor, A_PainAttack)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainAttack)
{
if (!self->target)
return;
const PClass *spawntype = GetSpawnType();
const PClass *spawntype = GetSpawnType(PUSH_PARAMINFO);
A_FaceTarget (self);
A_PainShootSkull (self, self->angle, spawntype);
}
DEFINE_ACTION_FUNCTION(AActor, A_DualPainAttack)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DualPainAttack)
{
if (!self->target)
return;
const PClass *spawntype = GetSpawnType();
const PClass *spawntype = GetSpawnType(PUSH_PARAMINFO);
A_FaceTarget (self);
A_PainShootSkull (self, self->angle + ANG45, spawntype);
A_PainShootSkull (self, self->angle - ANG45, spawntype);
}
DEFINE_ACTION_FUNCTION(AActor, A_PainDie)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainDie)
{
if (self->target != NULL && self->IsFriend (self->target))
{ // And I thought you were my friend!
self->flags &= ~MF_FRIENDLY;
}
const PClass *spawntype = GetSpawnType();
const PClass *spawntype = GetSpawnType(PUSH_PARAMINFO);
CALL_ACTION(A_NoBlocking, self);
A_PainShootSkull (self, self->angle + ANG90, spawntype);
A_PainShootSkull (self, self->angle + ANG180, spawntype);

View file

@ -325,7 +325,7 @@ static void MarinePunch(AActor *self, int damagemul)
}
}
DEFINE_ACTION_FUNCTION(AActor, A_M_Punch)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Punch)
{
int index=CheckIndex(1);
if (index<0) return;
@ -361,7 +361,7 @@ void P_GunShot2 (AActor *mo, bool accurate, int pitch, const PClass *pufftype)
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_M_FirePistol)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FirePistol)
{
if (self->target == NULL)
return;
@ -451,7 +451,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun2)
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_M_FireCGun)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FireCGun)
{
if (self->target == NULL)
return;

View file

@ -49,7 +49,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_TimeBomb)
self->z += 32*FRACUNIT;
self->RenderStyle = STYLE_Add;
self->alpha = FRACUNIT;
CALL_ACTION(A_Explode, self);
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, true);
if (self->z <= self->floorz + (128<<FRACBITS))
{
P_HitFloor (self);
}
}
class AArtiTimeBomb : public AInventory

View file

@ -59,7 +59,7 @@ extern bool P_AutoUseChaosDevice (player_t *player);
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_StaffAttack)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack)
{
angle_t angle;
int damage;
@ -72,7 +72,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_StaffAttack)
return;
}
int index = CheckIndex (2, NULL);
int index = CheckIndex (2);
if (index < 0) return;
damage = EvalExpressionI (StateParameters[index], self);
@ -233,7 +233,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL2)
//
//---------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_GauntletAttack)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
{
angle_t angle;
int damage;
@ -250,7 +250,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_GauntletAttack)
return;
}
int index = CheckIndex (1, NULL);
int index = CheckIndex (1);
if (index < 0) return;
power = EvalExpressionI (StateParameters[index], self);

View file

@ -60,7 +60,7 @@ bool AFighterWeaponPiece::TryPickup (AActor *toucher)
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_DropWeaponPieces)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces)
{
int index=CheckIndex(3);
if (index<0) return;

View file

@ -100,10 +100,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_BridgeOrbit)
}
static const PClass *GetBallType()
static const PClass *GetBallType(DECLARE_PARAMINFO)
{
const PClass *balltype = NULL;
int index=CheckIndex(1, NULL);
int index=CheckIndex(1);
if (index>=0)
{
balltype = PClass::FindClass((ENamedName)StateParameters[index]);
@ -114,7 +114,7 @@ static const PClass *GetBallType()
DEFINE_ACTION_FUNCTION(AActor, A_BridgeInit)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit)
{
angle_t startangle;
AActor *ball;
@ -128,7 +128,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BridgeInit)
// Spawn triad into world -- may be more than a triad now.
int ballcount = self->args[2]==0 ? 3 : self->args[2];
const PClass *balltype = GetBallType();
const PClass *balltype = GetBallType(PUSH_PARAMINFO);
for (int i = 0; i < ballcount; i++)
{
ball = Spawn(balltype, cx, cy, cz, ALLOW_REPLACE);

View file

@ -381,7 +381,7 @@ void ASpecialSpot::Destroy()
// will build a list of all mace spots in the level and spawn a
// mace. The rest of the spots will do nothing.
DEFINE_ACTION_FUNCTION(AActor, A_SpawnSingleItem)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnSingleItem)
{
AActor *spot = NULL;
DSpotState *state = DSpotState::GetSpotState();

View file

@ -750,21 +750,9 @@ bool FWeaponSlots::LocateWeapon (const PClass *type, int *const slot, int *const
static bool FindMostRecentWeapon (player_t *player, int *slot, int *index)
{
if (player->PendingWeapon != WP_NOCHANGE)
{
if (player->psprites[ps_weapon].state != NULL &&
player->psprites[ps_weapon].state->GetAction() == GET_ACTION(A_Raise))
{
if (LocalWeapons.LocateWeapon (player->PendingWeapon->GetClass(), slot, index))
{
return true;
}
return false;
}
else
{
return LocalWeapons.LocateWeapon (player->PendingWeapon->GetClass(), slot, index);
}
}
else if (player->ReadyWeapon != NULL)
{
AWeapon *weap = player->ReadyWeapon;

View file

@ -211,7 +211,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShowElectricFlash)
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_FireArrow)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireArrow)
{
angle_t savedangle;
@ -632,7 +632,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Burnination)
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_FireGrenade)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade)
{
const PClass *grenadetype;
player_t *player = self->player;

View file

@ -25,7 +25,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Bang4Cloud)
// -------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_GiveQuestItem)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GiveQuestItem)
{
int index=CheckIndex(1);
if (index<0) return;

View file

@ -81,6 +81,10 @@
const BYTE SF_FULLBRIGHT = 0x40;
struct Baggage;
class FScanner;
struct FActorInfo;
struct FState
{
WORD sprite;
@ -88,8 +92,8 @@ struct FState
SBYTE Misc1;
BYTE Misc2;
BYTE Frame;
actionf_p Action;
FState *NextState;
actionf_p ActionFunc;
int ParameterIndex;
inline int GetFrame() const
@ -116,15 +120,35 @@ struct FState
{
return NextState;
}
inline actionf_p GetAction() const
{
return Action;
}
inline void SetFrame(BYTE frame)
{
Frame = (Frame & SF_FULLBRIGHT) | (frame-'A');
}
void SetAction(PSymbolActionFunction *func, bool setdefaultparams = true)
{
if (func != NULL)
{
ActionFunc = func->Function;
if (setdefaultparams) ParameterIndex = func->defaultparameterindex+1;
}
else
{
ActionFunc = NULL;
if (setdefaultparams) ParameterIndex = 0;
}
}
inline bool CallAction(AActor *self)
{
if (ActionFunc != NULL)
{
ActionFunc(self, this, ParameterIndex);
return true;
}
else
{
return false;
}
}
static const PClass *StaticFindStateOwner (const FState *state);
static const PClass *StaticFindStateOwner (const FState *state, const FActorInfo *info);
};

View file

@ -2231,9 +2231,9 @@ enum ChaseFlags
CHF_DONTMOVE = 16,
};
DEFINE_ACTION_FUNCTION(AActor, A_Chase)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Chase)
{
int index=CheckIndex(3, &CallingState);
int index=CheckIndex(3);
if (index>=0)
{
int flags = EvalExpressionI (StateParameters[index+2], self);
@ -2262,10 +2262,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_VileChase)
A_DoChase (self, false, self->MeleeState, self->MissileState, true, !!(gameinfo.gametype & GAME_Raven), false);
}
DEFINE_ACTION_FUNCTION(AActor, A_ExtChase)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ExtChase)
{
// Now that A_Chase can handle state label parameters, this function has become rather useless...
int index=CheckIndex(4, &CallingState);
int index=CheckIndex(4);
if (index<0) return;
A_DoChase(self, false,
@ -2378,6 +2378,44 @@ DEFINE_ACTION_FUNCTION(AActor, A_XScream)
S_Sound (self, CHAN_VOICE, "misc/gibbed", 1, ATTN_NORM);
}
//===========================================================================
//
// A_ScreamAndUnblock
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_ScreamAndUnblock)
{
CALL_ACTION(A_Scream, self);
CALL_ACTION(A_NoBlocking, self);
}
//===========================================================================
//
// A_ActiveSound
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_ActiveSound)
{
if (self->ActiveSound)
{
S_Sound (self, CHAN_VOICE, self->ActiveSound, 1, ATTN_NORM);
}
}
//===========================================================================
//
// A_ActiveAndUnblock
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_ActiveAndUnblock)
{
CALL_ACTION(A_ActiveSound, self);
CALL_ACTION(A_NoBlocking, self);
}
//---------------------------------------------------------------------------
//
// Modifies the drop amount of this item according to the current skill's
@ -2549,11 +2587,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_Pain)
}
// killough 11/98: kill an object
DEFINE_ACTION_FUNCTION(AActor, A_Die)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Die)
{
ENamedName name;
int index=CheckIndex(1, &CallingState);
int index=CheckIndex(1);
if (index<0)
{
name = NAME_None;

View file

@ -41,7 +41,6 @@ DECLARE_ACTION(A_BossDeath)
DECLARE_ACTION(A_Pain)
DECLARE_ACTION(A_MonsterRail)
DECLARE_ACTION(A_NoBlocking)
DECLARE_ACTION(A_Explode)
DECLARE_ACTION(A_Scream)
DECLARE_ACTION(A_FreezeDeath)
DECLARE_ACTION(A_FreezeDeathChunks)

View file

@ -713,9 +713,9 @@ enum LO_Flags
LOF_FULLVOLSEESOUND = 16,
};
DEFINE_ACTION_FUNCTION(AActor, A_LookEx)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LookEx)
{
int index=CheckIndex(6, &CallingState);
int index=CheckIndex(6);
if (index<0) return;
int flags = EvalExpressionI (StateParameters[index], self);

View file

@ -517,17 +517,8 @@ bool AActor::SetState (FState *newstate)
}
}
if (newstate->GetAction())
if (newstate->CallAction(this))
{
// The parameterized action functions need access to the current state and
// if a function is supposed to work with both actors and weapons
// there is no real means to get to it reliably so I store it in a global variable here.
// Yes, I know this is truly awful but it is the only method I can think of
// that does not involve changing stuff throughout the code.
// Of course this should be rewritten ASAP.
CallingState = newstate;
newstate->GetAction() (this);
// Check whether the called action function resulted in destroying the actor
if (ObjectFlags & OF_EuthanizeMe)
return false;

View file

@ -83,7 +83,7 @@ void P_SetPsprite (player_t *player, int position, FState *state)
psp->state = state;
if (sv_fastweapons >= 2 && position == ps_weapon)
psp->tics = (state->Action == NULL) ? 0 : 1;
psp->tics = state->ActionFunc == NULL? 0 : 1;
else if (sv_fastweapons)
psp->tics = 1; // great for producing decals :)
else
@ -98,25 +98,17 @@ void P_SetPsprite (player_t *player, int position, FState *state)
psp->sy = state->GetMisc2()<<FRACBITS;
}
if (state->GetAction())
{
// The parameterized action functions need access to the current state and
// if a function is supposed to work with both actors and weapons
// there is no real means to get to it reliably so I store it in a global variable here.
// Yes, I know this is truly awful but it is the only method I can think of
// that does not involve changing stuff throughout the code.
// Of course this should be rewritten ASAP.
CallingState = state;
// Call action routine.
if (player->mo != NULL)
{
state->GetAction() (player->mo);
}
if (state->CallAction(player->mo))
{
if (!psp->state)
{
break;
}
}
}
state = psp->state->GetNextState();
} while (!psp->tics); // An initial state of 0 could cycle through.
}
@ -713,9 +705,9 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Light2)
}
}
DEFINE_ACTION_FUNCTION(AInventory, A_Light)
DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_Light)
{
int index=CheckIndex(1, &CallingState);
int index=CheckIndex(1);
if (self->player != NULL && index > 0)
{

View file

@ -1237,14 +1237,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_PlayerScream)
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_SkullPop)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullPop)
{
APlayerPawn *mo;
player_t *player;
// [GRB] Parameterized version
const PClass *spawntype = NULL;
int index = CheckIndex (1, NULL);
int index = CheckIndex (1);
if (index >= 0)
spawntype = PClass::FindClass((ENamedName)StateParameters[index]);
if (!spawntype || !spawntype->IsDescendantOf (RUNTIME_CLASS (APlayerChunk)))

View file

@ -100,9 +100,7 @@ IMPLEMENT_CLASS (AFakeInventory)
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
DECLARE_ACTION(A_ScreamAndUnblock)
DECLARE_ACTION(A_ActiveAndUnblock)
DECLARE_ACTION(A_ActiveSound)
PSymbolActionFunction *FindGlobalActionFunction(const char *name);
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
@ -367,24 +365,24 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
{
if (extra.bExplosive)
{
info->OwnedStates[extra.DeathStart].Action = GET_ACTION(A_Explode);
info->OwnedStates[extra.DeathStart].SetAction(FindGlobalActionFunction("A_Explode"));
}
}
else
{
// The first frame plays the death sound and
// the second frame makes it nonsolid.
info->OwnedStates[extra.DeathStart].Action= GET_ACTION(A_Scream);
info->OwnedStates[extra.DeathStart].SetAction(FindGlobalActionFunction("A_Scream"));
if (extra.bSolidOnDeath)
{
}
else if (extra.DeathStart + 1 < extra.DeathEnd)
{
info->OwnedStates[extra.DeathStart+1].Action = GET_ACTION(A_NoBlocking);
info->OwnedStates[extra.DeathStart+1].SetAction(FindGlobalActionFunction("A_NoBlocking"));
}
else
{
info->OwnedStates[extra.DeathStart].Action = GET_ACTION(A_ScreamAndUnblock);
info->OwnedStates[extra.DeathStart].SetAction(FindGlobalActionFunction("A_ScreamAndUnblock"));
}
if (extra.DeathHeight == 0) extra.DeathHeight = ((AActor*)(type->Defaults))->height;
@ -412,17 +410,17 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
// The first frame plays the burn sound and
// the second frame makes it nonsolid.
info->OwnedStates[extra.FireDeathStart].Action = GET_ACTION(A_ActiveSound);
info->OwnedStates[extra.FireDeathStart].SetAction(FindGlobalActionFunction("A_ActiveSound"));
if (extra.bSolidOnBurn)
{
}
else if (extra.FireDeathStart + 1 < extra.FireDeathEnd)
{
info->OwnedStates[extra.FireDeathStart+1].Action = GET_ACTION(A_NoBlocking);
info->OwnedStates[extra.FireDeathStart+1].SetAction(FindGlobalActionFunction("A_NoBlocking"));
}
else
{
info->OwnedStates[extra.FireDeathStart].Action = GET_ACTION(A_ActiveAndUnblock);
info->OwnedStates[extra.FireDeathStart].SetAction(FindGlobalActionFunction("A_ActiveAndUnblock"));
}
if (extra.BurnHeight == 0) extra.BurnHeight = ((AActor*)(type->Defaults))->height;
@ -442,13 +440,13 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
info->OwnedStates[i].NextState = &info->OwnedStates[info->NumOwnedStates-1];
info->OwnedStates[i].Tics = 5;
info->OwnedStates[i].Misc1 = 0;
info->OwnedStates[i].Action = GET_ACTION(A_FreezeDeath);
info->OwnedStates[i].SetAction(FindGlobalActionFunction("A_FreezeDeath"));
i = info->NumOwnedStates - 1;
info->OwnedStates[i].NextState = &info->OwnedStates[i];
info->OwnedStates[i].Tics = 1;
info->OwnedStates[i].Misc1 = 0;
info->OwnedStates[i].Action = GET_ACTION(A_FreezeDeathChunks);
info->OwnedStates[i].SetAction(FindGlobalActionFunction("A_FreezeDeathChunks"));
AddState("Ice", &info->OwnedStates[extra.IceDeathStart]);
}
else if (extra.bGenericIceDeath)
@ -859,40 +857,3 @@ static void ParseSpriteFrames (FActorInfo *info, TArray<FState> &states, FScanne
}
}
//===========================================================================
//
// A_ScreamAndUnblock
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_ScreamAndUnblock)
{
CALL_ACTION(A_Scream, self);
CALL_ACTION(A_NoBlocking, self);
}
//===========================================================================
//
// A_ActiveAndUnblock
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_ActiveAndUnblock)
{
CALL_ACTION(A_ActiveSound, self);
CALL_ACTION(A_NoBlocking, self);
}
//===========================================================================
//
// A_ActiveSound
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_ActiveSound)
{
if (self->ActiveSound)
{
S_Sound (self, CHAN_VOICE, self->ActiveSound, 1, ATTN_NORM);
}
}

View file

@ -265,6 +265,7 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
sym->SymbolType = SYM_ActionFunction;
sym->Arguments = args;
sym->Function = afd->Function;
sym->defaultparameterindex = -1;
if (cls->Symbols.AddSymbol (sym) == NULL)
{
delete sym;

View file

@ -84,6 +84,7 @@ struct AFuncDesc
AFuncDesc * FindFunction(const char * string);
//==========================================================================
//
// State parser
@ -125,11 +126,6 @@ float EvalExpressionF (int id, AActor *self, const PClass *cls=NULL);
bool EvalExpressionN (int id, AActor *self, const PClass *cls=NULL);
// A truly awful hack to get to the state that called an action function
// without knowing whether it has been called from a weapon or actor.
extern FState * CallingState;
int CheckIndex(int paramsize, FState ** pcallstate=NULL);
enum
{
ACMETA_BASE = 0x83000,
@ -167,42 +163,53 @@ enum EDefinitionType
// Macros to handle action functions. These are here so that I don't have to
// change every single use in case the parameters change.
#define DECLARE_ACTION(name) void AF_##name(AActor *self);
#define DECLARE_ACTION(name) void AF_##name(AActor *self, FState *, int);
// This distinction is here so that CALL_ACTION produces errors when trying to
// access a function that requires parameters.
#define DEFINE_ACTION_FUNCTION(cls, name) \
void AF_##name (AActor *); \
void AF_##name (AActor *self, FState *, int); \
AFuncDesc info_##cls##_##name = { #name, AF_##name }; \
MSVC_ASEG AFuncDesc *infoptr_##cls##_##name GCC_ASEG = &info_##cls##_##name; \
void AF_##name (AActor *self)
void AF_##name (AActor *self, FState *, int)
#define CALL_ACTION(name,self) AF_##name(self)
#define GET_ACTION(name) AF_##name
#define DEFINE_ACTION_FUNCTION_PARAMS(cls, name) \
void AFP_##name (AActor *self, FState *CallingState, int ParameterIndex); \
AFuncDesc info_##cls##_##name = { #name, AFP_##name }; \
MSVC_ASEG AFuncDesc *infoptr_##cls##_##name GCC_ASEG = &info_##cls##_##name; \
void AFP_##name (AActor *self, FState *CallingState, int ParameterIndex)
#define DECLARE_PARAMINFO FState *CallingState, int ParameterIndex
#define PUSH_PARAMINFO CallingState, ParameterIndex
#define CALL_ACTION(name,self) AF_##name(self, NULL, 0)
#define CheckIndex(count) (ParameterIndex-1)
#define ACTION_PARAM_START(count) \
int index = CheckIndex(count); \
if (index <= 0) return;
int ap_index_ = CheckIndex(count); \
if (ap_index_ <= 0) return;
#define ACTION_PARAM_START_OPTIONAL(count) \
int index = CheckIndex(count);
#define ACTION_INT_PARAM(var) \
int var = EvalExpressionI(StateParameters[index++], self);
#define ACTION_BOOL_PARAM(var) \
bool var = !!EvalExpressionI(StateParameters[index++], self);
#define ACTION_NOT_BOOL_PARAM(var) \
bool var = EvalExpressionN(StateParameters[index++], self);
#define ACTION_FIXED_PARAM(var) \
fixed_t var = fixed_t(EvalExpressionF(StateParameters[index++], self)*65536.f);
#define ACTION_FLOAT_PARAM(var) \
float var = EvalExpressionF(StateParameters[index++], self);
#define ACTION_CLASS_PARAM(var) \
const PClass *var = PClass::FindClass(ENamedName(StateParameters[index++]));
#define ACTION_STATE_PARAM(var) \
int var = StateParameters[index++];
#define ACTION_SOUND_PARAM(var) \
FSoundID var = StateParameters[index++];
#define ACTION_STRING_PARAM(var) \
const char *var = FName(ENamedName(StateParameters[index++]));
int ap_index_ = CheckIndex(count);
#define ACTION_PARAM_INT(var) \
int var = EvalExpressionI(StateParameters[ap_index_++], self);
#define ACTION_PARAM_BOOL(var) \
bool var = !!EvalExpressionI(StateParameters[ap_index_++], self);
#define ACTION_PARAM_NOT_BOOL(var) \
bool var = EvalExpressionN(StateParameters[ap_index_++], self);
#define ACTION_PARAM_FIXED(var) \
fixed_t var = fixed_t(EvalExpressionF(StateParameters[ap_index_++], self)*65536.f);
#define ACTION_PARAM_FLOAT(var) \
float var = EvalExpressionF(StateParameters[ap_index_++], self);
#define ACTION_PARAM_CLASS(var) \
const PClass *var = PClass::FindClass(ENamedName(StateParameters[ap_index_++]));
#define ACTION_PARAM_STATE(var) \
int var = StateParameters[ap_index_++];
#define ACTION_PARAM_SOUND(var) \
FSoundID var = StateParameters[ap_index_++];
#define ACTION_PARAM_STRING(var) \
const char *var = FName(ENamedName(StateParameters[ap_index_++]));
#endif

View file

@ -82,7 +82,6 @@ static FRandom pr_burst ("Burst");
// A truly awful hack to get to the state that called an action function
// without knowing whether it has been called from a weapon or actor.
FState * CallingState;
struct StateCallData
{
@ -114,11 +113,10 @@ bool ACustomInventory::CallStateChain (AActor *actor, FState * State)
while (State != NULL)
{
// Assume success. The code pointer will set this to false if necessary
CallingState = StateCall.State = State;
if (State->GetAction() != NULL)
{
StateCall.State = State;
StateCall.Result = true;
State->GetAction() (actor);
if (State->CallAction(actor))
{
// collect all the results. Even one successful call signifies overall success.
result |= StateCall.Result;
}
@ -150,23 +148,6 @@ bool ACustomInventory::CallStateChain (AActor *actor, FState * State)
return result;
}
//==========================================================================
//
// Let's isolate all handling of CallingState in this one place
// so that removing it later becomes easier
//
//==========================================================================
int CheckIndex(int paramsize, FState ** pcallstate)
{
if (CallingState->ParameterIndex == 0) return -1;
unsigned int index = (unsigned int) CallingState->ParameterIndex-1;
if (index > StateParameters.Size()-paramsize) return -1;
if (pcallstate) *pcallstate=CallingState;
return index;
}
//==========================================================================
//
// Simple flag changers
@ -195,34 +176,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_UnsetFloat)
//==========================================================================
//
// Customizable attack functions which use actor parameters.
// I think this is among the most requested stuff ever ;-)
//
//==========================================================================
static void DoAttack (AActor *self, bool domelee, bool domissile)
static void DoAttack (AActor *self, bool domelee, bool domissile,
int MeleeDamage, FSoundID MeleeSound, const PClass *MissileType,fixed_t MissileHeight)
{
int index=CheckIndex(4);
int MeleeDamage;
int MeleeSound;
FName MissileName;
fixed_t MissileHeight;
if (self->target == NULL) return;
if (index > 0)
{
MeleeDamage=EvalExpressionI(StateParameters[index], self);
MeleeSound=StateParameters[index+1];
MissileName=(ENamedName)StateParameters[index+2];
MissileHeight=fixed_t(EvalExpressionF(StateParameters[index+3], self)/65536.f);
}
else
{
MeleeDamage = self->GetClass()->Meta.GetMetaInt (ACMETA_MeleeDamage, 0);
MeleeSound = self->GetClass()->Meta.GetMetaInt (ACMETA_MeleeSound, 0);
MissileName=(ENamedName) self->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_None);
MissileHeight= self->GetClass()->Meta.GetMetaFixed (ACMETA_MissileHeight, 32*FRACUNIT);
}
A_FaceTarget (self);
if (domelee && MeleeDamage>0 && self->CheckMeleeRange ())
{
@ -231,14 +191,11 @@ static void DoAttack (AActor *self, bool domelee, bool domissile)
P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (damage, self->target, self);
}
else if (domissile && MissileName != NAME_None)
{
const PClass * ti=PClass::FindClass(MissileName);
if (ti)
else if (domissile && MissileType != NULL)
{
// This seemingly senseless code is needed for proper aiming.
self->z+=MissileHeight-32*FRACUNIT;
AActor * missile = P_SpawnMissileXYZ (self->x, self->y, self->z + 32*FRACUNIT, self, self->target, ti, false);
AActor * missile = P_SpawnMissileXYZ (self->x, self->y, self->z + 32*FRACUNIT, self, self->target, MissileType, false);
self->z-=MissileHeight-32*FRACUNIT;
if (missile)
@ -257,26 +214,42 @@ static void DoAttack (AActor *self, bool domelee, bool domissile)
}
}
}
}
DEFINE_ACTION_FUNCTION(AActor, A_MeleeAttack)
{
DoAttack(self, true, false);
int MeleeDamage = self->GetClass()->Meta.GetMetaInt (ACMETA_MeleeDamage, 0);
FSoundID MeleeSound = self->GetClass()->Meta.GetMetaInt (ACMETA_MeleeSound, 0);
DoAttack(self, true, false, MeleeDamage, MeleeSound, NULL, 0);
}
DEFINE_ACTION_FUNCTION(AActor, A_MissileAttack)
{
DoAttack(self, false, true);
const PClass *MissileType=PClass::FindClass((ENamedName) self->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_None));
fixed_t MissileHeight= self->GetClass()->Meta.GetMetaFixed (ACMETA_MissileHeight, 32*FRACUNIT);
DoAttack(self, false, true, 0, 0, MissileType, MissileHeight);
}
DEFINE_ACTION_FUNCTION(AActor, A_ComboAttack)
{
DoAttack(self, true, true);
int MeleeDamage = self->GetClass()->Meta.GetMetaInt (ACMETA_MeleeDamage, 0);
FSoundID MeleeSound = self->GetClass()->Meta.GetMetaInt (ACMETA_MeleeSound, 0);
const PClass *MissileType=PClass::FindClass((ENamedName) self->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_None));
fixed_t MissileHeight= self->GetClass()->Meta.GetMetaFixed (ACMETA_MissileHeight, 32*FRACUNIT);
DoAttack(self, true, true, MeleeDamage, MeleeSound, MissileType, MissileHeight);
}
DEFINE_ACTION_FUNCTION(AActor, A_BasicAttack)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BasicAttack)
{
DoAttack(self, true, true);
int index=CheckIndex(4);
if (index > 0)
{
int MeleeDamage=EvalExpressionI(StateParameters[index], self);
FSoundID MeleeSound=StateParameters[index+1];
const PClass *MissileType=PClass::FindClass((ENamedName)StateParameters[index+2]);
fixed_t MissileHeight=fixed_t(EvalExpressionF(StateParameters[index+3], self)/65536.f);
DoAttack(self, true, true, MeleeDamage, MeleeSound, MissileType, MissileHeight);
}
}
//==========================================================================
@ -286,23 +259,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_BasicAttack)
// misc field directly so they can be used in weapon states
//
//==========================================================================
static void DoPlaySound(AActor * self, int channel)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PlaySound)
{
int index=CheckIndex(1);
if (index<0) return;
int soundid = StateParameters[index];
S_Sound (self, channel, soundid, 1, ATTN_NORM);
S_Sound (self, CHAN_BODY, soundid, 1, ATTN_NORM);
}
DEFINE_ACTION_FUNCTION(AActor, A_PlaySound)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PlayWeaponSound)
{
DoPlaySound(self, CHAN_BODY);
}
int index=CheckIndex(1);
if (index<0) return;
DEFINE_ACTION_FUNCTION(AActor, A_PlayWeaponSound)
{
DoPlaySound(self, CHAN_WEAPON);
int soundid = StateParameters[index];
S_Sound (self, CHAN_WEAPON, soundid, 1, ATTN_NORM);
}
DEFINE_ACTION_FUNCTION(AActor, A_StopSound)
@ -310,7 +283,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_StopSound)
S_StopSound(self, CHAN_VOICE);
}
DEFINE_ACTION_FUNCTION(AActor, A_PlaySoundEx)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PlaySoundEx)
{
int index = CheckIndex(4);
if (index < 0) return;
@ -348,7 +321,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PlaySoundEx)
}
}
DEFINE_ACTION_FUNCTION(AActor, A_StopSoundEx)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StopSoundEx)
{
int index = CheckIndex (1);
if (index < 0) return;
@ -366,7 +339,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_StopSoundEx)
// Generic seeker missile function
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_SeekerMissile)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SeekerMissile)
{
int index=CheckIndex(2);
if (index<0) return;
@ -381,7 +354,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SeekerMissile)
// Hitscan attack with a customizable amount of bullets (specified in damage)
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_BulletAttack)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BulletAttack)
{
int i;
int bangle;
@ -488,10 +461,9 @@ static void DoJump(AActor * self, FState * CallingState, int offset)
// State jump function
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_Jump)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Jump)
{
FState * CallingState;
int index = CheckIndex(3, &CallingState);
int index = CheckIndex(3);
int maxchance;
if (index >= 0 &&
@ -516,10 +488,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Jump)
// State jump function
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_JumpIfHealthLower)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfHealthLower)
{
FState * CallingState;
int index=CheckIndex(2, &CallingState);
int index=CheckIndex(2);
if (index>=0 && self->health < EvalExpressionI (StateParameters[index], self))
DoJump(self, CallingState, StateParameters[index+1]);
@ -532,10 +503,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_JumpIfHealthLower)
// State jump function
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_JumpIfCloser)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfCloser)
{
FState * CallingState = NULL;
int index = CheckIndex(2, &CallingState);
int index = CheckIndex(2);
AActor * target;
if (!self->player)
@ -567,10 +537,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_JumpIfCloser)
// State jump function
//
//==========================================================================
void DoJumpIfInventory(AActor * self, AActor * owner)
void DoJumpIfInventory(AActor * self, AActor * owner, DECLARE_PARAMINFO)
{
FState * CallingState;
int index=CheckIndex(3, &CallingState);
int index=CheckIndex(3);
if (index<0) return;
ENamedName ItemType=(ENamedName)StateParameters[index];
@ -591,14 +560,14 @@ void DoJumpIfInventory(AActor * self, AActor * owner)
}
}
DEFINE_ACTION_FUNCTION(AActor, A_JumpIfInventory)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfInventory)
{
DoJumpIfInventory(self, self);
DoJumpIfInventory(self, self, PUSH_PARAMINFO);
}
DEFINE_ACTION_FUNCTION(AActor, A_JumpIfInTargetInventory)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfInTargetInventory)
{
DoJumpIfInventory(self, self->target);
DoJumpIfInventory(self, self->target, PUSH_PARAMINFO);
}
//==========================================================================
@ -607,7 +576,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_JumpIfInTargetInventory)
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_Explode)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode)
{
int damage;
int distance;
@ -650,7 +619,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Explode)
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_RadiusThrust)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusThrust)
{
int force = 0;
int distance = 0;
@ -678,7 +647,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_RadiusThrust)
// Execute a line special / script
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_CallSpecial)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CallSpecial)
{
int index=CheckIndex(6);
if (index<0) return;
@ -718,7 +687,7 @@ enum CM_Flags
CMF_CHECKTARGETDEAD = 8,
};
DEFINE_ACTION_FUNCTION(AActor, A_CustomMissile)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile)
{
int index=CheckIndex(6);
if (index<0) return;
@ -840,7 +809,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CustomMissile)
// An even more customizable hitscan attack
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_CustomBulletAttack)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack)
{
int index=CheckIndex(7);
if (index<0) return;
@ -887,7 +856,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CustomBulletAttack)
// A fully customizable melee attack
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_CustomMeleeAttack)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMeleeAttack)
{
int index=CheckIndex(5);
if (index<0) return;
@ -921,7 +890,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CustomMeleeAttack)
// A fully customizable combo attack
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_CustomComboAttack)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomComboAttack)
{
int index=CheckIndex(6);
if (index<0) return;
@ -978,10 +947,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CustomComboAttack)
// State jump function
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_JumpIfNoAmmo)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfNoAmmo)
{
FState * CallingState = NULL;
int index=CheckIndex(1, &CallingState);
int index=CheckIndex(1);
if (pStateCall != NULL) pStateCall->Result=false; // Jumps should never set the result for inventory state chains!
if (index<0 || !self->player || !self->player->ReadyWeapon || pStateCall != NULL) return; // only for weapons!
@ -997,7 +965,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_JumpIfNoAmmo)
// An even more customizable hitscan attack
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_FireBullets)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
{
int index=CheckIndex(7);
if (index<0 || !self->player) return;
@ -1060,7 +1028,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBullets)
// A_FireProjectile
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_FireCustomMissile)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile)
{
int index=CheckIndex(6);
if (index<0 || !self->player) return;
@ -1120,7 +1088,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCustomMissile)
// Berserk is not handled here. That can be done with A_CheckIfInventory
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_CustomPunch)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
{
int index=CheckIndex(5);
if (index<0 || !self->player) return;
@ -1177,7 +1145,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CustomPunch)
// customizable railgun attack function
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_RailAttack)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RailAttack)
{
int index=CheckIndex(7);
if (index<0 || !self->player) return;
@ -1208,7 +1176,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_RailAttack)
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_CustomRailgun)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun)
{
int index = CheckIndex(7);
if (index < 0) return;
@ -1267,7 +1235,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CustomRailgun)
//
//===========================================================================
static void DoGiveInventory(AActor * self, AActor * receiver)
static void DoGiveInventory(AActor * self, AActor * receiver, DECLARE_PARAMINFO)
{
int index=CheckIndex(2);
bool res=true;
@ -1307,14 +1275,14 @@ static void DoGiveInventory(AActor * self, AActor * receiver)
}
DEFINE_ACTION_FUNCTION(AActor, A_GiveInventory)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GiveInventory)
{
DoGiveInventory(self, self);
DoGiveInventory(self, self, PUSH_PARAMINFO);
}
DEFINE_ACTION_FUNCTION(AActor, A_GiveToTarget)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GiveToTarget)
{
DoGiveInventory(self, self->target);
DoGiveInventory(self, self->target, PUSH_PARAMINFO);
}
//===========================================================================
@ -1323,7 +1291,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_GiveToTarget)
//
//===========================================================================
void DoTakeInventory(AActor * self, AActor * receiver)
void DoTakeInventory(AActor * self, AActor * receiver, DECLARE_PARAMINFO)
{
int index=CheckIndex(2);
if (index<0 || receiver == NULL) return;
@ -1347,14 +1315,14 @@ void DoTakeInventory(AActor * self, AActor * receiver)
}
}
DEFINE_ACTION_FUNCTION(AActor, A_TakeInventory)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_TakeInventory)
{
DoTakeInventory(self, self);
DoTakeInventory(self, self, PUSH_PARAMINFO);
}
DEFINE_ACTION_FUNCTION(AActor, A_TakeFromTarget)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_TakeFromTarget)
{
DoTakeInventory(self, self->target);
DoTakeInventory(self, self->target, PUSH_PARAMINFO);
}
//===========================================================================
@ -1450,10 +1418,9 @@ static void InitSpawnedItem(AActor *self, AActor *mo, int flags)
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_SpawnItem)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem)
{
FState * CallingState;
int index=CheckIndex(5, &CallingState);
int index=CheckIndex(5);
if (index<0) return;
const PClass * missile= PClass::FindClass((ENamedName)StateParameters[index]);
@ -1502,10 +1469,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnItem)
// Enhanced spawning function
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_SpawnItemEx)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx)
{
FState * CallingState;
int index=CheckIndex(9, &CallingState);
int index=CheckIndex(9);
if (index<0) return;
const PClass * missile= PClass::FindClass((ENamedName)StateParameters[index]);
@ -1579,10 +1545,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnItemEx)
// Throws a grenade (like Hexen's fighter flechette)
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_ThrowGrenade)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ThrowGrenade)
{
FState * CallingState;
int index=CheckIndex(5, &CallingState);
int index=CheckIndex(5);
if (index<0) return;
const PClass * missile= PClass::FindClass((ENamedName)StateParameters[index]);
@ -1635,9 +1600,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrowGrenade)
// A_Recoil
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_Recoil)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Recoil)
{
int index=CheckIndex(1, NULL);
int index=CheckIndex(1);
if (index<0) return;
fixed_t xymom = fixed_t(EvalExpressionF (StateParameters[index], self) * FRACUNIT);
@ -1653,9 +1618,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Recoil)
// A_SelectWeapon
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_SelectWeapon)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SelectWeapon)
{
int index=CheckIndex(1, NULL);
int index=CheckIndex(1);
if (index<0 || self->player == NULL) return;
AWeapon * weaponitem = static_cast<AWeapon*>(self->FindInventory((ENamedName)StateParameters[index]));
@ -1678,9 +1643,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_SelectWeapon)
//===========================================================================
EXTERN_CVAR(Float, con_midtime)
DEFINE_ACTION_FUNCTION(AActor, A_Print)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Print)
{
int index=CheckIndex(3, NULL);
int index=CheckIndex(3);
if (index<0) return;
if (self->CheckLocalView (consoleplayer) ||
@ -1714,9 +1679,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Print)
// A_SetTranslucent
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_SetTranslucent)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTranslucent)
{
int index=CheckIndex(2, NULL);
int index=CheckIndex(2);
if (index<0) return;
fixed_t alpha = fixed_t(EvalExpressionF (StateParameters[index], self) * FRACUNIT);
@ -1735,11 +1700,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetTranslucent)
// Fades the actor in
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_FadeIn)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeIn)
{
fixed_t reduce = 0;
int index=CheckIndex(1, NULL);
int index=CheckIndex(1);
if (index>=0)
{
reduce = fixed_t(EvalExpressionF (StateParameters[index], self) * FRACUNIT);
@ -1759,11 +1724,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FadeIn)
// fades the actor out and destroys it when done
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_FadeOut)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeOut)
{
fixed_t reduce = 0;
int index=CheckIndex(1, NULL);
int index=CheckIndex(1);
if (index>=0)
{
reduce = fixed_t(EvalExpressionF (StateParameters[index], self) * FRACUNIT);
@ -1781,13 +1746,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FadeOut)
// A_SpawnDebris
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_SpawnDebris)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnDebris)
{
int i;
AActor * mo;
const PClass * debris;
int index=CheckIndex(4, NULL);
int index=CheckIndex(4);
if (index<0) return;
debris = PClass::FindClass((ENamedName)StateParameters[index]);
@ -1827,7 +1792,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnDebris)
// jumps if no player can see this actor
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_CheckSight)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSight)
{
if (pStateCall != NULL) pStateCall->Result=false; // Jumps should never set the result for inventory state chains!
@ -1836,8 +1801,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckSight)
if (playeringame[i] && P_CheckSight(players[i].camera,self,true)) return;
}
FState * CallingState;
int index=CheckIndex(1, &CallingState);
int index=CheckIndex(1);
if (index>=0) DoJump(self, CallingState, StateParameters[index]);
@ -1849,9 +1813,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckSight)
// Inventory drop
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_DropInventory)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropInventory)
{
int index=CheckIndex(1, &CallingState);
int index=CheckIndex(1);
if (index<0) return;
AInventory * inv = self->FindInventory((ENamedName)StateParameters[index]);
@ -1867,7 +1831,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DropInventory)
// A_SetBlend
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_SetBlend)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetBlend)
{
int index=CheckIndex(3);
if (index<0) return;
@ -1892,10 +1856,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetBlend)
// A_JumpIf
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_JumpIf)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIf)
{
FState * CallingState;
int index=CheckIndex(2, &CallingState);
int index=CheckIndex(2);
if (index<0) return;
INTBOOL expression = EvalExpressionI (StateParameters[index], self);
@ -1941,7 +1904,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KillChildren)
// A_CountdownArg
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_CountdownArg)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CountdownArg)
{
int index=CheckIndex(1);
if (index<0) return;
@ -1972,11 +1935,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CountdownArg)
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_Burst)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Burst)
{
int i, numChunks;
AActor * mo;
int index=CheckIndex(1, NULL);
int index=CheckIndex(1);
if (index<0) return;
const PClass * chunk = PClass::FindClass((ENamedName)StateParameters[index]);
if (chunk == NULL) return;
@ -2025,10 +1988,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Burst)
// [GRB] Jumps if actor is standing on floor
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_CheckFloor)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckFloor)
{
FState *CallingState = NULL;
int index = CheckIndex (1, &CallingState);
int index = CheckIndex (1);
if (pStateCall != NULL) pStateCall->Result=false; // Jumps should never set the result for inventory state chains!
if (self->z <= self->floorz && index >= 0)
@ -2060,7 +2022,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Stop)
// A_Respawn
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_Respawn)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn)
{
fixed_t x = self->SpawnPoint[0];
fixed_t y = self->SpawnPoint[1];
@ -2083,7 +2045,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Respawn)
self->SetState (self->SpawnState);
self->renderflags &= ~RF_INVISIBLE;
int index=CheckIndex(1, NULL);
int index=CheckIndex(1);
if (index<0 || EvalExpressionN (StateParameters[index], self))
{
Spawn<ATeleportFog> (x, y, self->z + TELEFOGHEIGHT, ALLOW_REPLACE);
@ -2103,13 +2065,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_Respawn)
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_PlayerSkinCheck)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PlayerSkinCheck)
{
if (pStateCall != NULL) pStateCall->Result=false; // Jumps should never set the result for inventory state chains!
if (self->player != NULL &&
skins[self->player->userinfo.skin].othergame)
{
int index = CheckIndex(1, &CallingState);
int index = CheckIndex(1);
if (index >= 0)
{
@ -2123,7 +2085,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PlayerSkinCheck)
// A_SetGravity
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_SetGravity)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetGravity)
{
int index=CheckIndex(1);
if (index<0) return;
@ -2160,10 +2122,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_ClearTarget)
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_JumpIfTargetInLOS)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS)
{
FState * CallingState = NULL;
int index = CheckIndex(3, &CallingState);
int index = CheckIndex(3);
angle_t an;
angle_t fov = angle_t(EvalExpressionF (StateParameters[index+1], self) * ANGLE_1);
INTBOOL projtarg = EvalExpressionI (StateParameters[index+2], self);
@ -2222,7 +2183,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_JumpIfTargetInLOS)
// Damages the master of this child by the specified amount. Negative values heal.
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_DamageMaster)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageMaster)
{
int index = CheckIndex(2);
if (index<0) return;
@ -2250,7 +2211,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DamageMaster)
// Damages the children of this master by the specified amount. Negative values heal.
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_DamageChildren)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageChildren)
{
TThinkerIterator<AActor> it;
AActor * mo;
@ -2286,7 +2247,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DamageChildren)
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_CheckForReload)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckForReload)
{
if ( self->player == NULL || self->player->ReadyWeapon == NULL )
return;

View file

@ -456,7 +456,7 @@ static void HandleDeprecatedFlags(AActor *defaults, bool set, int index)
// This cannot be placed in thingdef_codeptr because it needs the flag table
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_ChangeFlag)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeFlag)
{
int index=CheckIndex(2);
const char * flagname = FName((ENamedName)StateParameters[index]).GetChars();

View file

@ -119,6 +119,21 @@ AFuncDesc * FindFunction(const char * string)
}
//==========================================================================
//
// Find an action function in AActor's table
//
//==========================================================================
PSymbolActionFunction *FindGlobalActionFunction(const char *name)
{
PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(name, false);
if (sym != NULL && sym->SymbolType == SYM_ActionFunction)
return static_cast<PSymbolActionFunction*>(sym);
else
return NULL;
}
//==========================================================================
//
// Find a state address
@ -371,7 +386,6 @@ int PrepareStateParameters(FState * state, int numparams)
return paramindex;
}
void A_CallSpecial(AActor * self);
//==========================================================================
//
// DoActionSpecials
@ -414,7 +428,8 @@ bool DoActionSpecials(FScanner &sc, FState & state, bool multistate, int * state
{
sc.ScriptError ("Too many arguments to %s", specname.GetChars());
}
state.Action = GET_ACTION(A_CallSpecial);
state.SetAction(FindGlobalActionFunction("A_CallSpecial"), false);
return true;
}
return false;
@ -650,7 +665,7 @@ do_stop:
if (sym != NULL && sym->SymbolType == SYM_ActionFunction)
{
PSymbolActionFunction *afd = static_cast<PSymbolActionFunction *>(sym);
state.Action = afd->Function;
state.SetAction(afd, false);
if (!afd->Arguments.IsEmpty())
{
const char *params = afd->Arguments.GetChars();
@ -664,7 +679,11 @@ do_stop:
}
else
{
if (!sc.CheckString("(")) goto endofstate;
if (!sc.CheckString("("))
{
state.ParameterIndex = afd->defaultparameterindex+1;
goto endofstate;
}
}
int paramindex = PrepareStateParameters(&state, numparams);
@ -680,19 +699,6 @@ do_stop:
{
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();

View file

@ -329,7 +329,7 @@ OrgSprNames
StateMap
{
// S_NULL is implicit
DoomWeapon, FirstState, 1, // S_LIGHTDONE
Weapon, FirstState, 1, // S_LIGHTDONE
Fist, FirstState, 8, // S_PUNCH - S_PUNCH5
Pistol, FirstState, 8, // S_PISTOL - S_PISTOLFLASH
Shotgun, FirstState, 14, // S_SGUN - S_SGUNFLASH2

View file

@ -7,12 +7,6 @@
ACTOR DoomWeapon : Weapon
{
Weapon.Kickback 100
States
{
LightDone:
SHTG E 0 A_Light0
Stop
}
}
// --------------------------------------------------------------------------

View file

@ -1,6 +1,7 @@
ACTOR StrifeWeapon : DoomWeapon
ACTOR StrifeWeapon : Weapon
{
Weapon.Kickback 100
}
// Same as the bullet puff for Doom -----------------------------------------