Class GHAGRocketLauncher : GHAGWeapon
{
	default {
		Weapon.AmmoGive 0;
		Weapon.SlotNumber 5;
		Weapon.AmmoType1 "RocketAmmo";
		Weapon.AmmoType2 "RocketAmmo";
		+Weapon.NoAlert;
		Tag "Rockets";
		GHAGRocketLauncher.maxRockets 3;
		Weapon.AmmoUse1 1;
		Weapon.AmmoUse2 1;
	}
	
	GHAGNameClass names;
	
	int maxRockets;
	property maxRockets: maxRockets;
	int queuedRockets;
	
	override void BeginPlay()
	{
		super.BeginPlay();
	}
	
	override void DoEffect()
	{
		players[consoleplayer].WeaponState |= WF_WEAPONBOBBING;
		super.DoEffect();
	}
	
	override void tick()
	{
		super.tick();
	}
	
	string getRNGName() {
		return self.names.GetName();
	}
	

	States {
		Ready:
			HAND A 3 A_WeaponReady(WRF_AllowReload | WRF_ALLOWUSER1);
			Loop;
		Deselect:
			HAND A 1 A_GHAGLower();
			Loop;
		Select:
			HAND A 1 {
				A_GHAGRaise();
				if (GHAGGardevoir(invoker.owner).FloatGuns[0])
				{
					GHAGGardevoir(invoker.owner).FloatGuns[0].SetStateLabel('RocketIdle');
				}
			}
			Loop;
		Reload :
			TNT1 A 0
			{
				GHAGGardevoir(invoker.owner).FloatGuns[0].SetStateLabel('RocketSmash');
			}
			HAND AB 2 A_OverlayOffset(0, 0, -2, WOF_KEEPX | WOF_ADD);
			TNT1 A 0 A_StartSound("crush/can", CHAN_AUTO);
			HAND H 7;
			TNT1 A 0 {
				GHAGGardevoir(invoker.owner).FloatGuns[0].SetStateLabel('Hidden');
				GHAGGardevoir(invoker.owner).Hiding = true;
			}
			TNT1 A 0 A_FireProjectile("GHAGGrenadeRocket", 0, true, 0, 0, 0, -6.328125);
			HAND ABCDE 2;
			TNT1 A 0
			{
				GHAGGardevoir(invoker.owner).FloatGuns[0].SetStateLabel('RocketIdle');
				GHAGGardevoir(invoker.owner).Hiding = false;
			}
			HAND A 6;
			TNT1 A 0 A_SetNewTagName();
			goto Ready;
		Fire:
			HAND A 8 A_SetTics(GHAGGardevoir(self).GetTicModifier(8));
			TNT1 A 0 {
				GHAGGardevoir(invoker.owner).FloatGuns[0].SetStateLabel('Hidden');
				GHAGGardevoir(invoker.owner).Hiding = true;
				A_AlertMonsters();
				A_PsychicMissile();
			}
			HAND ABCDE 2;
			TNT1 A 0 A_SetNewTagName();
			TNT1 A 0
			{
				GHAGGardevoir(invoker.owner).FloatGuns[0].SetStateLabel('RocketIdle');
				GHAGGardevoir(invoker.owner).Hiding = false;
			}
			HAND A 2;
			TNT1 A 0 A_Refire();
			goto Ready;
		AltFire:
			HAND A 8;
			TNT1 A 0
			{
				
				if (invoker.queuedRockets < invoker.maxRockets && invoker.queuedRockets < (CountInv("RocketAmmo") - 1))
				{
					++invoker.queuedRockets;
					GHAGGardevoir(invoker.owner).FloatGuns[invoker.queuedRockets].SetStateLabel('RocketIdle');
				}
			}
			TNT1 A 0 A_Refire();
			TNT1 A 0 A_AlertMonsters();
		AltFireRelease:
			HAND ABCDE 1;
			TNT1 A 0
			{
				if (invoker.queuedRockets >= 0)
				{
					GHAGGardevoir(invoker.owner).FloatGuns[invoker.queuedRockets].SetStateLabel('Hidden');
					A_PsychicMissile();
					A_SetNewTagName();
					--invoker.queuedRockets;
					return ResolveState('AltFireRelease');
				}
				invoker.queuedRockets = 0;
				GHAGGardevoir(invoker.owner).Hiding = true;
				return ResolveState(null);
			}
			HAND A 10;
			TNT1 A 0 A_CheckReload();
			TNT1 A 0
			{
				GHAGGardevoir(invoker.owner).FloatGuns[0].SetStateLabel('RocketIdle');
				GHAGGardevoir(invoker.owner).Hiding = false;
			}
			goto Ready;
	}
	
	action void A_OverlayRocket()
	{
		GHAGGardevoir(invoker.owner).FloatGuns[0].SetStateLabel('RocketIdle');
	}
	
	action void A_SetNewTagName() 
	{
		if (!Invoker.names) Invoker.names = GHAGNameClass(Spawn("GHAGNameClass"));
		Invoker.setTag(Invoker.names.getName());
	}
	
	action void A_PsychicMissile() 
	{
		if (player == null)
		{
			return;
		}
		Weapon weap = player.ReadyWeapon;
		if (weap != null && invoker == weap && stateinfo != null && stateinfo.mStateType == STATE_Psprite)
		{
			if (!weap.DepleteAmmo (weap.bAltFire, true, 1))
				return;
		}
		
		let _locRocket = GHAGPsychicRocket(SpawnPlayerMissile("GHAGPsychicRocket"));
		if (_locRocket) {
			double _locSpeed = 20 + Max((40 * Min(2, GHAGGardevoir(self).GetRageModifier())), 5);
			if (_locSpeed < 10) _locRocket.bNoGravity = false;
			_locRocket.Vel3DFromAngle(_locSpeed, GHAGGardevoir(self).angle, GHAGGardevoir(self).pitch); 
			_locRocket.SetDamage(20 + Int(80 * GHAGGardevoir(self).GetRageModifier()));
			_locRocket.modifier = GHAGGardevoir(self).GetRageModifier();
			if (GHAGGardevoir(self).CountInv("PowerWeaponLevel2")) {
				_locRocket.seeker = true;
				_locRocket.bNoFriction = true;
				_locRocket.bBounceOnWalls = true;
				_locRocket.bBounceOnFloors = true;
				_locRocket.bBounceOnCeilings = true;
			}
		}
	}
}

Class GHAGPsychicRocket : Rocket
{

	double modifier;
	bool seeker;

	States {
		Spawn:
			MISL A 1 Bright;
			Loop;
		Death:
			TNT1 A 0 A_SetScale(1 + modifier, 1 + modifier);
			MISL B 8 Bright A_Explode(128 + Int(128 * modifier), Int(Min(256, 128 * (1 + modifier))), XF_HURTSOURCE | XF_THRUSTZ);
			MISL C 6 Bright;
			MISL D 4 Bright;
			Stop;
	}
}

Class GHAGGrenadeRocket : Actor
{
	default
	{
		Damage 30;
		Speed 25;
		Projectile;
		-NoGravity;
		-RocketTrail;
		+GrenadeTrail;
		+RollCenter;
		+RollSprite;
		+SEEKERMISSILE;
		+UseBounceState;
		BounceType "Doom";
		BounceSound "Grenade/Bounce";
		DeathSound "weapons/rocklx";
		Gravity 0.25;
		Radius 12;
		Height 12;
	}
	
	States
	{
		Spawn:
			ROCK B 1 A_SetRoll(invoker.roll + 23, SPF_INTERPOLATE);
			Loop;
		Bounce:
			ROCK B 0 A_SeekerMissile(0, 90, SMF_Look | SMF_PRECISE | SMF_CURSPEED, 256, 128);
			TNT1 A 0
			{
				if (!invoker.isVisible(invoker.tracer, true)) {
					invoker.tracer = null;
					A_SeekerMissile(0, 90, SMF_Look | SMF_PRECISE | SMF_CURSPEED, 256, 128);
				}
			}
			goto Spawn;
		Death:
			TNT1 A 0 {
				A_SetRoll(0);
				A_SetScale(1.5, 1.5);
				A_AlertMonsters();
			}
			MISL B 8 Bright A_Explode(-1, 192);
			MISL C 6 Bright;
			MISL D 4 Bright;
			Stop;
	}
}

Class GHAGNameClass : Actor
{

	int getMode;
	int wordtracker;
	int index;
	
	property getMode: getMode;
	property wordtracker: WordTracker;
	property names: names;
	property index: index;
	
	bool sillynames;
	
	default 
	{
		
		GHAGNameClass.getMode 0;
		GHAGNameClass.wordTracker 0;
		GHAGNameClass.index 0;
	}
	
	override void tick()
	{
		Super.tick();
	}
	
	//Your name here? Hit me up!
	static const string names[] =
	{
		"Joey", "Billy", "Kevy", "Kablooey", "Pill", "Martha", "Rachael", "Weasel", "Nash", "Emma",
		"Ghost", "Kekz", "Bob", "Jimmy-Bacon", "Cali", "Kesha", "Gutawer", "Hugo", "Psycho", "Try GZChaos!",
		"Romero", "Carmack", "Adrian", "Tom", "Sandy", "American", "Kid Mystic", "Trouble", "Peace Keeper",
		"Chocolate Thunder", "Vanilla Thunder", "Strawberry Thunder", "Pomegranate Fury", "Fuck you in particular",
		"Death from above", "Oh shit, he", "ASSHAT", "ASSCLOWN", "ASSFART", "RED", "BLUE", "GREEN", "YELLOW", "GOLD", "SILVER",
		"CRYSTAL", "Prof. Oak", "Prof. Elm", "Prof. Birch", "Prof. Rowan", "Prof. Juniper", "Prof. Sycamore", 
		"Prof. Kukui", "Prof. Magnolia", "RUBY", "SAPPHIRE", "EMERALD", "DIAMOND", "PEARL", "PLATINUM", "BLACK", "SCARLET", "VIOLET",
		"WHITE", "X", "Y", "SWORD", "SHIELD", "Explosive Diplomacy", "Diplomacy", "Zero Diplomacy", "Fuck you, Baltimore!",
		"Zabivaka, no!", "BASTARD!", "I AM CALM!", "Crocket", "Screaming Eagles!", "The Original", "Stanley",
		"Pikachu", "Shirely", "Surely", "Flynn", "Dacote", "Problem Solver", "Problem Causer", "9K38 Igla", "Bitterman",
		"Rocket", "Rocket No. 524", "Rocky", "Rocky Road", "Rocky Horror", "Not a shiny", "Wonder-trade me", "Fiddlyfaddlybiddlybaddlydiddlydoodlyhiddlyhoodly",
		"Problem Maker", "Problem Deleter", "Kibbles n' bits", "Howler Head", "Dr. Pepper", "Not Safe For Self Propulsion",
		"Safe For Self Propulsion", "Death Bringer", "Funny Name", "Funny Name Here", "Made you look", "Made you explode",
		"ZScript was a mistake", "AEUHHH????", "[No]", "[Added]", "[Already In]", "[DIY]", "[Duplicate]", "[Not Needed]",
		"[Closed]", "[???!?!?!?!????]", "Icon Killer", "This one's for Daisy", "Bottled Up Rage", "Explosive Personality",
		"Explosive Diarrhea", "Bottled Up Rage", "Can of Whoop Ass", "What", "Sin Killer", "MERCILESS EXTERMINATION",
		"SPEEEN", "Merry Christmas", "Apple!", "Hey!", "Apple, hey Apple!", "Adios", "Busting makes me feel good!",
		"Ok I Love You Bye Bye", "Not funny, didn't laugh", "Frag out", "Fire in the hole!", "50 Shades of Explode",
		"50 Shades of you're dead", "50 shades of gibitude", "50 shades of death", "ZoomyPop", "Zoomie Boomies",
		"Congrats! You've won!", "NOT THE BEES!", '"Dildo Joke Here"', "Help I'm trapped in a rocket factory!",
		"Sit down, That means you Billy!", "Lil' smokey", "Ayy Pappie!", "Sparky", "Charging Charlie", "Gloverfield",
		"Mister Roger's Middle Finger", "Fandango", "The Rectifier", "Buelah", "Chumlee", "Butterface", "Gone Fission",
		"Not your dad's colonoscopy", "Bitch Slap", "The Dreaded CONE", "Bloop", "Muzzle Maggot", "Track Trolls",
		"Breach Creature", "Bore Baby", "Novacaine", "Karma", "Karma Bringer", "Wake Up Call", "Hey! Listen!",
		"I like shorts!", "Hot explosives in your area!", "Happy Accident", "Chaos... Control!", "Chaos... Swiss Roll!",
		"Creeper", "Shoutout to Simpleflips", "Lamb sauce located", "Target Acquired", "Eightball", "Going out with a bang!",
		"Liam", "Olivia", "Noah", "Oliver", "Ava", "Elijah", "Charlotte", "William", "Sophia", "James", "Jesse", "Amelia",
		"Benjamin", "Isabella", "Lucas", "Mia", "Henry", "Evelyn", "Alexander", "Harper", "Bojack", "Princess", "Nguyen",
		"Todd", "Neal McBeal", "Margo Martindale", "Peanut Butter", "Hollyhock", "Judah", "Surprise!", "PK Rocket!",
		"PSY Rocket!", "The perfect gift", "Imp Encounter", "300mb!", "Dud", "Objection!", "Hold it!", "Take that!",
		"Silence!", "Perfect IV", "Laser!", "Caution!", "Goodnight Everybody!", "Helloooooo Nurse!", "Love", "Heart",
		"Brain", "Control", "CAFFEINATE!", "Wake up!", "Smack!", "That's great", "Fuck Hexen", "What is the time?",
		"Archvile repellant", "Raw kit lawn chair", "Hydrate", "Posture check", "You humour", "Major Arlene", "Kaapeli", "Bridge Burner",
		"Jimmy Squared", "You let me complicate you", "Excuse me", "Ultimate Cup of Coffee", "Try Haxe!", "Bosh", "Bish", "Chaz", "Bailey",
		"Coco", "Finn", "Perkele", "No niin", "Pee is stored in the rocket", "Rockets are stored in the balls",
		"Here's lookin' at you", "Rocket Launcher", "Wake your psyche up", "Dig your anger up", "Delete This",
		"Exterminate", "EXTERMINATUS", "TNT was a mistake", "BFG Division is overrated", "TOTTFISY is Overrated",
		"Shannon Cannon", "BOOCH", "This is a stroberry!", "Spine breaker", "The Negotiator", "Kitanai yasai",
		"Nan da kore!?", "Prepare for trouble!", "Banana Man", "BIMSNESS!", "TORNADO!", "Eyebrow plucker", "Beans",
		"Give 'em the BEANS", "Vladimir Put-it-in", "Jolf", "Violence & Gore", "Beef Whistler", "Harris", "Go chunt yourself",
		"Alper", "Dunn", "Remmi", "Shakar", "Uncle Had", "The Double Duece", "Proverbial", "Spoon", "Sanya", "Velvetic", "Yugiboy",
		"Large explosion hypothesis", "Blast Processing", "Missile toe", "boomshakalaka", "Energy egg", "Your turn will come..."
		
	};

	static const string navyseal[] = {
		"the", "fuck", "did", "you", "just", "fucking", "say", "about", "me,", "you", "little", "bitch?"
	};
	
	static const string awman[] = {
		"Ah man", "So", "way", "back", "in", "the", "mine,", "got", "our", "pickaxe", "swingin'", "from", "side", "to", "side!"
	};
	
	static const string shorts[] = {
		"They're comfy,", "And easy to wear!"
	};
	
	static const string spacemonkey[] = {
		"It starts", "With an", "Earth", "Quake", "Birds and Snakes", "an Airplane", "and", "BILLY JOEL", "Is not afraid..."
	};
	
	static const string contempt[] = {
		"me greatly", "with your", 'arrogance and contempt,', "a flood of accusations", "born from the poison", "of envy", "and smite", "of disrespect."
	};
	
	static const string teamrocket[] = {
		"And make it double!", "To protect the world from devastation!", "To unite all peoples within our nation!", "To denounce the evils of truth and love!", "To extend our reach to the stars above!", "Jessie!", "James!", "Team Rocket blasts off at the speed of light!", "Surrender now, or prepare to fight!", "Meowth! That's right!"
	};
	
	string GetName() {
	
		if(!Cvar.findCvar("GHAGsillyrocket").getBool()) return "Rockets";
		
		string rng_name = '[I am error]';
		
		switch (getMode)
		{
			case 0:
				index += random(1, int(GHAGNameClass.names.size() / 2)) * (random(0, 100) % 4 == 0 ? 1 : -1);
				index = index % GHAGNameClass.names.size();
				if (index < 0) index += GHAGNameClass.names.size();
				rng_name = GHAGNameClass.names[index];
				if (rng_name == "What") getMode = 1;
				if (rng_name == "Creeper") getMode = 2;
				if (rng_name == "I like shorts!") getMode = 3;
				if (rng_name == "That's great") getMode = 4;
				if (rng_name == "You humour") getMode = 5;
				if (rng_name == "Prepare for trouble!") getMode = 6;
				break;
			case 1:
				rng_name = GHAGNameClass.navyseal[wordtracker];
				wordtracker += 1;
				if (rng_name == "bitch?") {
					getMode = 0;
					wordTracker = 0;
				}
				break;
			case 2:
				rng_name = GHAGNameClass.awman[wordtracker];
				wordtracker += 1;
				if (rng_name == "side!") {
					getMode = 0;
					wordTracker = 0;
				}
				break;
			case 3:
				rng_name = GHAGNameClass.shorts[wordtracker];
				wordtracker += 1;
				if (rng_name == "And easy to wear!") {
					getMode = 0;
					wordTracker = 0;
				}
				break;
			case 4:
				rng_name = GHAGNameClass.spacemonkey[wordtracker];
				wordtracker += 1;
				if (rng_name == "Is not afraid...") {
					getMode = 0;
					wordTracker = 0;
				}
				break;
			case 5:
				rng_name = GHAGNameClass.contempt[wordtracker];
				wordtracker += 1;
				if (rng_name == "of disrespect.") {
					getMode = 0;
					wordTracker = 0;
				}
				break;
			case 6:
				rng_name = GHAGNameClass.teamrocket[wordtracker];
				wordtracker += 1;
				if (rng_name == "Meowth! That's right!") {
					getMode = 0;
					wordTracker = 0;
				}
				break;
		}
		
		return rng_name;
	}
}

Class GHAGRocketAmmo : CustomInventory replaces RocketAmmo 
{
	default {
		Inventory.pickupmessage "Found a piece of ordnance!";
		Inventory.pickupsound "misc/w_pkup";
		Inventory.amount 1;
	}
	
	override bool TryPickup(in out Actor toucher)
	{
		let gardie = GHAGGardevoir(Players[consoleplayer].mo);
		
		for (let probe = gardie.Inv; probe != NULL; probe = probe.Inv)
		{
			let item = RocketAmmo(probe);
			if (item) {
				if (gardie.countinv('rocketammo') >= item.maxamount) return false;
				else {
					if (gardie.countinv("GHAGRocketLauncher") == 0) {
						gardie.A_GiveInventory("GHAGRocketLauncher", 1);
						if (!gardie.chargingBlackHole) gardie.A_SelectWeapon("GHAGRocketLauncher");
					}
					gardie.A_GiveInventory("RocketAmmo", self.amount);
				}
			}
		}
		GoAwayAndDie();
		return true;
	}
	
	States
	{
		Spawn:
			ROCK A -1;
			Stop;
	}
}

Class GHAGRocketBox : GHAGRocketAmmo replaces RocketBox 
{
	default {
		inventory.pickupmessage "Found a box of ordnance!";
		inventory.pickupsound "misc/w_pkup";
		Inventory.Amount 5;
	}
	States
	{
		Spawn:
			BROK A -1;
			Stop;
	}
}