

//==========================================================================
//
// 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 = 70 + (random[IceTics]() & 63);
		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_PlaySound ("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_PlaySound ("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]() % (numChunks/4);
		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]()%3));
				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();
	}
	

}