mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-12-11 13:11:48 +00:00
196 lines
4.1 KiB
Text
196 lines
4.1 KiB
Text
|
|
|
|
//==========================================================================
|
|
//
|
|
// Ice chunk
|
|
//
|
|
//==========================================================================
|
|
|
|
class IceChunk : Actor
|
|
{
|
|
Default
|
|
{
|
|
Radius 3;
|
|
Height 4;
|
|
Mass 5;
|
|
Gravity 0.125;
|
|
+DROPOFF
|
|
+CANNOTPUSH
|
|
+FLOORCLIP
|
|
+NOTELEPORT
|
|
+NOBLOCKMAP
|
|
+MOVEWITHSECTOR
|
|
}
|
|
|
|
void A_IceSetTics ()
|
|
{
|
|
tics = random[IceTics](70, 133);
|
|
Name dtype = GetFloorTerrain().DamageMOD;
|
|
if (dtype == 'Fire')
|
|
{
|
|
tics >>= 2;
|
|
}
|
|
else if (dtype == 'Ice')
|
|
{
|
|
tics <<= 1;
|
|
}
|
|
}
|
|
|
|
States
|
|
{
|
|
Spawn:
|
|
ICEC ABCD 10 A_IceSetTics;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// A chunk of ice that is also a player
|
|
//
|
|
//==========================================================================
|
|
|
|
class IceChunkHead : PlayerChunk
|
|
{
|
|
Default
|
|
{
|
|
Radius 3;
|
|
Height 4;
|
|
Mass 5;
|
|
Gravity 0.125;
|
|
DamageType "Ice";
|
|
+DROPOFF
|
|
+CANNOTPUSH
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
ICEC A 0;
|
|
ICEC A 10 A_CheckPlayerDone;
|
|
wait;
|
|
}
|
|
}
|
|
|
|
|
|
extend class Actor
|
|
{
|
|
|
|
//============================================================================
|
|
//
|
|
// A_FreezeDeath
|
|
//
|
|
//============================================================================
|
|
|
|
void A_FreezeDeath()
|
|
{
|
|
|
|
int t = random[freezedeath]();
|
|
tics = 75+t+random[freezedeath]();
|
|
bSolid = bShootable = bNoBlood = bIceCorpse = bPushable = bTelestomp = bCanPass = bSlidesOnWalls = bCrashed = true;
|
|
Height = Default.Height;
|
|
A_SetRenderStyle(1, STYLE_Normal);
|
|
|
|
A_StartSound ("misc/freeze", CHAN_BODY);
|
|
|
|
// [RH] Andy Baker's stealth monsters
|
|
if (bStealth)
|
|
{
|
|
Alpha = 1;
|
|
visdir = 0;
|
|
}
|
|
|
|
if (player)
|
|
{
|
|
player.damagecount = 0;
|
|
player.poisoncount = 0;
|
|
player.bonuscount = 0;
|
|
}
|
|
else if (bIsMonster && special)
|
|
{ // Initiate monster death actions
|
|
A_CallSpecial(special, args[0], args[1], args[2], args[3], args[4]);
|
|
special = 0;
|
|
}
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_FreezeDeathChunks
|
|
//
|
|
//============================================================================
|
|
|
|
void A_FreezeDeathChunks()
|
|
{
|
|
if (Vel != (0,0,0) && !bShattering)
|
|
{
|
|
tics = 3*TICRATE;
|
|
return;
|
|
}
|
|
Vel = (0,0,0);
|
|
A_StartSound ("misc/icebreak", CHAN_BODY);
|
|
|
|
// [RH] In Hexen, this creates a random number of shards (range [24,56])
|
|
// with no relation to the size of the self shattering. I think it should
|
|
// base the number of shards on the size of the dead thing, so bigger
|
|
// things break up into more shards than smaller things.
|
|
// An actor with radius 20 and height 64 creates ~40 chunks.
|
|
int numChunks = max(4, int(radius * Height)/32);
|
|
int i = Random[FreezeDeathChunks](0, numChunks/4 - 1);
|
|
for (i = max(24, numChunks + i); i >= 0; i--)
|
|
{
|
|
double xo = (random[FreezeDeathChunks]() - 128)*radius / 128;
|
|
double yo = (random[FreezeDeathChunks]() - 128)*radius / 128;
|
|
double zo = (random[FreezeDeathChunks]() * Height / 255);
|
|
|
|
Actor mo = Spawn("IceChunk", Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
|
|
if (mo)
|
|
{
|
|
mo.SetState (mo.SpawnState + random[FreezeDeathChunks](0, 2));
|
|
mo.Vel.X = random2[FreezeDeathChunks]() / 128.;
|
|
mo.Vel.Y = random2[FreezeDeathChunks]() / 128.;
|
|
mo.Vel.Z = (mo.pos.Z - pos.Z) / Height * 4;
|
|
}
|
|
}
|
|
if (player)
|
|
{ // attach the player's view to a chunk of ice
|
|
Actor head = Spawn("IceChunkHead", pos + (0, 0, player.mo.ViewHeight), ALLOW_REPLACE);
|
|
if (head != null)
|
|
{
|
|
head.Vel.X = random2[FreezeDeathChunks]() / 128.;
|
|
head.Vel.Y = random2[FreezeDeathChunks]() / 128.;
|
|
head.Vel.Z = (head.pos.Z - pos.Z) / Height * 4;
|
|
|
|
head.health = health;
|
|
head.Angle = Angle;
|
|
if (head is "PlayerPawn")
|
|
{
|
|
head.player = player;
|
|
head.player.mo = PlayerPawn(head);
|
|
player = null;
|
|
head.ObtainInventory (self);
|
|
}
|
|
head.Pitch = 0.;
|
|
if (head.player.camera == self)
|
|
{
|
|
head.player.camera = head;
|
|
}
|
|
}
|
|
}
|
|
|
|
// [RH] Do some stuff to make this more useful outside Hexen
|
|
if (bBossDeath)
|
|
{
|
|
A_BossDeath();
|
|
}
|
|
A_NoBlocking();
|
|
|
|
SetStateLabel('null');
|
|
}
|
|
|
|
void A_GenericFreezeDeath()
|
|
{
|
|
A_SetTranslation('Ice');
|
|
A_FreezeDeath();
|
|
}
|
|
|
|
|
|
}
|