qzdoom/src/g_hexen/a_magelightning.cpp
Christoph Oelckers 1bd6ac028b - Converted a_doomhealth.cpp to DECORATE.
- Added a PickupMessage property to the internal actor parser, replaced
  most of the virtual PickupMessages with it and placed the code that
  reads the metadata into AInventory::PickupMessage. Now the
  PickupMessage method is truly virtual and I can do:
   Added a Health.LowMessage property to define double message items like
   Doom's medikit in DECORATE.
- Since defining Mana3 as an ammo type and then overriding the TryPickup
  method means that this item defeats all ammo checks in the game it might
  as well be defined as a CustomInventory item. At least this fixes the
  amount given in easy and very hard skills.
- Converted all ammo items to DECORATE.
- Changed internal property setting of ammo types and sister weapons
  to use fuglyname as for DECORATE definitions. This allows to export
  the ammo definitions into DECORATE definitions without doing it for
  the weapons themselves.
- Replaced obituary methods with actor properties.
- Fixed: The secret map check didn't work for maps inside Zips.



SVN r196 (trunk)
2006-06-17 20:29:41 +00:00

582 lines
18 KiB
C++

#include "actor.h"
#include "gi.h"
#include "m_random.h"
#include "s_sound.h"
#include "d_player.h"
#include "a_action.h"
#include "p_local.h"
#include "p_enemy.h"
#include "a_action.h"
#include "p_pspr.h"
#include "gstrings.h"
#include "a_hexenglobal.h"
#define ZAGSPEED FRACUNIT
static FRandom pr_lightningready ("LightningReady");
static FRandom pr_lightningclip ("LightningClip");
static FRandom pr_zap ("LightningZap");
static FRandom pr_zapf ("LightningZapF");
static FRandom pr_hit ("LightningHit");
void A_LightningReady (AActor *actor);
void A_MLightningAttack (AActor *actor);
void A_LightningClip (AActor *);
void A_LightningZap (AActor *);
void A_ZapMimic (AActor *);
void A_LastZap (AActor *);
void A_LightningRemove (AActor *);
void A_FreeTargMobj (AActor *);
// The Mage's Lightning Arc of Death ----------------------------------------
class AMWeapLightning : public AMageWeapon
{
DECLARE_ACTOR (AMWeapLightning, AMageWeapon)
};
FState AMWeapLightning::States[] =
{
#define S_MW_LIGHTNING1 0
S_BRIGHT (WMLG, 'A', 4, NULL , &States[S_MW_LIGHTNING1+1]),
S_BRIGHT (WMLG, 'B', 4, NULL , &States[S_MW_LIGHTNING1+2]),
S_BRIGHT (WMLG, 'C', 4, NULL , &States[S_MW_LIGHTNING1+3]),
S_BRIGHT (WMLG, 'D', 4, NULL , &States[S_MW_LIGHTNING1+4]),
S_BRIGHT (WMLG, 'E', 4, NULL , &States[S_MW_LIGHTNING1+5]),
S_BRIGHT (WMLG, 'F', 4, NULL , &States[S_MW_LIGHTNING1+6]),
S_BRIGHT (WMLG, 'G', 4, NULL , &States[S_MW_LIGHTNING1+7]),
S_BRIGHT (WMLG, 'H', 4, NULL , &States[S_MW_LIGHTNING1]),
#define S_MLIGHTNINGREADY (S_MW_LIGHTNING1+8)
S_BRIGHT (MLNG, 'A', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+1]),
S_BRIGHT (MLNG, 'A', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+2]),
S_BRIGHT (MLNG, 'A', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+3]),
S_BRIGHT (MLNG, 'A', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+4]),
S_BRIGHT (MLNG, 'A', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+5]),
S_BRIGHT (MLNG, 'A', 1, A_LightningReady , &States[S_MLIGHTNINGREADY+6]),
S_BRIGHT (MLNG, 'B', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+7]),
S_BRIGHT (MLNG, 'B', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+8]),
S_BRIGHT (MLNG, 'B', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+9]),
S_BRIGHT (MLNG, 'B', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+10]),
S_BRIGHT (MLNG, 'B', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+11]),
S_BRIGHT (MLNG, 'B', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+12]),
S_BRIGHT (MLNG, 'C', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+13]),
S_BRIGHT (MLNG, 'C', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+14]),
S_BRIGHT (MLNG, 'C', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+15]),
S_BRIGHT (MLNG, 'C', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+16]),
S_BRIGHT (MLNG, 'C', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+17]),
S_BRIGHT (MLNG, 'C', 1, A_LightningReady , &States[S_MLIGHTNINGREADY+18]),
S_BRIGHT (MLNG, 'B', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+19]),
S_BRIGHT (MLNG, 'B', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+20]),
S_BRIGHT (MLNG, 'B', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+21]),
S_BRIGHT (MLNG, 'B', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+22]),
S_BRIGHT (MLNG, 'B', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY+23]),
S_BRIGHT (MLNG, 'B', 1, A_WeaponReady , &States[S_MLIGHTNINGREADY]),
#define S_MLIGHTNINGDOWN (S_MLIGHTNINGREADY+24)
S_BRIGHT (MLNG, 'A', 1, A_Lower , &States[S_MLIGHTNINGDOWN]),
#define S_MLIGHTNINGUP (S_MLIGHTNINGDOWN+1)
S_BRIGHT (MLNG, 'A', 1, A_Raise , &States[S_MLIGHTNINGUP]),
#define S_MLIGHTNINGATK (S_MLIGHTNINGUP+1)
S_BRIGHT (MLNG, 'D', 3, NULL , &States[S_MLIGHTNINGATK+1]),
S_BRIGHT (MLNG, 'E', 3, NULL , &States[S_MLIGHTNINGATK+2]),
S_BRIGHT (MLNG, 'F', 4, A_MLightningAttack , &States[S_MLIGHTNINGATK+3]),
S_BRIGHT (MLNG, 'G', 4, NULL , &States[S_MLIGHTNINGATK+4]),
S_BRIGHT (MLNG, 'H', 3, NULL , &States[S_MLIGHTNINGATK+5]),
S_BRIGHT (MLNG, 'I', 3, NULL , &States[S_MLIGHTNINGATK+6]),
S_BRIGHT2 (MLNG, 'I', 6, NULL , &States[S_MLIGHTNINGATK+7], 0, 199),
S_BRIGHT2 (MLNG, 'C', 2, NULL , &States[S_MLIGHTNINGATK+8], 0, 55),
S_BRIGHT2 (MLNG, 'B', 2, NULL , &States[S_MLIGHTNINGATK+9], 0, 50),
S_BRIGHT2 (MLNG, 'B', 2, NULL , &States[S_MLIGHTNINGATK+10], 0, 45),
S_BRIGHT2 (MLNG, 'B', 2, NULL , &States[S_MLIGHTNINGREADY], 0, 40),
};
IMPLEMENT_ACTOR (AMWeapLightning, Hexen, 8040, 0)
PROP_Flags (MF_SPECIAL|MF_NOGRAVITY)
PROP_SpawnState (S_MW_LIGHTNING1)
PROP_Weapon_SelectionOrder (1100)
PROP_Weapon_AmmoUse1 (5)
PROP_Weapon_AmmoGive1 (25)
PROP_Weapon_UpState (S_MLIGHTNINGUP)
PROP_Weapon_DownState (S_MLIGHTNINGDOWN)
PROP_Weapon_ReadyState (S_MLIGHTNINGREADY)
PROP_Weapon_AtkState (S_MLIGHTNINGATK)
PROP_Weapon_HoldAtkState (S_MLIGHTNINGATK)
PROP_Weapon_Kickback (0)
PROP_Weapon_YAdjust (20)
PROP_Weapon_MoveCombatDist (23000000)
PROP_Weapon_AmmoType1 ("Mana2")
PROP_Weapon_ProjectileType ("LightningFloor")
PROP_Inventory_PickupMessage("$TXT_WEAPON_M3")
END_DEFAULTS
// Lightning ----------------------------------------------------------------
IMPLEMENT_ABSTRACT_ACTOR (ALightning)
int ALightning::SpecialMissileHit (AActor *thing)
{
if (thing->flags&MF_SHOOTABLE && thing != target)
{
if (thing->Mass != INT_MAX)
{
thing->momx += momx>>4;
thing->momy += momy>>4;
}
if ((!thing->player && !(thing->flags2&MF2_BOSS))
|| !(level.time&1))
{
if (thing->IsKindOf(RUNTIME_CLASS(ACentaur)))
{ // Lightning does more damage to centaurs
P_DamageMobj(thing, this, target, 9, MOD_ELECTRIC);
}
else
{
P_DamageMobj(thing, this, target, 3, MOD_ELECTRIC);
}
if (!(S_IsActorPlayingSomething (this, CHAN_WEAPON)))
{
S_Sound (this, CHAN_WEAPON, "MageLightningZap", 1, ATTN_NORM);
}
if (thing->flags3&MF3_ISMONSTER && pr_hit() < 64)
{
thing->Howl ();
}
}
health--;
if (health <= 0 || thing->health <= 0)
{
return 0;
}
if (flags3 & MF3_FLOORHUGGER)
{
if (lastenemy && ! lastenemy->tracer)
{
lastenemy->tracer = thing;
}
}
else if (!tracer)
{
tracer = thing;
}
}
return 1; // lightning zaps through all sprites
}
// Ceiling Lightning --------------------------------------------------------
class ALightningCeiling : public ALightning
{
DECLARE_ACTOR (ALightningCeiling, ALightning)
};
FState ALightningCeiling::States[] =
{
#define S_LIGHTNING_CEILING1 0
S_BRIGHT (MLFX, 'A', 2, A_LightningZap , &States[S_LIGHTNING_CEILING1+1]),
S_BRIGHT (MLFX, 'B', 2, A_LightningClip , &States[S_LIGHTNING_CEILING1+2]),
S_BRIGHT (MLFX, 'C', 2, A_LightningClip , &States[S_LIGHTNING_CEILING1+3]),
S_BRIGHT (MLFX, 'D', 2, A_LightningClip , &States[S_LIGHTNING_CEILING1]),
#define S_LIGHTNING_C_X1 (S_LIGHTNING_CEILING1+4)
S_BRIGHT (MLF2, 'A', 2, A_LightningRemove , &States[S_LIGHTNING_C_X1+1]),
S_BRIGHT (MLF2, 'B', 3, NULL , &States[S_LIGHTNING_C_X1+2]),
S_BRIGHT (MLF2, 'C', 3, NULL , &States[S_LIGHTNING_C_X1+3]),
S_BRIGHT (MLF2, 'D', 3, NULL , &States[S_LIGHTNING_C_X1+4]),
S_BRIGHT (MLF2, 'E', 3, NULL , &States[S_LIGHTNING_C_X1+5]),
S_BRIGHT (MLF2, 'K', 3, NULL , &States[S_LIGHTNING_C_X1+6]),
S_BRIGHT (MLF2, 'L', 3, NULL , &States[S_LIGHTNING_C_X1+7]),
S_BRIGHT (MLF2, 'M', 3, NULL , &States[S_LIGHTNING_C_X1+8]),
S_NORMAL (ACLO, 'E', 35, NULL , &States[S_LIGHTNING_C_X1+9]),
S_BRIGHT (MLF2, 'N', 3, NULL , &States[S_LIGHTNING_C_X1+10]),
S_BRIGHT (MLF2, 'O', 3, NULL , &States[S_LIGHTNING_C_X1+11]),
S_BRIGHT (MLF2, 'P', 4, NULL , &States[S_LIGHTNING_C_X1+12]),
S_BRIGHT (MLF2, 'Q', 3, NULL , &States[S_LIGHTNING_C_X1+13]),
S_BRIGHT (MLF2, 'P', 3, NULL , &States[S_LIGHTNING_C_X1+14]),
S_BRIGHT (MLF2, 'Q', 4, NULL , &States[S_LIGHTNING_C_X1+15]),
S_BRIGHT (MLF2, 'P', 3, NULL , &States[S_LIGHTNING_C_X1+16]),
S_BRIGHT (MLF2, 'O', 3, NULL , &States[S_LIGHTNING_C_X1+17]),
S_BRIGHT (MLF2, 'P', 3, NULL , &States[S_LIGHTNING_C_X1+18]),
S_BRIGHT (MLF2, 'P', 1, A_HideThing , &States[S_LIGHTNING_C_X1+19]),
S_NORMAL (ACLO, 'E', 1050, A_FreeTargMobj , NULL),
};
IMPLEMENT_ACTOR (ALightningCeiling, Hexen, -1, 0)
PROP_SpawnHealth (144)
PROP_SpeedFixed (25)
PROP_RadiusFixed (16)
PROP_HeightFixed (40)
PROP_Damage (8)
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF|MF_MISSILE)
PROP_Flags2 (MF2_NOTELEPORT|MF2_IMPACT|MF2_PCROSS)
PROP_Flags3 (MF3_CEILINGHUGGER)
PROP_RenderStyle (STYLE_Add)
PROP_SpawnState (S_LIGHTNING_CEILING1)
PROP_DeathState (S_LIGHTNING_C_X1)
END_DEFAULTS
// Floor Lightning ----------------------------------------------------------
class ALightningFloor : public ALightning
{
DECLARE_ACTOR (ALightningFloor, ALightning)
};
FState ALightningFloor::States[] =
{
#define S_LIGHTNING_FLOOR1 0
S_BRIGHT (MLFX, 'E', 2, A_LightningZap , &States[S_LIGHTNING_FLOOR1+1]),
S_BRIGHT (MLFX, 'F', 2, A_LightningClip , &States[S_LIGHTNING_FLOOR1+2]),
S_BRIGHT (MLFX, 'G', 2, A_LightningClip , &States[S_LIGHTNING_FLOOR1+3]),
S_BRIGHT (MLFX, 'H', 2, A_LightningClip , &States[S_LIGHTNING_FLOOR1]),
#define S_LIGHTNING_F_X1 (S_LIGHTNING_FLOOR1+4)
S_BRIGHT (MLF2, 'F', 2, A_LightningRemove , &States[S_LIGHTNING_F_X1+1]),
S_BRIGHT (MLF2, 'G', 3, NULL , &States[S_LIGHTNING_F_X1+2]),
S_BRIGHT (MLF2, 'H', 3, NULL , &States[S_LIGHTNING_F_X1+3]),
S_BRIGHT (MLF2, 'I', 3, NULL , &States[S_LIGHTNING_F_X1+4]),
S_BRIGHT (MLF2, 'J', 3, NULL , &States[S_LIGHTNING_F_X1+5]),
S_BRIGHT (MLF2, 'K', 3, NULL , &States[S_LIGHTNING_F_X1+6]),
S_BRIGHT (MLF2, 'L', 3, NULL , &States[S_LIGHTNING_F_X1+7]),
S_BRIGHT (MLF2, 'M', 3, NULL , &States[S_LIGHTNING_F_X1+8]),
S_NORMAL (ACLO, 'E', 20, NULL , &States[S_LIGHTNING_F_X1+9]),
S_BRIGHT (MLF2, 'N', 3, NULL , &States[S_LIGHTNING_F_X1+10]),
S_BRIGHT (MLF2, 'O', 3, NULL , &States[S_LIGHTNING_F_X1+11]),
S_BRIGHT (MLF2, 'P', 4, NULL , &States[S_LIGHTNING_F_X1+12]),
S_BRIGHT (MLF2, 'Q', 3, NULL , &States[S_LIGHTNING_F_X1+13]),
S_BRIGHT (MLF2, 'P', 3, NULL , &States[S_LIGHTNING_F_X1+14]),
S_BRIGHT (MLF2, 'Q', 4, A_LastZap , &States[S_LIGHTNING_F_X1+15]),
S_BRIGHT (MLF2, 'P', 3, NULL , &States[S_LIGHTNING_F_X1+16]),
S_BRIGHT (MLF2, 'O', 3, NULL , &States[S_LIGHTNING_F_X1+17]),
S_BRIGHT (MLF2, 'P', 3, NULL , &States[S_LIGHTNING_F_X1+18]),
S_BRIGHT (MLF2, 'P', 1, A_HideThing , &ALightningCeiling::States[S_LIGHTNING_C_X1+19]),
};
IMPLEMENT_ACTOR (ALightningFloor, Hexen, -1, 0)
PROP_SpawnHealth (144)
PROP_SpeedFixed (25)
PROP_RadiusFixed (16)
PROP_HeightFixed (40)
PROP_Damage (8)
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF|MF_MISSILE)
PROP_Flags2 (MF2_NOTELEPORT|MF2_IMPACT|MF2_PCROSS)
PROP_Flags3 (MF3_FLOORHUGGER)
PROP_RenderStyle (STYLE_Add)
PROP_SpawnState (S_LIGHTNING_FLOOR1)
PROP_DeathState (S_LIGHTNING_F_X1)
END_DEFAULTS
// Lightning Zap ------------------------------------------------------------
class ALightningZap : public AActor
{
DECLARE_ACTOR (ALightningZap, AActor)
public:
int SpecialMissileHit (AActor *thing);
};
FState ALightningZap::States[] =
{
#define S_LIGHTNING_ZAP1 0
S_BRIGHT (MLFX, 'I', 2, A_ZapMimic , &States[S_LIGHTNING_ZAP1+1]),
S_BRIGHT (MLFX, 'J', 2, A_ZapMimic , &States[S_LIGHTNING_ZAP1+2]),
S_BRIGHT (MLFX, 'K', 2, A_ZapMimic , &States[S_LIGHTNING_ZAP1+3]),
S_BRIGHT (MLFX, 'L', 2, A_ZapMimic , &States[S_LIGHTNING_ZAP1+4]),
S_BRIGHT (MLFX, 'M', 2, A_ZapMimic , &States[S_LIGHTNING_ZAP1]),
#define S_LIGHTNING_ZAP_X1 (S_LIGHTNING_ZAP1+5)
S_BRIGHT (MLFX, 'N', 2, NULL , &States[S_LIGHTNING_ZAP_X1+1]),
S_BRIGHT (MLFX, 'O', 2, NULL , &States[S_LIGHTNING_ZAP_X1+2]),
S_BRIGHT (MLFX, 'P', 2, NULL , &States[S_LIGHTNING_ZAP_X1+3]),
S_BRIGHT (MLFX, 'Q', 2, NULL , &States[S_LIGHTNING_ZAP_X1+4]),
S_BRIGHT (MLFX, 'R', 2, NULL , &States[S_LIGHTNING_ZAP_X1+5]),
S_BRIGHT (MLFX, 'S', 2, NULL , &States[S_LIGHTNING_ZAP_X1+6]),
S_BRIGHT (MLFX, 'T', 2, NULL , &States[S_LIGHTNING_ZAP_X1+7]),
S_BRIGHT (MLFX, 'U', 2, NULL , NULL),
};
IMPLEMENT_ACTOR (ALightningZap, Hexen, -1, 0)
PROP_RadiusFixed (15)
PROP_HeightFixed (35)
PROP_Damage (2)
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF|MF_MISSILE)
PROP_RenderStyle (STYLE_Add)
PROP_SpawnState (S_LIGHTNING_ZAP1)
PROP_DeathState (S_LIGHTNING_ZAP_X1+7)
END_DEFAULTS
int ALightningZap::SpecialMissileHit (AActor *thing)
{
AActor *lmo;
if (thing->flags&MF_SHOOTABLE && thing != target)
{
lmo = lastenemy;
if (lmo)
{
if (lmo->flags3 & MF3_FLOORHUGGER)
{
if (lmo->lastenemy && !lmo->lastenemy->tracer)
{
lmo->lastenemy->tracer = thing;
}
}
else if (!lmo->tracer)
{
lmo->tracer = thing;
}
if (!(level.time&3))
{
lmo->health--;
}
}
}
return -1;
}
//============================================================================
//
// A_LightningReady
//
//============================================================================
void A_LightningReady (AActor *actor)
{
A_WeaponReady (actor);
if (pr_lightningready() < 160)
{
S_Sound (actor, CHAN_WEAPON, "MageLightningReady", 1, ATTN_NORM);
}
}
//============================================================================
//
// A_LightningClip
//
//============================================================================
void A_LightningClip (AActor *actor)
{
AActor *cMo;
AActor *target = NULL;
int zigZag;
if (actor->flags3 & MF3_FLOORHUGGER)
{
if (actor->lastenemy == NULL)
{
return;
}
actor->z = actor->floorz;
target = actor->lastenemy->tracer;
}
else if (actor->flags3 & MF3_CEILINGHUGGER)
{
actor->z = actor->ceilingz-actor->height;
target = actor->tracer;
}
if (actor->flags3 & MF3_FLOORHUGGER)
{ // floor lightning zig-zags, and forces the ceiling lightning to mimic
cMo = actor->lastenemy;
zigZag = pr_lightningclip();
if((zigZag > 128 && actor->special1 < 2) || actor->special1 < -2)
{
P_ThrustMobj(actor, actor->angle+ANG90, ZAGSPEED);
if(cMo)
{
P_ThrustMobj(cMo, actor->angle+ANG90, ZAGSPEED);
}
actor->special1++;
}
else
{
P_ThrustMobj(actor, actor->angle-ANG90, ZAGSPEED);
if(cMo)
{
P_ThrustMobj(cMo, cMo->angle-ANG90, ZAGSPEED);
}
actor->special1--;
}
}
if(target)
{
if(target->health <= 0)
{
P_ExplodeMissile(actor, NULL);
}
else
{
actor->angle = R_PointToAngle2(actor->x, actor->y, target->x, target->y);
actor->momx = 0;
actor->momy = 0;
P_ThrustMobj (actor, actor->angle, actor->Speed>>1);
}
}
}
//============================================================================
//
// A_LightningZap
//
//============================================================================
void A_LightningZap (AActor *actor)
{
AActor *mo;
fixed_t deltaZ;
A_LightningClip(actor);
actor->health -= 8;
if (actor->health <= 0)
{
actor->SetState (actor->DeathState);
return;
}
if (actor->flags3 & MF3_FLOORHUGGER)
{
deltaZ = 10*FRACUNIT;
}
else
{
deltaZ = -10*FRACUNIT;
}
mo = Spawn<ALightningZap> (actor->x+((pr_zap()-128)*actor->radius/256),
actor->y+((pr_zap()-128)*actor->radius/256),
actor->z+deltaZ);
if (mo)
{
mo->lastenemy = actor;
mo->momx = actor->momx;
mo->momy = actor->momy;
mo->target = actor->target;
if (actor->flags3 & MF3_FLOORHUGGER)
{
mo->momz = 20*FRACUNIT;
}
else
{
mo->momz = -20*FRACUNIT;
}
}
if ((actor->flags3 & MF3_FLOORHUGGER) && pr_zapf() < 160)
{
S_Sound (actor, CHAN_BODY, "MageLightningContinuous", 1, ATTN_NORM);
}
}
//============================================================================
//
// A_MLightningAttack2
//
//============================================================================
void A_MLightningAttack2 (AActor *actor)
{
AActor *fmo, *cmo;
fmo = P_SpawnPlayerMissile (actor, RUNTIME_CLASS(ALightningFloor));
cmo = P_SpawnPlayerMissile (actor, RUNTIME_CLASS(ALightningCeiling));
if (fmo)
{
fmo->special1 = 0;
fmo->lastenemy = cmo;
A_LightningZap (fmo);
}
if (cmo)
{
cmo->tracer = NULL;
cmo->lastenemy = fmo;
A_LightningZap (cmo);
}
S_Sound (actor, CHAN_BODY, "MageLightningFire", 1, ATTN_NORM);
}
//============================================================================
//
// A_MLightningAttack
//
//============================================================================
void A_MLightningAttack (AActor *actor)
{
A_MLightningAttack2(actor);
if (actor->player != NULL)
{
AWeapon *weapon = actor->player->ReadyWeapon;
if (weapon != NULL)
{
weapon->DepleteAmmo (weapon->bAltFire);
}
}
}
//============================================================================
//
// A_ZapMimic
//
//============================================================================
void A_ZapMimic (AActor *actor)
{
AActor *mo;
mo = actor->lastenemy;
if (mo)
{
if (mo->state >= mo->DeathState)
{
P_ExplodeMissile (actor, NULL);
}
else
{
actor->momx = mo->momx;
actor->momy = mo->momy;
}
}
}
//============================================================================
//
// A_LastZap
//
//============================================================================
void A_LastZap (AActor *actor)
{
AActor *mo;
mo = Spawn<ALightningZap> (actor->x, actor->y, actor->z);
if (mo)
{
mo->SetState (&ALightningZap::States[S_LIGHTNING_ZAP_X1]);
mo->momz = 40*FRACUNIT;
mo->damage = 0;
}
}
//============================================================================
//
// A_LightningRemove
//
//============================================================================
void A_LightningRemove (AActor *actor)
{
AActor *mo;
mo = actor->lastenemy;
if (mo)
{
mo->lastenemy = NULL;
P_ExplodeMissile (mo, NULL);
}
}