mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-28 15:02:39 +00:00
- scriptified Hexen's lightning weapon.
This commit is contained in:
parent
7b5a589635
commit
f9a1388066
6 changed files with 228 additions and 289 deletions
|
@ -860,8 +860,6 @@ set( NOT_COMPILED_SOURCE_FILES
|
|||
sc_man_scanner.h
|
||||
sc_man_scanner.re
|
||||
g_hexen/a_heresiarch.cpp
|
||||
g_hexen/a_magecone.cpp
|
||||
g_hexen/a_magelightning.cpp
|
||||
g_hexen/a_magestaff.cpp
|
||||
g_hexen/a_serpent.cpp
|
||||
g_hexen/a_spike.cpp
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
// Include all the Hexen stuff here to reduce compile time
|
||||
#include "a_heresiarch.cpp"
|
||||
#include "a_magelightning.cpp"
|
||||
#include "a_magestaff.cpp"
|
||||
#include "a_serpent.cpp"
|
||||
#include "a_spike.cpp"
|
||||
|
|
|
@ -1,274 +0,0 @@
|
|||
/*
|
||||
#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 "a_action.h"
|
||||
#include "p_pspr.h"
|
||||
#include "gstrings.h"
|
||||
#include "a_hexenglobal.h"
|
||||
#include "vm.h"
|
||||
#include "g_level.h"
|
||||
*/
|
||||
|
||||
#define ZAGSPEED 1.
|
||||
|
||||
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");
|
||||
|
||||
DECLARE_ACTION(A_LightningClip)
|
||||
DECLARE_ACTION(A_LightningZap)
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// A_LightningReady
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LightningReady)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE(AActor);
|
||||
|
||||
DoReadyWeapon(self);
|
||||
if (pr_lightningready() < 160)
|
||||
{
|
||||
S_Sound (self, CHAN_WEAPON, "MageLightningReady", 1, ATTN_NORM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// A_LightningClip
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LightningClip)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
|
||||
AActor *cMo;
|
||||
AActor *target = NULL;
|
||||
int zigZag;
|
||||
|
||||
if (self->flags3 & MF3_FLOORHUGGER)
|
||||
{
|
||||
if (self->lastenemy == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
self->SetZ(self->floorz);
|
||||
target = self->lastenemy->tracer;
|
||||
}
|
||||
else if (self->flags3 & MF3_CEILINGHUGGER)
|
||||
{
|
||||
self->SetZ(self->ceilingz - self->Height);
|
||||
target = self->tracer;
|
||||
}
|
||||
if (self->flags3 & MF3_FLOORHUGGER)
|
||||
{ // floor lightning zig-zags, and forces the ceiling lightning to mimic
|
||||
cMo = self->lastenemy;
|
||||
zigZag = pr_lightningclip();
|
||||
if((zigZag > 128 && self->special1 < 2) || self->special1 < -2)
|
||||
{
|
||||
self->Thrust(self->Angles.Yaw + 90, ZAGSPEED);
|
||||
if(cMo)
|
||||
{
|
||||
cMo->Thrust(self->Angles.Yaw + 90, ZAGSPEED);
|
||||
}
|
||||
self->special1++;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->Thrust(self->Angles.Yaw - 90, ZAGSPEED);
|
||||
if(cMo)
|
||||
{
|
||||
cMo->Thrust(self->Angles.Yaw - 90, ZAGSPEED);
|
||||
}
|
||||
self->special1--;
|
||||
}
|
||||
}
|
||||
if(target)
|
||||
{
|
||||
if(target->health <= 0)
|
||||
{
|
||||
P_ExplodeMissile(self, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->Angles.Yaw = self->AngleTo(target);
|
||||
self->VelFromAngle(self->Speed / 2);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// A_LightningZap
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LightningZap)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
|
||||
PClassActor *lightning = PClass::FindActor(self->GetClass()->MissileName);
|
||||
AActor *mo;
|
||||
|
||||
if (lightning == NULL)
|
||||
{
|
||||
lightning = PClass::FindActor(NAME_LightningZap);
|
||||
}
|
||||
|
||||
CALL_ACTION(A_LightningClip, self);
|
||||
|
||||
self->health -= 8;
|
||||
if (self->health <= 0)
|
||||
{
|
||||
self->SetState (self->FindState(NAME_Death));
|
||||
return 0;
|
||||
}
|
||||
double deltaX = (pr_zap() - 128) * self->radius / 256;
|
||||
double deltaY = (pr_zap() - 128) * self->radius / 256;
|
||||
double deltaZ = (self->flags3 & MF3_FLOORHUGGER) ? 10 : -10;
|
||||
|
||||
mo = Spawn(lightning, self->Vec3Offset(deltaX, deltaY, deltaZ), ALLOW_REPLACE);
|
||||
if (mo)
|
||||
{
|
||||
mo->lastenemy = self;
|
||||
mo->Vel.X = self->Vel.X;
|
||||
mo->Vel.Y = self->Vel.Y;
|
||||
mo->Vel.Z = (self->flags3 & MF3_FLOORHUGGER) ? 20 : -20;
|
||||
mo->target = self->target;
|
||||
}
|
||||
if ((self->flags3 & MF3_FLOORHUGGER) && pr_zapf() < 160)
|
||||
{
|
||||
S_Sound (self, CHAN_BODY, self->ActiveSound, 1, ATTN_NORM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// A_MLightningAttack
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_MLightningAttack)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE(AActor);
|
||||
PARAM_CLASS_DEF(floor, AActor);
|
||||
PARAM_CLASS_DEF(ceiling, AActor);
|
||||
|
||||
AActor *fmo, *cmo;
|
||||
|
||||
fmo = P_SpawnPlayerMissile (self, floor);
|
||||
cmo = P_SpawnPlayerMissile (self, ceiling);
|
||||
if (fmo)
|
||||
{
|
||||
fmo->special1 = 0;
|
||||
fmo->lastenemy = cmo;
|
||||
CALL_ACTION(A_LightningZap, fmo);
|
||||
}
|
||||
if (cmo)
|
||||
{
|
||||
cmo->tracer = NULL;
|
||||
cmo->lastenemy = fmo;
|
||||
CALL_ACTION(A_LightningZap, cmo);
|
||||
}
|
||||
S_Sound (self, CHAN_BODY, "MageLightningFire", 1, ATTN_NORM);
|
||||
|
||||
if (self->player != NULL)
|
||||
{
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
weapon->DepleteAmmo (weapon->bAltFire);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// A_ZapMimic
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ZapMimic)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
|
||||
AActor *mo;
|
||||
|
||||
mo = self->lastenemy;
|
||||
if (mo)
|
||||
{
|
||||
if (mo->state >= mo->FindState(NAME_Death))
|
||||
{
|
||||
P_ExplodeMissile (self, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->Vel.X = mo->Vel.X;
|
||||
self->Vel.Y = mo->Vel.Y;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// A_LastZap
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LastZap)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PClassActor *lightning = PClass::FindActor(self->GetClass()->MissileName);
|
||||
|
||||
AActor *mo;
|
||||
|
||||
if (lightning == NULL)
|
||||
{
|
||||
lightning = PClass::FindActor(NAME_LightningZap);
|
||||
}
|
||||
mo = Spawn(lightning, self->Pos(), ALLOW_REPLACE);
|
||||
if (mo)
|
||||
{
|
||||
mo->SetState (mo->FindState (NAME_Death));
|
||||
mo->Vel.Z = 40;
|
||||
mo->SetDamage(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// A_LightningRemove
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_LightningRemove)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
|
||||
AActor *mo;
|
||||
|
||||
mo = self->lastenemy;
|
||||
if (mo)
|
||||
{
|
||||
mo->lastenemy = NULL;
|
||||
P_ExplodeMissile (mo, NULL, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1751,6 +1751,15 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
|
|||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, ExplodeMissile)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_POINTER_DEF(line, line_t);
|
||||
PARAM_OBJECT_DEF(target, AActor);
|
||||
P_ExplodeMissile(self, line, target);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void AActor::PlayBounceSound(bool onfloor)
|
||||
{
|
||||
|
|
|
@ -289,6 +289,7 @@ class Actor : Thinker native
|
|||
native void NoiseAlert(Actor emitter, bool splash = false, double maxdist = 0);
|
||||
native void ClearBounce();
|
||||
|
||||
native void ExplodeMissile(line lin = null, Actor target = null);
|
||||
native void RestoreDamage();
|
||||
native int SpawnHealth();
|
||||
native void SetDamage(int dmg);
|
||||
|
|
|
@ -16,9 +16,6 @@ class MWeapLightning : MageWeapon
|
|||
Tag "$TAG_MWEAPLIGHTNING";
|
||||
}
|
||||
|
||||
action native void A_LightningReady();
|
||||
action native void A_MLightningAttack(class<Actor> floor = "LightningFloor", class<Actor> ceiling = "LightningCeiling");
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
@ -50,6 +47,57 @@ class MWeapLightning : MageWeapon
|
|||
MLNG B 2 Bright Offset (0, 40);
|
||||
Goto Ready;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// A_LightningReady
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
action void A_LightningReady()
|
||||
{
|
||||
A_WeaponReady();
|
||||
if (random[LightningReady]() < 160)
|
||||
{
|
||||
A_PlaySound ("MageLightningReady", CHAN_WEAPON);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// A_MLightningAttack
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
action void A_MLightningAttack(class<Actor> floor = "LightningFloor", class<Actor> ceiling = "LightningCeiling")
|
||||
{
|
||||
LightningFloor fmo = LightningFloor(SpawnPlayerMissile (floor));
|
||||
LightningCeiling cmo = LightningCeiling(SpawnPlayerMissile (ceiling));
|
||||
if (fmo)
|
||||
{
|
||||
fmo.special1 = 0;
|
||||
fmo.lastenemy = cmo;
|
||||
fmo.A_LightningZap();
|
||||
}
|
||||
if (cmo)
|
||||
{
|
||||
cmo.tracer = NULL;
|
||||
cmo.lastenemy = fmo;
|
||||
cmo.A_LightningZap();
|
||||
}
|
||||
A_PlaySound ("MageLightningFire", CHAN_BODY);
|
||||
|
||||
if (player != NULL)
|
||||
{
|
||||
Weapon weapon = player.ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
weapon.DepleteAmmo (weapon.bAltFire);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Ceiling Lightning --------------------------------------------------------
|
||||
|
@ -76,7 +124,7 @@ class Lightning : Actor
|
|||
if ((!thing.player && !thing.bBoss) || !(level.time&1))
|
||||
{
|
||||
thing.DamageMobj(self, target, 3, 'Electric');
|
||||
A_PlaySound(self.AttackSound, CHAN_WEAPON, 1, true);
|
||||
A_PlaySound(AttackSound, CHAN_WEAPON, 1, true);
|
||||
if (thing.bIsMonster && random[LightningHit]() < 64)
|
||||
{
|
||||
thing.Howl ();
|
||||
|
@ -106,6 +154,8 @@ class Lightning : Actor
|
|||
|
||||
class LightningCeiling : Lightning
|
||||
{
|
||||
const ZAGSPEED = 1;
|
||||
|
||||
Default
|
||||
{
|
||||
Health 144;
|
||||
|
@ -118,10 +168,6 @@ class LightningCeiling : Lightning
|
|||
RenderStyle "Add";
|
||||
}
|
||||
|
||||
native void A_LightningZap();
|
||||
native void A_LightningClip();
|
||||
native void A_LightningRemove();
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
@ -143,6 +189,126 @@ class LightningCeiling : Lightning
|
|||
ACLO E 1050;
|
||||
Stop;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// A_LightningClip
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void A_LightningClip()
|
||||
{
|
||||
Actor cMo;
|
||||
Actor target = NULL;
|
||||
int zigZag;
|
||||
|
||||
if (bFloorHugger)
|
||||
{
|
||||
if (lastenemy == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SetZ(floorz);
|
||||
target = lastenemy.tracer;
|
||||
}
|
||||
else if (bCeilingHugger)
|
||||
{
|
||||
SetZ(ceilingz - Height);
|
||||
target = tracer;
|
||||
}
|
||||
if (bFloorHugger)
|
||||
{ // floor lightning zig-zags, and forces the ceiling lightning to mimic
|
||||
cMo = lastenemy;
|
||||
zigZag = random[LightningClip]();
|
||||
if((zigZag > 128 && special1 < 2) || special1 < -2)
|
||||
{
|
||||
Thrust(ZAGSPEED, angle + 90);
|
||||
if(cMo)
|
||||
{
|
||||
cMo.Thrust(ZAGSPEED, angle + 90);
|
||||
}
|
||||
special1++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Thrust(ZAGSPEED,angle - 90);
|
||||
if(cMo)
|
||||
{
|
||||
cMo.Thrust(ZAGSPEED, angle - 90);
|
||||
}
|
||||
special1--;
|
||||
}
|
||||
}
|
||||
if(target)
|
||||
{
|
||||
if(target.health <= 0)
|
||||
{
|
||||
ExplodeMissile();
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = AngleTo(target);
|
||||
VelFromAngle(Speed / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// A_LightningZap
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void A_LightningZap()
|
||||
{
|
||||
Class<Actor> lightning = MissileName;
|
||||
if (lightning == NULL) lightning = "LightningZap";
|
||||
|
||||
A_LightningClip();
|
||||
|
||||
health -= 8;
|
||||
if (health <= 0)
|
||||
{
|
||||
SetStateLabel ("Death");
|
||||
return;
|
||||
}
|
||||
double deltaX = (random[LightningZap]() - 128) * radius / 256;
|
||||
double deltaY = (random[LightningZap]() - 128) * radius / 256;
|
||||
double deltaZ = (bFloorHugger) ? 10 : -10;
|
||||
|
||||
Actor mo = Spawn(lightning, Vec3Offset(deltaX, deltaY, deltaZ), ALLOW_REPLACE);
|
||||
if (mo)
|
||||
{
|
||||
mo.lastenemy = self;
|
||||
mo.Vel.X = Vel.X;
|
||||
mo.Vel.Y = Vel.Y;
|
||||
mo.Vel.Z = (bFloorHugger) ? 20 : -20;
|
||||
mo.target = target;
|
||||
}
|
||||
if (bFloorHugger && random[LightningZap]() < 160)
|
||||
{
|
||||
A_PlaySound (ActiveSound, CHAN_BODY);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// A_LightningRemove
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void A_LightningRemove()
|
||||
{
|
||||
Actor mo = lastenemy;
|
||||
if (mo)
|
||||
{
|
||||
bNoTarget = true; // tell A_ZapMimic that we are dead. The original code did a state pointer compare which is not safe.
|
||||
mo.lastenemy = NULL;
|
||||
mo.ExplodeMissile ();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Floor Lightning ----------------------------------------------------------
|
||||
|
@ -156,8 +322,6 @@ class LightningFloor : LightningCeiling
|
|||
RenderStyle "Add";
|
||||
}
|
||||
|
||||
native void A_LastZap();
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
@ -176,6 +340,26 @@ class LightningFloor : LightningCeiling
|
|||
MLF2 P 1 Bright A_HideThing;
|
||||
Goto Super::Death + 19;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// A_LastZap
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void A_LastZap()
|
||||
{
|
||||
Class<Actor> lightning = MissileName;
|
||||
if (lightning == NULL) lightning = "LightningZap";
|
||||
|
||||
Actor mo = Spawn(lightning, self.Pos, ALLOW_REPLACE);
|
||||
if (mo)
|
||||
{
|
||||
mo.SetStateLabel ("Death");
|
||||
mo.Vel.Z = 40;
|
||||
mo.SetDamage(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lightning Zap ------------------------------------------------------------
|
||||
|
@ -194,8 +378,6 @@ class LightningZap : Actor
|
|||
Obituary "$OB_MPMWEAPLIGHTNING";
|
||||
}
|
||||
|
||||
native void A_ZapMimic();
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
@ -235,4 +417,28 @@ class LightningZap : Actor
|
|||
return -1;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// A_ZapMimic
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void A_ZapMimic()
|
||||
{
|
||||
Actor mo = lastenemy;
|
||||
if (mo)
|
||||
{
|
||||
if (mo.bNoTarget)
|
||||
{
|
||||
ExplodeMissile ();
|
||||
}
|
||||
else
|
||||
{
|
||||
Vel.X = mo.Vel.X;
|
||||
Vel.Y = mo.Vel.Y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue