Version "3.4"

Class PowerBloodMana : Powerup
{
	const Total = 3;
	int PrevAmmo[Total];
	
	// The effect, called every tic.
	override void DoEffect()
	{
		if (!Owner || Owner.health < 1)	return;
		
		// Note: When adding or removing entries from here, make sure to update
		// the 'Total' const above to match the number of entries.
		static const Class<Inventory> Ammos[] =
		{
			"BlueMana",
			"GreenMana",
			"GoldMana"
		};
		
		int TotalDamage = 0;
		for (int i = 0; i < Ammos.Size(); i++)
		{
			int CurAmmo = Owner.CountInv(Ammos[i]);

			// Don't record negative numbers. That just means a player picked up
			// ammo. Positive numbers means ammo was drained.
			TotalDamage += Max(0, PrevAmmo[i] - CurAmmo);
			
			// Update the new ammo count.
			PrevAmmo[i] = CurAmmo;
		}
		
		if (TotalDamage > 0)
		{
			Owner.DamageMobj(self, self, TotalDamage, "Normal", DMG_THRUSTLESS|DMG_NO_ARMOR|DMG_NO_FACTOR|DMG_NO_PROTECT);
		}
		
		Super.DoEffect();
	}
}

//=====================================================================
//
// Melee Weapons (improving their hit detection)
//
//=====================================================================

class FGauntlets : FWeapFist replaces FWeapFist
{
	Default
	{
		Tag "Fists";
		+WEAPON.CHEATNOTWEAPON;
		+BLOODSPLATTER;
		+WEAPON.MELEEWEAPON;
		+INVENTORY.UNDROPPABLE;
		Weapon.SisterWeapon "FGauntletsPowered";
		Weapon.KickBack 150;
		MeleeRange 128;
	}
	States
	{
	Select:
		FPCH A 1 A_Raise;
		TNT1 A 0 A_Raise;
		Loop;
	Deselect:
		FPCH A 1 A_Lower;
		TNT1 A 0 A_Lower;
		Loop;
	Ready:
		FPCH A 1 A_WeaponReady;
		Loop;
	Fire:
		FPCH B 4 Offset (5, 40);
		FPCH C 4 Offset (5, 40);
		FPCH D 4 Offset (5, 40) A_FPunchAttack;
		FPCH C 4 Offset (5, 40);
		FPCH B 4 Offset (5, 40) A_ReFire;
		Goto Ready;
	Fire2:
		FPCH DE 4 Offset (5,40);
		FPCH E 1 Offset (15,50);
		FPCH E 1 Offset (25,60);
		FPCH E 1 Offset (35,70);
		FPCH E 1 Offset (45,80);
		FPCH E 1 Offset (55,90);
		FPCH E 1 Offset (65,90);
		FPCH E 10 Offset (0,150);
		Goto Ready;
	AltFire:
		FPCH B 2 Offset (5,40);
		FPCH C 2 Offset (5,40);
		FPCH F 3 Offset (5,40) A_FistAltAttack;// A_CustomPunch(random(40,55),1,0,"PunchPuff",128)
		FPCH G 3 Offset (5,40);
		FPCH H 3 Offset (5,40) A_FistAltAttack;// A_CustomPunch(random(40,55),1,0,"PunchPuff",128)
		FPCH I 2 Offset (5,40);
		FPCH J 2 Offset (5,40);
		TNT1 A 8 A_ReFire;
		Goto Ready;
	}

	action void A_FistAltAttack()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[FistAltAtk](40, 55);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE, slope, damage, 'Melee', "PunchPuff", true, t);
					if (t.linetarget != null)
					{
						AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "MacePuff");
	}
}

// Powered

class FGauntletsPowered : Gauntlets
{
	Default
	{
		Tag "Fists";
		+WEAPON.POWERED_UP;
		+WEAPON.CHEATNOTWEAPON;
		Weapon.YAdjust 9;
		Weapon.SisterWeapon "FGauntlets";
	}
	States
	{
	Ready:
		FPCH KLM 4 A_WeaponReady;
		Loop;
	Select:
		FPCH A 1 A_Raise;
		TNT1 A 0 A_Raise;
		Loop;
	Deselect:
		FPCH A 1 A_Lower;
		TNT1 A 0 A_Lower;
		Loop;
	Fire:
		FPCH N 4 A_PlaySound("weapons/gauntletsuse",7);
		FPCH O 4;
	Hold:
		FPCH P 4 Bright A_GauntletLifeDrainAttack(1);
		FPCH Q 4 Bright A_GauntletLifeDrainAttack(1);
		FPCH R 4 Bright A_GauntletLifeDrainAttack(1);
		FPCH O 4 A_ReFire;
		FPCH N 4 A_Light0;
		Goto Ready;
	AltFire:
		FPCH S 4 A_PlaySound("weapons/gauntletsuse", CHAN_WEAPON);
		FPCH T 4;
	AltHold:
		FPCH U 4 Bright A_GauntletManaDrainAttack(0);
		FPCH V 4 Bright A_GauntletManaDrainAttack(0);
		FPCH W 4 Bright A_GauntletManaDrainAttack(0);
		FPCH T 4 A_ReFire;
		FPCH S 4 A_Light0;
		Goto Ready;
	}

	action void A_GauntletLifeDrainAttack (int power)
	{
		int damage;
		double dist;
		Class<Actor> pufftype;
		FTranslatedLineTarget t;
		int actualdamage = 0;
		Actor puff;

		if (player == null)
		{
			return;
		}

		Weapon weapon = player.ReadyWeapon;
		if (weapon != null)
		{
			if (!weapon.DepleteAmmo (weapon.bAltFire))
				return;
			
			player.GetPSprite(PSP_WEAPON).x = ((random[GauntletAtk](0, 3)) - 2);
			player.GetPSprite(PSP_WEAPON).y = WEAPONTOP + (random[GauntletAtk](0, 3));
		}
		double ang = angle;
		if (power)
		{
			damage = random[GauntletAtk](1, 8) * 5;
			dist = 4*DEFMELEERANGE;
			ang += random2[GauntletAtk]() * (2.8125 / 256);
			pufftype = "GauntletPuff4";
		}
		else
		{
			damage = random[GauntletAtk](1, 8) * 5;
			dist = 4*DEFMELEERANGE;
			ang += random2[GauntletAtk]() * (5.625 / 256);
			pufftype = "GauntletPuff3";
		}
		double slope = AimLineAttack (ang, dist);
		[puff, actualdamage] = LineAttack (ang, dist, slope, damage, 'Melee', pufftype, false, t);
		if (!t.linetarget)
		{
			if (random[GauntletAtk]() > 64)
			{
				player.extralight = !player.extralight;
			}
			A_PlaySound ("weapons/gauntletson", CHAN_AUTO);
			return;
		}
		int randVal = random[GauntletAtk]();
		if (randVal < 64)
		{
			player.extralight = 0;
		}
		else if (randVal < 160)
		{
			player.extralight = 1;
		}
		else
		{
			player.extralight = 2;
		}
		if (power)
		{
			if (!t.linetarget.bDontDrain) GiveBody (actualdamage >> 2);
			A_PlaySound ("weapons/gauntletspowhit", CHAN_AUTO);
		}
		else
		{
			A_PlaySound ("weapons/gauntletshit", CHAN_AUTO);
		}
		// turn to face target
		ang = t.angleFromSource;
		double anglediff = deltaangle(angle, ang);

		if (anglediff < 0.0)
		{
			if (anglediff < -4.5)
				angle = ang + 90.0 / 21;
			else
				angle -= 4.5;
		}
		else
		{
			if (anglediff > 4.5)
				angle = ang - 90.0 / 21;
			else
				angle += 4.5;
		}
		bJustAttacked = true;
	}

	action void A_GauntletManaDrainAttack (int power)
	{
		int damage;
		double dist;
		Class<Actor> pufftype;
		FTranslatedLineTarget t;
		int actualdamage = 0;
		Actor puff;

		if (player == null)
		{
			return;
		}

		Weapon weapon = player.ReadyWeapon;
		if (weapon != null)
		{
			if (!weapon.DepleteAmmo (weapon.bAltFire))
				return;
			
			player.GetPSprite(PSP_WEAPON).x = ((random[GauntletAtk](0, 3)) - 2);
			player.GetPSprite(PSP_WEAPON).y = WEAPONTOP + (random[GauntletAtk](0, 3));
		}
		double ang = angle;
		if (power)
		{
			damage = random[GauntletAtk](1, 8) * 5;
			dist = 4*DEFMELEERANGE;
			ang += random2[GauntletAtk]() * (2.8125 / 256);
			pufftype = "GauntletPuff2";
		}
		else
		{
			damage = random[GauntletAtk](1, 8) * 5;
			dist = 4*DEFMELEERANGE;
			ang += random2[GauntletAtk]() * (5.625 / 256);
			pufftype = "GauntletPuff3";
		}
		double slope = AimLineAttack (ang, dist);
		[puff, actualdamage] = LineAttack (ang, dist, slope, damage, 'GManaDrain', pufftype, false, t);
		if (!t.linetarget)
		{
			if (random[GauntletAtk]() > 64)
			{
				player.extralight = !player.extralight;
			}
			A_PlaySound ("weapons/gauntletson", CHAN_AUTO);
			return;
		}
		int randVal = random[GauntletAtk]();
		if (randVal < 64)
		{
			player.extralight = 0;
		}
		else if (randVal < 160)
		{
			player.extralight = 1;
		}
		else
		{
			player.extralight = 2;
		}
		if (power)
		{
			if (!t.linetarget.bDontDrain) GiveBody (actualdamage >> 1);
			A_PlaySound ("weapons/gauntletspowhit", CHAN_AUTO);
		}
		else
		{
			A_PlaySound ("weapons/gauntletshit", CHAN_AUTO);
		}
		// turn to face target
		ang = t.angleFromSource;
		double anglediff = deltaangle(angle, ang);

		if (anglediff < 0.0)
		{
			if (anglediff < -4.5)
				angle = ang + 90.0 / 21;
			else
				angle -= 4.5;
		}
		else
		{
			if (anglediff > 4.5)
				angle = ang - 90.0 / 21;
			else
				angle += 4.5;
		}
		bJustAttacked = true;
	}
}

//-----------------------------------------------



class VorpalBlade : FighterWeapon// 6151
{
	Default
	{
		Tag "Vorpal Blade";
		+FLOORCLIP;
		+WEAPON.AXEBLOOD;
		+WEAPON.MELEEWEAPON;
		+WEAPON.AMMO_OPTIONAL;
		Scale 0.7;
		Obituary "%o was beheaded by %k's vorpal blade.";
		Inventory.PickupMessage "Vorpal Blade";
	}
	States
	{
	Spawn:
		WVPL A -1;
		Loop;
	Ready:
		VRPL A 0 A_StopSound(6);
		VRPL A 0 A_JumpIfInventory("UberchargeActive",1,9);
		VRPL A 0 A_JumpIfInventory("Ubercharge",100,2);
		VRPL A 1 A_WeaponReady;
		Goto Ready;
		VRPL QQQRRR 1 A_WeaponReady;
		Goto Ready+1;
		VRPL A 0 A_PlaySound("weapons/vorpalblade/fire",6,0.5,1);
		VRPL A 0 A_JumpIfInventory("UberchargeActive",1,2);
		VRPL A 0 A_StopSound(6);
		Goto Ready+1;
		VRPL H 1 A_WeaponReady;
		VRPL A 0 A_JumpIfInventory("UberchargeActive",1,2);
		VRPL A 0 A_StopSound(6);
		Goto Ready+1;
		VRPL H 1 A_WeaponReady;
		VRPL A 0 A_JumpIfInventory("UberchargeActive",1,2);
		VRPL A 0 A_StopSound(6);
		Goto Ready+1;
		VRPL H 1 A_WeaponReady;
		VRPL A 0 A_JumpIfInventory("UberchargeActive",1,2);
		VRPL A 0 A_StopSound(6);
		Goto Ready+1;
		VRPL I 1 A_WeaponReady;
		VRPL A 0 A_JumpIfInventory("UberchargeActive",1,2);
		VRPL A 0 A_StopSound(6);
		Goto Ready+1;
		VRPL I 1 A_WeaponReady;
		VRPL A 0 A_JumpIfInventory("UberchargeActive",1,2);
		VRPL A 0 A_StopSound(6);
		Goto Ready+1;
		VRPL I 1 A_WeaponReady;
		VRPL A 0 A_JumpIfInventory("UberchargeActive",1,2);
		VRPL A 0 A_StopSound(6);
		Goto Ready+1;
		VRPL J 1 A_WeaponReady;
		VRPL A 0 A_JumpIfInventory("UberchargeActive",1,2);
		VRPL A 0 A_StopSound(6);
		Goto Ready+1;
		VRPL J 1 A_WeaponReady;
		VRPL A 0 A_JumpIfInventory("UberchargeActive",1,2);
		VRPL A 0 A_StopSound(6);
		Goto Ready+1;
		VRPL J 1 A_WeaponReady;
		Goto Ready+1;
	Select:
		TNT1 A 0 A_GiveInventory("AxeBloodCheck",1);
		VRPL A 1 A_Raise;
		TNT1 AA 0 A_Raise;
		Loop;
	Deselect:
		TNT1 A 0 A_TakeInventory("AxeBloodCheck",1);
		VRPL A 0 A_StopSound(6);
		VRPL A 1 A_Lower;
		TNT1 AA 0 A_Lower;
		Loop;
	Fire:
		VRPL A 0 A_JumpIfInventory("UberchargeActive",1,"UberchargeInUse");
		VRPL A 0 A_StopSound(6);
		VRPL A 0 A_JumpIfInventory("Ubercharge",100,"UberchargeFull");
		VRPL B 2 Offset (117, 20) A_PlaySound("weapons/vorpalblade/attack",8,0.4,0); // (60, 20)
		VRPL B 1 Offset (87, 33); // (30, 33)
		VRPL B 2 Offset (60, 45); // (8, 45)
		VRPL C 1 Offset (60, 45); // (8, 45)
		VRPL D 1 Offset (60, 45); // (8, 45)
		VRPL E 1 Offset (60, 45) A_VorpalAttack;//A_CustomPunch(random(45,65),1,16,"VorpalPuff",150); // 115, 160 (8, 45)
		VRPL E 1 Offset (41, 58) A_VorpalAttack;//A_CustomPunch(random(45,65),1,16,"VorpalPuff",150); // (-11, 58)
		VRPL F 1 Offset (60, 45) A_VorpalAttack;//A_CustomPunch(random(45,65),1,16,"VorpalPuff",150); // (8, 45)
		VRPL F 2 Offset (44, 74); // (-8, 74)
		VRPL F 1 Offset (32, 96); // (-20, 96)
		VRPL F 6 Offset (19, 160); // (-33, 160)
		VRPL G 1;
		VRPL A 1 Offset (8, 75) A_ReFire;
		VRPL A 1 Offset (8, 65);
		VRPL A 1 Offset (8, 60);
		VRPL A 1 Offset (8, 55);
		VRPL A 1 Offset (8, 50);
		VRPL A 1 Offset (8, 45);
		Goto Ready+1;
	UberchargeFull:
		VRPL B 2 Offset (117, 20) A_PlaySound("weapons/vorpalblade/attack",8,0.4,0); // (60, 20)
		VRPL B 1 Offset (87, 33); // (30, 33)
		VRPL B 2 Offset (60, 45); // (8, 45)
		VRPL S 1 Offset (-46, 45); // (8, 45)
		VRPL T 1 Offset (60, 45); // (8, 45)
		VRPL U 1 Offset (60, 45) A_VorpalFullChargeAttack;//A_CustomPunch(random(55,75),1,16,"VorpalPuff",150); // 140, 190 // (8, 45)
		VRPL U 1 Offset (41, 58) A_VorpalFullChargeAttack;//A_CustomPunch(random(55,75),1,16,"VorpalPuff",150); // (-11, 58)
		VRPL V 1 Offset (60, 45) A_VorpalFullChargeAttack;//A_CustomPunch(random(55,75),1,16,"VorpalPuff",150); // (8, 45)
		VRPL V 2 Offset (44, 74); // (-8, 74)
		VRPL V 1 Offset (32, 96); // (-20, 96)
		VRPL V 6 Offset (19, 160); // (-33, 160)
		VRPL G 1;
		VRPL Q 1 Offset (8, 75) A_ReFire;
		VRPL Q 1 Offset (8, 65);
		VRPL Q 1 Offset (8, 60);
		VRPL R 1 Offset (8, 55);
		VRPL R 1 Offset (8, 50);
		VRPL R 1 Offset (8, 45);
		Goto Ready+1;
	UberchargeInUse:
		VRPL A 0 A_JumpIfInventory("FullCharge",1,"FireFull");
		VRPL A 0 A_JumpIfInventory("90PercentCharge",1,"Fire90");
		VRPL A 0 A_JumpIfInventory("80PercentCharge",1,"Fire80");
		VRPL A 0 A_JumpIfInventory("70PercentCharge",1,"Fire70");
		VRPL A 0 A_JumpIfInventory("60PercentCharge",1,"Fire60");
		VRPL A 0 A_JumpIfInventory("50PercentCharge",1,"Fire50");
		VRPL A 0 A_JumpIfInventory("40PercentCharge",1,"Fire40");
		VRPL A 0 A_JumpIfInventory("30PercentCharge",1,"Fire30");
		VRPL A 0 A_JumpIfInventory("20PercentCharge",1,"Fire20");
		VRPL A 0 A_JumpIfInventory("10PercentCharge",1,"Fire10");
		VRPL A 0 A_StopSound(6);
		Goto Fire;
	FireFull:
		VRPL K 2 Offset (117, 20) A_PlaySound("weapons/vorpalblade/attack",8,0.4,0); // (60, 20)
		VRPL K 1 Offset (87, 33); // (30, 33)
		VRPL K 2 Offset (60, 45); // (8, 45)
		VRPL L 1 Offset (60, 45); // (8, 45)
		VRPL M 1 Offset (60, 45); // (8, 45)
		VRPL N 0 Offset (60, 45) A_FireProjectile("VorpalSlash",0,0,0,0,4);
		VRPL N 0 Offset (60, 45) A_VorpalFlamingAttackFull;//A_CustomPunch(random(145,170),1,16,"UberchargePuffFull",156); // (8, 45)
		VRPL N 1 Offset (41, 58) A_VorpalFlamingAttackFull;//A_CustomPunch(random(145,170),1,16,"UberchargePuffFull",156); // (-11, 45)
		VRPL O 1 Offset (60, 45) A_VorpalFlamingAttackFull;//A_CustomPunch(random(145,170),1,16,"UberchargePuffFull",156); // (8, 45)
		VRPL O 2 Offset (44, 74); // (-8, 74)
		VRPL O 1 Offset (32, 96); // (-20, 96)
		VRPL O 6 Offset (19, 160); // (-33, 160)
		VRPL P 1;
		VRPL I 1 Offset (8, 75) A_ReFire;
		VRPL I 1 Offset (8, 65);
		VRPL I 1 Offset (8, 60);
		VRPL J 1 Offset (8, 55);
		VRPL J 1 Offset (8, 50);
		VRPL J 1 Offset (8, 45);
		Goto Ready+1;
	Fire90:
		VRPL K 2 Offset (117, 20) A_PlaySound("weapons/vorpalblade/attack",8,0.4,0);
		VRPL K 1 Offset (87, 33);
		VRPL K 2 Offset (60, 45);
		VRPL L 1 Offset (60, 45);
		VRPL M 1 Offset (60, 45);
		VRPL N 1 Offset (60, 45) A_VorpalFlamingAttack90;//A_CustomPunch(random(130,150),1,16,"UberchargePuff",156); // 300, 350
		VRPL N 1 Offset (41, 58) A_VorpalFlamingAttack90;//A_CustomPunch(random(130,150),1,16,"UberchargePuff",156);
		VRPL O 1 Offset (60, 45) A_VorpalFlamingAttack90;//A_CustomPunch(random(130,150),1,16,"UberchargePuff",156);
		VRPL O 2 Offset (44, 74);
		VRPL O 1 Offset (32, 96);
		VRPL O 6 Offset (19, 160);
		VRPL P 1;
		VRPL I 1 Offset (8, 75) A_ReFire;
		VRPL I 1 Offset (8, 65);
		VRPL I 1 Offset (8, 60);
		VRPL J 1 Offset (8, 55);
		VRPL J 1 Offset (8, 50);
		VRPL J 1 Offset (8, 45);
		Goto Ready+1;
	Fire80:
		VRPL K 2 Offset (117, 20) A_PlaySound("weapons/vorpalblade/attack",8,0.4,0);
		VRPL K 1 Offset (87, 33);
		VRPL K 2 Offset (60, 45);
		VRPL L 1 Offset (60, 45);
		VRPL M 1 Offset (60, 45);
		VRPL N 1 Offset (60, 45) A_VorpalFlamingAttack80;//A_CustomPunch(random(120,140),1,16,"UberchargePuff",156); // 285, 335
		VRPL N 1 Offset (41, 58) A_VorpalFlamingAttack80;//A_CustomPunch(random(120,140),1,16,"UberchargePuff",156);
		VRPL O 1 Offset (60, 45) A_VorpalFlamingAttack80;//A_CustomPunch(random(120,140),1,16,"UberchargePuff",156);
		VRPL O 2 Offset (44, 74);
		VRPL O 1 Offset (32, 96);
		VRPL O 6 Offset (19, 160);
		VRPL P 1;
		VRPL I 1 Offset (8, 75) A_ReFire;
		VRPL I 1 Offset (8, 65);
		VRPL I 1 Offset (8, 60);
		VRPL J 1 Offset (8, 55);
		VRPL J 1 Offset (8, 50);
		VRPL J 1 Offset (8, 45);
		Goto Ready+1;
	Fire70:
		VRPL K 2 Offset (117, 20) A_PlaySound("weapons/vorpalblade/attack",8,0.4,0);
		VRPL K 1 Offset (87, 33);
		VRPL K 2 Offset (60, 45);
		VRPL L 1 Offset (60, 45);
		VRPL M 1 Offset (60, 45);
		VRPL N 1 Offset (60, 45) A_VorpalFlamingAttack70;//A_CustomPunch(random(115,125),1,16,"UberchargePuff",156); // 270, 320
		VRPL N 1 Offset (41, 58) A_VorpalFlamingAttack70;//A_CustomPunch(random(115,125),1,16,"UberchargePuff",156);
		VRPL O 1 Offset (60, 45) A_VorpalFlamingAttack70;//A_CustomPunch(random(115,125),1,16,"UberchargePuff",156);
		VRPL O 2 Offset (44, 74);
		VRPL O 1 Offset (32, 96);
		VRPL O 6 Offset (19, 160);
		VRPL P 1;
		VRPL I 1 Offset (8, 75) A_ReFire;
		VRPL I 1 Offset (8, 65);
		VRPL I 1 Offset (8, 60);
		VRPL J 1 Offset (8, 55);
		VRPL J 1 Offset (8, 50);
		VRPL J 1 Offset (8, 45);
		Goto Ready+1;
	Fire60:
		VRPL K 2 Offset (117, 20) A_PlaySound("weapons/vorpalblade/attack",8,0.4,0);
		VRPL K 1 Offset (87, 33);
		VRPL K 2 Offset (60, 45);
		VRPL L 1 Offset (60, 45);
		VRPL M 1 Offset (60, 45);
		VRPL N 1 Offset (60, 45) A_VorpalFlamingAttack60;//A_CustomPunch(random(110,120),1,16,"UberchargePuff",156); // 240, 290
		VRPL N 1 Offset (41, 58) A_VorpalFlamingAttack60;//A_CustomPunch(random(110,120),1,16,"UberchargePuff",156);
		VRPL O 1 Offset (60, 45) A_VorpalFlamingAttack60;//A_CustomPunch(random(110,120),1,16,"UberchargePuff",156);
		VRPL O 2 Offset (44, 74);
		VRPL O 1 Offset (32, 96);
		VRPL O 6 Offset (19, 160);
		VRPL P 1;
		VRPL I 1 Offset (8, 75) A_ReFire;
		VRPL I 1 Offset (8, 65);
		VRPL I 1 Offset (8, 60);
		VRPL J 1 Offset (8, 55);
		VRPL J 1 Offset (8, 50);
		VRPL J 1 Offset (8, 45);
		Goto Ready+1;
	Fire50:
		VRPL K 2 Offset (117, 20) A_PlaySound("weapons/vorpalblade/attack",8,0.4,0);
		VRPL K 1 Offset (87, 33);
		VRPL K 2 Offset (60, 45);
		VRPL L 1 Offset (60, 45);
		VRPL M 1 Offset (60, 45);
		VRPL N 1 Offset (60, 45) A_VorpalFlamingAttack50;//A_CustomPunch(random(105,115),1,16,"UberchargePuff",156); // 225, 275
		VRPL N 1 Offset (41, 58) A_VorpalFlamingAttack50;//A_CustomPunch(random(105,115),1,16,"UberchargePuff",156);
		VRPL O 1 Offset (60, 45) A_VorpalFlamingAttack50;//A_CustomPunch(random(105,115),1,16,"UberchargePuff",156);
		VRPL O 2 Offset (44, 74);
		VRPL O 1 Offset (32, 96);
		VRPL O 6 Offset (19, 160);
		VRPL P 1;
		VRPL I 1 Offset (8, 75) A_ReFire;
		VRPL I 1 Offset (8, 65);
		VRPL I 1 Offset (8, 60);
		VRPL J 1 Offset (8, 55);
		VRPL J 1 Offset (8, 50);
		VRPL J 1 Offset (8, 45);
		Goto Ready+1;
	Fire40:
		VRPL K 2 Offset (117, 20) A_PlaySound("weapons/vorpalblade/attack",8,0.4,0);
		VRPL K 1 Offset (87, 33);
		VRPL K 2 Offset (60, 45);
		VRPL L 1 Offset (60, 45);
		VRPL M 1 Offset (60, 45);
		VRPL N 1 Offset (60, 45) A_VorpalFlamingAttack40;//A_CustomPunch(random(100,110),1,16,"UberchargePuff",156); // 210, 260
		VRPL N 1 Offset (41, 58) A_VorpalFlamingAttack40;//A_CustomPunch(random(100,110),1,16,"UberchargePuff",156);
		VRPL O 1 Offset (60, 45) A_VorpalFlamingAttack40;//A_CustomPunch(random(100,110),1,16,"UberchargePuff",156);
		VRPL O 2 Offset (44, 74);
		VRPL O 1 Offset (32, 96);
		VRPL O 6 Offset (19, 160);
		VRPL P 1;
		VRPL I 1 Offset (8, 75) A_ReFire;
		VRPL I 1 Offset (8, 65);
		VRPL I 1 Offset (8, 60);
		VRPL J 1 Offset (8, 55);
		VRPL J 1 Offset (8, 50);
		VRPL J 1 Offset (8, 45);
		Goto Ready+1;
	Fire30:
		VRPL K 2 Offset (117, 20) A_PlaySound("weapons/vorpalblade/attack",8,0.4,0);
		VRPL K 1 Offset (87, 33);
		VRPL K 2 Offset (60, 45);
		VRPL L 1 Offset (60, 45);
		VRPL M 1 Offset (60, 45);
		VRPL N 1 Offset (60, 45) A_VorpalFlamingAttack30;//A_CustomPunch(random(90,100),1,16,"UberchargePuff",156); // 180, 230
		VRPL N 1 Offset (41, 58) A_VorpalFlamingAttack30;//A_CustomPunch(random(90,100),1,16,"UberchargePuff",156);
		VRPL O 1 Offset (60, 45) A_VorpalFlamingAttack30;//A_CustomPunch(random(90,100),1,16,"UberchargePuff",156);
		VRPL O 2 Offset (44, 74);
		VRPL O 1 Offset (32, 96);
		VRPL O 6 Offset (19, 160);
		VRPL P 1;
		VRPL I 1 Offset (8, 75) A_ReFire;
		VRPL I 1 Offset (8, 65);
		VRPL I 1 Offset (8, 60);
		VRPL J 1 Offset (8, 55);
		VRPL J 1 Offset (8, 50);
		VRPL J 1 Offset (8, 45);
		Goto Ready+1;
	Fire20:
		VRPL K 2 Offset (117, 20) A_PlaySound("weapons/vorpalblade/attack",8,0.4,0);
		VRPL K 1 Offset (87, 33);
		VRPL K 2 Offset (60, 45);
		VRPL L 1 Offset (60, 45);
		VRPL M 1 Offset (60, 45);
		VRPL N 1 Offset (60, 45) A_VorpalFlamingAttack20;//A_CustomPunch(random(85,95),1,16,"UberchargePuff",156); // 165, 215
		VRPL N 1 Offset (41, 58) A_VorpalFlamingAttack20;//A_CustomPunch(random(85,95),1,16,"UberchargePuff",156);
		VRPL O 1 Offset (60, 45) A_VorpalFlamingAttack20;//A_CustomPunch(random(85,95),1,16,"UberchargePuff",156);
		VRPL O 2 Offset (44, 74);
		VRPL O 1 Offset (32, 96);
		VRPL O 6 Offset (19, 160);
		VRPL P 1;
		VRPL I 1 Offset (8, 75) A_ReFire;
		VRPL I 1 Offset (8, 65);
		VRPL I 1 Offset (8, 60);
		VRPL J 1 Offset (8, 55);
		VRPL J 1 Offset (8, 50);
		VRPL J 1 Offset (8, 45);
		Goto Ready+1;
	Fire10:
		VRPL K 2 Offset (117, 20) A_PlaySound("weapons/vorpalblade/attack",8,0.4,0);
		VRPL K 1 Offset (87, 33);
		VRPL K 2 Offset (60, 45);
		VRPL L 1 Offset (60, 45);
		VRPL M 1 Offset (60, 45);
		VRPL N 1 Offset (60, 45) A_VorpalFlamingAttack10;//A_CustomPunch(random(80,90),1,16,"UberchargePuff",156); // 150, 200
		VRPL N 1 Offset (41, 58) A_VorpalFlamingAttack10;//A_CustomPunch(random(80,90),1,16,"UberchargePuff",156);
		VRPL O 1 Offset (60, 45) A_VorpalFlamingAttack10;//A_CustomPunch(random(80,90),1,16,"UberchargePuff",156);
		VRPL O 2 Offset (44, 74);
		VRPL O 1 Offset (32, 96);
		VRPL O 6 Offset (19, 160);
		VRPL P 1;
		VRPL I 1 Offset (8, 75) A_ReFire;
		VRPL I 1 Offset (8, 65);
		VRPL I 1 Offset (8, 60);
		VRPL J 1 Offset (8, 55);
		VRPL J 1 Offset (8, 50);
		VRPL J 1 Offset (8, 45);
		Goto Ready+1;
	AltFire:
		VRPL A 0 A_JumpIfInventory("UberchargeActive",1,"UberchargeInUse");
		VRPL A 0 A_JumpIfInventory("Ubercharge",10,1);
		Goto Ready;
		VRPL A 0 A_PlaySound("Ignite",7,1.0,0);
		VRPL HIJ 3;
		VRPL A 0 A_GiveInventory("UberchargeActive",1);
		VRPL A 0 A_SpawnItemEx("UberchargeSpawner",0,0,0,0,0,0,0,32,0);
		VRPL A 0 A_JumpIfInventory("Ubercharge",100,"FullActivated");
		VRPL A 0 A_JumpIfInventory("Ubercharge",90,"90PercentActivated");
		VRPL A 0 A_JumpIfInventory("Ubercharge",80,"80PercentActivated");
		VRPL A 0 A_JumpIfInventory("Ubercharge",70,"70PercentActivated");
		VRPL A 0 A_JumpIfInventory("Ubercharge",60,"60PercentActivated");
		VRPL A 0 A_JumpIfInventory("Ubercharge",50,"50PercentActivated");
		VRPL A 0 A_JumpIfInventory("Ubercharge",40,"40PercentActivated");
		VRPL A 0 A_JumpIfInventory("Ubercharge",30,"30PercentActivated");
		VRPL A 0 A_JumpIfInventory("Ubercharge",20,"20PercentActivated");
		VRPL A 0 A_JumpIfInventory("Ubercharge",10,"10PercentActivated");
		Goto Ready+1;
	FullActivated:
		VRPL A 0 A_GiveInventory("FullCharge",1);
		VRPL A 0 A_GiveInventory("UberchargeResistance",1);
		VRPL A 0 A_GiveInventory("UberchargeSpeedFull",1);
		Goto Ready+1;
	90PercentActivated:
		VRPL A 0 A_GiveInventory("UberchargeResistance",1);
		VRPL A 0 A_GiveInventory("UberchargeSpeed90",1);
		VRPL A 0 A_GiveInventory("90PercentCharge",1);
		Goto Ready+1;
	80PercentActivated:
		VRPL A 0 A_GiveInventory("UberchargeResistance",1);
		VRPL A 0 A_GiveInventory("UberchargeSpeed80",1);
		VRPL A 0 A_GiveInventory("80PercentCharge",1);
		Goto Ready+1;
	70PercentActivated:
		VRPL A 0 A_GiveInventory("UberchargeResistance",1);
		VRPL A 0 A_GiveInventory("UberchargeSpeed70",1);
		VRPL A 0 A_GiveInventory("70PercentCharge",1);
		Goto Ready+1;
	60PercentActivated:
		VRPL A 0 A_GiveInventory("UberchargeResistance",1);
		VRPL A 0 A_GiveInventory("UberchargeSpeed60",1);
		VRPL A 0 A_GiveInventory("60PercentCharge",1);
		Goto Ready+1;
	50PercentActivated:
		VRPL A 0 A_GiveInventory("UberchargeResistance",1);
		VRPL A 0 A_GiveInventory("50PercentCharge",1);
		Goto Ready+1;
	40PercentActivated:
		VRPL A 0 A_GiveInventory("UberchargeResistance",1);
		VRPL A 0 A_GiveInventory("40PercentCharge",1);
		Goto Ready+1;
	30PercentActivated:
		VRPL A 0 A_GiveInventory("UberchargeResistance",1);
		VRPL A 0 A_GiveInventory("30PercentCharge",1);
		Goto Ready+1;
	20PercentActivated:
		VRPL A 0 A_GiveInventory("UberchargeResistance",1);
		VRPL A 0 A_GiveInventory("20PercentCharge",1);
		Goto Ready+1;
	10PercentActivated:
		VRPL A 0 A_GiveInventory("UberchargeResistance",1);
		VRPL A 0 A_GiveInventory("10PercentCharge",1);
		Goto Ready+1;
	}


	action void A_VorpalAttack()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[VorpalAtk](45, 65);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 16, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 16, slope, damage, 'Melee', "VorpalPuff", true, t);
					if (t.linetarget != null)
					{
						//AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "VorpalPuff");
	}


	action void A_VorpalFullChargeAttack()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[VorpalAtk](55, 75);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 16, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 16, slope, damage, 'Melee', "VorpalPuff", true, t);
					if (t.linetarget != null)
					{
						//AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "VorpalPuff");
	}

	action void A_VorpalFlamingAttackFull()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[VorpalAtk](145, 170);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 20, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 20, slope, damage, 'Melee', "UberchargePuff", true, t);
					if (t.linetarget != null)
					{
						//AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "UberchargePuff");
	}

	action void A_VorpalFlamingAttack90()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[VorpalAtk](130, 150);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 20, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 20, slope, damage, 'Melee', "UberchargePuff", true, t);
					if (t.linetarget != null)
					{
						//AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "UberchargePuff");
	}

	action void A_VorpalFlamingAttack80()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[VorpalAtk](120, 140);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 20, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 20, slope, damage, 'Melee', "UberchargePuff", true, t);
					if (t.linetarget != null)
					{
						//AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "UberchargePuff");
	}

	action void A_VorpalFlamingAttack70()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[VorpalAtk](115, 125);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 20, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 20, slope, damage, 'Melee', "UberchargePuff", true, t);
					if (t.linetarget != null)
					{
						//AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "UberchargePuff");
	}

	action void A_VorpalFlamingAttack60()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[VorpalAtk](110, 120);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 20, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 20, slope, damage, 'Melee', "UberchargePuff", true, t);
					if (t.linetarget != null)
					{
						//AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "UberchargePuff");
	}

	action void A_VorpalFlamingAttack50()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[VorpalAtk](105, 115);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 20, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 20, slope, damage, 'Melee', "UberchargePuff", true, t);
					if (t.linetarget != null)
					{
						//AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "UberchargePuff");
	}

	action void A_VorpalFlamingAttack40()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[VorpalAtk](100, 110);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 20, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 20, slope, damage, 'Melee', "UberchargePuff", true, t);
					if (t.linetarget != null)
					{
						//AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "UberchargePuff");
	}

	action void A_VorpalFlamingAttack30()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[VorpalAtk](90, 100);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 20, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 20, slope, damage, 'Melee', "UberchargePuff", true, t);
					if (t.linetarget != null)
					{
						//AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "UberchargePuff");
	}

	action void A_VorpalFlamingAttack20()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[VorpalAtk](85, 95);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 20, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 20, slope, damage, 'Melee', "UberchargePuff", true, t);
					if (t.linetarget != null)
					{
						//AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "UberchargePuff");
	}

	action void A_VorpalFlamingAttack10()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[VorpalAtk](80, 90);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 20, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 20, slope, damage, 'Melee', "UberchargePuff", true, t);
					if (t.linetarget != null)
					{
						//AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "UberchargePuff");
	}
}

//-----------------------------------------------

class TimonsAxe : FighterWeapon replaces FWeapAxe
{
	Default
	{
		Tag "Timon's Battle Axe";
		+FLOORCLIP;
		+WEAPON.MELEEWEAPON;
		+WEAPON.AMMO_OPTIONAL;
		+WEAPON.ALT_AMMO_OPTIONAL;
		Weapon.SisterWeapon "TimonsAxePowered";
		Inventory.PickupMessage "Timon's Battle Axe";
		Weapon.AmmoType1 "BlueMana";
		Weapon.AmmoType2 "BlueMana";
		Weapon.AmmoGive1 25;
		Weapon.AmmoUse1 1; // 2 with RoW, 3 without
		Weapon.AmmoUse2 1; // 1 with RoW, 2 without
		Weapon.YAdjust -12;
		Weapon.KickBack 50;
	}
	States
	{
	Spawn:
		WFAX A -1;
	        Loop;
	Select: 
		FAXE A 1 A_Raise;
		TNT1 AA 0 A_Raise;
		Loop;
	Deselect: 
		FAXE A 1 A_Lower;
		TNT1 AA 0 A_Lower; 
		Loop;
	Ready:
		TNT1 A 0 A_JumpIfInventory("PowerWeaponLevel2",1,"ReadyPowered");
		FAXE A 0 A_JumpIfInventory("BlueMana",2,2);
		FAXE A 1 A_WeaponReady;
		Loop;
		FAXE LLL 1 A_WeaponReady;
		FAXE MMM 1 A_WeaponReady;
		Loop;
	ReadyPowered:
		TNT1 A 0 A_JumpIfInventory("PowerWeaponLevel2",1,1);
		Goto Ready;
		FAXE A 0 A_JumpIfInventory("BlueMana",2,2);
		FAXE A 1 A_WeaponReady;
		Loop;
		REDX AAA 1 A_WeaponReady;
		REDX BBB 1 A_WeaponReady;
		Loop;
	Fire:
		FAXE B 0 Offset (15, 32) A_JumpIfInventory("BlueMana",2,"FireGlow");
		FAXE B 3 Offset (15, 32);
		FAXE C 3 Offset (15, 32);
		FAXE D 2 Offset (15, 32);
		FAXE D 1 OffSet (-5, 70) A_TimonAxeAttack;//A_CustomPunch(random(80,100),1,0,"BattleAxePuff",144);
		FAXE D 2 Offset (-25, 90);
		FAXE E 1 Offset (15, 32);
		FAXE E 2 Offset (10, 54);
		FAXE E 4 Offset (10, 150);
		FAXE A 1 Offset (0, 60) A_ReFire;
		FAXE A 1 Offset (0, 52);
		FAXE A 1 Offset (0, 44);
		FAXE A 1 Offset (0, 36);
		FAXE A 1;
		Goto Ready;
	FireGlow:
		FAXE N 3 Offset (15, 32);
		FAXE O 3 Offset (15, 32);
		FAXE P 2 Offset (15, 32);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,2);
		TNT1 AA 0 A_TimonAxeAmmoUser;//A_CustomPunch(1,1,1,"NoPuff",144);
		FAXE P 1 Offset (-5, 70) A_TimonAxeAttack;//A_CustomPunch(random(220,260),1,1,"BattleAxePuffGlow",144); // 140, 170
		FAXE P 2 Offset (-25, 90);
		FAXE Q 1 Offset (15, 32);
		FAXE Q 2 Offset (10, 54);
		FAXE Q 4 Offset (10, 150);
		FAXE A 1 Offset (0, 60) A_ReFire;
		FAXE A 1 Offset (0, 52);
		FAXE A 1 Offset (0, 44);
		FAXE A 1 Offset (0, 36);
		FAXE A 1;
		Goto Ready;
	AltFire:
		FAXE B 0 Offset (15, 32) A_JumpIfInventory("BlueMana",2,"AltFireGlow");
		FAXE B 3 Offset (15, 32);
		FAXE C 3 Offset (15, 32);
		FAXE D 2 Offset (15, 32);
		FAXE D 1 Offset (-5, 70) A_TimonAxeAttack;//A_CustomPunch(random(80,100),1,0,"BattleAxePuff",144);
		FAXE D 2 Offset (-25, 90);
		FAXE E 1 Offset (15, 32);
		FAXE E 2 Offset (10, 54);
		FAXE E 4 Offset (10, 150);
		FAXE A 1 Offset (0, 60) A_ReFire;
		FAXE A 1 Offset (0, 52);
		FAXE A 1 Offset (0, 44);
		FAXE A 1 Offset (0, 36);
		FAXE A 1;
		Goto Ready;
	AltFireGlow:
		FAXE N 4 Offset (15, 32);
		FAXE O 3 Offset (15, 32);
		FAXE P 2 Offset (15, 32);
		FAXE P 0 Offset (15, 32) A_JumpIfInventory("PowerHalfMana",1,2);
		FAXE P 0 Offset (15, 32) A_FireProjectile("AmmoUser",0,1,0);
		FAXE P 0 Offset (15, 32) A_PlaySound("FighterHammerMiss", CHAN_WEAPON, 1.0, 0);
		FAXE P 1 Offset (-5, 70) A_FireProjectile("ThrownAxe",0,1,0,0,0);
		FAXE P 2 Offset (-25, 90);
		FAXE Q 1 Offset (15, 32);
		FAXE Q 2 Offset (10, 54);
		FAXE Q 5 Offset (10, 150);
		FAXE A 1 Offset (0, 60) A_Refire;
		FAXE A 1 Offset (0, 52);
		FAXE A 1 Offset (0, 44);
		FAXE A 1 Offset (0, 36);
		FAXE A 1;
		Goto Ready;
	}

	action void A_TimonAxeAttack()
	{
		FTranslatedLineTarget t;

		if (player == null)
		{
			return;
		}

		int damage = random[AxeAtk](80, 100);
//		damage += random[AxeAtk](0, 7);
		int power = 0;
		Weapon weapon = player.ReadyWeapon;
		class<Actor> pufftype;
		int usemana;
		if ((usemana = (weapon.Ammo1 && weapon.Ammo1.Amount > 0)))
		{
//			damage <<= 1;
			damage = random[AxeAtk](220, 260);
			power = 6;
			pufftype = "AxePuffGlow";
		}
		else
		{
			pufftype = "AxePuff";
		}
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2.25 * DEFMELEERANGE, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2.25 * DEFMELEERANGE, slope, damage, 'Melee', pufftype, true, t);
					if (t.linetarget != null)
					{
						if (t.linetarget.bIsMonster || t.linetarget.player)
						{
							t.linetarget.Thrust(power, t.attackAngleFromSource);
						}
						AdjustPlayerAngle(t);
						
						weapon.DepleteAmmo (weapon.bAltFire, false);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		self.weaponspecial = 0;

		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', pufftype, true);
	}

	action void A_TimonAxeAmmoUser()
	{
		FTranslatedLineTarget t;

		if (player == null)
		{
			return;
		}

		int damage = 0;
		int power = 0;
		Weapon weapon = player.ReadyWeapon;
		class<Actor> pufftype;
		int usemana;
		if ((usemana = (weapon.Ammo1 && weapon.Ammo1.Amount > 0)))
		{
			damage = 0;
			power = 0;
			pufftype = "NoPuff";
		}
		else
		{
			pufftype = "NoPuff";
		}
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2.25 * DEFMELEERANGE, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2.25 * DEFMELEERANGE, slope, damage, 'Melee', pufftype, true, t);
					if (t.linetarget != null)
					{
						if (t.linetarget.bIsMonster || t.linetarget.player)
						{
							t.linetarget.Thrust(power, t.attackAngleFromSource);
						}
						//AdjustPlayerAngle(t);
						
						weapon.DepleteAmmo (weapon.bAltFire, false);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		self.weaponspecial = 0;

		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', pufftype, true);
	}
}

// Powered

class TimonsAxePowered : TimonsAxe
{
	Default
	{
		Tag "Timon's Battle Axe";
		+FLOORCLIP;
		+WEAPON.MELEEWEAPON;
		+WEAPON.AMMO_OPTIONAL;
		+WEAPON.ALT_AMMO_OPTIONAL;
		+WEAPON.POWERED_UP;
		Weapon.SisterWeapon "TimonsAxe";
		Weapon.AmmoType1 "BlueMana";
		Weapon.AmmoType2 "BlueMana";
		Weapon.AmmoUse1 3; // 3 with RoW, 6 without
		Weapon.AmmoUse2 2; // 2 with RoW, 4 without
		Weapon.AmmoGive 0;
		Weapon.YAdjust -12;
		Weapon.KickBack 100;
	}
	States
	{
	Select: 
		FAXE A 1 A_Raise;
		TNT1 AA 0 A_Raise;
		Loop;
	Deselect: 
		FAXE A 1 A_Lower;
		TNT1 AA 0 A_Lower; 
		Loop;
	Fire:
		FAXE B 0 Offset (15, 32) A_JumpIfInventory("BlueMana",2,"FireGlow");
		FAXE B 3 Offset (15, 32);
		FAXE C 2 Offset (15, 32);
		FAXE D 2 Offset (15, 32);
		FAXE D 1 OffSet (-5, 70) A_TimonAxePoweredAttack;//A_CustomPunch(random(110,130),1,0,"BattleAxePuff",144);
		FAXE D 2 Offset (-25, 90);
		FAXE E 1 Offset (15, 32);
		FAXE E 2 Offset (10, 54);
		FAXE E 3 Offset (10, 150);
		FAXE A 1 Offset (0, 60) A_ReFire;
		FAXE A 1 Offset (0, 52);
		FAXE A 1 Offset (0, 44);
		FAXE A 1 Offset (0, 36);
		FAXE A 1;
		Goto Ready;
	FireGlow:
		REDX C 3 Offset (15, 32);
		REDX D 2 Offset (15, 32);
		REDX E 2 Offset (15, 32);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,2);
		TNT1 A 0 A_TimonAxeAmmoUser;//A_CustomPunch(1,1,1,"NoPuff",144);
		REDX E 1 Offset (-5, 70) A_TimonAxePoweredAttack;//A_CustomPunch(random(460,550),1,1,"RedAxePuffGlow",144); // 300, 360
		REDX E 2 Offset (-25, 90);
		REDX F 1 Offset (15, 32);
		REDX F 2 Offset (10, 54);
		REDX F 3 Offset (10, 150);
		FAXE A 1 Offset (0, 60) A_ReFire;
		FAXE A 1 Offset (0, 52);
		FAXE A 1 Offset (0, 44);
		FAXE A 1 Offset (0, 36);
		FAXE A 1;
		Goto Ready;
	AltFire:
		FAXE B 0 Offset (15, 32) A_JumpIfInventory("BlueMana",2,"AltFireGlow");
		FAXE B 3 Offset (15, 32);
		FAXE C 2 Offset (15, 32);
		FAXE D 2 Offset (15, 32);
		FAXE D 1 Offset (-5, 70) A_TimonAxePoweredAttack;//A_CustomPunch(random(110,130),1,0,"BattleAxePuff",144);
		FAXE D 2 Offset (-25, 90);
		FAXE E 1 Offset (15, 32);
		FAXE E 2 Offset (10, 54);
		FAXE E 5 Offset (10, 150);
		FAXE A 1 Offset (0, 60) A_ReFire;
		FAXE A 1 Offset (0, 52);
		FAXE A 1 Offset (0, 44);
		FAXE A 1 Offset (0, 36);
		FAXE A 1;
		Goto Ready;
	AltFireGlow:
		REDX C 3 Offset (15, 32);
		REDX D 2 Offset (15, 32);
		REDX E 2 Offset (15, 32);
		REDX E 0 A_JumpIfInventory("PowerHalfMana",1,2);
		REDX E 0 A_FireProjectile("AmmoUser",0,1,0);
		REDX E 0 Offset (15, 32) A_PlaySound("FighterHammerMiss", CHAN_WEAPON, 1.0, 0);
		REDX E 1 Offset (-5, 70) A_FireProjectile("ThrownRedAxe",0,1,0,0,0);
		REDX E 2 Offset (-25, 90);
		REDX F 1 Offset (15, 32);
		REDX F 2 Offset (10, 54);
		REDX F 5 Offset (10, 150);
		FAXE A 1 Offset (0, 60) A_Refire;
		FAXE A 1 Offset (0, 52);
		FAXE A 1 Offset (0, 44);
		FAXE A 1 Offset (0, 36);
		FAXE A 1;
		Goto Ready;
	}

	action void A_TimonAxePoweredAttack()
	{
		FTranslatedLineTarget t;

		if (player == null)
		{
			return;
		}

		int damage = random[AxeAtk](110, 130);
//		damage += random[AxeAtk](0, 7);
		int power = 0;
		Weapon weapon = player.ReadyWeapon;
		class<Actor> pufftype;
		int usemana;
		if ((usemana = (weapon.Ammo1 && weapon.Ammo1.Amount > 0)))
		{
//			damage <<= 1;
			damage = random[AxeAtk](460, 550);
			power = 6;
			pufftype = "RedAxePuffGlow";
		}
		else
		{
			pufftype = "AxePuff";
		}
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2.25 * DEFMELEERANGE, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2.25 * DEFMELEERANGE, slope, damage, 'Melee', pufftype, true, t);
					if (t.linetarget != null)
					{
						if (t.linetarget.bIsMonster || t.linetarget.player)
						{
							t.linetarget.Thrust(power, t.attackAngleFromSource);
						}
						AdjustPlayerAngle(t);
						
						weapon.DepleteAmmo (weapon.bAltFire, false);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		self.weaponspecial = 0;

		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', pufftype, true);
	}
	action void A_TimonAxeAmmoUser()
	{
		FTranslatedLineTarget t;

		if (player == null)
		{
			return;
		}

		int damage = 0;
		int power = 0;
		Weapon weapon = player.ReadyWeapon;
		class<Actor> pufftype;
		int usemana;
		if ((usemana = (weapon.Ammo1 && weapon.Ammo1.Amount > 0)))
		{
			damage = 0;
			power = 0;
			pufftype = "NoPuff";
		}
		else
		{
			pufftype = "NoPuff";
		}
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2.25 * DEFMELEERANGE, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2.25 * DEFMELEERANGE, slope, damage, 'Melee', pufftype, true, t);
					if (t.linetarget != null)
					{
						if (t.linetarget.bIsMonster || t.linetarget.player)
						{
							t.linetarget.Thrust(power, t.attackAngleFromSource);
						}
						//AdjustPlayerAngle(t);
						
						weapon.DepleteAmmo (weapon.bAltFire, false);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		self.weaponspecial = 0;

		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', pufftype, true);
	}
}

//-----------------------------------------------

//ACTOR FHammer : FWeapHammer replaces FWeapHammer

class FHammer : FWeapHammer replaces FWeapHammer
{
	Default
	{
		Tag "Hammer Of Retribution";
		+BLOODSPLATTER;
		+WEAPON.AMMO_OPTIONAL;
		+WEAPON.ALT_AMMO_OPTIONAL;
		+WEAPON.MELEEWEAPON;
		Weapon.AmmoUse1 1; // 2 with RoW, 3 without
		Weapon.AmmoUse2 1; // 1 with RoW, 2 without
		Weapon.AmmoGive1 25;
		Weapon.KickBack 150;
		Weapon.YAdjust -10;
		Weapon.SisterWeapon "FHammerPowered";
		Weapon.AmmoType1 "GreenMana";
		Weapon.AmmoType2 "GreenMana";
		Inventory.PickupMessage "Hammer Of Retribution";
	}
	States
	{
	Spawn:
		WFHM A -1;
		Stop;
	Select:
		FHMR A 1 A_Raise;
		TNT1 AA 0 A_Raise;
		Loop;
	Deselect:
		FHMR A 1 A_Lower;
		TNT1 AA 0 A_Lower;
		Loop;
	Ready:
		TNT1 A 0 A_JumpIfInventory("PowerWeaponLevel2",1,"ReadyPowered");
		FHMR A 1 A_WeaponReady;
		Loop;
	ReadyPowered:
		TNT1 A 0 A_JumpIfInventory("PowerWeaponLevel2",1,1);
		Goto Ready;
		FHMR A 1 A_WeaponReady;
		Loop;
	Fire:
		FHMR B 4 Offset (5, 0);
		FHMR C 3 Offset (5, 0) A_HammerMeleeAttack;//A_CustomPunch(random(135,160),1,0,"FHammerPuff",128);
		FHMR D 3 Offset (5, 0);
		FHMR E 2 Offset (5, 0);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,"FireHalfMana");
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("GreenMana",3,2);
		FHMR E 0 Offset (5, 0) A_Jump(256,5);
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("HammerCheck",1,4);
		TNT1 AA 0 A_FireProjectile("AmmoUser",0,1,0);
		FHMR E 0 Offset (5, 150) A_FireProjectile("FHammerMissile",0,1,0,0);
		FHMR E 8 Offset (5, 150);
		FHMR A 1 Offset (0, 60);
		FHMR A 1 Offset (0, 50);
		FHMR A 1 Offset (0, 40);
		FHMR A 1;
		Goto Ready;
	FireHalfMana:
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("GreenMana",1,2);
		FHMR E 0 Offset (5, 0) A_Jump(256,4);
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("HammerCheck",1,3);
		TNT1 A 0 A_FireProjectile("AmmoUser",0,1,0);
		FHMR E 0 Offset (5, 150) A_FireProjectile("FHammerMissile",0,1,0,0);
		FHMR E 8 Offset (5, 150);
		FHMR A 1 Offset (0, 60);
		FHMR A 1 Offset (0, 50);
		FHMR A 1 Offset (0, 40);
		FHMR A 1;
		Goto Ready;
	AltFire:
		FHMR B 4 Offset (5, 0);
		FHMR C 3 Offset (5, 0) A_HammerMeleeAttack;//A_CustomPunch(random(120,140),1,0,"FHammerPuff",128);
		FHMR D 3 Offset (5, 0);
		FHMR E 2 Offset (5, 0);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,"AltFireHalfMana");
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("GreenMana",2,2);
		FHMR E 0 Offset (5, 0) A_Jump(256,4);
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("HammerCheck",1,3);
		TNT1 A 0 A_FireProjectile("AmmoUser",0,1,0);
		FHMR E 0 Offset (5, 150) A_FireProjectile("HomingHammer",0,1,0,0);
		FHMR E 8 Offset (5, 150);
		FHMR A 1 Offset (0, 60);
		FHMR A 1 Offset (0, 50);
		FHMR A 1 Offset (0, 40);
		FHMR A 1;
		Goto Ready;
	AltFireHalfMana:
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("GreenMana",1,2);
		FHMR E 0 Offset (5, 0) A_Jump(256,3);
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("HammerCheck",1,2);
		FHMR E 0 Offset (5, 150) A_FireProjectile("HomingHammer",0,1,0,0);
		FHMR E 8 Offset (5, 150);
		FHMR A 1 Offset (0, 60);
		FHMR A 1 Offset (0, 50);
		FHMR A 1 Offset (0, 40);
		FHMR A 1;
		Goto Ready;
	}

	action void A_HammerMeleeAttack()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[HammerAtk](135, 160);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 8, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 8, slope, damage, 'Melee', "HammerPuff", true, t);
					if (t.linetarget != null)
					{
						AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "HammerPuff");
	}
}

// Powered

class FHammerPowered : FHammer
{
	Default
	{
		Tag "Hammer Of Retribution";
		Weapon.SelectionOrder 900;
		+BLOODSPLATTER;
		+WEAPON.AMMO_OPTIONAL;
		+WEAPON.ALT_AMMO_OPTIONAL;
		+WEAPON.MELEEWEAPON;
		+WEAPON.POWERED_UP;
		Weapon.AmmoUse1 3; // 3 with RoW, 6 without
		Weapon.AmmoUse2 2; // 2 with RoW, 4 without
		Weapon.AmmoGive1 0;
		Weapon.KickBack 200;
		Weapon.YAdjust -10;
		Weapon.SisterWeapon "FHammer";
		Weapon.AmmoType1 "GreenMana";
		Inventory.PickupMessage "Hammer Of Retribution";
	}
	States
	{
	Spawn:
		WFHM A -1;
		Stop;
	Select:
		FHMR A 1 A_Raise;
		TNT1 AA 0 A_Raise;
		Loop;
	Deselect:
		FHMR A 1 A_Lower;
		TNT1 AA 0 A_Lower;
		Loop;
	Fire:
		FHMR B 4 Offset (5, 0);
		FHMR C 3 Offset (5, 0) A_HammerPoweredMeleeAttack;//A_CustomPunch(random(300,360),1,0,"FHammerPuff",128);
		FHMR D 3 Offset (5, 0);
		FHMR E 2 Offset (5, 0);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,"FireHalfMana");
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("GreenMana",6,2);
		FHMR E 0 Offset (5, 0) A_Jump(256,4);
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("HammerCheck",1,3);
		TNT1 A 0 A_FireProjectile("AmmoUser",0,1,0);
		FHMR E 0 Offset (5, 150) A_FireProjectile("NapalmHammer",0,1,0,0);
		FHMR E 8 Offset (5, 150);
		FHMR A 1 Offset (0, 60);
		FHMR A 1 Offset (0, 50);
		FHMR A 1 Offset (0, 40);
		FHMR A 1;
		Goto Ready;
	FireHalfMana:
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("GreenMana",3,2);
		FHMR E 0 Offset (5, 0) A_Jump(256,3);
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("HammerCheck",1,2);
		FHMR E 0 Offset (5, 150) A_FireProjectile("NapalmHammer",0,1,0,0);
		FHMR E 8 Offset (5, 150);
		FHMR A 1 Offset (0, 60);
		FHMR A 1 Offset (0, 50);
		FHMR A 1 Offset (0, 40);
		FHMR A 1;
		Goto Ready;
	AltFire:
		FHMR B 4 Offset (5, 0);
		FHMR C 3 Offset (5, 0) A_HammerPoweredMeleeAttack;//A_CustomPunch(random(280,340),1,0,"FHammerPuff",128);
		FHMR D 3 Offset (5, 0);
		FHMR E 2 Offset (5, 0);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,"FireHalfMana");
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("GreenMana",4,2);
		FHMR E 0 Offset (5, 0) A_Jump(256,4);
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("HammerCheck",1,3);
		TNT1 A 0 A_FireProjectile("AmmoUser",0,1,0);
		FHMR E 0 Offset (5, 150) A_FireProjectile("HomingNapalmHammer",0,1,0,0);
		FHMR E 8 Offset (5, 150);
		FHMR A 1 Offset (0, 60);
		FHMR A 1 Offset (0, 50);
		FHMR A 1 Offset (0, 40);
		FHMR A 1;
		Goto Ready;
	AltFireHalfMana:
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("GreenMana",2,2);
		FHMR E 0 Offset (5, 0) A_Jump(256,3);
		FHMR E 0 Offset (5, 0) A_JumpIfInventory("HammerCheck",1,2);
		FHMR E 0 Offset (5, 150) A_FireProjectile("HomingNapalmHammer",0,1,0,0);
		FHMR E 8 Offset (5, 150);
		FHMR A 1 Offset (0, 60);
		FHMR A 1 Offset (0, 50);
		FHMR A 1 Offset (0, 40);
		FHMR A 1;
		Goto Ready;
	}

	action void A_HammerPoweredMeleeAttack()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[HammerAtk](280, 340);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 8, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 8, slope, damage, 'Melee', "HammerPuff", true, t);
					if (t.linetarget != null)
					{
						AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "HammerPuff");
	}
}

//-----------------------------------------------

//ACTOR Quietus : FWeapQuietus replaces FWeapQuietus

class Quietus : FWeapQuietus replaces FWeapQuietus
{
	Default
	{
		Tag "Quietus";
		-WEAPON.PRIMARY_USES_BOTH;
		+WEAPON.AMMO_OPTIONAL;
		+WEAPON.ALT_AMMO_OPTIONAL;
		Weapon.AmmoUse1 1; // 4 with RoW (full hit), 2 without
		Weapon.AmmoUse2 7; // 7 with RoW, 14 without
		Weapon.AmmoGive1 25;
		Weapon.AmmoGive2 0;
		Weapon.KickBack 150;
		Weapon.YAdjust 10;
		Weapon.AmmoType1 "GoldMana";
		Weapon.AmmoType2 "GoldMana";
		Weapon.SisterWeapon "QuietusPowered";
		Inventory.PickupMessage "Quietus Assembled";
		Inventory.PickupSound "4thweapon/pickup";
	}
	States
	{
	Spawn:
		TNT1 A -1;
		Stop;
	Select:
		FSRD A 0 A_JumpIfInventory("GoldMana",1,1);
		Goto SelectNoMana;
		FSRD A 1 Bright A_Raise;
		TNT1 AA 0 A_Raise;
		Loop;
	SelectNoMana:
		FSD3 A 1 A_Raise;
		TNT1 AA 0 A_Raise;
		Loop;
	Deselect:
		FSRD A 0 A_JumpIfInventory("GoldMana",1,1);
		Goto DeselectNoMana;
		FSRD A 1 Bright A_Lower;
		TNT1 AA 0 A_Lower;
		Loop;
	DeselectNoMana:
		FSD3 A 1 A_Lower;
		TNT1 AA 0 A_Lower;
		Loop;
	 Ready:
		FSRD A 0 A_JumpIfInventory("GoldMana",1,1);
		Goto ReadyNoMana;
		FSRD A 0 A_JumpIfInventory("PowerWeaponLevel2",1,"ReadyPowered");
		FSRD AAAA 1 Bright A_WeaponReady;
		FSRD B 0 A_JumpIfInventory("PowerWeaponLevel2",1,"ReadyPowered");
		FSRD BBBB 1 Bright A_WeaponReady;
		FSRD C 0 A_JumpIfInventory("PowerWeaponLevel2",1,"ReadyPowered");
		FSRD CCCC 1 Bright A_WeaponReady;
		Loop;
	ReadyNoMana:
		FSD3 A 0 A_JumpIfInventory("GoldMana",1,"Ready");
		FSD3 A 1 A_WeaponReady;
		Loop;
	ReadyPowered:
		FSRD A 0 A_JumpIfInventory("PowerWeaponLevel2",1,1);
		Goto Ready;
		FSD2 AAAA 1 Bright A_WeaponReady;
		FSRD B 0 A_JumpIfInventory("PowerWeaponLevel2",1,1);
		Goto Ready;
		FSD2 BBBB 1 Bright A_WeaponReady;
		FSRD C 0 A_JumpIfInventory("PowerWeaponLevel2",1,1);
		Goto Ready;
		FSD2 CCCC 1 Bright A_WeaponReady;
		Loop;
	Fire:
		FSRD A 0 A_JumpIfInventory("GoldMana",1,1);
		Goto FireNoMana;
		FSRD D 3 Bright Offset (5, 36);
		FSRD E 3 Bright Offset (5, 36);
		FSRD F 1 Bright Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(180,210),1,17,"QuietusPuff",160);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,3);
		FSRD F 1 Bright Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(180,210),1,17,"QuietusPuff",160);
		FSRD F 0 Bright Offset (5, 36) A_Jump(256,2);
		FSRD F 1 Bright Offset (5, 36) A_QuietusMeleeAttackRoW;//A_CustomPunch(random(180,210),1,16,"QuietusPuff",160);
		FSRD G 1 Bright Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(180,210),1,17,"QuietusPuff",160);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,3);
		FSRD G 1 Bright Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(180,210),1,17,"QuietusPuff",160);
		FSRD G 0 Bright Offset (5, 36) A_Jump(256,2);
		FSRD G 1 Bright Offset (5, 36) A_QuietusMeleeAttackRoW;//A_CustomPunch(random(180,210),1,16,"QuietusPuff",160);
		FSRD H 1 Bright Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(180,210),1,17,"QuietusPuff",160);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,3);
		FSRD H 1 Bright Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(180,210),1,17,"QuietusPuff",160);
		FSRD H 0 Bright Offset (5, 36) A_Jump(256,2);
		FSRD H 1 Bright Offset (5, 36) A_QuietusMeleeAttackRoW;//A_CustomPunch(random(180,210),1,16,"QuietusPuff",160);
		FSRD I 2 Bright Offset (5, 36);
		FSRD I 7 Bright Offset (5, 150);
		FSRD A 0 A_JumpIfInventory("GoldMana",1,1);
		Goto FireNoMana+7;
		FSRD A 1 Bright Offset (5, 60);
		FSRD B 1 Bright Offset (5, 55);
		FSRD C 1 Bright Offset (5, 50);
		FSRD A 1 Bright Offset (5, 45);
		FSRD B 1 Bright Offset (5, 40);
		Goto Ready;
	FireNoMana:
		FSD3 BC 3 Offset (5, 36);
		FSD3 D 1 Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(60,80),1,16,"QuietusPuffNoMana",160);
		FSD3 D 1 Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(60,80),1,16,"QuietusPuffNoMana",160);
		FSD3 E 1 Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(60,80),1,16,"QuietusPuffNoMana",160);
		FSD3 E 1 Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(60,80),1,16,"QuietusPuffNoMana",160);
		FSD3 F 1 Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(60,80),1,16,"QuietusPuffNoMana",160);
		FSD3 F 1 Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(60,80),1,16,"QuietusPuffNoMana",160);
		FSD3 H 2 Offset (5, 36);
		TNT1 A 7;
		FSD3 A 1 Offset (5, 60);
		FSD3 A 1 Offset (5, 55);
		FSD3 A 1 Offset (5, 50);
		FSD3 A 1 Offset (5, 45);
		FSD3 A 1 Offset (5, 40);
		Goto Ready;
	AltFire:
		FSRD A 0 A_JumpIfInventory("GoldMana",1,1);
		Goto FireNoMana;
		FSRD DE 3 Bright Offset (5, 36);
		FSRD F 1 Bright Offset (5, 36);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,2);
		TNT1 A 0 A_FireProjectile("AmmoUser",0,1,0);
		FSRD G 1 Bright Offset (5, 36) A_FSwordAttack;
		FSRD H 1 Bright Offset (5, 36);
		FSRD I 2 Bright Offset (5, 36);
		FSRD I 10 Bright Offset (5, 150);
		FSRD A 1 Bright Offset (5, 60);
		FSRD B 1 Bright Offset (5, 55);
		FSRD C 1 Bright Offset (5, 50);
		FSRD A 1 Bright Offset (5, 45);
		FSRD B 1 Bright Offset (5, 40);
		Goto Ready;
	}
	action void A_QuietusMeleeAttack()
	{
		FTranslatedLineTarget t;

		if (player == null)
		{
			return;
		}

		int damage = random[SwordAtk](60, 80);
		int power = 0;
		Weapon weapon = player.ReadyWeapon;
		class<Actor> pufftype;
		int usemana;
		if ((usemana = (weapon.Ammo1 && weapon.Ammo1.Amount > 0)))
		{
			damage = random[SwordAtk](180, 210);
			power = 2;
			pufftype = "QuietusPuff";
		}
		else
		{
			pufftype = "QuietusPuffNoMana";
		}
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 24, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 24, slope, damage, 'Melee', pufftype, true, t);
					if (t.linetarget != null)
					{
						if (t.linetarget.bIsMonster || t.linetarget.player)
						{
							t.linetarget.Thrust(power, t.attackAngleFromSource);
						}
						//AdjustPlayerAngle(t);
						
						weapon.DepleteAmmo (weapon.bAltFire, false);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		self.weaponspecial = 0;

		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', pufftype, true);
	}

	action void A_QuietusMeleeAttackRoW()
	{
		FTranslatedLineTarget t;

		if (player == null)
		{
			return;
		}

		int damage = random[SwordAtk](60, 80);
		int power = 0;
		Weapon weapon = player.ReadyWeapon;
		class<Actor> pufftype;
		int usemana;
		if ((usemana = (weapon.Ammo1 && weapon.Ammo1.Amount > 0)))
		{
			damage = random[SwordAtk](180, 210);
			power = 2;
			pufftype = "QuietusPuff";
		}
		else
		{
			pufftype = "QuietusPuffNoMana";
		}
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 24, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 24, slope, damage, 'Melee', pufftype, true, t);
					if (t.linetarget != null)
					{
						if (t.linetarget.bIsMonster || t.linetarget.player)
						{
							t.linetarget.Thrust(power, t.attackAngleFromSource);
						}
						//AdjustPlayerAngle(t);
						
						//weapon.DepleteAmmo (weapon.bAltFire, false);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		self.weaponspecial = 0;

		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', pufftype, true);
	}
}
// Powered

class QuietusPowered : Quietus
{
	Default
	{
		Tag "Quietus";
		+WEAPON.AMMO_OPTIONAL;
		+WEAPON.ALT_AMMO_OPTIONAL;
		-WEAPON.PRIMARY_USES_BOTH;
		+WEAPON.POWERED_UP;
		Weapon.AmmoGive1 0;
		Weapon.AmmoGive2 0;
		Weapon.AmmoUse1 1; // 1 with RoW, 2 without
		Weapon.AmmoUse2 12; // 12 with RoW, 24 without
		Weapon.KickBack 150;
		Weapon.AmmoType1 "GoldMana";
		Weapon.AmmoType2 "GoldMana";
		Weapon.SisterWeapon "Quietus";
		Inventory.PickupMessage "Quietus Assembled";
		Inventory.PickupSound "WeaponBuild";
	}
	States
	{
	Spawn:
		TNT1 A -1;
		Stop;
	Select:
		FSD2 A 0 A_JumpIfInventory("GoldMana",1,1);
		Goto SelectNoMana;
		FSD2 A 1 Bright A_Raise;
		TNT1 AA 0 A_Raise;
		Loop;
	SelectNoMana:
		FSD3 A 1 A_Raise;
		TNT1 AA 0 A_Raise;
		Loop;
	Deselect:
		FSD2 A 0 A_JumpIfInventory("GoldMana",1,1);
		Goto DeselectNoMana;
		FSD2 A 1 Bright A_Lower;
		TNT1 AA 0 A_Lower;
		Loop;
	DeselectNoMana:
		FSD3 A 1 A_Lower;
		TNT1 AA 0 A_Lower;
		Loop;
	Fire:
		FSD2 A 0 A_JumpIfInventory("GoldMana",1,1);
		Goto FireNoMana;
		FSD2 D 3 Bright Offset (5, 36);
		FSD2 E 3 Bright Offset (5, 36);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,2);
		TNT1 A 0 A_QuietusAmmoUser;//A_CustomPunch(1,1,1,"NoPuff",160);
		FSD2 F 1 Bright Offset (5, 36) A_QuietusPoweredMeleeAttack;//A_CustomPunch(random(360,425),1,17,"QuietusPoweredPuff",160);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,2);
		TNT1 A 0 A_QuietusAmmoUser;//A_CustomPunch(1,1,1,"NoPuff",160);
		FSD2 F 1 Bright Offset (5, 36) A_QuietusPoweredMeleeAttack;//A_CustomPunch(random(360,425),1,17,"QuietusPoweredPuff",160);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,2);
		TNT1 A 0 A_QuietusAmmoUser;//A_CustomPunch(1,1,1,"NoPuff",160);
		FSD2 G 1 Bright Offset (5, 36) A_QuietusPoweredMeleeAttack;//A_CustomPunch(random(360,425),1,17,"QuietusPoweredPuff",160);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,2);
		TNT1 A 0 A_QuietusAmmoUser;//A_CustomPunch(1,1,1,"NoPuff",160);
		FSD2 G 1 Bright Offset (5, 36) A_QuietusPoweredMeleeAttack;//A_CustomPunch(random(360,425),1,17,"QuietusPoweredPuff",160);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,2);
		TNT1 A 0 A_QuietusAmmoUser;//A_CustomPunch(1,1,1,"NoPuff",160);
		FSD2 H 1 Bright Offset (5, 36) A_QuietusPoweredMeleeAttack;//A_CustomPunch(random(360,425),1,17,"QuietusPoweredPuff",160);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,2);
		TNT1 A 0 A_QuietusAmmoUser;//A_CustomPunch(1,1,1,"NoPuff",160);
		FSD2 H 1 Bright Offset (5, 36) A_QuietusPoweredMeleeAttack;//A_CustomPunch(random(360,425),1,17,"QuietusPoweredPuff",160);
		FSD2 I 2 Bright Offset (5, 36);
		FSD2 I 7 Bright Offset (5, 150);
		FSRD A 0 A_JumpIfInventory("GoldMana",1,1);
		Goto FireNoMana+7;
		FSD2 A 1 Bright Offset (5, 60);
		FSD2 B 1 Bright Offset (5, 55);
		FSD2 C 1 Bright Offset (5, 50);
		FSD2 A 1 Bright Offset (5, 45);
		FSD2 B 1 Bright Offset (5, 40);
		Goto Ready;
	FireNoMana:
		FSD3 BC 3 Offset (5, 36);
		FSD3 D 1 Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(80,100),1,16,"QuietusPuffNoMana",160);
		FSD3 D 1 Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(80,100),1,16,"QuietusPuffNoMana",160);
		FSD3 E 1 Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(80,100),1,16,"QuietusPuffNoMana",160);
		FSD3 E 1 Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(80,100),1,16,"QuietusPuffNoMana",160);
		FSD3 F 1 Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(80,100),1,16,"QuietusPuffNoMana",160);
		FSD3 F 1 Offset (5, 36) A_QuietusMeleeAttack;//A_CustomPunch(random(80,100),1,16,"QuietusPuffNoMana",160);
		FSD3 H 2 Offset (5, 36);
		TNT1 A 7;
		FSD3 A 1 Offset (5, 60);
		FSD3 A 1 Offset (5, 55);
		FSD3 A 1 Offset (5, 50);
		FSD3 A 1 Offset (5, 45);
		FSD3 A 1 Offset (5, 40);
		Goto Ready;
	AltFire:
		FSRD A 0 A_JumpIfInventory("GoldMana",1,1);
		Goto FireNoMana;
		FSD2 DE 3 Bright Offset (5, 36);
		FSD2 F 0 Bright Offset (5, 36) A_PlaySound("weapons/quietus/powered", CHAN_WEAPON, 1.0, 0);
		FSD2 F 1 Bright Offset (5, 36);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,2);
		TNT1 A 0 A_FireProjectile("AmmoUser",0,1,0);
		FSD2 G 0 Bright Offset (5, 36) A_FireProjectile("QuietusPFloorAttack",27,0,-18);
		FSD2 G 0 Bright Offset (5, 36) A_FireProjectile("QuietusPFloorAttack",21,0,-14);
		FSD2 G 0 Bright Offset (5, 36) A_FireProjectile("QuietusPFloorAttack",15,0,-10);
		FSD2 G 0 Bright Offset (5, 36) A_FireProjectile("QuietusPFloorAttack",9,0,-6);
		FSD2 G 0 Bright Offset (5, 36) A_FireProjectile("QuietusPFloorAttack",3,0,-2);
		FSD2 G 0 Bright Offset (5, 36) A_FireProjectile("QuietusPFloorAttack",-3,0,2);
		FSD2 G 0 Bright Offset (5, 36) A_FireProjectile("QuietusPFloorAttack",-9,0,6);
		FSD2 G 0 Bright Offset (5, 36) A_FireProjectile("QuietusPFloorAttack",-15,0,10);
		FSD2 G 0 Bright Offset (5, 36) A_FireProjectile("QuietusPFloorAttack",-21,0,14);
		FSD2 G 1 Bright Offset (5, 36) A_FireProjectile("QuietusPFloorAttack",-27,1,18);
		FSD2 H 1 Bright Offset (5, 36);
		FSD2 I 2 Bright Offset (5, 36);
		FSD2 I 10 Bright Offset (5, 150);
		FSD2 A 1 Bright Offset (5, 60);
		FSD2 B 1 Bright Offset (5, 55);
		FSD2 C 1 Bright Offset (5, 50);
		FSD2 A 1 Bright Offset (5, 45);
		FSD2 B 1 Bright Offset (5, 40);
		Goto Ready;
	}

	action void A_QuietusPoweredMeleeAttack()
	{
		FTranslatedLineTarget t;

		if (player == null)
		{
			return;
		}

		int damage = random[SwordAtk](80, 100);
		int power = 0;
		Weapon weapon = player.ReadyWeapon;
		class<Actor> pufftype;
		int usemana;
		if ((usemana = (weapon.Ammo1 && weapon.Ammo1.Amount > 0)))
		{
			damage = random[SwordAtk](360, 425);
			power = 3;
			pufftype = "QuietusPoweredPuff";
		}
		else
		{
			pufftype = "QuietusPuffNoMana";
		}
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 24, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 24, slope, damage, 'Melee', pufftype, true, t);
					if (t.linetarget != null)
					{
						if (t.linetarget.bIsMonster || t.linetarget.player)
						{
							t.linetarget.Thrust(power, t.attackAngleFromSource);
						}
						//AdjustPlayerAngle(t);
						
						weapon.DepleteAmmo (weapon.bAltFire, false);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		self.weaponspecial = 0;

		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', pufftype, true);
	}

	action void A_QuietusAmmoUser()
	{
		FTranslatedLineTarget t;

		if (player == null)
		{
			return;
		}

		int damage = 0;
		int power = 0;
		Weapon weapon = player.ReadyWeapon;
		class<Actor> pufftype;
		int usemana;
		if ((usemana = (weapon.Ammo1 && weapon.Ammo1.Amount > 0)))
		{
			damage = 0;
			power = 0;
			pufftype = "NoPuff";
		}
		else
		{
			pufftype = "NoPuff";
		}
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 24, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 24, slope, damage, 'Melee', pufftype, true, t);
					if (t.linetarget != null)
					{
						if (t.linetarget.bIsMonster || t.linetarget.player)
						{
							t.linetarget.Thrust(power, t.attackAngleFromSource);
						}
						//AdjustPlayerAngle(t);
						
						weapon.DepleteAmmo (weapon.bAltFire, false);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		self.weaponspecial = 0;

		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', pufftype, true);
	}
}

//-----------------------------------------------

class ClericMace : CWeapMace replaces CWeapMace
{
	Default
	{
		Weapon.SelectionOrder 3500;
		Weapon.KickBack 150;
		Weapon.YAdjust -8;
		+BLOODSPLATTER;
		+WEAPON.MELEEWEAPON;
		+WEAPON.CHEATNOTWEAPON;
		+INVENTORY.UNDROPPABLE;
		Obituary "$OB_MPCWEAPMACE";
		Tag "Mace";
		Weapon.SisterWeapon "ClericMacePowered";
	}

	States
	{
	Select:
		CMCE A 1 A_Raise;
		Loop;
	Deselect:
		CMCE A 1 A_Lower;
		Loop;
	Ready:
		CMCE A 1 A_WeaponReady;
		Loop;
	Fire:
		CMCE B 2 Offset (75, 20); // 60
		CMCE B 1 Offset (45, 33); // 30
		CMCE B 2 Offset (23, 45); // 8
		CMCE C 1 Offset (23, 45); // 8
		CMCE D 1 Offset (23, 45); // 8
		CMCE E 1 Offset (23, 45); // 8
		CMCE E 1 Offset (4, 58) A_ClericMaceAttack;//A_CustomPunch(random(55,70),1,1,"MacePuff",136) // -11
		CMCE F 1 Offset (23, 45); // 8
		CMCE F 2 Offset (7, 74); // -8
		CMCE F 1 Offset (-5, 96); // -20
		CMCE F 6 Offset (-18, 160); // -33
		CMCE A 1 Offset (8, 75) A_ReFire;
		CMCE A 1 Offset (8, 65);
		CMCE A 1 Offset (8, 60);
		CMCE A 1 Offset (8, 55);
		CMCE A 1 Offset (8, 50);
		CMCE A 1 Offset (8, 45);
		Goto Ready;
	AltFire:
		CMCE B 2 Offset (75, 20);
		CMCE B 1 Offset (45, 33);
		CMCE B 2 Offset (23, 45);
		CMCE C 1 Offset (23, 45);
		CMCE D 1 Offset (23, 45);
		CMCE E 1 Offset (23, 45);
		CMCE E 1 Offset (4, 58) A_ClericMaceAltAttack;//A_CustomPunch(random(120,130),1,1,"AltMacePuff",136)
		CMCE F 1 Offset (23, 45);
		CMCE F 2 Offset (7, 74);
		CMCE F 1 Offset (-5, 96);
		CMCE F 6 Offset (-18, 160);
		TNT1 A 6;
		CMCE A 1 Offset (8, 75) A_ReFire;
		CMCE A 1 Offset (8, 65);
		CMCE A 1 Offset (8, 60);
		CMCE A 1 Offset (8, 55);
		CMCE A 1 Offset (8, 50);
		CMCE A 1 Offset (8, 45);
		Goto Ready;
	}

	action void A_ClericMaceAttack()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[MaceAtk](55, 70);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 8, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 8, slope, damage, 'Melee', "MacePuff", true, t);
					if (t.linetarget != null)
					{
						AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "MacePuff");
	}

	action void A_ClericMaceAltAttack()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[MaceAtk](120, 130);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 8, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 8, slope, damage, 'Melee', "AltMacePuff", true, t);
					if (t.linetarget != null)
					{
						AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "AltMacePuff");
	}
}

// Powered

class ClericMacePowered : ClericMace
{
	Default
	{
		Tag "Mace";
		Weapon.SelectionOrder 3500;
		Weapon.KickBack 150;
		Weapon.YAdjust -8;
		Weapon.SisterWeapon "ClericMace";
		+BLOODSPLATTER;
		+WEAPON.POWERED_UP;
		+WEAPON.MELEEWEAPON;
		+WEAPON.CHEATNOTWEAPON;
	}

	States
	{
	Select:
		CMCE A 1 A_Raise;
		TNT1 A 0 A_Raise;
		Loop;
	Deselect:
		CMCE A 1 A_Lower;
		TNT1 A 0 A_Lower;
		Loop;
	Fire:
		CMCE B 2 Offset (60, 20);
		CMCE B 1 Offset (30, 33);
		CMCE B 2 Offset (8, 45);
		CMCE C 1 Offset (8, 45);
		CMCE D 1 Offset (8, 45);
		CMCE E 1 Offset (8, 45);
		CMCE E 1 Offset (-11, 58) A_ClericMacePoweredAttack;//A_CustomPunch(random(155,170),1,1,"LDMacePuff",136);
		CMCE F 1 Offset (8, 45);
		CMCE F 2 Offset (-8, 74);
		CMCE F 1 Offset (-20, 96);
		CMCE F 6 Offset (-33, 160);
		CMCE A 1 Offset (8, 75) A_ReFire;
		CMCE A 1 Offset (8, 65);
		CMCE A 1 Offset (8, 60);
		CMCE A 1 Offset (8, 55);
		CMCE A 1 Offset (8, 50);
		CMCE A 1 Offset (8, 45);
		Goto Ready;
	AltFire:
		CMCE B 2 Offset (60, 20);
		CMCE B 1 Offset (30, 33);
		CMCE B 2 Offset (8, 45);
		CMCE C 1 Offset (8, 45);
		CMCE D 1 Offset (8, 45);
		CMCE E 1 Offset (8, 45);
		CMCE E 1 Offset (-11, 58) A_ClericMacePoweredAltAttack;//A_CustomPunch(random(185,220),1,1,"MDMacePuff",136);
		CMCE F 1 Offset (8, 45);
		CMCE F 2 Offset (-8, 74);
		CMCE F 1 Offset (-20, 96);
		CMCE F 6 Offset (-33, 160);
		TNT1 A 6;
		CMCE A 1 Offset (8, 75) A_ReFire;
		CMCE A 1 Offset (8, 65);
		CMCE A 1 Offset (8, 60);
		CMCE A 1 Offset (8, 55);
		CMCE A 1 Offset (8, 50);
		CMCE A 1 Offset (8, 45);
		Goto Ready;
	}

	action void A_ClericMacePoweredAttack()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[MaceAtk](155, 170);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 8, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 8, slope, damage, 'Melee', "LDMacePuff", true, t);
					if (t.linetarget != null)
					{
						AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "LDMacePuff");
	}

	action void A_ClericMacePoweredAltAttack()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[MaceAtk](185, 220);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 8, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 8, slope, damage, 'Melee', "MDMacePuff", true, t);
					if (t.linetarget != null)
					{
						AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "MDMacePuff");
	}

}

//-----------------------------------------------

class Sickle : MageWeapon

{
	Default
	{
		Tag "Sickle";
		+NOEXTREMEDEATH;
		+BLOODSPLATTER;
		+WEAPON.MELEEWEAPON;
		+INVENTORY.UNDROPPABLE;
		+WEAPON.CHEATNOTWEAPON;
		Weapon.SisterWeapon "SicklePowered";
	}
	States
	{
	Select:
		SCKL A 1 A_Raise;
		TNT1 A 0 A_Raise;
		Loop;
	Deselect:
		SCKL A 1 A_lower;
		TNT1 A 0 A_lower;
		Loop;
	Ready:
		SCKL A 1 A_WeaponReady;
		Loop;
	Fire:
		SCKL A 1 Offset (64,46);
		SCKL A 1 Offset (48,42);
		SCKL A 1 Offset (32,38);
		SCKL B 1 Offset (34,50);
		SCKL B 1 Offset (10,48);
		SCKL B 1 Offset (-14,50);
		SCKL C 1 Offset (18,32) A_SickleAttack;//A_Custompunch(random(50,65),1,0,"HammerPuff",140)
		SCKL C 1 Offset (-12,36);
		SCKL C 1 Offset (-42,44);
		SCKL C 1 Offset (-72,56);
		SCKL D 1 Offset (13,35);
		SCKL D 1 Offset (-7,50);
		SCKL D 1 Offset (-27,65);
		TNT1 A 5;
		TNT1 A 0 A_ReFire;
		TNT1 A 2;
		SCKL N 2;
		Goto Ready;
	Altfire:
		SCKL N 2;
		TNT1 A 2;
	AltHold:
		TNT1 A 0 A_Jump(100,"Altfire2");
	Altfire1:
		SCKL A 1;
		SCKL E 1;
		SCKL F 1 Offset (2,30);
		SCKL G 1 Offset (2,32);
		SCKL G 1 Offset (-16,44);
		SCKL G 1 Offset (-34,56);
		SCKL H 1 Offset (24,32) A_SickleAltAttack1;//A_CustomPunch(random(115,125),1,0,"HammerPuff",140)
		SCKL H 1 Offset (14,52);
		SCKL H 1 Offset (4,72);
		TNT1 A 15;
		TNT1 A 0 A_ReFire;
		TNT1 A 2;
		SCKL N 2;
		Goto Ready;
	Altfire2:
		SCKL I 1 Offset (36,38);
		SCKL I 1 Offset (32,32);
		SCKL J 1;
		SCKL K 1 Offset (32,42);
		SCKL L 1 Offset (30,28);
		SCKL L 1 Offset (4,36);
		SCKL L 1 Offset (-22,48) A_SickleAltAttack2;//A_CustomPunch(random(130,140),1,0,"HammerPuff",140)
		SCKL M 1 Offset (16,42);
		SCKL M 1 Offset (-22,72);
		TNT1 A 15;
		TNT1 A 0 A_ReFire;
		TNT1 A 2;
		SCKL N 2;
		Goto Ready;
	}

	action void A_SickleAttack()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[SickleAtk](50, 65);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 12, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 12, slope, damage, 'Melee', "HammerPuff", true, t);
					if (t.linetarget != null)
					{
						AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "HammerPuff");
	}

	action void A_SickleAltAttack1()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[SickleAtk](115, 125);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 12, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 12, slope, damage, 'Melee', "HammerPuff", true, t);
					if (t.linetarget != null)
					{
						AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "HammerPuff");
	}

	action void A_SickleAltAttack2()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[SickleAtk](130, 140);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 12, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 12, slope, damage, 'Melee', "HammerPuff", true, t);
					if (t.linetarget != null)
					{
						AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "HammerPuff");
	}
}

// Powered

class SicklePowered : Sickle
{
	Default
	{
		Tag "Sickle";
		+BLOODSPLATTER;
		+NOEXTREMEDEATH;
		+WEAPON.MELEEWEAPON;
		+INVENTORY.UNDROPPABLE;
		+WEAPON.POWERED_UP;
		+WEAPON.CHEATNOTWEAPON;
		Weapon.SisterWeapon "Sickle";
	}
	States
	{
	Select:
		SCKL A 1 A_Raise;
		TNT1 A 0 A_Raise;
		Loop;
	Deselect:
		SCKL A 1 A_Lower;
		TNT1 A 0 A_Lower;
		Loop;
	Fire:
		SCKL A 1 Offset (64,46);
		SCKL A 1 Offset (48,42);
		SCKL A 1 Offset (32,38);
		SCKL B 1 Offset (34,50);
		SCKL B 1 Offset (10,48);
		SCKL B 1 Offset (-14,50);
		SCKL C 1 Offset (18,32) A_SicklePoweredAttack;//A_Custompunch(random(140,160),1,0,"LDSicklePuff",140)
		SCKL C 1 Offset (-12,36);
		SCKL C 1 Offset (-42,44);
		SCKL C 1 Offset (-72,56);
		SCKL D 1 Offset (13,35);
		SCKL D 1 Offset (-7,50);
		SCKL D 1 Offset (-27,65);
		TNT1 A 5;
		TNT1 A 0 A_ReFire;
		TNT1 A 2;
		SCKL N 2;
		Goto Ready;
	Altfire:
		SCKL N 2;
		TNT1 A 2;
	AltHold:
		TNT1 A 0 A_Jump(85,"Altfire2");
	Altfire1:
		SCKL A 1;
		SCKL E 1;
		SCKL F 1 Offset (2,30);
		SCKL G 1 Offset (2,32);
		SCKL G 1 Offset (-16,44);
		SCKL G 1 Offset (-34,56);
		SCKL H 1 Offset (24,32) A_SicklePoweredAltAttack1;//A_CustomPunch(random(180,200),1,0,"MDSicklePuff",140)
		SCKL H 1 Offset (14,52);
		SCKL H 1 Offset (4,72);
		TNT1 A 15;
		TNT1 A 0 A_ReFire;
		TNT1 A 2;
		SCKL N 2;
		Goto Ready;
	Altfire2:
		SCKL I 1 Offset (36,38);
		SCKL I 1 Offset (32,32);
		SCKL J 1;
		SCKL K 1 Offset (32,42);
		SCKL L 1 Offset (30,28);
		SCKL L 1 Offset (4,36);
		SCKL L 1 Offset (-22,48) A_SicklePoweredAltAttack2;//A_CustomPunch(random(190,220),1,0,"MDSicklePuff",140)
		SCKL M 1 Offset (16,42);
		SCKL M 1 Offset (-22,72);
		TNT1 A 15;
		TNT1 A 0 A_ReFire;
		TNT1 A 2;
		SCKL N 2;
		Goto Ready;
	}

	action void A_SicklePoweredAttack()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[SickleAtk](140, 160);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 8, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 8, slope, damage, 'Melee', "LDSicklePuff", true, t);
					if (t.linetarget != null)
					{
						AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "LDSicklePuff");
	}

	action void A_SicklePoweredAltAttack1()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[SickleAtk](180, 200);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 8, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 8, slope, damage, 'Melee', "MDSicklePuff", true, t);
					if (t.linetarget != null)
					{
						AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "MDSicklePuff");
	}

	action void A_SicklePoweredAltAttack2()
	{
		FTranslatedLineTarget t;
	
		if (player == null)
		{
			return;
		}
	
		int damage = random[SickleAtk](180, 200);
		for (int i = 0; i < 16; i++)
		{
			for (int j = 1; j >= -1; j -= 2)
			{
				double ang = angle + j*i*(45. / 16);
				double slope = AimLineAttack(ang, 2 * DEFMELEERANGE + 8, t, 0., ALF_CHECK3D);
				if (t.linetarget)
				{
					LineAttack(ang, 2 * DEFMELEERANGE + 8, slope, damage, 'Melee', "MDSicklePuff", true, t);
					if (t.linetarget != null)
					{
						AdjustPlayerAngle(t);
						return;
					}
				}
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;
	
		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "MDSicklePuff");
	}
}

//-----------------------------------------------

class FrostShards : MWeapFrost replaces MWeapFrost
{
	Default
	{
		Tag "Frost Shards";
		Weapon.AmmoGive1 25;
		Weapon.AmmoGive2 0;
		Weapon.AmmoType1 "BlueMana";
		Weapon.AmmoType2 "BlueMana";
		Weapon.SisterWeapon "FrostShardsPowered";
		Weapon.AmmoUse1 1; // 2 with RoW, 3 without
		Weapon.AmmoUse2 2; // 2 with RoW, 4 without
	}
	States
	{
	Select:
		CONE A 1 A_Raise;
		TNT1 A 0 A_Raise;
		Loop;
	Deselect:
		CONE A 1 A_Lower;
		TNT1 A 0 A_Lower;
		Loop;
	Ready:
		CONE A 1 A_WeaponReady;
		Loop;
	Fire:
		CONE B 0 A_JumpIfInventory("PowerHalfMana",1,3);
		CONE B 0 A_JumpIfInventory("BlueMana",3,4);
		CONE B 0 A_SelectWeapon("Sickle");
		Goto Deselect;
		CONE B 0 A_JumpIfInventory("BlueMana",2,2);
		CONE B 0 A_SelectWeapon("Sickle");
		Goto Deselect;
		CONE B 2;
		CONE C 2;
	Hold:
		CONE D 3;
		CONE E 3;
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,2);
		TNT1 AA 0 A_FireProjectile("AmmoUser",0,1,0);
//		CONE F 0 A_FireConePL1;
		CONE F 3 A_FShardsAttack;//A_CustomPunch(random(180,210),1,0,"FrostShardsPuff",64);
		CONE G 3;
		CONE A 4;
		Goto Ready;
	AltFire:
		CONE B 0 A_JumpIfInventory("PowerHalfMana",1,3);
		CONE B 0 A_JumpIfInventory("BlueMana",4,4);
		CONE B 0 A_SelectWeapon("Sickle");
		Goto Deselect;
		CONE B 0 A_JumpIfInventory("BlueMana",2,2);
		CONE B 0 A_SelectWeapon("Sickle");
		Goto Deselect;
		CONE B 2;
		CONE C 2;
	AltHold:
		CONE D 3;
		CONE E 5;
		CONE E 3 A_PlaySound("weapons/frostshards/altfire", CHAN_WEAPON, 1.0, 0);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,2);
		TNT1 A 0 A_FireProjectile("AmmoUser",0,1,0);
		CONE F 3 A_FireProjectile("AbsoluteZero",0,1,0,0);
		CONE G 3;
		CONE A 7;
		Goto Ready;
	}

	action void A_FShardsAttack()
	{
		bool conedone=false;
		FTranslatedLineTarget t;

		if (player == null)
		{
			return;
		}

		Weapon weapon = player.ReadyWeapon;
		if (weapon != null)
		{
			if (!weapon.DepleteAmmo (weapon.bAltFire))
				return;
		}
		A_PlaySound ("MageShardsFire", CHAN_WEAPON);

		int damage = random[MageCone](230, 265); //(90, 105);
		for (int i = 0; i < 16; i++)
		{
			double ang = angle + i*(45./16);
			double slope = AimLineAttack (ang, 1.25 * DEFMELEERANGE, t, 0., ALF_CHECK3D);
			if (t.linetarget)
			{
				t.linetarget.DamageMobj (self, self, damage, 'Ice', DMG_USEANGLE, t.angleFromSource);
				conedone = true;
				break;
			}
		}

		// didn't find any creatures, so fire projectiles
		if (!conedone)
		{
			Actor mo = SpawnPlayerMissile ("FrostMissile");
			if (mo)
			{
				mo.special1 = FrostMissile.SHARDSPAWN_LEFT|FrostMissile.SHARDSPAWN_DOWN|FrostMissile.SHARDSPAWN_UP|FrostMissile.SHARDSPAWN_RIGHT;
				mo.special2 = 3; // Set sperm count (levels of reproductivity)
				mo.target = self;
				mo.args[0] = 3;		// Mark Initial shard as super damage
			}
		}
	}
}

// Powered

class FrostShardsPowered : FrostShards
{
	Default
	{
		Tag "Frost Shards";
		Weapon.AmmoType1 "BlueMana";
		Weapon.AmmoType2 "BlueMana";
		Weapon.AmmoGive1 0;
		Weapon.AmmoGive2 0;
		+WEAPON.POWERED_UP;
		Weapon.SisterWeapon "FrostShards";
		Weapon.AmmoUse1 2; // 2 with RoW, 4 without
		Weapon.AmmoUse2 5; // 5 with RoW, 10 without
	}
	States
	{
	Select:
		CONE A 1 A_Raise;
		TNT1 A 0 A_Raise;
		Loop;
	Deselect:
		CONE A 1 A_Lower;
		TNT1 A 0 A_Lower;
		Loop;
	Fire:
		CONE B 0 A_JumpIfInventory("PowerHalfMana",1,3);
		CONE B 0 A_JumpIfInventory("BlueMana",4,4);
		CONE B 0 A_SelectWeapon("Sickle");
		Goto Deselect;
		CONE B 0 A_JumpIfInventory("BlueMana",2,2);
		CONE B 0 A_SelectWeapon("Sickle");
		Goto Deselect;
		CONE B 2;
		CONE C 2;
	Hold:
		CONE D 3;
		CONE E 3;
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,2);
		TNT1 A 0 A_FireProjectile("AmmoUser",0,1,0);
		TNT1 A 0 A_PlaySound("weapons/frostshards/powered/fire", CHAN_WEAPON, 1.0, 0);
		TNT1 AAAAAAAAAAA 0 A_FireProjectile("FreezeSpike",frandom(-4,4),0,7,8);
		CONE F 3 A_FireProjectile("FreezeSpike",frandom(-4,4),1,7,8);
		CONE G 4;
		CONE A 4;
		Goto Ready;
	AltFire:
		CONE B 0 A_JumpIfInventory("PowerHalfMana",1,3);
		CONE B 0 A_JumpIfInventory("BlueMana",10,4);
		CONE B 0 A_SelectWeapon("Sickle");
		Goto Deselect;
		CONE B 0 A_JumpIfInventory("BlueMana",5,2);
		CONE B 0 A_SelectWeapon("Sickle");
		Goto Deselect;
		CONE B 4 A_PlaySound("weapons/frostshards/powered/charge", CHAN_AUTO, 1.0, 0);
		CONE F 8;
	AltHold:
		CONE C 3;
		CONE D 4;
		CONE E 4;
		CONE E 3 A_PlaySound("weapons/frostshards/powered/altfire", CHAN_WEAPON, 1.0, 0);
		TNT1 A 0 A_JumpIfInventory("PowerHalfMana",1,2);
		TNT1 A 0 A_FireProjectile("AmmoUser",0,1,0);
		CONE F 3 A_FireProjectile("IceDragonHead",0,1,0,0);
		CONE G 3;
		CONE A 10;
		Goto Ready;
	}
}

//=====================================================================
//
// Arc of Death (removing the random enemy pushing, which was really bad for floating enemies)
//
//=====================================================================

//-----------------------------------------------

class MWeapLightning2 : MageWeapon
{
	Default
	{
		+NOGRAVITY
		Weapon.SelectionOrder 1100;
		Weapon.AmmoUse1 5;
		Weapon.AmmoGive1 25;
		Weapon.KickBack 0;
		Weapon.YAdjust 20;
		Weapon.AmmoType1 "Mana2";
		Weapon.AmmoType2 "Mana2";
		Inventory.PickupMessage "$TXT_WEAPON_M3";
		Tag "$TAG_MWEAPLIGHTNING";
	}

	States
	{
	Spawn:
		WMLG ABCDEFGH 4 Bright;
		Loop;
	Select:
		MLNG A 1 Bright A_Raise;
		Loop;
	Deselect:
		MLNG A 1 Bright A_Lower;
		Loop;
	Ready:
		MLNG AAAAA 1 Bright A_WeaponReady;
		MLNG A 1 Bright A_LightningReady;
		MLNG BBBBBB 1 Bright A_WeaponReady;
		MLNG CCCCC 1 Bright A_WeaponReady;
		MLNG C 1 Bright A_LightningReady;
		MLNG BBBBBB 1 Bright A_WeaponReady;
		Loop;
	Fire:
		MLNG DE 3 Bright;
		MLNG F 4 Bright A_MLightningAttack;
		MLNG G 4 Bright;
		MLNG HI 3 Bright;
		MLNG I 6 Bright Offset (0, 199);
		MLNG C 2 Bright Offset (0, 55);
		MLNG B 2 Bright Offset (0, 50);
		MLNG B 2 Bright Offset (0, 45);
		MLNG B 2 Bright Offset (0, 40);
		Goto Ready;
	}
	
	action void A_LightningReady()
	{
		A_WeaponReady();
		if (random[LightningReady]() < 160)
		{
			A_PlaySound ("MageLightningReady", CHAN_WEAPON);
		}
	}

	action void A_MLightningAttack(class<Actor> floor = "MLightningFloor", class<Actor> ceiling = "MLightningCeiling")
	{
		MLightningFloor fmo = MLightningFloor(SpawnPlayerMissile (floor));
		MLightningCeiling cmo = MLightningCeiling(SpawnPlayerMissile (ceiling));
		if (fmo)
		{
			fmo.special1 = 0;
			fmo.lastenemy = cmo;
			fmo.A_MLightningZap();
		}
		if (cmo)
		{
			cmo.tracer = NULL;
			cmo.lastenemy = fmo;
			cmo.A_MLightningZap();
		}
		A_PlaySound ("MageLightningFire", CHAN_BODY);

		if (player != NULL)
		{
			Weapon weapon = player.ReadyWeapon;
			if (weapon != NULL)
			{
				weapon.DepleteAmmo (weapon.bAltFire);
			}
		}
	}

	
}


class MLightning : Lightning replaces Lightning
{
	Default
	{
		MissileType "LightningZap";
		AttackSound "MageLightningZap";
		ActiveSound "MageLightningContinuous";
		Obituary "$OB_MPMWEAPLIGHTNING";

		+NODAMAGETHRUST
		+FOILINVUL
	}
	
	override int SpecialMissileHit (Actor thing)
	{
		if (thing.bShootable && thing != target)
		{
			if ((!thing.player && !thing.bBoss) || !(level.time&1))
			{
				thing.DamageMobj(self, target, 4, 'Electric', DMG_FOILINVUL);
				A_PlaySound(AttackSound, CHAN_WEAPON|CHAN_NOSTOP, 1, false);
				if (thing.bIsMonster && random[LightningHit]() < 64)
				{
					thing.Howl ();
				}
			}
			health--;
			if (health <= 0 || thing.health <= 0)
			{
				return 0;
			}
			if (bFloorHugger)
			{
				if (lastenemy && ! lastenemy.tracer)
				{
					lastenemy.tracer = thing;
				}
			}
			else if (!tracer)
			{
				tracer = thing;
			}
		}
		return 1; // lightning zaps through all sprites
	}
	
}

class MLightningCeiling : LightningCeiling replaces LightningCeiling
{
	const ZAGSPEED = 1;

	Default
	{
		MissileType "LightningZap";
		AttackSound "MageLightningZap";
		ActiveSound "MageLightningContinuous";
		Obituary "$OB_MPMWEAPLIGHTNING";

		+NODAMAGETHRUST
	}

	States
	{
	Spawn:
		MLFX A 2 Bright A_MLightningZap;
		MLFX BCD 2 Bright A_MLightningClip;
		Loop;
	Death:
		MLF2 A 2 Bright A_MLightningRemove;
		MLF2 BCDEKLM 3 Bright;
		ACLO E 35;
		MLF2 NO 3 Bright;
		MLF2 P 4 Bright;
		MLF2 QP 3 Bright;
		MLF2 Q 4 Bright;
		MLF2 P 3 Bright;
		MLF2 O 3 Bright;
		MLF2 P 3 Bright;
		MLF2 P 1 Bright A_HideThing;
		ACLO E 1050;
		Stop;
	}
	
	override int SpecialMissileHit (Actor thing)
	{
		if (thing.bShootable && thing != target)
		{
			if ((!thing.player && !thing.bBoss) || !(level.time&1))
			{
				thing.DamageMobj(self, target, 4, 'Electric', DMG_FOILINVUL);
				A_PlaySound(AttackSound, CHAN_WEAPON|CHAN_NOSTOP, 1, false);
				if (thing.bIsMonster && random[LightningHit]() < 64)
				{
					thing.Howl ();
				}
			}
			health--;
			if (health <= 0 || thing.health <= 0)
			{
				return 0;
			}
			if (bFloorHugger)
			{
				if (lastenemy && ! lastenemy.tracer)
				{
					lastenemy.tracer = thing;
				}
			}
			else if (!tracer)
			{
				tracer = thing;
			}
		}
		return 1; // lightning zaps through all sprites
	}

	void A_MLightningClip()
	{
		Actor cMo;
		Actor target = NULL;
		int zigZag;

		if (bFloorHugger)
		{
			if (lastenemy == NULL)
			{
				return;
			}
			SetZ(floorz);
			target = lastenemy.tracer;
		}
		else if (bCeilingHugger)
		{
			SetZ(ceilingz - Height);
			target = tracer;
		}
		if (bFloorHugger)
		{ // floor lightning zig-zags, and forces the ceiling lightning to mimic
			cMo = lastenemy;
			zigZag = random[MLightningClip]();
			if((zigZag > 128 && special1 < 2) || special1 < -2)
			{
				Thrust(ZAGSPEED, angle + 90);
				if(cMo)
				{
					cMo.Thrust(ZAGSPEED, angle + 90);
				}
				special1++;
			}
			else
			{
				Thrust(ZAGSPEED,angle - 90);
				if(cMo)
				{
					cMo.Thrust(ZAGSPEED, angle - 90);
				}
				special1--;
			}
		}
		if(target)
		{
			if(target.health <= 0)
			{
				ExplodeMissile();
			}
			else
			{
				angle = AngleTo(target);
				VelFromAngle(Speed / 2);
			}
		}
	}

	void A_MLightningZap()
	{
		Class<Actor> lightning = MissileName;
		if (lightning == NULL) lightning = "LightningZap";

		A_MLightningClip();

		health -= 8;
		if (health <= 0)
		{
			SetStateLabel ("Death");
			return;
		}
		double deltaX = (random[LightningZap]() - 128) * radius / 256;
		double deltaY = (random[LightningZap]() - 128) * radius / 256;
		double deltaZ = (bFloorHugger) ? 10 : -10;

		Actor mo = Spawn(lightning, Vec3Offset(deltaX, deltaY, deltaZ), ALLOW_REPLACE);
		if (mo)
		{
			mo.lastenemy = self;
			mo.Vel.X = Vel.X;
			mo.Vel.Y = Vel.Y;
			mo.Vel.Z = (bFloorHugger) ? 20 : -20;
			mo.target = target;
		}
		if (bFloorHugger && random[LightningZap]() < 160)
		{
			A_PlaySound (ActiveSound, CHAN_BODY);
		}
	}

	void A_MLightningRemove()
	{
		Actor mo = lastenemy;
		if (mo)
		{
			bNoTarget = true;	// tell A_ZapMimic that we are dead. The original code did a state pointer compare which is not safe.
			mo.lastenemy = NULL;
			mo.ExplodeMissile ();
		}
	}	
}

class MLightningFloor : MLightningCeiling replaces LightningFloor
{
	Default
	{
		-CEILINGHUGGER
		+FLOORHUGGER
		+NODAMAGETHRUST
		+ZDOOMTRANS
		RenderStyle "Add";
	}

	States
	{
	Spawn:
		MLFX E 2 Bright A_MLightningZap;
		MLFX FGH 2 Bright A_MLightningClip;
		Loop;
	Death:
		MLF2 F 2 Bright A_MLightningRemove;
		MLF2 GHIJKLM 3 Bright;
		ACLO E 20;
		MLF2 NO 3 Bright;
		MLF2 P 4 Bright;
		MLF2 QP 3 Bright;
		MLF2 Q 4 Bright A_LastZap;
		MLF2 POP 3 Bright;
		MLF2 P 1 Bright A_HideThing;
		Goto Super::Death + 19;
	}
	
	void A_LastZap()
	{
		Class<Actor> lightning = MissileName;
		if (lightning == NULL) lightning = "LightningZap";
		
		Actor mo = Spawn(lightning, self.Pos, ALLOW_REPLACE);
		if (mo)
		{
			mo.SetStateLabel ("Death");
			mo.Vel.Z = 40;
			mo.SetDamage(0);
		}
	}
}

//-----------------------------------------------

class OKMinion : Actor
{
	Default
	{
		Health 520;
		Radius 24;
		Height 78;
		Mass 450;
		Speed 12;
		PainChance 40;
		MeleeRange 100;
		Species "OblivionKnight";
		DamageFactor "Sacred", 1.5;
		DamageFactor "Holy", 1.4;
		DamageFactor "Consecrate", 1.25;
		DamageFactor "Electric", 1.25;
		MONSTER;
		-SOLID
		-COUNTKILL
		+INVULNERABLE
		+FLOORCLIP
		+DONTMORPH
		+DONTBLAST
		+NOINFIGHTSPECIES
		+DONTHARMSPECIES
		+SPECIALFLOORCLIP
		+STAYMORPHED
		+INVISIBLE
		PainChance 0;
		SeeSound "uknight/sight";
		AttackSound "uknight/attack";
		PainSound "uknight/pain";
		DeathSound "uknight/death";
		ActiveSound "uknight/sight";
		Obituary "$OB_BONEKNIGHT";
		HitObituary "$OB_BONEKNIGHTHIT";
	}

	States
	{
	Spawn:
		UNDK AB 15 A_Look;
		Loop;
	See:
		UNDK A 0 A_JumpIfInventory("UKRisenCheck",1,"Chase");
		UNDK A 2 A_UKnightRaiseInit;
		UNDK A 2 A_UKnightRaise;
		UNDK A 2 A_FaceTarget;
		UNDK AA 2 A_UKnightRaise;
		Goto See+2;
	Chase:
		UNDK A 0 A_GiveInventory("UKRisenCheck",1);
		UNDK ABCD 4 A_Chase;
		Loop;
	Melee:
	Missile:
		UNDK G 0 A_Jump(216,6);
		UNDK E 10 A_FaceTarget;
		UNDK F 8 A_FaceTarget;
		UNDK G 2 A_PlaySound("uknight/attack",CHAN_5);
		UNDK G 6 A_CustomComboAttack("UndeadRedAxe",36,6*random(1,8),"uknight/attack2");
		UNDK G 0 A_Jump(256,5);
		UNDK E 10 A_FaceTarget;
		UNDK F 8 A_FaceTarget;
		UNDK G 2 A_PlaySound("uknight/attack",CHAN_5);
		UNDK G 6 A_CustomComboAttack("UndeadAxe",36,3*random(1,8),"uknight/attack2");
		UNDK G 0 A_Jump(216,6);
		UNDK E 10 A_FaceTarget;
		UNDK F 8 A_FaceTarget;
		UNDK G 2 A_PlaySound("uknight/attack",CHAN_5);
		UNDK G 6 A_CustomComboAttack("UndeadRedAxe",36,6*random(1,8),"uknight/attack2");
		UNDK G 0 A_Jump(256,5);
		UNDK E 10 A_FaceTarget;
		UNDK F 8 A_FaceTarget;
		UNDK G 2 A_PlaySound("uknight/attack",CHAN_5);
		UNDK G 6 A_CustomComboAttack("UndeadAxe",36,3*random(1,8),"uknight/attack2");
		UNDK G 0;	
		Goto Chase;
	Pain:
		UNDK H 3;
		UNDK H 3 A_Pain;
		Goto Chase;
	Death:
		UNDK I 6;
		UNDK J 6 A_Scream;
		UNDK K 6;
		UNDK L 6 A_NoBlocking;
		UNDK MN 6;
		UNDK O 200;
		UNDK O 2 A_FadeOut(0.05);
		Wait;
	Death.Frost:
		"####" "#" 2;
		UNDK I 1 A_IceGuyDie;
		Stop;
	Ice:
		"####" "#" 2;
		UNDK I 1 A_IceGuyDie;
		Stop;
	}
	
	void A_UKnightRaiseInit()
	{
		bInvisible = false;
		bNonShootable = false;
		bDontBlast = false;
//		bShootable = true;
		bSolid = true;
		Floorclip = Height;
	}

	void A_UKnightRaise()
	{
		if (RaiseMobj (3))
		{
			// Reached it's target height
			// [RH] Once a buried wraith is fully raised, it should be
			// morphable, right?
			bDontMorph = false;
			bInvulnerable = false;
			bSpecialFloorClip = false;
			SetStateLabel ("Chase");
			// [RH] Reset PainChance to a normal wraith's.
			PainChance = GetDefaultByType("Wraith").PainChance;
		}

		SpawnDirt (radius);
	}

	
}

class UKRisenCheck : Inventory
{
	Default
	{
		Inventory.Amount 1;
		Inventory.MaxAmount 1;
	}
}

//-----------------------------------------------

class SpikeFloor : Actor replaces ThrustFloorDown
{
	Default
	{
		Radius 20;
		Height 128;
		Obituary "%o stood on the wrong spot";
	}

	States
	{
	Spawn:
		TSPK C 1;
		Loop;
	ThrustEmerge:
		SPKD A 2 A_PlaySound("ThrustSpikeLower");
		SPKD B 2;
		SPKD C 2 A_SetSolid;
		SPKD DEFGH 2 A_ThrustImpale;
		SPKD I 1 A_CeilingSpikeUp;
		SPKD I 1 A_BloodCheck;
		Wait;
	SpikeHitSomething:
		SPKD R 2;
		Wait;
	BloodThrustEmerge:
		SPKD J 2 A_PlaySound("ThrustSpikeLower");
		SPKD K 2;
		SPKD L 2 A_SetSolid;
		SPKD MNOPQ 2 A_ThrustImpale;
		SPKD R 2 A_CeilingSpikeUp;
		Wait;
	ThrustRetract:
		SPKD H 2 A_PlaySound("ThrustSpikeRaise");
		SPKD GFED 2;
		SPKD C 2 A_UnSetSolid;
		SPKD BA 2 A_CeilingSpikeDown;
		Goto Spawn;
	BloodThrustRetract:
		SPKD Q 2 A_PlaySound("ThrustSpikeRaise");
		SPKD PONM 2;
		SPKD L 2 A_UnSetSolid;
		SPKD KJ 2 A_CeilingSpikeDown;
		Goto Spawn;
	}
	void A_CeilingSpikeUp()
	{
		args[0] = 1;
	}
	void A_CeilingSpikeDown()
	{
		args[0] = 0;
	}
	void A_BloodCheck()
	{
		if(args[1] == 1)
		{
			SetStateLabel("SpikeHitSomething");
		}
	}
	override void Activate (Actor activator)
	{
		if (args[0] == 0)
		{
			A_PlaySound ("ThrustSpikeRaise", CHAN_BODY);
			bInvisible = false;
			if (args[1])
				SetStateLabel("BloodThrustEmerge");
			else
				SetStateLabel("ThrustEmerge");
		}
	}
	override void Deactivate (Actor activator)
	{
		if (args[0] == 1)
		{
			A_PlaySound ("ThrustSpikeLower", CHAN_BODY);
			if (args[1])
				SetStateLabel("BloodThrustRetract");
			else
				SetStateLabel("ThrustRetract");
		}
	}
	
	//===========================================================================
	//
	// Thrust floor stuff
	//
	// Thrust Spike Variables
	//		args[0]		0 = lowered,  1 = raised
	//		args[1]		0 = normal,   1 = bloody
	//===========================================================================
	
	void A_ThrustImpale()
	{
		BlockThingsIterator it = BlockThingsIterator.Create(self);
		while (it.Next())
		{
			let targ = it.thing;
			double blockdist = radius + it.thing.radius;
			if (abs(targ.pos.x - it.Position.X) >= blockdist || abs(targ.pos.y - it.Position.Y) >= blockdist)
				continue;

			// Q: Make this z-aware for everything? It never was before.
			if (targ.pos.z + targ.height < pos.z || targ.pos.z > pos.z + height)
				continue;
			{
				if (CurSector.PortalGroup != targ.CurSector.PortalGroup)
					continue;
			}

			if (!targ.bShootable)
				continue;

			if (targ == self)
				continue;	// don't clip against self

			int newdam = targ.DamageMobj (self, self, 10001, 'Crush', DMG_THRUSTLESS);
			targ.TraceBleed (newdam > 0 ? newdam : 10001, null);
			args[1] = 1;	// Mark thrust thing as bloody
		}
	}
}

//-----------------------------------------------

class SpikeCeiling : Actor replaces ThrustFloorUp
{
	Default
	{
		+SPAWNCEILING
		+CEILINGHUGGER
		+NOGRAVITY
		-FLOORCLIP
		Radius 20;
		Height 128;
		Obituary "%o got a splitting headache";
	}

	States
	{
	Spawn:
		SPKU S 1;
		Loop;
	ThrustDescend:
		SPKU A 2 A_PlaySound("ThrustSpikeLower");
		SPKU B 2;
		SPKU C 2 A_SetSolid;
		SPKU DEFGH 2 A_ThrustImpale;
		SPKU I 1 A_CeilingSpikeDown;
		SPKU I 1 A_BloodCheck;
		Wait;
	SpikeHitSomething:
		SPKU R 2;
		Wait;
	BloodThrustDescend:
		SPKU J 2 A_PlaySound("ThrustSpikeLower");
		SPKU K 2;
		SPKU L 2 A_SetSolid;
		SPKU MNOPQ 2 A_ThrustImpale;
		SPKU R 2 A_CeilingSpikeDown;
		Wait;
	ThrustRetract:
		SPKU H 2 A_PlaySound("ThrustSpikeRaise");
		SPKU GFED 2;
		SPKU C 2 A_UnSetSolid;
		SPKU BA 2 A_CeilingSpikeUp;
		Goto Spawn;
	BloodThrustRetract:
		SPKU Q 2 A_PlaySound("ThrustSpikeRaise");
		SPKU PONM 2;
		SPKU L 2 A_UnSetSolid;
		SPKU KJ 2 A_CeilingSpikeUp;
		Goto Spawn;
	}
	void A_CeilingSpikeUp()
	{
		args[0] = 0;
	}

	void A_CeilingSpikeDown()
	{
		args[0] = 1;
	}
	void A_BloodCheck()
	{
		if(args[1] == 1)
		{
			SetStateLabel("SpikeHitSomething");
		}
	}
	override void Activate (Actor activator)
	{
		if (args[0] == 0)
		{
			A_PlaySound ("ThrustSpikeRaise", CHAN_BODY);
			bInvisible = false;
			if (args[1])
				SetStateLabel("BloodThrustDescend");
			else
				SetStateLabel("ThrustDescend");
		}
	}
	override void Deactivate (Actor activator)
	{
		if (args[0] == 1)
		{
			A_PlaySound ("ThrustSpikeLower", CHAN_BODY);
			if (args[1])
				SetStateLabel("BloodThrustRetract");
			else
				SetStateLabel("ThrustRetract");
		}
	}
	
	//===========================================================================
	//
	// Thrust ceiling stuff
	//
	// Thrust Spike Variables
	//		args[0]		0 = lowered,  1 = raised
	//		args[1]		0 = normal,   1 = bloody
	//===========================================================================
	
	void A_ThrustImpale()
	{
		BlockThingsIterator it = BlockThingsIterator.Create(self);
		while (it.Next())
		{
			let targ = it.thing;
			double blockdist = radius + it.thing.radius;
			if (abs(targ.pos.x - it.Position.X) >= blockdist || abs(targ.pos.y - it.Position.Y) >= blockdist)
				continue;

			// Q: Make this z-aware for everything? It never was before.
//			if (targ.pos.z + targ.height < pos.z || targ.pos.z > pos.z + height)
			if (targ.pos.z > pos.z || targ.pos.z + targ.height < pos.z)
				continue;
//			{
//				if (CurSector.PortalGroup != targ.CurSector.PortalGroup)
//					continue;
//			}

			if (!targ.bShootable)
				continue;

			if (targ == self)
				continue;	// don't clip against self

			int newdam = targ.DamageMobj (self, self, 10001, 'Crush', DMG_THRUSTLESS);
			targ.TraceBleed (newdam > 0 ? newdam : 10001, null);
			args[1] = 1;	// Mark thrust thing as bloody
		}
	}
}

// Testing stuff

Class AbominationHandler : EventHandler
{
//	override void WorldThingDamaged( WorldEvent e )
//	{
//		if ( !e.Thing.player ) return;
//		if ( e.DamageType == 'Eldrich' )
//		{
//			AbMadness cnt = AbMadness(e.Thing.FindInventory("AbMadness"));
//			if ( !cnt ) e.Thing.GiveInventory("AbMadness",e.Damage*40*Random[Insane](3,5));
//			else if ( cnt.special1 )
//			{
//				if ( e.DamageSource ) cnt.Amount = min(cnt.MaxAmount,cnt.Amount+e.Damage*30*Random[Insane](3,5));
//				else cnt.Amount = min(cnt.MaxAmount,cnt.Amount+e.Damage*3*Random[Insane](3,5));
//			}
//			else cnt.Amount = min(cnt.MaxAmount,cnt.Amount+e.Damage*40*Random[Insane](3,5));
//		}
//		if ( e.DamageSource is 'AbominationMadnessShot' )
//		{
//			AbMadness cnt = AbMadness(e.Thing.FindInventory("AbMadness"));
//			if ( !cnt ) e.Thing.GiveInventory("AbMadness",1700);
//			else if ( cnt.special1 ) cnt.Amount = min(cnt.MaxAmount,cnt.Amount+e.Damage*3*Random[Insane](3,5));
//			else cnt.Amount = min(cnt.MaxAmount,cnt.Amount+e.Damage*10*Random[Insane](3,5));
//		}
//	}

	override void PlayerRespawned( PlayerEvent e )
	{
		if ( players[e.playernumber].mo )
		{
			let cnt = players[e.playernumber].mo.FindInventory("AbMadness");
			if ( cnt ) cnt.amount = 0;
		}
	}

	override void WorldLoaded( WorldEvent e )
	{
		// "pre-cache" shader
		Shader.SetEnabled(players[consoleplayer],"madness1",true);
		Shader.SetEnabled(players[consoleplayer],"madness2",true);
		Shader.SetEnabled(players[consoleplayer],"madness1",false);
		Shader.SetEnabled(players[consoleplayer],"madness2",false);
	}

	override void RenderOverlay( RenderEvent e )
	{
		let cnt = e.Camera.FindInventory("AbMadness");
		if ( cnt && (cnt.amount > 0) )
		{
			Shader.SetEnabled(players[consoleplayer],"madness1",true);
			Shader.SetEnabled(players[consoleplayer],"madness2",true);
			if ( cnt.special1 )
			{
				Shader.SetUniform1f(players[consoleplayer],"madness1","dfact",clamp(cnt.amount*0.00075-0.3,0.0,1.0));
				Shader.SetUniform1f(players[consoleplayer],"madness2","dfact",clamp(cnt.amount*0.00075-0.3,0.0,1.0));
				Shader.SetUniform1f(players[consoleplayer],"madness2","tun",clamp(cnt.amount*0.001-1.0,0.0,0.8));
			}
			else
			{
				Shader.SetUniform1f(players[consoleplayer],"madness1","dfact",clamp(cnt.amount*0.00075-0.9,0.0,1.0));
				Shader.SetUniform1f(players[consoleplayer],"madness2","dfact",clamp(cnt.amount*0.00075-0.9,0.0,1.0));
				Shader.SetUniform1f(players[consoleplayer],"madness2","tun",clamp(cnt.amount*0.0025-4.0,0.0,0.8));
			}
			Shader.SetUniform1f(players[consoleplayer],"madness1","timer",(gametic+e.Fractic)/35.);
			Shader.SetUniform1f(players[consoleplayer],"madness2","timer",(gametic+e.Fractic)/35.);
		}
		else
		{
			Shader.SetEnabled(players[consoleplayer],"madness1",false);
			Shader.SetEnabled(players[consoleplayer],"madness2",false);
		}
	}
}

Class AbMadness : Inventory
{
	Default
	{
		+INVENTORY.UNDROPPABLE;
		+INVENTORY.UNTOSSABLE;
		+INVENTORY.KEEPDEPLETED;
		Inventory.MaxAmount 1700;
		Tag "Madness";
	}
	override void DoEffect()
	{
		Super.DoEffect();
		if ( !owner || (amount <= 0) ) return;
		if ( special1 )
		{
			owner.A_SetAngle(owner.angle+sin(level.time*1.4325)*0.000234346*min(amount,1000),SPF_INTERPOLATE);
			owner.A_SetPitch(owner.pitch+sin(level.time*1.6346)*0.000243457*min(amount,1000),SPF_INTERPOLATE);
		}
		if ( !(level.time%4) && !Random[Insane](0,3) )
		{
			owner.A_SetAngle(owner.angle+cos(level.time*8.4325)*0.000434346*amount,SPF_INTERPOLATE);
			owner.A_SetPitch(owner.pitch+cos(level.time*8.6346)*0.000443457*amount,SPF_INTERPOLATE);
		}
		if ( amount >= maxamount )
		{
			special1 = 1;
		}
		if ( owner.Health <= 0 ) amount -= max(3,8-amount/400);
		else if ( special1 ) amount -= max(1,12-amount/150);
		else amount -= max(2,6-amount/350);
		if ( amount <= 0 )
		{
			special1 = 0;
			amount = 0;
		}
	}
}
