mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-12-02 08:53:42 +00:00
ebd2c27e0a
- merged the FrontBlock searcher for the Bloodscourge into RoughMonsterSearch. This also fixes the bug that the searcher was not initialized properly for the MageBoss.
476 lines
8.8 KiB
Text
476 lines
8.8 KiB
Text
|
|
// Serpent ------------------------------------------------------------------
|
|
|
|
class Serpent : Actor
|
|
{
|
|
Default
|
|
{
|
|
Health 90;
|
|
PainChance 96;
|
|
Speed 12;
|
|
Radius 32;
|
|
Height 70;
|
|
Mass 0x7fffffff;
|
|
Monster;
|
|
-SHOOTABLE
|
|
+NOBLOOD
|
|
+CANTLEAVEFLOORPIC +NONSHOOTABLE
|
|
+STAYMORPHED +DONTBLAST +NOTELEOTHER
|
|
+INVISIBLE
|
|
SeeSound "SerpentSight";
|
|
AttackSound "SerpentAttack";
|
|
PainSound "SerpentPain";
|
|
DeathSound "SerpentDeath";
|
|
HitObituary "$OB_SERPENTHIT";
|
|
}
|
|
|
|
States
|
|
{
|
|
Spawn:
|
|
SSPT H 10 A_Look;
|
|
Loop;
|
|
See:
|
|
SSPT HH 1 A_Chase("Melee", null, CHF_NIGHTMAREFAST|CHF_NOPLAYACTIVE);
|
|
SSPT H 2 A_SerpentHumpDecide;
|
|
Loop;
|
|
Pain:
|
|
SSPT L 5;
|
|
SSPT L 5 A_Pain;
|
|
Dive:
|
|
SSDV ABC 4;
|
|
SSDV D 4 A_UnSetShootable;
|
|
SSDV E 3 A_PlaySound("SerpentActive", CHAN_BODY);
|
|
SSDV F 3;
|
|
SSDV GH 4;
|
|
SSDV I 3;
|
|
SSDV J 3 A_SerpentHide;
|
|
Goto See;
|
|
Melee:
|
|
SSPT A 1 A_UnHideThing;
|
|
SSPT A 1 A_PlaySound("SerpentBirth", CHAN_BODY);
|
|
SSPT B 3 A_SetShootable;
|
|
SSPT C 3;
|
|
SSPT D 4 A_SerpentCheckForAttack;
|
|
Goto Dive;
|
|
Death:
|
|
SSPT O 4;
|
|
SSPT P 4 A_Scream;
|
|
SSPT Q 4 A_NoBlocking;
|
|
SSPT RSTUVWXYZ 4;
|
|
Stop;
|
|
XDeath:
|
|
SSXD A 4;
|
|
SSXD B 4 A_SpawnItemEx("SerpentHead", 0, 0, 45);
|
|
SSXD C 4 A_NoBlocking;
|
|
SSXD DE 4;
|
|
SSXD FG 3;
|
|
SSXD H 3 A_SerpentSpawnGibs;
|
|
Stop;
|
|
Ice:
|
|
SSPT [ 5 A_FreezeDeath;
|
|
SSPT [ 1 A_FreezeDeathChunks;
|
|
Wait;
|
|
Walk:
|
|
SSPT IJI 5 A_Chase("Attack", null, CHF_NIGHTMAREFAST);
|
|
SSPT J 5 A_SerpentCheckForAttack;
|
|
Goto Dive;
|
|
Hump:
|
|
SSPT H 3 A_SerpentUnHide;
|
|
SSPT EFGEF 3 A_SerpentRaiseHump;
|
|
SSPT GEF 3;
|
|
SSPT GEFGE 3 A_SerpentLowerHump;
|
|
SSPT F 3 A_SerpentHide;
|
|
Goto See;
|
|
Attack:
|
|
SSPT K 6 A_FaceTarget;
|
|
SSPT L 5 A_SerpentChooseAttack;
|
|
Goto MeleeAttack;
|
|
MeleeAttack:
|
|
SSPT N 5 A_SerpentMeleeAttack;
|
|
Goto Dive;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_SerpentUnHide
|
|
//
|
|
//============================================================================
|
|
|
|
void A_SerpentUnHide()
|
|
{
|
|
bInvisible = false;
|
|
Floorclip = 24;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_SerpentHide
|
|
//
|
|
//============================================================================
|
|
|
|
void A_SerpentHide()
|
|
{
|
|
bInvisible = true;
|
|
Floorclip = 0;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_SerpentRaiseHump
|
|
//
|
|
// Raises the hump above the surface by raising the floorclip level
|
|
//============================================================================
|
|
|
|
void A_SerpentRaiseHump()
|
|
{
|
|
Floorclip -= 4;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_SerpentLowerHump
|
|
//
|
|
//============================================================================
|
|
|
|
void A_SerpentLowerHump()
|
|
{
|
|
Floorclip += 4;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_SerpentHumpDecide
|
|
//
|
|
// Decided whether to hump up, or if the mobj is a serpent leader,
|
|
// to missile attack
|
|
//============================================================================
|
|
|
|
void A_SerpentHumpDecide()
|
|
{
|
|
if (MissileState != NULL)
|
|
{
|
|
if (random[SerpentHump]() > 30)
|
|
{
|
|
return;
|
|
}
|
|
else if (random[SerpentHump]() < 40)
|
|
{ // Missile attack
|
|
SetState (MeleeState);
|
|
return;
|
|
}
|
|
}
|
|
else if (random[SerpentHump]() > 3)
|
|
{
|
|
return;
|
|
}
|
|
if (!CheckMeleeRange ())
|
|
{ // The hump shouldn't occur when within melee range
|
|
if (MissileState != NULL && random[SerpentHump]() < 128)
|
|
{
|
|
SetState (MeleeState);
|
|
}
|
|
else
|
|
{
|
|
SetStateLabel("Hump");
|
|
A_PlaySound ("SerpentActive", CHAN_BODY);
|
|
}
|
|
}
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_SerpentCheckForAttack
|
|
//
|
|
//============================================================================
|
|
|
|
void A_SerpentCheckForAttack()
|
|
{
|
|
if (!target)
|
|
{
|
|
return;
|
|
}
|
|
if (MissileState != NULL)
|
|
{
|
|
if (!CheckMeleeRange ())
|
|
{
|
|
SetStateLabel ("Attack");
|
|
return;
|
|
}
|
|
}
|
|
if (CheckMeleeRange2 ())
|
|
{
|
|
SetStateLabel ("Walk");
|
|
}
|
|
else if (CheckMeleeRange ())
|
|
{
|
|
if (random[SerpentAttack]() < 32)
|
|
{
|
|
SetStateLabel ("Walk");
|
|
}
|
|
else
|
|
{
|
|
SetStateLabel ("Attack");
|
|
}
|
|
}
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_SerpentChooseAttack
|
|
//
|
|
//============================================================================
|
|
|
|
void A_SerpentChooseAttack()
|
|
{
|
|
if (!target || CheckMeleeRange())
|
|
{
|
|
return;
|
|
}
|
|
if (MissileState != NULL)
|
|
{
|
|
SetState (MissileState);
|
|
}
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_SerpentMeleeAttack
|
|
//
|
|
//============================================================================
|
|
|
|
void A_SerpentMeleeAttack()
|
|
{
|
|
if (!target)
|
|
{
|
|
return;
|
|
}
|
|
if (CheckMeleeRange ())
|
|
{
|
|
int damage = random[SerpentAttack](1, 8) * 5;
|
|
int newdam = target.DamageMobj (self, self, damage, 'Melee');
|
|
target.TraceBleed (newdam > 0 ? newdam : damage, self);
|
|
A_PlaySound ("SerpentMeleeHit", CHAN_BODY);
|
|
}
|
|
if (random[SerpentAttack]() < 96)
|
|
{
|
|
A_SerpentCheckForAttack();
|
|
}
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_SerpentSpawnGibs
|
|
//
|
|
//============================================================================
|
|
|
|
void A_SerpentSpawnGibs()
|
|
{
|
|
static const class<Actor> GibTypes[] =
|
|
{
|
|
"SerpentGib3",
|
|
"SerpentGib2",
|
|
"SerpentGib1"
|
|
};
|
|
|
|
for (int i = 2; i >= 0; --i)
|
|
{
|
|
double x = (random[SerpentGibs]() - 128) / 16.;
|
|
double y = (random[SerpentGibs]() - 128) / 16.;
|
|
|
|
Actor mo = Spawn (GibTypes[i], Vec2OffsetZ(x, y, floorz + 1), ALLOW_REPLACE);
|
|
if (mo)
|
|
{
|
|
mo.Vel.X = (random[SerpentGibs]() - 128) / 1024.f;
|
|
mo.Vel.Y = (random[SerpentGibs]() - 128) / 1024.f;
|
|
mo.Floorclip = 6;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Serpent Leader -----------------------------------------------------------
|
|
|
|
class SerpentLeader : Serpent
|
|
{
|
|
Default
|
|
{
|
|
Mass 200;
|
|
Obituary "$OB_SERPENT";
|
|
}
|
|
States
|
|
{
|
|
Missile:
|
|
SSPT N 5 A_CustomMissile("SerpentFX", 32, 0);
|
|
Goto Dive;
|
|
}
|
|
}
|
|
|
|
// Serpent Missile Ball -----------------------------------------------------
|
|
|
|
class SerpentFX : Actor
|
|
{
|
|
Default
|
|
{
|
|
Speed 15;
|
|
Radius 8;
|
|
Height 10;
|
|
Damage 4;
|
|
Projectile;
|
|
-ACTIVATEIMPACT -ACTIVATEPCROSS
|
|
RenderStyle "Add";
|
|
DeathSound "SerpentFXHit";
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SSFX A 0;
|
|
SSFX A 3 Bright A_PlaySound("SerpentFXContinuous", CHAN_BODY, 1.0, 1);
|
|
SSFX BAB 3 Bright;
|
|
Goto Spawn+1;
|
|
Death:
|
|
SSFX C 4 Bright A_StopSound(CHAN_BODY);
|
|
SSFX DEFGH 4 Bright;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
// Serpent Head -------------------------------------------------------------
|
|
|
|
class SerpentHead : Actor
|
|
{
|
|
Default
|
|
{
|
|
Radius 5;
|
|
Height 10;
|
|
Gravity 0.125;
|
|
+NOBLOCKMAP
|
|
}
|
|
|
|
States
|
|
{
|
|
Spawn:
|
|
SSXD IJKLMNOP 4 A_SerpentHeadCheck;
|
|
Loop;
|
|
Death:
|
|
SSXD S -1;
|
|
Loop;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_SerpentHeadCheck
|
|
//
|
|
//============================================================================
|
|
|
|
void A_SerpentHeadCheck()
|
|
{
|
|
if (pos.z <= floorz)
|
|
{
|
|
if (GetFloorTerrain().IsLiquid)
|
|
{
|
|
HitFloor ();
|
|
Destroy();
|
|
}
|
|
else
|
|
{
|
|
SetStateLabel ("NAME_Death");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Serpent Gib 1 ------------------------------------------------------------
|
|
|
|
class SerpentGib1 : Actor
|
|
{
|
|
Default
|
|
{
|
|
Radius 3;
|
|
Height 3;
|
|
+NOBLOCKMAP +NOGRAVITY
|
|
}
|
|
|
|
States
|
|
{
|
|
Spawn:
|
|
SSXD Q 6;
|
|
SSXD Q 6 A_FloatGib;
|
|
SSXD QQ 8 A_FloatGib;
|
|
SSXD QQ 12 A_FloatGib;
|
|
SSXD Q 232 A_DelayGib;
|
|
SSXD QQ 12 A_SinkGib;
|
|
SSXD QQQ 8 A_SinkGib;
|
|
Stop;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_FloatGib
|
|
//
|
|
//============================================================================
|
|
|
|
void A_FloatGib()
|
|
{
|
|
Floorclip -= 1;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_SinkGib
|
|
//
|
|
//============================================================================
|
|
|
|
void A_SinkGib()
|
|
{
|
|
Floorclip += 1;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_DelayGib
|
|
//
|
|
//============================================================================
|
|
|
|
void A_DelayGib()
|
|
{
|
|
tics -= random[DelayGib]() >> 2;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// Serpent Gib 2 ------------------------------------------------------------
|
|
|
|
class SerpentGib2 : SerpentGib1
|
|
{
|
|
States
|
|
{
|
|
Spawn:
|
|
SSXD R 6;
|
|
SSXD R 6 A_FloatGib;
|
|
SSXD RR 8 A_FloatGib;
|
|
SSXD RR 12 A_FloatGib;
|
|
SSXD R 232 A_DelayGib;
|
|
SSXD RR 12 A_SinkGib;
|
|
SSXD RRR 8 A_SinkGib;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
// Serpent Gib 3 ------------------------------------------------------------
|
|
|
|
class SerpentGib3 : SerpentGib1
|
|
{
|
|
States
|
|
{
|
|
Spawn:
|
|
SSXD T 6;
|
|
SSXD T 6 A_FloatGib;
|
|
SSXD TT 8 A_FloatGib;
|
|
SSXD TT 12 A_FloatGib;
|
|
SSXD T 232 A_DelayGib;
|
|
SSXD TT 12 A_SinkGib;
|
|
SSXD TTT 8 A_SinkGib;
|
|
Stop;
|
|
}
|
|
}
|