Class GHAGShotgun : GHAGWeapon
{
	default
	{
		Weapon.AmmoUse1 1;
		Weapon.SlotNumber 3;
		Weapon.AmmoType1 "Shell";
		Weapon.AmmoType2 "Shell";
		+Weapon.Ammo_Optional;
		+WEAPON.ALT_AMMO_OPTIONAL;
		Tag "1912 Shotgun";
	}
	
	bool batmode;
	
	int getShotgunCount()
	{
		return owner.countInv("GHAGShotgunOverlay");
	}
	
	override void BeginPlay()
	{
		self.batMode = false;
		
		super.beginPlay();
	}
	
	override void tick()
	{
		Super.tick();
		
		setTag(Cvar.findCvar("GHAGShotgunName").getString());
		//setTag('Yar har har');
	}
	
	states
	{
		Select:
			TNT1 A 0 A_JumpIf(invoker.batmode, "Select.batmode");
			HAND A 1
			{
				A_OverlayShotguns();
				A_GHAGRaise();
			}
			Loop;
		Select.BatMode:
			GSHT I 1
			{
				A_OverlayShotguns();
				A_GHAGRaise();
			}
			Loop;
		Deselect:
			TNT1 A 0 A_JumpIf(invoker.batmode, "Deselect.batmode");
			HAND A 1
			{
				A_OverlayShotguns();
				A_GHAGLower();
			}
			Loop;
		Deselect.BatMode:
			GSHT I 1
			{
				A_OverlayShotguns();
				A_GHAGLower();
			}
			Loop;
		Ready:
			TNT1 A 0 A_JumpIf(invoker.BatMode, "Ready.Batmode");
			HAND A 1
			{
				A_OverlayShotguns();
				A_WeaponReady(WRF_ALLOWRELOAD | WRF_ALLOWUSER1);
			}
			Loop;
		Ready.BatMode:
			GSHT I 1
			{
				A_OverlayShotguns();
				A_WeaponReady(WRF_ALLOWRELOAD | WRF_ALLOWUSER1);
			}
			goto Ready;
		Reload:
			TNT1 A 0 A_JumpIf(!Invoker.Batmode, "Reload.BatMode"); 
			TNT1 A 0 A_JumpIf(Invoker.Batmode, "Reload.DeBatMode"); 
			goto Ready;
		Reload.DeBatMode:
			GSHT I 4;
			GSHT H 4;
			TNT1 A 0
			{
				Invoker.batmode = false;
				GHAGGardevoir(invoker.owner).updateWeapons = true;
				A_OverlayShotguns();
			}
			goto Ready;
		Reload.BatMode:
			TNT1 A 0
			{
				Invoker.batmode = true;
				GHAGGardevoir(invoker.owner).updateWeapons = true;
				A_OverlayShotguns();
			}
			GSHT H 4;
			GSHT I 4;
			goto Ready;
		Fire:
			TNT1 A 0 A_JumpIf(invoker.batmode, "Fire.Swing");
			TNT1 A 0 A_JumpIf(invoker.countInv("shell") == 0, "DryFire");
			HAND A 3 {
				A_SetTics(GHAGGardevoir(self).GetTicModifier(3));
				A_OverlayShotguns();
			}
			HAND B 2 Bright {
				int pellets = int(floor(14 * GHAGGardevoir(Self).GetRageModifier()) * (GHAGGardevoir(self).rageValue > GHAGGardevoir(self).rageConstant ? 2 : 1));
				A_FireBullets(4, 4, 10 + pellets, 5, invoker.pufftype);
				A_StartSound("weapons/shotgf", CHAN_AUTO);
				A_SetTics(GHAGGardevoir(self).GetTicModifier(2));
				bool powered = invoker.owner.CountInv("PowerWeaponLevel2") >= 1;
				A_OverlayShotguns(true);
			}
			HAND CCDDD 1 Bright;
			HAND E 3 A_SetTics(GHAGGardevoir(self).GetTicModifier(3));
			HAND FGAAAAA 3 A_SetTics(GHAGGardevoir(self).GetTicModifier(3));
			HAND A 7 A_ReFire();
			Goto Ready;
		Fire.Swing:
			TNT1 A 0 A_OverlayPivot(0, 0.75, 0.75);
			GSHT IIII 1 {
				A_OverlayRotate(0, 25, WOF_ADD);
			}
			GSHT I 0 {
				FTranslatedLineTarget t;
				double ang = angle + Random2() * (5.625 / 256);
				double pitch = AimLineAttack(ang, 64, null, 0., ALF_CHECK3D);
				int damage = invoker.owner.CountInv("PowerWeaponLevel2") >= 1 ? 256 : 128;
				LineAttack(ang, 64, pitch, damage, 'Melee', "BulletPuff", LAF_ISMELEEATTACK, t);
				A_StartSound("skeleton/swing", CHAN_WEAPON);
				if (t.linetarget)
				{
					Actor target = t.linetarget;
					float rage = GHAGGardevoir(players[consoleplayer].mo).getRageModifier();
					A_StartSound("fists/LPUNCH", CHAN_WEAPON);
					ShottyThwackBlastActor(target, 64 + (64 * rage), 16 + (16 * rage), "", true);
					if (target.health > 0) target.setStateLabel("Pain");
					if (invoker.owner.CountInv("PowerWeaponLevel2") >= 1) A_Quake(10, 3, 0, 10);
				}
			}
			GSHT IIII 4 
			{
				A_OverlayRotate(0, -25, WOF_ADD);
				A_SetTics(GHAGGardevoir(self).GetTicModifier(4));
			}
			goto Ready;
		AltFire:
			TNT1 A 0 A_JumpIf(invoker.batmode, "AltFire.SingleShot");
			TNT1 A 0 A_JumpIf(invoker.countInv("shell") == 0, "DryFire");
			HAND A 3 A_OverlayShotguns();
			HAND B 1 Bright {
				invoker.AmmoUse2 = invoker.getShotgunCount();
				A_FireBullets(6, 6, int((15 * invoker.getShotgunCount()) + (15 * GHAGGardevoir(Self).GetRageModifier())), 5, invoker.pufftype);
				A_StartSound("weapons/shotgf", CHAN_AUTO);
				A_OverlayShotguns(true, true);
			}
			HAND CCDDD 1 Bright;
			HAND E 2;
			HAND FGAAAAA 3;
			TNT1 A 0 A_Refire();
			goto Ready;
		AltFire.SingleShot:
			TNT1 A 0 A_JumpIf(invoker.countInv("shell") == 0, "Ready");
			TNT1 A 0 A_JumpIf(invoker.getShotgunCount() <= 1, "Ready");
			GSHT I 3 A_OverlayShotguns();
			GSHT I 1 Bright {
				int pellets = int(floor(14 * GHAGGardevoir(Self).GetRageModifier()) * (GHAGGardevoir(self).rageValue > GHAGGardevoir(self).rageConstant ? 2 : 1));
				A_FireBullets(4, 4, 10 + pellets, 5, invoker.pufftype);
				A_StartSound("weapons/shotgf", CHAN_AUTO);
				A_SetTics(GHAGGardevoir(self).GetTicModifier(2));
				bool powered = invoker.owner.CountInv("PowerWeaponLevel2") >= 1;
				A_OverlayShotguns(true);
			}
			GSHT I 5;
			GSHT I 2;
			GSHT I 21;
			TNT1 A 0 A_Refire();
			goto Ready;
		Ready.Overlay:
			GSHT A 1;
			Loop;
		Nothing.Overlay:
			TNT1 A 1;
			Loop;
		Fire.Overlay:
			GSHT G 5 Bright;
		Pump.Overlay :
			GSHT A 3 A_SetTics(GHAGGardevoir(self).GetTicModifier(3));
			GSHT A 2 A_SetTics(GHAGGardevoir(self).GetTicModifier(2));
			GSHT A 5 A_SetTics(GHAGGardevoir(self).GetTicModifier(5));
			TNT1 A 0 A_StartSound("weapons/shotpm", CHAN_WEAPON);
			GSHT C 5 A_SetTics(GHAGGardevoir(self).GetTicModifier(5));
			GSHT D 4 A_SetTics(GHAGGardevoir(self).GetTicModifier(4));
			GSHT E 5 
			{
				A_SetTics(GHAGGardevoir(self).GetTicModifier(5));
				A_StartSound("weapons/shotpl", CHAN_WEAPON);
			}
			GSHT A 999;
			stop;
		AltFire.Overlay:
			GSHT G 5 Bright;
		AltPump.Overlay :
			GSHT A 3;
			GSHT A 2;
			GSHT A 5;
			TNT1 A 0 A_StartSound("weapons/shotpm", CHAN_WEAPON);
			GSHT C 5;
			GSHT D 4;
			GSHT E 5 A_StartSound("weapons/shotpl", CHAN_WEAPON);
			GSHT A 999;
			stop;
		DryFire:
			TNT1 A 0 A_StartSound("weapons/dryfire", CHAN_AUTO);
			HAND ABCDE 3;
			HAND A 5 A_SetTics(GHAGGardevoir(self).GetTicModifier(max(5, GHAGGardevoir(self).getTicModifier(10))));
			goto Ready;
	}
	
	override void SetBulletPuff(int firemode)
	{
		pufftype = 'BulletPuff';
		int bullets = 0;
		
		switch (firemode)
		{
			case 0:
				bullets = Int(floor(14 * GHAGGardevoir(owner).GetRageModifier()) * (GHAGGardevoir(owner).rageValue > GHAGGardevoir(owner).rageConstant ? 2 : 1));
				break;
			case 1:
				bullets = Int(15 * getShotgunCount()) + Int(15 * GHAGGardevoir(owner).GetRageModifier());
				break;
			default:
				break;
		}
		
		if (bullets > 30) pufftype = 'GHAGBulletPuff';
	}
	
	Action void A_OverlayShotguns(bool RollForFire = false, bool AltFire = false)
	{
		let gardie = GHAGGardevoir(invoker.owner);
		if (gardie.FloatGuns.Size())
		{
			if (RollForFire)
			{
				int rng = random(invoker.batmode, (Min(invoker.getShotgunCount() - 1, 3)));
				if (invoker.getShotgunCount() > 1 && rng == invoker.lastRNG) 
				{
					if (invoker.getShotgunCount() == 2 && invoker.batmode) rng = 1;
					else
					{
						while (rng == invoker.lastRNG)
						{
							rng = random(invoker.batmode, (invoker.getShotgunCount() - 1));
						}
					}
				}
				invoker.lastRNG = rng;
				
				gardie.FloatGuns[rng].SetStateLabel('ShotgunFire');
			}
			if (AltFire)
			{
				for (int i = 0; i < invoker.getShotgunCount(); ++i)
				{
					gardie.FloatGuns[i].SetStateLabel('ShotgunFire');
				}
			}
		}
	}
	
	Action void ShottyThwackBlastActor (Actor victim, double strength, double speed, Class<Actor> blasteffect, bool dontdamage)
	{
		if (!victim.SpecialBlastHandling (self, strength))
		{
			return;
		}

		double ang = AngleTo(victim);
		Vector2 move = AngleToVector(ang, speed);
		victim.Vel.XY = move;

		// Spawn blast puff
		ang -= 180.;
		Vector3 spawnpos = victim.Vec3Offset(
			(victim.radius + 1) * cos(ang),
			(victim.radius + 1) * sin(ang),
			(victim.Height / 2) - victim.Floorclip);
		Actor mo = blasteffect? Spawn (blasteffect, spawnpos, ALLOW_REPLACE) : null;
		if (mo)
		{
			mo.Vel.XY = victim.Vel.XY;
		}
		if (victim.bMissile)
		{
			// [RH] Floor and ceiling huggers should not be blasted vertically.
			if (!victim.bFloorHugger && !victim.bCeilingHugger)
			{
				victim.Vel.Z = 8;
				if (mo != null) mo.Vel.Z = 8;
			}
		}
		else
		{
			victim.Vel.Z = 1000. / victim.Mass;
		}
		if (victim.player)
		{
			// Players handled automatically
		}
		else if (!dontdamage)
		{
			victim.bBlasted = true;
		}
		if (victim.bTouchy)
		{ // Touchy objects die when blasted
			victim.bArmed = false; // Disarm
			victim.DamageMobj(self, self, victim.health, 'Melee', DMG_FORCED|DMG_EXPLOSION);
		}
	}
}

class GHAGShotgunOverlay : Inventory
{
	default
	{
		Inventory.MaxAmount 4;
		Inventory.pickupMessage "Seized an extra shotgun!";
	}
	
	override void beginplay()
	{
		super.beginPlay();
		
		if (GameInfo.GameType == 2) Self.MaxAmount = 2;
	}
}