From f9a13880667bd3e486bada16f425ca33e3b9f1d0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Nov 2016 22:14:18 +0100 Subject: [PATCH] - scriptified Hexen's lightning weapon. --- src/CMakeLists.txt | 2 - src/g_hexen/a_hexenmisc.cpp | 1 - src/g_hexen/a_magelightning.cpp | 274 ------------------ src/p_mobj.cpp | 9 + wadsrc/static/zscript/actor.txt | 1 + wadsrc/static/zscript/hexen/magelightning.txt | 230 ++++++++++++++- 6 files changed, 228 insertions(+), 289 deletions(-) delete mode 100644 src/g_hexen/a_magelightning.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6111d1714..1abd8e71b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/g_hexen/a_hexenmisc.cpp b/src/g_hexen/a_hexenmisc.cpp index e6f27c434..45a407faa 100644 --- a/src/g_hexen/a_hexenmisc.cpp +++ b/src/g_hexen/a_hexenmisc.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" diff --git a/src/g_hexen/a_magelightning.cpp b/src/g_hexen/a_magelightning.cpp deleted file mode 100644 index 794e6660b..000000000 --- a/src/g_hexen/a_magelightning.cpp +++ /dev/null @@ -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; -} diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 250927a5a..22b52d18b 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -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) { diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 189f70090..94adbf227 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -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); diff --git a/wadsrc/static/zscript/hexen/magelightning.txt b/wadsrc/static/zscript/hexen/magelightning.txt index b778451ac..343c96012 100644 --- a/wadsrc/static/zscript/hexen/magelightning.txt +++ b/wadsrc/static/zscript/hexen/magelightning.txt @@ -16,9 +16,6 @@ class MWeapLightning : MageWeapon Tag "$TAG_MWEAPLIGHTNING"; } - action native void A_LightningReady(); - action native void A_MLightningAttack(class floor = "LightningFloor", class 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 floor = "LightningFloor", class 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 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 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; + } + } + } + + }