mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-24 21:21:04 +00:00
- scriptified Hexen's Firedemon.
This commit is contained in:
parent
213b3f1fe4
commit
49ef541513
8 changed files with 264 additions and 258 deletions
|
@ -868,7 +868,6 @@ set( NOT_COMPILED_SOURCE_FILES
|
||||||
g_hexen/a_fighterhammer.cpp
|
g_hexen/a_fighterhammer.cpp
|
||||||
g_hexen/a_fighterplayer.cpp
|
g_hexen/a_fighterplayer.cpp
|
||||||
g_hexen/a_fighterquietus.cpp
|
g_hexen/a_fighterquietus.cpp
|
||||||
g_hexen/a_firedemon.cpp
|
|
||||||
g_hexen/a_flechette.cpp
|
g_hexen/a_flechette.cpp
|
||||||
g_hexen/a_flies.cpp
|
g_hexen/a_flies.cpp
|
||||||
g_hexen/a_fog.cpp
|
g_hexen/a_fog.cpp
|
||||||
|
|
|
@ -1,248 +0,0 @@
|
||||||
/*
|
|
||||||
#include "actor.h"
|
|
||||||
#include "info.h"
|
|
||||||
#include "p_local.h"
|
|
||||||
#include "s_sound.h"
|
|
||||||
#include "p_enemy.h"
|
|
||||||
#include "a_action.h"
|
|
||||||
#include "m_random.h"
|
|
||||||
#include "vm.h"
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define FIREDEMON_ATTACK_RANGE (64*8.)
|
|
||||||
|
|
||||||
static FRandom pr_firedemonrock ("FireDemonRock");
|
|
||||||
static FRandom pr_smbounce ("SMBounce");
|
|
||||||
static FRandom pr_firedemonchase ("FiredChase");
|
|
||||||
static FRandom pr_firedemonsplotch ("FiredSplotch");
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
// Fire Demon AI
|
|
||||||
//
|
|
||||||
// special1 index into floatbob
|
|
||||||
// special2 whether strafing or not
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// A_FiredSpawnRock
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
void A_FiredSpawnRock (AActor *actor)
|
|
||||||
{
|
|
||||||
AActor *mo;
|
|
||||||
PClassActor *rtype;
|
|
||||||
|
|
||||||
switch (pr_firedemonrock() % 5)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
rtype = PClass::FindActor("FireDemonRock1");
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
rtype = PClass::FindActor("FireDemonRock2");
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
rtype = PClass::FindActor("FireDemonRock3");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
rtype = PClass::FindActor("FireDemonRock4");
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
default:
|
|
||||||
rtype = PClass::FindActor("FireDemonRock5");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
double xo = (pr_firedemonrock() - 128) / 16.;
|
|
||||||
double yo = (pr_firedemonrock() - 128) / 16.;
|
|
||||||
double zo = pr_firedemonrock() / 32.;
|
|
||||||
mo = Spawn (rtype, actor->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
|
|
||||||
if (mo)
|
|
||||||
{
|
|
||||||
mo->target = actor;
|
|
||||||
mo->Vel.X = (pr_firedemonrock() - 128) / 64.;
|
|
||||||
mo->Vel.Y = (pr_firedemonrock() - 128) / 64.;
|
|
||||||
mo->Vel.Z = (pr_firedemonrock() / 64.);
|
|
||||||
mo->special1 = 2; // Number bounces
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize fire demon
|
|
||||||
actor->special2 = 0;
|
|
||||||
actor->flags &= ~MF_JUSTATTACKED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// A_FiredRocks
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_FiredRocks)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
|
||||||
|
|
||||||
A_FiredSpawnRock (self);
|
|
||||||
A_FiredSpawnRock (self);
|
|
||||||
A_FiredSpawnRock (self);
|
|
||||||
A_FiredSpawnRock (self);
|
|
||||||
A_FiredSpawnRock (self);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// A_SmBounce
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_SmBounce)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
|
||||||
|
|
||||||
// give some more velocity (x,y,&z)
|
|
||||||
self->SetZ(self->floorz + 1);
|
|
||||||
self->Vel.Z = 2. + pr_smbounce() / 64.;
|
|
||||||
self->Vel.X = pr_smbounce() % 3;
|
|
||||||
self->Vel.Y = pr_smbounce() % 3;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// A_FiredAttack
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_FiredAttack)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
|
||||||
|
|
||||||
if (self->target == NULL)
|
|
||||||
return 0;
|
|
||||||
AActor *mo = P_SpawnMissile (self, self->target, PClass::FindActor("FireDemonMissile"));
|
|
||||||
if (mo) S_Sound (self, CHAN_BODY, "FireDemonAttack", 1, ATTN_NORM);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// A_FiredChase
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
|
||||||
|
|
||||||
int weaveindex = self->special1;
|
|
||||||
AActor *target = self->target;
|
|
||||||
DAngle ang;
|
|
||||||
double dist;
|
|
||||||
|
|
||||||
if (self->reactiontime) self->reactiontime--;
|
|
||||||
if (self->threshold) self->threshold--;
|
|
||||||
|
|
||||||
// Float up and down
|
|
||||||
self->AddZ(BobSin(weaveindex));
|
|
||||||
self->special1 = (weaveindex + 2) & 63;
|
|
||||||
|
|
||||||
// Ensure it stays above certain height
|
|
||||||
if (self->Z() < self->floorz + 64)
|
|
||||||
{
|
|
||||||
self->AddZ(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!self->target || !(self->target->flags&MF_SHOOTABLE))
|
|
||||||
{ // Invalid target
|
|
||||||
P_LookForPlayers (self,true, NULL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strafe
|
|
||||||
if (self->special2 > 0)
|
|
||||||
{
|
|
||||||
self->special2--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self->special2 = 0;
|
|
||||||
self->Vel.X = self->Vel.Y = 0;
|
|
||||||
dist = self->Distance2D(target);
|
|
||||||
if (dist < FIREDEMON_ATTACK_RANGE)
|
|
||||||
{
|
|
||||||
if (pr_firedemonchase() < 30)
|
|
||||||
{
|
|
||||||
ang = self->AngleTo(target);
|
|
||||||
if (pr_firedemonchase() < 128)
|
|
||||||
ang += 90;
|
|
||||||
else
|
|
||||||
ang -= 90;
|
|
||||||
self->Thrust(ang, 8);
|
|
||||||
self->special2 = 3; // strafe time
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FaceMovementDirection (self);
|
|
||||||
|
|
||||||
// Normal movement
|
|
||||||
if (!self->special2)
|
|
||||||
{
|
|
||||||
if (--self->movecount<0 || !P_Move (self))
|
|
||||||
{
|
|
||||||
P_NewChaseDir (self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do missile attack
|
|
||||||
if (!(self->flags & MF_JUSTATTACKED))
|
|
||||||
{
|
|
||||||
if (P_CheckMissileRange (self) && (pr_firedemonchase() < 20))
|
|
||||||
{
|
|
||||||
self->SetState (self->MissileState);
|
|
||||||
self->flags |= MF_JUSTATTACKED;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self->flags &= ~MF_JUSTATTACKED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// make active sound
|
|
||||||
if (pr_firedemonchase() < 3)
|
|
||||||
{
|
|
||||||
self->PlayActiveSound ();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// A_FiredSplotch
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_FiredSplotch)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
|
||||||
|
|
||||||
AActor *mo;
|
|
||||||
|
|
||||||
mo = Spawn ("FireDemonSplotch1", self->Pos(), ALLOW_REPLACE);
|
|
||||||
if (mo)
|
|
||||||
{
|
|
||||||
mo->Vel.X = (pr_firedemonsplotch() - 128) / 32.;
|
|
||||||
mo->Vel.Y = (pr_firedemonsplotch() - 128) / 32.;
|
|
||||||
mo->Vel.Z = (pr_firedemonsplotch() / 64.) + 3;
|
|
||||||
}
|
|
||||||
mo = Spawn ("FireDemonSplotch2", self->Pos(), ALLOW_REPLACE);
|
|
||||||
if (mo)
|
|
||||||
{
|
|
||||||
mo->Vel.X = (pr_firedemonsplotch() - 128) / 32.;
|
|
||||||
mo->Vel.Y = (pr_firedemonsplotch() - 128) / 32.;
|
|
||||||
mo->Vel.Z = (pr_firedemonsplotch() / 64.) + 3;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include "a_fighterhammer.cpp"
|
#include "a_fighterhammer.cpp"
|
||||||
#include "a_fighterplayer.cpp"
|
#include "a_fighterplayer.cpp"
|
||||||
#include "a_fighterquietus.cpp"
|
#include "a_fighterquietus.cpp"
|
||||||
#include "a_firedemon.cpp"
|
|
||||||
#include "a_flechette.cpp"
|
#include "a_flechette.cpp"
|
||||||
#include "a_flies.cpp"
|
#include "a_flies.cpp"
|
||||||
#include "a_fog.cpp"
|
#include "a_fog.cpp"
|
||||||
|
|
|
@ -449,3 +449,10 @@ void FaceMovementDirection(AActor *actor)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(AActor, FaceMovementDirection)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
FaceMovementDirection(self);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -414,6 +414,12 @@ bool P_CheckMissileRange (AActor *actor)
|
||||||
return actor->SuggestMissileAttack (dist);
|
return actor->SuggestMissileAttack (dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(AActor, CheckMissileRange)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
ACTION_RETURN_BOOL(P_CheckMissileRange(self));
|
||||||
|
}
|
||||||
|
|
||||||
bool AActor::SuggestMissileAttack (double dist)
|
bool AActor::SuggestMissileAttack (double dist)
|
||||||
{
|
{
|
||||||
// new version encapsulates the different behavior in flags instead of virtual functions
|
// new version encapsulates the different behavior in flags instead of virtual functions
|
||||||
|
@ -707,6 +713,11 @@ bool P_Move (AActor *actor)
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
DEFINE_ACTION_FUNCTION(AActor, MonsterMove)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
ACTION_RETURN_BOOL(P_Move(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -1030,7 +1041,12 @@ void P_NewChaseDir(AActor * actor)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(AActor, NewChaseDir)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
P_NewChaseDir(self);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
|
@ -3327,6 +3327,13 @@ void AActor::PlayActiveSound ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(AActor, PlayActiveSound)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
self->PlayActiveSound();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool AActor::IsOkayToAttack (AActor *link)
|
bool AActor::IsOkayToAttack (AActor *link)
|
||||||
{
|
{
|
||||||
if (!(player // Original AActor::IsOkayToAttack was only for players
|
if (!(player // Original AActor::IsOkayToAttack was only for players
|
||||||
|
@ -6877,6 +6884,13 @@ DEFINE_ACTION_FUNCTION(AActor, deltaangle) // should this be global?
|
||||||
ACTION_RETURN_FLOAT(deltaangle(DAngle(a1), DAngle(a2)).Degrees);
|
ACTION_RETURN_FLOAT(deltaangle(DAngle(a1), DAngle(a2)).Degrees);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(AActor, Distance2D)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
PARAM_OBJECT(other, AActor);
|
||||||
|
ACTION_RETURN_FLOAT(self->Distance2D(other));
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, AddZ)
|
DEFINE_ACTION_FUNCTION(AActor, AddZ)
|
||||||
{
|
{
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
|
|
@ -66,9 +66,11 @@ class Actor : Thinker native
|
||||||
native float GetBobOffset(float frac = 0);
|
native float GetBobOffset(float frac = 0);
|
||||||
native void SetDamage(int dmg);
|
native void SetDamage(int dmg);
|
||||||
native static bool isDehState(state st);
|
native static bool isDehState(state st);
|
||||||
|
native double Distance2D(Actor other);
|
||||||
native void SetOrigin(vector3 newpos, bool moving);
|
native void SetOrigin(vector3 newpos, bool moving);
|
||||||
native void SetXYZ(vector3 newpos);
|
native void SetXYZ(vector3 newpos);
|
||||||
native Actor GetPointer(int aaptr);
|
native Actor GetPointer(int aaptr);
|
||||||
|
native void FaceMovementDirection();
|
||||||
native static Actor Spawn(class<Actor> type, vector3 pos = (0,0,0), int replace = NO_REPLACE);
|
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 SpawnMissile(Actor dest, class<Actor> type, Actor owner = null);
|
||||||
native Actor SpawnMissileZ (double z, Actor dest, class<Actor> type);
|
native Actor SpawnMissileZ (double z, Actor dest, class<Actor> type);
|
||||||
|
@ -84,6 +86,9 @@ class Actor : Thinker native
|
||||||
native Actor, int LineAttack(double angle, double distance, double pitch, int damage, Name damageType, class<Actor> pufftype, int flags = 0, out FTranslatedLineTarget victim = null);
|
native Actor, int LineAttack(double angle, double distance, double pitch, int damage, Name damageType, class<Actor> pufftype, int flags = 0, out FTranslatedLineTarget victim = null);
|
||||||
native bool CheckSight(Actor target, int flags = 0);
|
native bool CheckSight(Actor target, int flags = 0);
|
||||||
native bool HitFriend();
|
native bool HitFriend();
|
||||||
|
native bool MonsterMove();
|
||||||
|
native void NewChaseDir();
|
||||||
|
native bool CheckMissileRange();
|
||||||
native bool SetState(state st, bool nofunction = false);
|
native bool SetState(state st, bool nofunction = false);
|
||||||
native void LinkToWorld();
|
native void LinkToWorld();
|
||||||
native void UnlinkFromWorld();
|
native void UnlinkFromWorld();
|
||||||
|
@ -104,6 +109,7 @@ class Actor : Thinker native
|
||||||
native bool TeleportMove(Vector3 pos, bool telefrag, bool modifyactor = true);
|
native bool TeleportMove(Vector3 pos, bool telefrag, bool modifyactor = true);
|
||||||
native double DistanceBySpeed(Actor other, double speed);
|
native double DistanceBySpeed(Actor other, double speed);
|
||||||
native name GetSpecies();
|
native name GetSpecies();
|
||||||
|
native void PlayActiveSound();
|
||||||
|
|
||||||
// DECORATE compatible functions
|
// DECORATE compatible functions
|
||||||
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
|
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
class FireDemon : Actor
|
class FireDemon : Actor
|
||||||
{
|
{
|
||||||
|
const FIREDEMON_ATTACK_RANGE = 64*8.;
|
||||||
|
int strafecount;
|
||||||
|
|
||||||
Default
|
Default
|
||||||
{
|
{
|
||||||
Health 80;
|
Health 80;
|
||||||
|
@ -23,11 +26,6 @@ class FireDemon : Actor
|
||||||
Obituary "$OB_FIREDEMON";
|
Obituary "$OB_FIREDEMON";
|
||||||
}
|
}
|
||||||
|
|
||||||
native void A_FiredRocks();
|
|
||||||
native void A_FiredChase();
|
|
||||||
native void A_FiredAttack();
|
|
||||||
native void A_FiredSplotch();
|
|
||||||
|
|
||||||
States
|
States
|
||||||
{
|
{
|
||||||
Spawn:
|
Spawn:
|
||||||
|
@ -71,6 +69,208 @@ class FireDemon : Actor
|
||||||
FDMN R 1 A_FreezeDeathChunks;
|
FDMN R 1 A_FreezeDeathChunks;
|
||||||
Wait;
|
Wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// Fire Demon AI
|
||||||
|
//
|
||||||
|
// special1 index into floatbob
|
||||||
|
// strafecount whether strafing or not
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// A_FiredSpawnRock
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
private void A_FiredSpawnRock ()
|
||||||
|
{
|
||||||
|
Actor mo;
|
||||||
|
class<Actor> rtype;
|
||||||
|
|
||||||
|
switch (random[FireDemonRock](0, 4))
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
rtype = "FireDemonRock1";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
rtype = "FireDemonRock2";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
rtype = "FireDemonRock3";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
rtype = "FireDemonRock4";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
default:
|
||||||
|
rtype = "FireDemonRock5";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
double xo = (random[FireDemonRock]() - 128) / 16.;
|
||||||
|
double yo = (random[FireDemonRock]() - 128) / 16.;
|
||||||
|
double zo = random[FireDemonRock]() / 32.;
|
||||||
|
mo = Spawn (rtype, Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
|
||||||
|
if (mo)
|
||||||
|
{
|
||||||
|
mo.target = self;
|
||||||
|
mo.Vel.X = (random[FireDemonRock]() - 128) / 64.;
|
||||||
|
mo.Vel.Y = (random[FireDemonRock]() - 128) / 64.;
|
||||||
|
mo.Vel.Z = (random[FireDemonRock]() / 64.);
|
||||||
|
mo.special1 = 2; // Number bounces
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize fire demon
|
||||||
|
strafecount = 0;
|
||||||
|
bJustAttacked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// A_FiredRocks
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
void A_FiredRocks()
|
||||||
|
{
|
||||||
|
A_FiredSpawnRock ();
|
||||||
|
A_FiredSpawnRock ();
|
||||||
|
A_FiredSpawnRock ();
|
||||||
|
A_FiredSpawnRock ();
|
||||||
|
A_FiredSpawnRock ();
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// A_FiredAttack
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void A_FiredAttack()
|
||||||
|
{
|
||||||
|
if (target == null) return;
|
||||||
|
Actor mo = SpawnMissile (target, "FireDemonMissile");
|
||||||
|
if (mo) A_PlaySound ("FireDemonAttack", CHAN_BODY);
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// A_FiredChase
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void A_FiredChase()
|
||||||
|
{
|
||||||
|
int weaveindex = special1;
|
||||||
|
double ang;
|
||||||
|
double dist;
|
||||||
|
|
||||||
|
if (reactiontime) reactiontime--;
|
||||||
|
if (threshold) threshold--;
|
||||||
|
|
||||||
|
// Float up and down
|
||||||
|
AddZ(BobSin(weaveindex));
|
||||||
|
special1 = (weaveindex + 2) & 63;
|
||||||
|
|
||||||
|
// Ensure it stays above certain height
|
||||||
|
if (pos.Z < floorz + 64)
|
||||||
|
{
|
||||||
|
AddZ(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!target || !target.bShootable)
|
||||||
|
{ // Invalid target
|
||||||
|
LookForPlayers (true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strafe
|
||||||
|
if (strafecount > 0)
|
||||||
|
{
|
||||||
|
strafecount--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strafecount = 0;
|
||||||
|
Vel.X = Vel.Y = 0;
|
||||||
|
dist = Distance2D(target);
|
||||||
|
if (dist < FIREDEMON_ATTACK_RANGE)
|
||||||
|
{
|
||||||
|
if (random[FiredChase]() < 30)
|
||||||
|
{
|
||||||
|
ang = AngleTo(target);
|
||||||
|
if (random[FiredChase]() < 128)
|
||||||
|
ang += 90;
|
||||||
|
else
|
||||||
|
ang -= 90;
|
||||||
|
Thrust(8, ang);
|
||||||
|
strafecount = 3; // strafe time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FaceMovementDirection ();
|
||||||
|
|
||||||
|
// Normal movement
|
||||||
|
if (!strafecount)
|
||||||
|
{
|
||||||
|
if (--movecount<0 || !MonsterMove ())
|
||||||
|
{
|
||||||
|
NewChaseDir ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do missile attack
|
||||||
|
if (!bJustAttacked)
|
||||||
|
{
|
||||||
|
if (CheckMissileRange () && (random[FiredChase]() < 20))
|
||||||
|
{
|
||||||
|
SetState (MissileState);
|
||||||
|
bJustAttacked = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bJustAttacked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make active sound
|
||||||
|
if (random[FiredChase]() < 3)
|
||||||
|
{
|
||||||
|
PlayActiveSound ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// A_FiredSplotch
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void A_FiredSplotch()
|
||||||
|
{
|
||||||
|
Actor mo;
|
||||||
|
|
||||||
|
mo = Spawn ("FireDemonSplotch1", Pos, ALLOW_REPLACE);
|
||||||
|
if (mo)
|
||||||
|
{
|
||||||
|
mo.Vel.X = (random[FireDemonSplotch]() - 128) / 32.;
|
||||||
|
mo.Vel.Y = (random[FireDemonSplotch]() - 128) / 32.;
|
||||||
|
mo.Vel.Z = (random[FireDemonSplotch]() / 64.) + 3;
|
||||||
|
}
|
||||||
|
mo = Spawn ("FireDemonSplotch2", Pos, ALLOW_REPLACE);
|
||||||
|
if (mo)
|
||||||
|
{
|
||||||
|
mo.Vel.X = (random[FireDemonSplotch]() - 128) / 32.;
|
||||||
|
mo.Vel.Y = (random[FireDemonSplotch]() - 128) / 32.;
|
||||||
|
mo.Vel.Z = (random[FireDemonSplotch]() / 64.) + 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FireDemonSplotch1 -------------------------------------------------------
|
// FireDemonSplotch1 -------------------------------------------------------
|
||||||
|
@ -124,8 +324,6 @@ class FireDemonRock1 : Actor
|
||||||
+NOTELEPORT
|
+NOTELEPORT
|
||||||
}
|
}
|
||||||
|
|
||||||
native void A_SmBounce();
|
|
||||||
|
|
||||||
States
|
States
|
||||||
{
|
{
|
||||||
Spawn:
|
Spawn:
|
||||||
|
@ -137,6 +335,21 @@ class FireDemonRock1 : Actor
|
||||||
FDMN S 200;
|
FDMN S 200;
|
||||||
Stop;
|
Stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// A_SmBounce
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void A_SmBounce()
|
||||||
|
{
|
||||||
|
// give some more velocity (x,y,&z)
|
||||||
|
SetZ(floorz + 1);
|
||||||
|
Vel.Z = 2. + random[SMBounce]() / 64.;
|
||||||
|
Vel.X = random[SMBounce](0, 2);
|
||||||
|
Vel.Y = random[SMBounce](0, 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FireDemonRock2 ------------------------------------------------------------
|
// FireDemonRock2 ------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in a new issue