mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
- scriptified Heretic's wizard.
This commit is contained in:
parent
a5f9eb5be1
commit
14a9c13113
7 changed files with 135 additions and 102 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -56,6 +56,8 @@ class Actor : Thinker native
|
|||
|
||||
native static readonly<Actor> GetDefaultByType(class<Actor> cls);
|
||||
native static float deltaangle(float ang1, float ang2);
|
||||
native static float GetDefaultSpeed(class<Actor> 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<Actor> type, vector3 pos = (0,0,0), int replace = NO_REPLACE);
|
||||
native Actor SpawnMissile(Actor dest, class<Actor> type, Actor owner = null);
|
||||
native Actor SpawnMissileZ (double z, Actor dest, class<Actor> type);
|
||||
native Actor SpawnMissileAngleZSpeed (double z, class<Actor> type, float angle, double vz, double speed, Actor owner = null, bool checkspawn = true);
|
||||
|
||||
native Actor OldSpawnMissile(Actor dest, class<Actor> type, Actor owner = null);
|
||||
native Actor SpawnPuff(class<Actor> pufftype, vector3 pos, float hitdir, float particledir, int updown, int flags = 0, Actor vict = null);
|
||||
|
||||
|
@ -144,6 +148,26 @@ class Actor : Thinker native
|
|||
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<Actor> type, float angle, double vz)
|
||||
{
|
||||
return SpawnMissileAngleZSpeed (pos.z + 32 + GetBobOffset(), type, angle, vz, GetDefaultSpeed (type));
|
||||
}
|
||||
|
||||
Actor SpawnMissileAngleZ (double z, class<Actor> 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)
|
||||
{
|
||||
Actor aptr = GetPointer(ptr);
|
||||
|
|
|
@ -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.);
|
||||
|
|
|
@ -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 --------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue