mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-29 23:33:00 +00:00
450 lines
8 KiB
Text
450 lines
8 KiB
Text
|
|
// FireDemon ----------------------------------------------------------------
|
|
|
|
class FireDemon : Actor
|
|
{
|
|
const FIREDEMON_ATTACK_RANGE = 64*8.;
|
|
int fdstrafecount;
|
|
|
|
Default
|
|
{
|
|
Health 80;
|
|
ReactionTime 8;
|
|
PainChance 1;
|
|
Speed 13;
|
|
Radius 20;
|
|
Height 68;
|
|
Mass 75;
|
|
Damage 1;
|
|
Monster;
|
|
+DROPOFF +NOGRAVITY +FLOAT
|
|
+FLOORCLIP +INVULNERABLE +TELESTOMP
|
|
SeeSound "FireDemonSpawn";
|
|
PainSound "FireDemonPain";
|
|
DeathSound "FireDemonDeath";
|
|
ActiveSound "FireDemonActive";
|
|
Obituary "$OB_FIREDEMON";
|
|
}
|
|
|
|
States
|
|
{
|
|
Spawn:
|
|
FDMN X 5 Bright;
|
|
FDMN EFG 10 Bright A_Look;
|
|
Goto Spawn + 1;
|
|
See:
|
|
FDMN E 8 Bright;
|
|
FDMN F 6 Bright;
|
|
FDMN G 5 Bright;
|
|
FDMN F 8 Bright;
|
|
FDMN E 6 Bright;
|
|
FDMN G 7 Bright A_FiredRocks;
|
|
FDMN HI 5 Bright;
|
|
FDMN J 5 Bright A_UnSetInvulnerable;
|
|
Chase:
|
|
FDMN ABC 5 Bright A_FiredChase;
|
|
Loop;
|
|
Pain:
|
|
FDMN D 0 Bright A_UnSetInvulnerable;
|
|
FDMN D 6 Bright A_Pain;
|
|
Goto Chase;
|
|
Missile:
|
|
FDMN K 3 Bright A_FaceTarget;
|
|
FDMN KKK 5 Bright A_FiredAttack;
|
|
Goto Chase;
|
|
Crash:
|
|
XDeath:
|
|
FDMN M 5 A_FaceTarget;
|
|
FDMN N 5 A_NoBlocking;
|
|
FDMN O 5 A_FiredSplotch;
|
|
Stop;
|
|
Death:
|
|
FDMN D 4 Bright A_FaceTarget;
|
|
FDMN L 4 Bright A_Scream;
|
|
FDMN L 4 Bright A_NoBlocking;
|
|
FDMN L 200 Bright;
|
|
Stop;
|
|
Ice:
|
|
FDMN R 5 A_FreezeDeath;
|
|
FDMN R 1 A_FreezeDeathChunks;
|
|
Wait;
|
|
}
|
|
|
|
|
|
|
|
|
|
//============================================================================
|
|
// Fire Demon AI
|
|
//
|
|
// special1 index into floatbob
|
|
// fdstrafecount 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
|
|
fdstrafecount = 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 (fdstrafecount > 0)
|
|
{
|
|
fdstrafecount--;
|
|
}
|
|
else
|
|
{
|
|
fdstrafecount = 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);
|
|
fdstrafecount = 3; // strafe time
|
|
}
|
|
}
|
|
}
|
|
|
|
FaceMovementDirection ();
|
|
|
|
// Normal movement
|
|
if (!fdstrafecount)
|
|
{
|
|
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 -------------------------------------------------------
|
|
|
|
class FireDemonSplotch1 : Actor
|
|
{
|
|
Default
|
|
{
|
|
ReactionTime 8;
|
|
Radius 3;
|
|
Height 16;
|
|
Mass 100;
|
|
+DROPOFF +CORPSE
|
|
+NOTELEPORT +FLOORCLIP
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
FDMN P 3;
|
|
FDMN P 6 A_QueueCorpse;
|
|
FDMN Y -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
// FireDemonSplotch2 -------------------------------------------------------
|
|
|
|
class FireDemonSplotch2 : FireDemonSplotch1
|
|
{
|
|
States
|
|
{
|
|
Spawn:
|
|
FDMN Q 3;
|
|
FDMN Q 6 A_QueueCorpse;
|
|
FDMN Z -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
// FireDemonRock1 ------------------------------------------------------------
|
|
|
|
class FireDemonRock1 : Actor
|
|
{
|
|
Default
|
|
{
|
|
ReactionTime 8;
|
|
Radius 3;
|
|
Height 5;
|
|
Mass 16;
|
|
+NOBLOCKMAP +DROPOFF +MISSILE
|
|
+NOTELEPORT
|
|
}
|
|
|
|
States
|
|
{
|
|
Spawn:
|
|
FDMN S 4;
|
|
Loop;
|
|
Death:
|
|
FDMN S 5 A_SmBounce;
|
|
XDeath:
|
|
FDMN S 200;
|
|
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 ------------------------------------------------------------
|
|
|
|
class FireDemonRock2 : FireDemonRock1
|
|
{
|
|
States
|
|
{
|
|
Spawn:
|
|
FDMN T 4;
|
|
Loop;
|
|
Death:
|
|
FDMN T 5 A_SmBounce;
|
|
XDeath:
|
|
FDMN T 200;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
// FireDemonRock3 ------------------------------------------------------------
|
|
|
|
class FireDemonRock3 : FireDemonRock1
|
|
{
|
|
States
|
|
{
|
|
Spawn:
|
|
FDMN U 4;
|
|
Loop;
|
|
Death:
|
|
FDMN U 5 A_SmBounce;
|
|
XDeath:
|
|
FDMN U 200;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
// FireDemonRock4 ------------------------------------------------------------
|
|
|
|
class FireDemonRock4 : FireDemonRock1
|
|
{
|
|
States
|
|
{
|
|
Spawn:
|
|
FDMN V 4;
|
|
Loop;
|
|
Death:
|
|
FDMN V 5 A_SmBounce;
|
|
XDeath:
|
|
FDMN V 200;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
// FireDemonRock5 ------------------------------------------------------------
|
|
|
|
class FireDemonRock5 : FireDemonRock1
|
|
{
|
|
States
|
|
{
|
|
Spawn:
|
|
FDMN W 4;
|
|
Loop;
|
|
Death:
|
|
FDMN W 5 A_SmBounce;
|
|
XDeath:
|
|
FDMN W 200;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
// FireDemonMissile -----------------------------------------------------------
|
|
|
|
class FireDemonMissile : Actor
|
|
{
|
|
Default
|
|
{
|
|
ReactionTime 8;
|
|
Speed 10;
|
|
Radius 10;
|
|
Height 6;
|
|
Mass 5;
|
|
Damage 1;
|
|
DamageType "Fire";
|
|
Projectile;
|
|
RenderStyle "Add";
|
|
DeathSound "FireDemonMissileHit";
|
|
+ZDOOMTRANS
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
FDMB A 5 Bright;
|
|
Loop;
|
|
Death:
|
|
FDMB BCDE 5 Bright;
|
|
Stop;
|
|
}
|
|
}
|