/**********************************************************
RunUO 2.0 AoV C# script file
Official Age of Valor Script :: www.uovalor.com
Last modified by 
Filepath: scripts\_custom\engines\Event System\events\CTF\CtfEventController.cs
Lines of code: 275
***********************************************************/


using Server;
using System;
using Server.Mobiles;
using Server.Items;


namespace Server.EventSystem
{
	public class CtfEventController : BaseEventController
	{
		public override int m_MinTeams { get { return  2; } }
		public override int m_MaxTeams { get { return  4; } }
		
		
		//CTF specific serialized vars		
		private Point3D[] m_TeamxStart = new Point3D[4];
		private int[] m_TeamxPoints = new int[4];
		private int m_maxpoints;
		
		private string[] m_TeamxName = new string[4];
		
		private string m_stealmessage = "Took the flag";  
		private string m_returnmessage = "Returned the flag"; 	
		
		private bool m_FlagMustBeHome;
		private TimeSpan m_TimeOutDropFlag;
		private TimeSpan m_TimeOutHoldFlag;
		
		[CommandProperty( AccessLevel.GameMaster )]
		public Point3D Team1Start
		{
			get { return m_TeamxStart[0]; }
			set { m_TeamxStart[0] = value;Modify(); }
		}
		[CommandProperty( AccessLevel.GameMaster )]
		public Point3D Team2Start
		{
			get { return m_TeamxStart[1]; }
			set { m_TeamxStart[1] = value;Modify(); }
		}
		[CommandProperty( AccessLevel.GameMaster )]
		public Point3D Team3Start
		{
			get { return m_TeamxStart[2]; }
			set { m_TeamxStart[2] = value; Modify();}
		}
		[CommandProperty( AccessLevel.GameMaster )]
		public Point3D Team4Start
		{
			get { return m_TeamxStart[3]; }
			set { m_TeamxStart[3] = value;Modify(); }
		}
		
		
		[CommandProperty( AccessLevel.GameMaster )]
		public int MaxPoints
		{
			get { return m_maxpoints; }
			set { m_maxpoints = value;Modify(); }
		}
		
		
		[CommandProperty( AccessLevel.GameMaster )]
		public string Team1Name
		{
			get { return m_TeamxName[0]; }
			set { m_TeamxName[0] = value;Modify(); }
		}
		[CommandProperty( AccessLevel.GameMaster )]
		public string Team2Name
		{
			get { return m_TeamxName[1]; }
			set { m_TeamxName[1] = value; Modify();}
		}
		[CommandProperty( AccessLevel.GameMaster )]
		public string Team3Name
		{
			get { return m_TeamxName[2]; }
			set { m_TeamxName[2] = value;Modify(); }
		}
		[CommandProperty( AccessLevel.GameMaster )]
		public string Team4Name
		{
			get { return m_TeamxName[3]; }
			set { m_TeamxName[3] = value;Modify(); }
		}	

		[CommandProperty( AccessLevel.GameMaster )]
		public string MessageSteal
		{
			get { return m_stealmessage; }
			set { m_stealmessage = value;Modify(); }
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public string MessageReturn
		{
			get { return m_returnmessage; }
			set { m_returnmessage = value;Modify(); }
		}
		
		[CommandProperty( AccessLevel.GameMaster )]
		public bool FlagMustBeHome
		{
			get { return m_FlagMustBeHome; }
			set { m_FlagMustBeHome = value;Modify(); }
		}		

		
		[CommandProperty( AccessLevel.GameMaster )]
		public TimeSpan TimeOutDropFlag
		{
			get { return m_TimeOutDropFlag; }
			set { m_TimeOutDropFlag = value;Modify(); }
		}		
		
		[CommandProperty( AccessLevel.GameMaster )]
		public TimeSpan TimeOutHoldFlag
		{
			get { return m_TimeOutHoldFlag; }
			set { m_TimeOutHoldFlag = value; Modify();}
		}			
		
		
		
		[Constructable]
		public CtfEventController() : base()
		{
			

			//defaults:
			Team1Name="Blue Team";
			Team2Name="Red Team";
			Team3Name="Yellow Team";
			Team4Name="Green Team";		
		}
		
		/*OPTIONAL OVERRIDES
		protected override void OnPreStart() 						//when registration starts
		protected override void OnStartEvent()						//when event starts
		protected override void OnStopEvent()						//when event ends
		public override void StartTeleportMobile(Mobile mob)			//teleport mobile on event start
		public override void StopTeleportMobile(Mobile mob)			//teleport mobile on event end
		protected override void OnRegister(Mobile mob)				//when mob registers
		protected override void OnEventTick()						//while event is on
		public override bool RegionOnDamage(Mobile m, ref int damage)	//when mob is damaged
		public override bool RegionOnResurrect(Mobile m)				//when mob is rezed
		public override void RegionOnBeforeDeath(Mobile m)			//When mob dies
		public override bool RegionAllowBeneficial(Mobile from, Mobile target)	//return whether those mobs can attack each other or not
		public override bool RegionAllowHarmful(Mobile from, Mobile target)		//return whether those mobs can benifit each other or not
		public override int GetTeamHueOverride(int teamnum)			//get hue color for team
		public override string GetTeamName(int teamnum)				//get team name
		*/
		
		int flagtakenteam=0;
		
		public bool CanTakeFlag(int team)
		{
			return (flagtakenteam==team || flagtakenteam==0 || !FlagMustBeHome);
		}
		
		
		
		public void OnTakeFlag(int teamnum,Mobile taker)
		{
			if(teamnum<1 || teamnum>TeamsAmt)return;
			flagtakenteam=taker.Team;
			EventBroadcast(String.Format("{0}: {1}",GetTeamName(teamnum),MessageSteal),true);
			taker.SolidHueOverride=2045;
		}
		
		public void OnReturnFlag(int teamnum,bool showmsg)
		{
			if(teamnum<1 || teamnum>TeamsAmt)return;
			flagtakenteam=0;
			if(showmsg)EventBroadcast(String.Format("{0}: {1}",GetTeamName(teamnum),MessageReturn),true);
		}	

		public void OnCaptureFlag(int teamnum,Mobile scorer)
		{
			if(teamnum<1 || teamnum>TeamsAmt)return;
			
			flagtakenteam=0;
			
			if(scorer!=null)scorer.SolidHueOverride=GetTeamHueOverride(scorer.Team);
			
			bool stopctf=false;
			
			m_TeamxPoints[teamnum-1]++;
			
			if(m_TeamxPoints[teamnum-1]>=MaxPoints)
			{						
				EventBroadcast(String.Format("{0}: {1}",GetTeamName(teamnum),"Won the CTF!"),true);		
				stopctf=true;
			}			
			
			
			string stats="Stats: ";
			
			for(int i=1;i<=TeamsAmt;i++)stats += String.Format("{0}: {1} ",GetTeamName(i),m_TeamxPoints[i-1]);
			
		
			EventBroadcast(String.Format("{0}: {1}",GetTeamName(teamnum),"Scored a point!"),true);
			EventBroadcast(stats,true);
			
			if(stopctf)StopEvent();
		}		
		
		public static CtfFlag GetFlag(Mobile m)
		{
			Item armed = m.FindItemOnLayer(Layer.OneHanded);
			if(armed!=null && armed is CtfFlag)return (CtfFlag)armed;
			
			armed = m.FindItemOnLayer(Layer.TwoHanded);
			if(armed!=null && armed is CtfFlag)return (CtfFlag)armed;
			
			if(m.Backpack!=null)armed = m.Backpack.FindItemByType( typeof( CtfFlag ) ) as CtfFlag;
			
			return null;
		}
		
		


		
		public override bool RegionOnBeforeDeath(Mobile m)
		{			
			if(m.Team<1 || m.Team>TeamsAmt || m is BaseCreature)return true; //assume its someone outside of event
			
			m.IsFakeDead=true;
			
			//check if mob has flag, if yes, drop to ground
			if(m.Backpack!=null)
			{
				CtfFlag flag = GetFlag(m);
				
				if(flag!=null)
				{
					flag.DropToGround();
					m.SolidHueOverride=GetTeamHueOverride(m.Team);
				}
			}
			
			if(m.LastKiller==m)EventBroadcast(String.Format("{0} commited suicide",m.Name),true);
			else if(m.LastKiller!=null)EventBroadcast(String.Format("{0} was killed by {1}",m.Name,m.LastKiller.Name),true);
			else EventBroadcast(String.Format("{0} was killed",m.Name),true);
			
			//bring player back to start and rez
			
			new DeathTeleportTimer(this,m,m_TeamxStart[m.Team-1],TeleportStartMap,5).Start();
			
			
			return true;	
		}
		
		
		public override bool RegionOnDoubleClick(Mobile m, object o)
		{
			if(GetFlag(m)!=null && !(o is CtfFlag) && !(o is BaseDoor))
			{
				m.SendMessage("You cannot do that while you hold the flag!");
				return false;
			}
			return base.RegionOnDoubleClick(m, o);
		}
		
		
		public override bool RegionOnSkillUse(Mobile m, int skill)
		{
			if(GetFlag(m)!=null)
			{
				m.SendMessage("You cannot use skills while you hold the flag!");
				return false;
			}
			return base.RegionOnSkillUse(m, skill);
		}
		
		
		public override bool RegionOnBeginSpellCast(Mobile from, ISpell s)
		{		
			if(GetFlag(from)!=null)
			{
				from.SendMessage("You cannot cast spells while you hold the flag!");
				return false;
			}
			return base.RegionOnBeginSpellCast(from,s);
		}
		
		
		
		protected override void OnStopEvent()
		{
			for(int i=0;i<4;i++)m_TeamxPoints[i]=0;//reset points
		}
		
		
		public override void StartTeleportMobile(Mobile mob)
		{
			if(mob.Team<1 || mob.Team>4)return; //this should never happpen, but just in case...
		
			MoveMobile(mob,m_TeamxStart[mob.Team-1],TeleportStartMap);
		}


		public override int GetTeamHueOverride(int teamnum)
		{
			switch(teamnum)
			{
				case 1: return 97;
				case 2: return 37;
				case 3: return 53;
				case 4: return 67;
			}
			
			return -1;
		}
		
		
		
		
		
		public override string GetTeamName(int teamnum)
		{
			if(teamnum<0 || teamnum>TeamsAmt)return "undefined";
			
			return	m_TeamxName[teamnum-1];
		}
				
		

		protected override void OnEventTick()
		{
		
			//if(0.03>Utility.RandomDouble())StopEvent();
		}
				
		
		public CtfEventController( Serial serial ) : base( serial )
		{
		}

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			writer.Write( (int) 2 ); // version	

			
			writer.Write(m_TeamxStart[0]);
			writer.Write(m_TeamxStart[1]);
			writer.Write(m_TeamxStart[2]);
			writer.Write(m_TeamxStart[3]);
			
			writer.Write(m_TeamxPoints[0]);
			writer.Write(m_TeamxPoints[1]);
			writer.Write(m_TeamxPoints[2]);
			writer.Write(m_TeamxPoints[3]);
			
			writer.Write(m_TeamxName[0]);
			writer.Write(m_TeamxName[1]);
			writer.Write(m_TeamxName[2]);
			writer.Write(m_TeamxName[3]);	
			
			writer.Write(m_maxpoints);			

			writer.Write(m_stealmessage);
			writer.Write(m_returnmessage);
			writer.Write(m_FlagMustBeHome);
			
			writer.Write(m_TimeOutDropFlag);
			writer.Write(m_TimeOutHoldFlag);
			
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			int version = reader.ReadInt();	
			
			for(int i=0;i<4;i++)m_TeamxStart[i]=reader.ReadPoint3D();
			for(int i=0;i<4;i++)m_TeamxPoints[i]=reader.ReadInt();
			for(int i=0;i<4;i++)m_TeamxName[i]=reader.ReadString();
			
			m_maxpoints=reader.ReadInt();	
			m_stealmessage=reader.ReadString();	
			m_returnmessage=reader.ReadString();

			if(version>=1)m_FlagMustBeHome=reader.ReadBool();
			
			if(version>=2)
			{
			m_TimeOutDropFlag=reader.ReadTimeSpan();
			m_TimeOutHoldFlag=reader.ReadTimeSpan();
			}
		}		
		
		

	}

}