Class GHAGPsychoCutterOverlay : Inventory
{
	default
	{
		Inventory.MaxAmount 4;
	}
	
	override void beginplay()
	{
		super.beginPlay();
		
		if (GameInfo.GameType == 2) Self.MaxAmount = 2;
	}
}

Class GHAGExtraPsychoCutter : CustomInventory replaces Chainsaw
{
	default
	{
		+Floatbob;
		Inventory.PickupMessage "Gardevoir can't learn Psycho Cutter? Hahahahaha!";
		Inventory.pickupsound "misc/w_pkup";
	}
	States
	{
		Spawn:
			CSAW A 1 Bright
			{
				let player = players[consoleplayer].mo;
				int limit = GameInfo.GameType == 1 ? 4 : 2;
				if (player.countinv("GHAGPsychoCutterOverlay") == limit)
				{
					invoker.spawn("GHAGRageCandyBar", invoker.pos);
					invoker.destroy();
				}
			}
			Loop;
		Pickup :
			TNT1 A 0
			{
				let player = GHAGGardevoir(players[consoleplayer].mo);
				player.updateWeapons = true;
				player.giveInventory("GHAGPsychoCutterOverlay", 1);
				if (player.countinv("GHAGPsychoCutter") == 0) {
					player.giveInventory("GHAGPsychoCutter", 1);
					A_SelectWeapon("GHAGPsychoCutter");
				}
			}
			stop;
	}
}

Class GHAGExtraPsychoCutterDrop : CustomInventory
{
	bool touched;
	default
	{
		+Floatbob;
		+DontGib;
		Inventory.PickupMessage "";
		Inventory.pickupsound "misc/w_pkup";
	}
	
	States
	{
		Spawn:
			CSAW A 1 Bright;
			Loop;
		Pickup :
			TNT1 A 0
			{
				if (!invoker.touched) //Prevents chainsaw duplicating
				{
					invoker.touched = true;
					let player = GHAGGardevoir(players[consoleplayer].mo);
					player.giveInventory("GHAGPsychoCutterOverlay", 1);
					if (player.countinv("GHAGPsychoCutter") == 0) player.giveInventory("GHAGPsychoCutter", 1);
					player.updateWeapons = true;
				}
			}
			stop;
	}
}

Class GHAGPsychoCutter : GHAGWeapon
{
	Default
	{
		Weapon.SlotNumber 1;
		Tag "Psycho Cutter";
	}
	
	override void tick()
	{
		Super.tick();
		
		setTag(Cvar.findCvar("GHAGChainsawName").getString());
	}
	
	int getChainsawCount()
	{
		return owner.countInv('GHAGPsychoCutterOverlay') * (owner.CountInv("PowerWeaponLevel2") >= 1 ? 2 : 1);
	}
	
	bool firing;
	
	States
	{
		Select:
			HAND A 1 {
				A_GHAGRaise();
				A_OverlayChainsaws();
			}
			Loop;
		Deselect:
			HAND A 1
			{
				A_GHAGLower();
				A_OverlayChainsaws();
			}
			Loop;
		Ready:
			HAND A 1 
			{
				A_WeaponReady(WRF_ALLOWUSER1);
				A_OverlayChainsaws();
			}
			Loop;
		Fire:
			HAND J 4
			{
				invoker.firing = true;
			}
			TNT1 A 0 {
				for (int i = 0; i < invoker.getChainsawCount(); ++i)
				{
					A_Saw(	"weapons/sawfull", 
							"weapons/sawhit", 
							2 * invoker.getChainsawCount(), 
							"BulletPuff", 
							SF_NOUSEAMMO | SF_NOPULLIN | SF_NOTURN, 
							56 + (8 * invoker.getChainsawCount() + (44 * GHAGGardevoir(self).getRageModifier())), 
							4.8125 * invoker.getChainsawCount()
						);
				}
			}
			TNT1 A 0 A_Refire();
			TNT1 A 0
			{
				invoker.firing = false;
			}
			goto Ready;
		AltFire:
			TNT1 A 0
			{
				if (countinv('GHAGPsychoCutterOverlay') == 0) return resolveState('Ready');
				return resolveState(null);
			}
			TNT1 A 0
			{
				TakeInventory('GHAGPsychoCutterOverlay', 1);
				A_FireProjectile('GHAGPsychoProjectile'); 
				A_OverlayChainsaws(false);
				GHAGGardevoir(self).updateWeapons = true;
			}
			HAND AABBCCDDEE 1 A_OverlayChainsaws(false);
			goto Ready;
		Overlay:
			PSAW AABB 1 A_JumpIf(invoker.getChainsawCount() == 0, "OverlayClear");
			loop;
		OverlayClear:
			TNT1 A 0;
			stop;
	}
	
	Action Void A_OverlayChainsaws(bool _psycho = false)
	{

	}
	
	//Reduce duplicate code for A_Overlay shared between both modes
	Action void A_DrawChainsaw(statelabel statename, int layer, bool _override)
	{
		A_Overlay(layer, statename, _override);
		A_OverlayFlags(layer, PSPF_ADDBOB, false);
		int i = (layer + 1) * -1;
		if (i % 2 != 0) A_OverlayFlags(layer, PSPF_FLIP | PSPF_MIRROR, true);
	}
	
}

Class GHAGPsychoProjectile : Actor
{
	default
	{
		+RollSprite;
		+HitTarget;
		+SkyExplode;
		+DontGib;
		Projectile;
		Speed 40;
		DropItem "GHAGExtraPsychoCutterDrop";
	}
	
	int lifespan;
	int bloodscale;
	float pos_x;
	float pos_y;
	float pos_z;

	override void BeginPlay()
	{
		Super.BeginPlay();
		A_SetRoll(random(0, 360));
		bloodscale = lifespan = 5 + Int(10 * GHAGGardevoir(players[consoleplayer].mo).GetRageModifier());
		Self.speed = 20 + (20 * GHAGGardevoir(players[consoleplayer].mo).getRageModifier());
	}
	states
	{
		Spawn:
			CSAW AB 1 Bright;
			Loop;
		Death :
			CSAW A 1 Bright {
				if (Invoker.target)
				{
					if (Invoker.target.bIsMonster) {
						pos_x = random(int(-(Invoker.target.radius / 2)), int(Invoker.target.radius / 2));
						pos_y = random(int(-(Invoker.target.radius / 2)), int(Invoker.target.radius / 2));
						pos_z = random(10, int(Invoker.target.height));
						return resolveState('Lacerate');
					}
				}
				A_NoBlocking();
				return resolveState(null);
			}
			stop;
		Lacerate:
			CSAW ABABA 1 Bright;
			TNT1 A 0
			{
				A_StartSound("weapons/chainhit", CHAN_AUTO);
				Self.SetOrigin((Invoker.target.pos.x + pos_x + random(-1, 1), Invoker.target.pos.y + pos_y + random(-1, 1), Invoker.target.pos.z + pos_z + random(-1, 1)), true);
				int damage = int((random() % 10 + 1) * 1.5);
				Invoker.target.damagemobj(self, GHAGGardevoir(players[consoleplayer].mo), damage, 'Melee');
				for (int i = 0; i < bloodscale; ++ i) 
				{
					Vector3 bloodpos = invoker.pos;
					bloodpos.x += random(-3, 3);
					bloodpos.y += random(-3, 3);
					bloodpos.z += random(-3, 3);
					Invoker.target.spawnblood(bloodpos, invoker.angle, damage);
				}
				--lifespan;
				if (lifespan == 0 || !Invoker.target || Invoker.target.health <= 0) 
				{
					return ResolveState('LacerationDeath');
				}
				return resolveState(null);
			}
			loop;
		LacerationDeath :
			CSAW A 1 Bright A_NoBlocking();
			stop;
	}
}