All pastes #68815 Raw Edit

Asmir

public text v1 · immutable
#68815 ·published 2006-06-22 03:36 UTC
rendered paste body
using System;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Commands;
using Server.Network;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Regions;

namespace Server.DuelSystem
{
	public class DuelingPit : Item
	{
		private static ArrayList m_Pits = new ArrayList();
		public static ArrayList Pits{ get{ return m_Pits; } }
		
		#region Properties
		private Arena m_Arena;
		private Announcer m_Announcer;
		private Wall m_Wall;
		private DuelRegion m_DuelRegion;
		private BufferRegion m_BufferRegion;
		private ContenderInfo m_Challenger, m_Defender;
		private ArrayList m_Contenders;
		private bool m_InUse, m_InProgress, m_Disposing;
		private Timer m_Timer;
		private Hashtable m_Damage;

		public Arena Arena{ get{ return m_Arena; } }
		public bool Disposing{ get{ return m_Disposing; } }
		public bool InUse{ get{ return m_InUse; } set{ m_InUse = value; } }
		public BufferRegion BufferRegion{ get{ return m_BufferRegion; } }

		public ArrayList Contenders
		{
			get
			{
				if ( m_Contenders == null )
					m_Contenders = new ArrayList( 2 );
				
				return m_Contenders;
			}
		}
		
		public bool InProgress
		{
			get{ return m_InProgress; }
			set
			{
				m_InProgress = value;

				foreach ( Mobile m in Contenders )
					m.Delta( MobileDelta.Noto );
			}
		}

		[CommandProperty(AccessLevel.GameMaster)]
		public bool ForceDispose
		{
			get{ return false; }
			set
			{
				if ( m_InUse && value )
					Dispose();

			}
		}
		#endregion
		
		#region Constructors
		[Constructable]
		public DuelingPit() : base( 0x1BC3 )
		{
			Name = "pit control";

			Movable = false;
			Visible = false;
			
			m_Contenders = new ArrayList( 2 );
			m_Damage = new Hashtable( 2 );
			
			m_Arena = new Arena( this );
			m_Announcer = new Announcer( this );
			m_DuelRegion = new DuelRegion( this );
			m_BufferRegion = new BufferRegion( this );

			UpdateRegions();
			
			m_Pits.Add( this );
		}
		
		public DuelingPit( Serial serial ) : base( serial )
		{
		}
		#endregion
		
		#region Serialization
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			
			writer.Write( (int)1 );
			
			writer.Write( m_Challenger != null );
			if ( m_Challenger != null )
				m_Challenger.Serialize( writer );
			
			writer.Write( m_Defender != null );
			if ( m_Defender != null )
				m_Defender.Serialize( writer );

			writer.Write( m_Arena );
			writer.Write( m_Announcer );
			writer.Write( m_Wall );
			
		}
		
		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			
			int version = reader.ReadInt();
			
			switch( version )
			{
				case 1:
				{
					if ( reader.ReadBool() )
						m_Challenger = new ContenderInfo( reader );

					if ( reader.ReadBool() )
						m_Defender = new ContenderInfo( reader );

					goto case 0;
				}
				case 0:
				{
					m_Arena = reader.ReadItem() as Arena;
					m_Announcer = reader.ReadMobile() as Announcer;
					m_Wall = reader.ReadItem() as Wall;

					break;
				}
			}
			
			if ( m_Wall != null )
				m_Wall.Delete();
			
			m_DuelRegion = new DuelRegion( this );
			Region.AddRegion( m_DuelRegion );
			
			m_BufferRegion = new BufferRegion( this );
			Region.AddRegion( m_BufferRegion );

			UpdateRegions();

			m_Contenders = new ArrayList( 2 );
			m_Damage = new Hashtable( 2 );

			m_Pits.Add( this );
		}
		#endregion
		
		#region Methods
		public static DuelingPit FindOpenPit()
		{
			for ( int i = 0; i < Pits.Count; ++i )
			{
				if ( i >= m_Pits.Count )
					break;
				
				DuelingPit pit = (DuelingPit)Pits[i];
				
				if ( pit != null )
				{
					if ( pit.Map == null || pit.Map == Map.Internal )
						pit.Delete();
					else if ( !pit.InUse )
						return pit;
				}
			}
			
			return null;
		}
		
		private void OnTick_Callback( object state )
		{
			((ConfirmationMoongate)state).Delete();
		}
		
		public void Begin( ChallengeRequest request )
		{
			if ( request == null || request.Challenger == null || request.Defender == null )
				return;
			
			m_InUse = true;
			
			Contenders.Add( request.Challenger );
			Contenders.Add( request.Defender );
			
			m_Wall = new Wall();
			m_Wall.MoveToWorld( Location, Map );
			
			m_Challenger = new ContenderInfo( request.Challenger, new Point3D( X-3, Y, Z ), Map );
			m_Defender = new ContenderInfo( request.Defender, new Point3D( X+3, Y, Z ), Map );
			
			ConfirmationMoongate gate = new ConfirmationMoongate( m_DuelRegion.GoLocation, Map );
			gate.ItemID = 0x1FD4;
			gate.GumpWidth = 300;
			gate.GumpHeight = 100;
			gate.TitleNumber = 1062051;
			gate.TitleColor = 30720;
			gate.MessageString = "Do you wish to spectate this duel?";
			gate.MessageColor = 0xFFC000;
			
			gate.MoveToWorld( m_Challenger.ReturnPos, m_Challenger.ReturnMap );
			
			Timer.DelayCall( TimeSpan.FromSeconds( 10.0 ), new TimerStateCallback( OnTick_Callback ), gate );
			
			Announce( "The duel will start in six seconds!" );
			
			m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 6.5 ), new TimerCallback( Fight ) );
		}
		
		public void Fight()
		{
			if ( m_Disposing )
				return;
			
			Announce( "GO! GO! GO!" );
			
			if ( m_Wall != null )
				m_Wall.Delete();
			
			foreach ( Mobile m in Contenders )
				m.Frozen = false;
			
			InProgress = true;
			
			if ( Config.UseEndTimer )
				m_Timer = Timer.DelayCall( TimeSpan.FromMinutes( 5.0 ), new TimerCallback( End ) );
		}

		public void End()
		{
			if ( m_Disposing || !m_InProgress )
				return;

			InProgress = false;

			if ( m_Timer != null )
				m_Timer.Stop();
			
			RealmPlayer champion = GetChampion();
			
			int num = -3;
			foreach ( Mobile m in Contenders )
			{
				m.Frozen = true;
				DuelHelper.RemoveSpellEffects( m );
				m.MoveToWorld( new Point3D( X+num, Y, Z ), Map );
				num += 6;
			}
			
			foreach ( RealmPlayer m in Contenders )
			{
				if ( champion != null )
				{
					Timer.DelayCall( TimeSpan.FromSeconds( 2.0 ), new TimerStateCallback( Message_Callback ), new object[] {m, (champion == m)} );

					if ( champion != m )
						DuelHelper.CalculatePoints( champion, m );
				}
			}
			
			if ( champion == null )
				Announce( "The match has ended in a draw!" );
			else
				Announce( "{0} has won the match!", champion.Name );
			
			m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), new TimerCallback( Dispose ) );
		}
		
		public void Dispose()
		{
			if ( m_Disposing )
				return;
			
			m_Disposing = true;
			
			if ( m_Wall != null )
				m_Wall.Delete();
			
			if ( m_Timer != null )
				m_Timer.Stop();
			
			if ( m_Challenger != null )
				m_Challenger.ReturnHome();
			
			if ( m_Defender != null )
				m_Defender.ReturnHome();
			
			m_Challenger = null;
			m_Defender = null;
			
			InProgress = false;
			
			foreach ( RealmPlayer m in Contenders )
				m.SetCanRegenHits( true );
			
			Contenders.Clear();
			m_Damage.Clear();
			
			m_InUse = m_Disposing = false;
		}
		
		private void Message_Callback( object state )
		{
			object[] objects = (object[])state;
			Mobile from = (Mobile)objects[0];
			bool isChampion = (bool)objects[1];
			
			if ( isChampion )
				from.PublicOverheadMessage( Network.MessageType.Regular, 0x44 , false, "You are the winner!" );
			else
				from.PublicOverheadMessage( Network.MessageType.Regular, 0x20, false, "You have lost the duel." );
		}
		
		private RealmPlayer GetChampion()
		{
			RealmPlayer mob = null;
			foreach ( RealmPlayer m in Contenders )
			{
				if ( mob == null )
				{
					mob = m;
					continue;
				}
				
				if ( Config.UseEndTimer && mob.Hits > 0 && m.Hits > 0 )
				{
					if ( GetDamage( m ) == GetDamage( mob ) )
						mob = null;
					else if ( GetDamage( m ) > GetDamage( mob ) )
						mob = m;
				}
				else if ( m.Hits == mob.Hits )
					mob = null;
				else if ( m.Hits > mob.Hits )
				mob = m;
					
			}
			
			return mob;
		}
		
		private int GetDamage( Mobile from )
		{
			object o = m_Damage[from];
			
			if ( o == null )
				return 0;
			
			return (int)o;
		}
		
		public void AddDamage( Mobile from, int damage )
		{
			if ( Config.UseEndTimer )
				return;
			
			int num = 0;
			object o = m_Damage[from];
			
			if ( o != null )
				num = (int)o;
			
			num += damage;
			m_Damage[from] = num;
		}
		
		public bool IsContender( Mobile m )
		{
			if ( m_Contenders.Contains( m ) )
				return true;
			
			return false;
		}
		
		public void UpdateRegions()
		{
			ArrayList coords = new ArrayList();
			coords.Add( new Rectangle2D( X-5, Y-5, 11, 11 ) );
			
			m_DuelRegion.Coords = coords;
			
			m_DuelRegion.GoLocation = new Point3D( X+6, Y-6, Z+5 );
			m_DuelRegion.MinZ = Z;
			
			coords = new ArrayList();
			coords.Add( new Rectangle2D( X-20, Y-20, 40, 40 ) );
			
			m_BufferRegion.Coords = coords;
		}
		
		public void Announce( string format, params object[] args )
		{
			Announce( String.Format( format, args ) );
		}
		
		public void Announce( string message )
		{
			if ( m_Announcer == null )
				return;

			m_Announcer.Yell( message );
		}
		#endregion

		public override void OnDoubleClick( Mobile from )
		{
			if ( m_InUse && from.AccessLevel > AccessLevel.Counselor )
			{
				Dispose();
				from.SendMessage( "You have terminated the match!" );
			}
		}

		public override void OnLocationChange( Point3D oldLocation )
		{
			if ( Deleted )
				return;

			if ( m_InUse )
				Dispose();

			if ( m_Arena != null )
				m_Arena.MoveToWorld( Location, Map );
			
			if ( m_Announcer != null )
				m_Announcer.MoveToWorld( new Point3D( X, Y-6, Z+5) , Map );

			UpdateRegions();
		}
		
		public override void OnMapChange()
		{
			if ( Deleted )
				return;

			if ( m_InUse )
				Dispose();

			if ( m_Arena != null )
				m_Arena.Map = Map;

			if ( m_Announcer != null )
				m_Announcer.Map = Map;

			if ( m_DuelRegion != null )
				m_DuelRegion.Map = Map;

			if ( m_BufferRegion != null )
				m_BufferRegion.Map = Map;
			
			UpdateRegions();
		}
		
		public override void OnAfterDelete()
		{
			base.OnAfterDelete();
			
			if ( m_InUse )
				Dispose();

			if ( m_Arena != null )
				m_Arena.Delete();

			if ( m_Announcer != null )
				m_Announcer.Delete();

			if ( m_DuelRegion != null )
				Region.RemoveRegion( m_DuelRegion );

			if ( m_BufferRegion != null )
				Region.RemoveRegion( m_BufferRegion );
			
			if ( m_Pits.Contains( this ) )
				m_Pits.Remove( this );
		}
	}
}