mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-01 00:21:43 +00:00
- Restructured the action function interface to remove the dependence on
the global CallingState variable. SVN r1163 (trunk)
This commit is contained in:
parent
b1d36182c4
commit
1957659b1b
34 changed files with 408 additions and 425 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 -----------------------------------------------------------
|
||||
|
|
|
@ -40,8 +40,7 @@
|
|||
class AActor;
|
||||
class player_t;
|
||||
struct pspdef_s;
|
||||
|
||||
typedef void (*actionf_p)( AActor* );
|
||||
struct FState;
|
||||
|
||||
class FThinkerIterator;
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
36
src/info.h
36
src/info.h
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -7,12 +7,6 @@
|
|||
ACTOR DoomWeapon : Weapon
|
||||
{
|
||||
Weapon.Kickback 100
|
||||
States
|
||||
{
|
||||
LightDone:
|
||||
SHTG E 0 A_Light0
|
||||
Stop
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
ACTOR StrifeWeapon : DoomWeapon
|
||||
ACTOR StrifeWeapon : Weapon
|
||||
{
|
||||
Weapon.Kickback 100
|
||||
}
|
||||
|
||||
// Same as the bullet puff for Doom -----------------------------------------
|
||||
|
|
Loading…
Reference in a new issue