From 14a9c13113982870410856bb7faf8d6633208d4f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 11 Nov 2016 23:32:13 +0100 Subject: [PATCH] - scriptified Heretic's wizard. --- src/CMakeLists.txt | 1 - src/g_heretic/a_wizard.cpp | 95 ------------------------ src/p_mobj.cpp | 27 +++++++ src/scripting/codegeneration/codegen.cpp | 14 +++- wadsrc/static/zscript/actor.txt | 24 ++++++ wadsrc/static/zscript/constants.txt | 7 ++ wadsrc/static/zscript/heretic/wizard.txt | 69 +++++++++++++++-- 7 files changed, 135 insertions(+), 102 deletions(-) delete mode 100644 src/g_heretic/a_wizard.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9f5b0346c..b2f23afb1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -857,7 +857,6 @@ set( NOT_COMPILED_SOURCE_FILES g_heretic/a_hereticartifacts.cpp g_heretic/a_hereticweaps.cpp g_heretic/a_ironlich.cpp - g_heretic/a_wizard.cpp g_hexen/a_bats.cpp g_hexen/a_bishop.cpp g_hexen/a_blastradius.cpp diff --git a/src/g_heretic/a_wizard.cpp b/src/g_heretic/a_wizard.cpp deleted file mode 100644 index 271fd5592..000000000 --- a/src/g_heretic/a_wizard.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* -#include "actor.h" -#include "info.h" -#include "m_random.h" -#include "s_sound.h" -#include "p_local.h" -#include "p_enemy.h" -#include "a_action.h" -#include "gstrings.h" -#include "vm.h" -*/ - -static FRandom pr_wizatk3 ("WizAtk3"); - -//---------------------------------------------------------------------------- -// -// PROC A_GhostOff -// -//---------------------------------------------------------------------------- - -DEFINE_ACTION_FUNCTION(AActor, A_GhostOff) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->RenderStyle = STYLE_Normal; - self->flags3 &= ~MF3_GHOST; - return 0; -} - -//---------------------------------------------------------------------------- -// -// PROC A_WizAtk1 -// -//---------------------------------------------------------------------------- - -DEFINE_ACTION_FUNCTION(AActor, A_WizAtk1) -{ - PARAM_SELF_PROLOGUE(AActor); - - A_FaceTarget (self); - CALL_ACTION(A_GhostOff, self); - return 0; -} - -//---------------------------------------------------------------------------- -// -// PROC A_WizAtk2 -// -//---------------------------------------------------------------------------- - -DEFINE_ACTION_FUNCTION(AActor, A_WizAtk2) -{ - PARAM_SELF_PROLOGUE(AActor); - - A_FaceTarget (self); - self->Alpha = HR_SHADOW; - self->RenderStyle = STYLE_Translucent; - self->flags3 |= MF3_GHOST; - return 0; -} - -//---------------------------------------------------------------------------- -// -// PROC A_WizAtk3 -// -//---------------------------------------------------------------------------- - -DEFINE_ACTION_FUNCTION(AActor, A_WizAtk3) -{ - PARAM_SELF_PROLOGUE(AActor); - - AActor *mo; - - CALL_ACTION(A_GhostOff, self); - if (!self->target) - { - return 0; - } - S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); - if (self->CheckMeleeRange()) - { - int damage = pr_wizatk3.HitDice (4); - int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); - return 0; - } - PClassActor *fx = PClass::FindActor("WizardFX1"); - mo = P_SpawnMissile (self, self->target, fx); - if (mo != NULL) - { - P_SpawnMissileAngle(self, fx, mo->Angles.Yaw - 45. / 8, mo->Vel.Z); - P_SpawnMissileAngle(self, fx, mo->Angles.Yaw + 45. / 8, mo->Vel.Z); - } - return 0; -} diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 400fe8c74..94b739135 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6041,6 +6041,13 @@ static double GetDefaultSpeed(PClassActor *type) return GetDefaultByType(type)->Speed; } +DEFINE_ACTION_FUNCTION(AActor, GetDefaultSpeed) +{ + PARAM_PROLOGUE; + PARAM_CLASS(type, AActor); + ACTION_RETURN_FLOAT(GetDefaultSpeed(type)); +} + //--------------------------------------------------------------------------- // // FUNC P_SpawnMissile @@ -6283,6 +6290,19 @@ AActor *P_SpawnMissileAngleZSpeed (AActor *source, double z, return (!checkspawn || P_CheckMissileSpawn(mo, source->radius)) ? mo : NULL; } +DEFINE_ACTION_FUNCTION(AActor, SpawnMissileAngleZSpeed) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_FLOAT(z); + PARAM_CLASS(type, AActor); + PARAM_ANGLE(angle); + PARAM_FLOAT(vz); + PARAM_FLOAT(speed); + PARAM_OBJECT_DEF(owner, AActor); + PARAM_BOOL_DEF(checkspawn); + ACTION_RETURN_OBJECT(P_SpawnMissileAngleZSpeed(self, z, type, angle, vz, speed, owner, checkspawn)); +} + /* ================ = @@ -6879,6 +6899,13 @@ DEFINE_ACTION_FUNCTION(AActor, GetDefaultByType) ACTION_RETURN_OBJECT(GetDefaultByType(cls)); } +DEFINE_ACTION_FUNCTION(AActor, GetBobOffset) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_FLOAT_DEF(frac); + ACTION_RETURN_FLOAT(self->GetBobOffset(frac)); +} + // This combines all 3 variations of the internal function DEFINE_ACTION_FUNCTION(AActor, VelFromAngle) { diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index 5e212dfe3..2759e41ba 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -6680,7 +6680,19 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx) return nullptr; } } - + } + else + { + if ((unsigned)implicit < argtypes.Size() && argtypes[implicit] != nullptr) + { + auto flags = Function->Variants[0].ArgFlags[implicit]; + if (!(flags & VARF_Optional)) + { + ScriptPosition.Message(MSG_ERROR, "Insufficient arguments in call to %s", Function->SymbolName.GetChars()); + delete this; + return nullptr; + } + } } if (failed) { diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 0baac6bf0..d9fd23a46 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -56,6 +56,8 @@ class Actor : Thinker native native static readonly GetDefaultByType(class cls); native static float deltaangle(float ang1, float ang2); + native static float GetDefaultSpeed(class type); + native float GetBobOffset(float frac = 0); native void SetDamage(int dmg); native static bool isDehState(state st); native void SetOrigin(vector3 newpos, bool moving); @@ -64,6 +66,8 @@ class Actor : Thinker native native static Actor Spawn(class type, vector3 pos = (0,0,0), int replace = NO_REPLACE); native Actor SpawnMissile(Actor dest, class type, Actor owner = null); native Actor SpawnMissileZ (double z, Actor dest, class type); + native Actor SpawnMissileAngleZSpeed (double z, class type, float angle, double vz, double speed, Actor owner = null, bool checkspawn = true); + native Actor OldSpawnMissile(Actor dest, class type, Actor owner = null); native Actor SpawnPuff(class pufftype, vector3 pos, float hitdir, float particledir, int updown, int flags = 0, Actor vict = null); @@ -143,6 +147,26 @@ class Actor : Thinker native void A_SetRipMax(int maximum) { RipLevelMax = maximum; } void A_ScreamAndUnblock() { A_Scream(); A_NoBlocking(); } void A_ActiveAndUnblock() { A_ActiveSound(); A_NoBlocking(); } + + //--------------------------------------------------------------------------- + // + // FUNC P_SpawnMissileAngle + // + // Returns NULL if the missile exploded immediately, otherwise returns + // a mobj_t pointer to the missile. + // + //--------------------------------------------------------------------------- + + Actor SpawnMissileAngle (class type, float angle, double vz) + { + return SpawnMissileAngleZSpeed (pos.z + 32 + GetBobOffset(), type, angle, vz, GetDefaultSpeed (type)); + } + + Actor SpawnMissileAngleZ (double z, class type, double angle, double vz) + { + return SpawnMissileAngleZSpeed (z, type, angle, vz, GetDefaultSpeed (type)); + } + void A_SetScale(float scalex, float scaley = 0, int ptr = AAPTR_DEFAULT, bool usezero = false) { diff --git a/wadsrc/static/zscript/constants.txt b/wadsrc/static/zscript/constants.txt index 9562e3f40..7c3038a74 100644 --- a/wadsrc/static/zscript/constants.txt +++ b/wadsrc/static/zscript/constants.txt @@ -883,3 +883,10 @@ enum EReplace NO_REPLACE = 0, ALLOW_REPLACE = 1 } + +// This translucency value produces the closest match to Heretic's TINTTAB. +// ~40% of the value of the overlaid image shows through. +const HR_SHADOW = (0x6800 / 65536.); +// Hexen's TINTTAB is the same as Heretic's, just reversed. +const HX_SHADOW = (0x9800 / 65536.); +const HX_ALTSHADOW = (0x6800 / 65536.); diff --git a/wadsrc/static/zscript/heretic/wizard.txt b/wadsrc/static/zscript/heretic/wizard.txt index d33e2dd8a..d146ae220 100644 --- a/wadsrc/static/zscript/heretic/wizard.txt +++ b/wadsrc/static/zscript/heretic/wizard.txt @@ -26,11 +26,6 @@ class Wizard : Actor DropItem "ArtiTomeOfPower", 4, 0; } - native void A_GhostOff (); - native void A_WizAtk1 (); - native void A_WizAtk2 (); - native void A_WizAtk3 (); - States { Spawn: @@ -70,6 +65,70 @@ class Wizard : Actor WZRD M -1 A_SetFloorClip; Stop; } + + //---------------------------------------------------------------------------- + // + // PROC A_GhostOff + // + //---------------------------------------------------------------------------- + + void A_GhostOff () + { + A_SetRenderStyle(1.0, STYLE_Normal); + bGhost = false; + } + + //---------------------------------------------------------------------------- + // + // PROC A_WizAtk1 + // + //---------------------------------------------------------------------------- + + void A_WizAtk1 () + { + A_FaceTarget (); + A_GhostOff(); + } + + //---------------------------------------------------------------------------- + // + // PROC A_WizAtk2 + // + //---------------------------------------------------------------------------- + + void A_WizAtk2 () + { + A_FaceTarget (); + A_SetRenderStyle(HR_SHADOW, STYLE_Translucent); + bGhost = true; + } + + //---------------------------------------------------------------------------- + // + // PROC A_WizAtk3 + // + //---------------------------------------------------------------------------- + + void A_WizAtk3 () + { + A_GhostOff(); + if (!target) return; + A_PlaySound (AttackSound, CHAN_WEAPON); + if (CheckMeleeRange()) + { + int damage = random[WizAtk3](1, 8) * 4; + int newdam = target.DamageMobj (self, self, damage, 'Melee'); + target.TraceBleed (newdam > 0 ? newdam : damage, self); + return; + } + Actor mo = SpawnMissile (target, "WizardFX1"); + if (mo != null) + { + SpawnMissileAngle("WizardFX1", mo.Angle - 45. / 8, mo.Vel.Z); + SpawnMissileAngle("WizardFX1", mo.Angle + 45. / 8, mo.Vel.Z); + } + } + } // Projectile --------------------------------------------------------