Class GHAGNailGun : GHAGWeapon
{
	
	Default
	{
		Weapon.AmmoUse1 1;
		Weapon.AmmoUse2 1;
		Weapon.SlotNumber 4;
		Weapon.AmmoType1 "Clip";
		Weapon.AmmoType2 "Clip";
		Tag "Nail Gun";
	}
	
	override void BeginPlay()
	{
		Super.beginPlay();
	}
	
	override void Tick()
	{
		Super.tick();
		
		setTag(Cvar.findCvar("GHAGNailgunName").getString());
	}	

	int getNailgunCount()
	{
		return owner.countInv("GHAGNailgunOverlay");
	}

	States
	{
		Spawn:
			NAIL A 1;
			Loop;
		Select :
			HAND A 1 
			{	
				A_GHAGRaise();
				A_OverlayNailgun();
			}
			Loop;
		Deselect :
			HAND A 1 
			{
				A_GHAGLower();
				A_OverlayNailgun();
			}
			Loop;
		Ready :
			HAND A 1 {
				A_OverlayNailgun();
				A_WeaponReady(WRF_ALLOWUSER1);
			}
			Loop;
		Fire:
			HAND ABC 1;
			HAND D 1
			{
				A_OverlayNailgun(true);
			}
			HAND EF 1;
			HAND G 10 A_Refire();
			goto Ready;
		AltFire:
			HAND ABC 1;
			HAND D 1
			{
				A_OverlayNailgun(false, true);
			}
			HAND EF 1;
			HAND G 10 A_Refire();
			goto Ready;
		AltFire.Overlay:
		Fire.Overlay:
			NAIL BCDEFEDCB 1;
		Ready.Overlay:
			NAIL B 1;
			Loop;
		
	}
	
	Action void A_OverlayNailgun(bool RollForFire = false, bool AltFire = false)
	{
		int rng = random(0, (Min(invoker.getNailgunCount() - 1, 3)));
		
		for (int i = 0; i <invoker.getNailgunCount(); ++i)
		{
			
			int layer = -1 * (i + 1);
			
			if (i == rng && RollForFire) {
				A_FireNails(i);
			}
			else if (altFire)
			{
				A_FireNails(i);
			}
		}

		if (player == null)
		{
			return;
		}
	}
	
	Action Void A_FireNails(int layer)
	{
		Vector2 pos = (0, 0);
	
		switch (layer)
		{
			case 0:
				pos.x = 15;
				pos.y = 2;
				break;
			case 1:
				pos.x = -15;
				pos.y = 2;
				break;
			case 2:
				pos.x = 25;
				pos.y = 15;
				break;
			case 3:
				pos.x = -25;
				pos.y = 15;
				break;
			default :
		}
	
		let _locNails = GHAGNailProjectile(A_FireAimedProjectile("GHAGNailProjectile", true, pos.x, pos.y));
		if (_locNails) {
			_locNails.Vel3DFromAngle(60 + (40 * Min(2, GHAGGardevoir(self).GetRageModifier())), _locNails.angle, _locNails.pitch);
			_locNails.setDamage(getDefaultByType(_locNails.getClass()).damage + int(10 * GHAGGardevoir(self).GetRageModifier()));
		}
	}
	
	action Actor A_FireAimedProjectile(class<Actor> missiletype, bool useammo = true, double spawnofs_xy = 0, double spawnheight = 0, int flags = 0)
	{
		let misl = A_FireProjectile(missiletype, 0, useammo, spawnofs_xy, spawnheight, flags, 0);
		if (misl)
		{
			FLineTraceData data;
			Vector3 end;
			bool hit = LineTrace(angle, PLAYERMISSILERANGE, pitch, TRF_SOLIDACTORS|TRF_THRUHITSCAN, player.viewz-pos.z, data: data);
			if (hit && data.hitType != TRACE_CrossingPortal)
				end = (pos.xy, player.viewz) + (AngleToVector(angle,cos(pitch)), -sin(pitch)) * data.distance;
			else
				end = (pos.xy, player.viewz) + (AngleToVector(angle,cos(pitch)), -sin(pitch)) * PLAYERMISSILERANGE;
        
			Vector3 spawnPos = (pos.xy, misl.pos.z);
			if (spawnofs_xy)
				spawnPos.xy = pos.xy + AngleToVector(angle-90)*spawnofs_xy;
        
			Vector3 diff = end - spawnPos;
			double l = diff.Length();
			if (l > 0)
			{
				diff /= l;
				misl.angle = atan2(diff.y, diff.x);
				misl.pitch = -asin(diff.z);
				misl.vel = diff * misl.vel.Length();
			}
		}
    
		return misl;
	}
}

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

Class GHAGNailProjectile : Actor
{
	Default
	{
		Projectile;
		+Ripper;
		-NoGravity;
		Speed 60;
		Damage 4;
		Radius 3;
		Height 3;
		SeeSound "weapons/nailshot";
	}
	
	States
	{
		Spawn:
			NLPJ A 1;
			Loop;
		Death:
			NLPJ BCDEFG 1;
			stop;
	}
}