Class UPlayer : UTPlayer
{
	Default
	{
		//Player.StartItem "Automag";
		//Player.StartItem "DispersionPistol";
		//Player.StartItem "UMiniAmmo", 30;
	}

	// Have to modify the give cheat to handle UT armor
	override void CheatGive( String name, int amount )
	{
		if ( PlayerNumber() != consoleplayer )
			A_Log(String.Format("%s is a cheater: give %s\n",player.GetUserName(),name));
		if ( !player.mo || (player.health <= 0) ) return;
		int giveall = ALL_NO;
		if ( name ~== "all" ) giveall = ALL_YES;
		else if (name ~== "everything") giveall = ALL_YESYES;
		if ( name ~== "health" )
		{
			if ( amount > 0 )
			{
				health += amount;
				player.health = health;
			}
			else player.health = health = GetMaxHealth(true);
		}
		if ( giveall || (name ~== "backpack") )
		{
			// Select the correct type of backpack based on the game
			let type = (class<Inventory>)(gameinfo.backpacktype);
			if ( type ) GiveInventory(type,1,true);
			if ( !giveall ) return;
		}
		if ( giveall || (name ~== "ammo") )
		{
			// Find every unique type of ammo. Give it to the player if
			// he doesn't have it already, and set each to its maximum.
			for ( int i=0; i<AllActorClasses.Size(); i++ )
			{
				let type = (class<Ammo>)(AllActorClasses[i]);
				if ( !type || (type.GetParentClass() != "Ammo") )
					continue;
				// Only give if it's for a valid weapon, unless using "give everything"
				bool isvalid = false;
				for ( int j=0; j<AllActorClasses.Size(); j++ )
				{
					let type2 = (class<Weapon>)(AllActorClasses[j]);
					if ( !type2 ) continue;
					let rep = GetReplacement(type2);
					if ( (rep != type2) && !(rep is "DehackedPickup") ) continue;
					readonly<Weapon> weap = GetDefaultByType(type2);
					if ( !player.weapons.LocateWeapon(type2) || (weap.bCheatNotWeapon && (giveall != ALL_YESYES)) ) continue;
					if ( (weap.AmmoType1 == type) || (weap.AmmoType2 == type) )
					{
						isvalid = true;
						break;
					}
				}
				if ( !isvalid ) continue;
				let ammoitem = FindInventory(type);
				if ( !ammoitem )
				{
					ammoitem = Inventory(Spawn(type));
					ammoitem.AttachToOwner(self);
					ammoitem.Amount = ammoitem.MaxAmount;
				}
				else if ( ammoitem.Amount < ammoitem.MaxAmount )
					ammoitem.Amount = ammoitem.MaxAmount;
			}
			if ( !giveall ) return;
		}
		if ( giveall || (name ~== "armor") )
		{
			// Doomreal gives the player all subclasses of UnrealArmor
			for ( int i=0; i<AllActorClasses.Size(); i++ )
			{
				if ( !(AllActorClasses[i].GetParentClass() is "UnrealArmor") ) continue;
				let item = Inventory(Spawn(AllActorClasses[i]));
				if ( !item.CallTryPickup(self) ) item.Destroy();
			}
			if ( !giveall ) return;
		}
		if ( giveall || (name ~== "keys") )
		{
			for ( int i=0; i<AllActorClasses.Size(); i++ )
			{
				if ( !(AllActorClasses[i] is "Key") ) continue;
				let keyitem = GetDefaultByType(AllActorClasses[i]);
				if ( keyitem.special1 )
				{
					let item = Inventory(Spawn(AllActorClasses[i]));
					if ( !item.CallTryPickup(self) ) item.Destroy();
				}
			}
			if ( !giveall ) return;
		}
		if ( giveall || (name ~== "weapons") )
		{
			let savedpending = player.PendingWeapon;
			for ( int i=0; i<AllActorClasses.Size(); i++ )
			{
				let type = (class<Weapon>)(AllActorClasses[i]);
				if ( !type || (type == "Weapon") ) continue;
				// Don't give replaced weapons unless the replacement was done by Dehacked.
				let rep = GetReplacement(type);
				if ( (rep == type) || (rep is "DehackedPickup") )
				{
					// Give the weapon only if it is set in a weapon slot.
					if ( !player.weapons.LocateWeapon(type) ) continue;
					readonly<Weapon> def = GetDefaultByType(type);
					if ( (giveall == ALL_YESYES) || !def.bCheatNotWeapon )
						GiveInventory(type,1,true);
				}
			}
			player.PendingWeapon = savedpending;
			if ( !giveall ) return;
		}
		if ( giveall || (name ~== "artifacts") )
		{
			for ( int i=0; i<AllActorClasses.Size(); i++ )
			{
				let type = (class<Inventory>)(AllActorClasses[i]);
				if ( !type ) continue;
				let def = GetDefaultByType (type);
				if ( def.Icon.isValid() && (def.MaxAmount > 1) &&
					!(type is "PuzzleItem") && !(type is "Powerup") && !(type is "Ammo") &&	!(type is "Armor"))
				{
					// Do not give replaced items unless using "give everything"
					if ( (giveall == ALL_YESYES) || (GetReplacement(type) == type) )
						GiveInventory(type,(amount<=0)?def.MaxAmount:amount,true);
				}
			}
			if ( !giveall ) return;
		}
		if ( giveall || (name ~== "puzzlepieces") )
		{
			for ( int i=0; i<AllActorClasses.Size(); i++ )
			{
				let type = (class<PuzzleItem>)(AllActorClasses[i]);
				if ( !type ) continue;
				let def = GetDefaultByType(type);
				if ( !def.Icon.isValid() ) continue;
				// Do not give replaced items unless using "give everything"
				if ( (giveall == ALL_YESYES) || (GetReplacement(type) == type) )
					GiveInventory(type,(amount<=0)?def.MaxAmount:amount,true);
			}
			if ( !giveall ) return;
		}
		if ( giveall ) return;
		let type = name;
		if ( !type )
		{
			if ( PlayerNumber() == consoleplayer )
				A_Log(String.Format("Unknown item \"%s\"\n",name));
		}
		else GiveInventory(type,amount,true);
	}
}

Class UPlayerMale1 : UPlayer
{
	Default
	{
		Player.SoundClass "umale";
		Player.DisplayName "$N_MALE1";
		Player.Portrait "";
		UTPlayer.VoiceType VOICE_MaleOne;
		-NOMENU;
	}
}
Class UPlayerMale2 : UPlayer
{
	Default
	{
		Player.SoundClass "umale";
		Player.DisplayName "$N_MALE2";
		Player.Portrait "";
		UTPlayer.VoiceType VOICE_MaleOne;
		-NOMENU;
	}
}
Class UPlayerMale3 : UPlayer
{
	Default
	{
		Player.SoundClass "umale";
		Player.DisplayName "$N_MALE3";
		Player.Portrait "";
		UTPlayer.VoiceType VOICE_MaleTwo;
		-NOMENU;
	}
}
Class UPlayerFemale1 : UPlayer
{
	Default
	{
		Player.SoundClass "ufemale";
		Player.DisplayName "$N_FEMALE1";
		Player.Portrait "";
		UTPlayer.VoiceType VOICE_FemaleTwo;
		-NOMENU;
	}
}
Class UPlayerFemale2 : UPlayer
{
	Default
	{
		Player.SoundClass "ufemale";
		Player.DisplayName "$N_FEMALE2";
		Player.Portrait "";
		UTPlayer.VoiceType VOICE_FemaleOne;
		-NOMENU;
	}
}

Class UnrealInventory : Inventory
{
	bool bActive;	// is currently activated
	int Charge;	// for timed items
	int DefaultCharge;

	Property Charge : DefaultCharge;

	// Drawstuffs under HUD
	virtual ui void PreRender( double lbottom ) {}
	// Drawstuffs over HUD
	virtual ui void PostRender( double lbottom ) {}

	Default
	{
		+INVENTORY.INVBAR;
		UnrealInventory.Charge 0;
	}
}

Class UnrealStaticHandler : StaticEventHandler
{
	ui TextureID tex[6];
	ui int mtics, cur;
	ui String lastmusic;

	ui void StartMenu()
	{
		CVar protomenu = CVar.GetCVar('stinger_introtype',players[consoleplayer]);
		if ( !protomenu ) return;	// this can happen
		int proto = protomenu.GetInt();
		tex[0] = TexMan.CheckForTexture("graphics/UnLogo0.png",TexMan.Type_Any);
		tex[1] = TexMan.CheckForTexture("graphics/UnLogo1.png",TexMan.Type_Any);
		tex[2] = TexMan.CheckForTexture("graphics/UnLogo2.png",TexMan.Type_Any);
		tex[3] = TexMan.CheckForTexture("graphics/UnBg.png",TexMan.Type_Any);
		tex[4] = TexMan.CheckForTexture("graphics/97Bg.png",TexMan.Type_Any);
		tex[5] = TexMan.CheckForTexture("graphics/95Bg.png",TexMan.Type_Any);
		if ( proto > 1 ) S_ChangeMusic("Unreal");
		else if ( proto == 1 ) S_ChangeMusic("Unreal2");
		else S_ChangeMusic("FlyBy");
		cur = proto;
	}

	override void OnRegister()
	{
		// remove the UT static handler
		let hnd = UTStaticHandler(StaticEventHandler.Find("UTStaticHandler"));
		if ( hnd ) hnd.Destroy();
	}

	override void ConsoleProcess( ConsoleEvent e )
	{
		if ( gamestate != GS_TITLELEVEL ) return;
		if ( e.Name ~== "refreshmenu" ) StartMenu();
	}

	override void PostUiTick()
	{
		if ( gamestate != GS_TITLELEVEL ) return;
		if ( gametic <= 0 ) StartMenu();
		if ( musplaying.Name != lastmusic )
		{
			mtics = 0;
			lastmusic = musplaying.Name;
		}
		else mtics++;
	}

	override void RenderOverlay( RenderEvent e )
	{
		// we have to stand in for the UT handler on this function
		// although it doesn't make much sense yet
		if ( players[consoleplayer].camera.player && players[consoleplayer].camera.player.ReadyWeapon && (players[consoleplayer].camera.player.ReadyWeapon is 'UTWeapon') )
			UTWeapon(players[consoleplayer].camera.player.ReadyWeapon).RenderOverlay(e);
		if ( gamestate != GS_TITLELEVEL ) return;
		double ar = Screen.GetAspectRatio();
		Vector2 tsize = TexMan.GetScaledSize(tex[cur+3]);
		double sar = tsize.x/tsize.y;
		Vector2 vsize;
		if ( sar > ar ) vsize = (tsize.y*ar,tsize.y);
		else if ( sar < ar ) vsize = (tsize.x,tsize.x/ar);
		else vsize = tsize;
		Screen.DrawTexture(tex[cur+3],false,(vsize.x-tsize.x)/2,(vsize.y-tsize.y)/2,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true);
		Screen.Dim("Black",clamp(1.-((mtics+e.FracTic)/Thinker.TICRATE)*.2,0.,1.),0,0,Screen.GetWidth(),Screen.GetHeight());
		if ( menuactive ) return;
		tsize = TexMan.GetScaledSize(tex[cur]);
		sar = tsize.x/tsize.y;
		if ( sar > ar ) vsize = (tsize.x,tsize.x/ar);
		else if ( sar < ar ) vsize = (tsize.y*ar,tsize.y);
		else vsize = tsize;
		double alf = clamp(((mtics+e.FracTic)/Thinker.TICRATE)-8,0.,1.);
		Screen.DrawTexture(tex[cur],false,(vsize.x-tsize.x)/2,(vsize.y-tsize.y)/2,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true,DTA_Alpha,alf);
	}
}

Class UnrealMainHandler : EventHandler
{
	override void CheckReplacement( ReplaceEvent e )
	{
		if ( (e.Replacee == 'Shotgun') || (e.Replacee == 'SuperShotgun') || (e.Replacee == 'Crossbow') )
		{
			/*if ( !Random[Replacements](0,3) ) e.Replacement = 'Enforcer';
			else if ( Random[Replacements](0,1) ) */e.Replacement = 'Stinger';
			/*else e.Replacement = 'ShockRifle';*/
		}
		else if ( (e.Replacee == 'RocketLauncher') || (e.Replacee == 'PhoenixRod') )
		{
			/*if ( Random[Replacements](0,1) ) */e.Replacement = 'UFlakCannon';
			/*else e.Replacement = 'UTRocketLauncher';*/
		}
		else if ( e.Replacee == 'Backpack' ) e.Replacement = 'UnrealBackpack';
	}
}
