context: using System;
  using System.Collections;
  using Server;
  using Server.Targeting;
  using Server.Network;
  using Server.Mobiles;
  using Server.Factions;
  using Server.Spells;
  using Server.Spells.Spellweaving;
  
  namespace Server.SkillHandlers
  {
  	public class AnimalTaming
  	{
  		private static Hashtable m_BeingTamed = new Hashtable();
  
  		public static void Initialize()
  		{
  			SkillInfo.Table[(int)SkillName.AnimalTaming].Callback = new SkillUseCallback( OnUse );
  		}
  
  		private static bool m_DisableMessage;
  
  		public static bool DisableMessage
  		{
  			get{ return m_DisableMessage; }
  			set{ m_DisableMessage = value; }
  		}
  
  		public static TimeSpan OnUse( Mobile m )
  		{
  			m.RevealingAction();
  
  			m.Target = new InternalTarget();
  			m.RevealingAction();
  
  			if ( !m_DisableMessage )
  				m.SendLocalizedMessage( 502789 ); // Tame which animal?
  
  			return TimeSpan.FromHours( 6.0 );
  		}
  
  		public static bool CheckMastery( Mobile tamer, BaseCreature creature )
  		{
  			BaseCreature familiar = (BaseCreature)Spells.Necromancy.SummonFamiliarSpell.Table[tamer];
  
  			if ( familiar != null && !familiar.Deleted && familiar is DarkWolfFamiliar )
  			{
  				if ( creature is DireWolf || creature is GreyWolf || creature is TimberWolf || creature is WhiteWolf || creature is BakeKitsune )
  					return true;
  			}
  
  			return false;
  		}
  
  		public static bool MustBeSubdued( BaseCreature bc )
  		{
  			return bc.SubdueBeforeTame && (bc.Hits > (bc.HitsMax / 10));
  		}
  
  		public static void ScaleStats( BaseCreature bc, double scalar )
  		{
  			if ( bc.RawStr > 0 )
  				bc.RawStr = (int)Math.Max( 1, bc.RawStr * scalar );
  
  			if ( bc.RawDex > 0 )
  				bc.RawDex = (int)Math.Max( 1, bc.RawDex * scalar );
  
  			if ( bc.RawInt > 0 )
  				bc.RawInt = (int)Math.Max( 1, bc.RawInt * scalar );
  
  			if ( bc.HitsMaxSeed > 0 )
  			{
  				bc.HitsMaxSeed = (int)Math.Max( 1, bc.HitsMaxSeed * scalar );
  				bc.Hits = bc.Hits;
  				}
  
  			if ( bc.StamMaxSeed > 0 )
  			{
  				bc.StamMaxSeed = (int)Math.Max( 1, bc.StamMaxSeed * scalar );
  				bc.Stam = bc.Stam;
  			}
  		}
  
  		public static void ScaleSkills( BaseCreature bc, double scalar )
  		{
  			ScaleSkills( bc, scalar, scalar );
  		}
  
  		public static void ScaleSkills( BaseCreature bc, double scalar, double capScalar )
  		{
  			for ( int i = 0; i < bc.Skills.Length; ++i )
  			{
  				bc.Skills[i].Base *= scalar;
  
  				bc.Skills[i].Cap = Math.Max( 100.0, bc.Skills[i].Cap * capScalar );
  
  				if ( bc.Skills[i].Base > bc.Skills[i].Cap )
  				{
  					bc.Skills[i].Cap = bc.Skills[i].Base;
  				}
  			}
  		}
  
  		private class InternalTarget : Target
  		{
  			private bool m_SetSkillTime = true;
  
  			public InternalTarget() :  base ( 2, false, TargetFlags.None )
  			{
  			}
  
  			protected override void OnTargetFinish( Mobile from )
  			{
  				if ( m_SetSkillTime )
  					from.NextSkillTime = DateTime.Now;
  			}
  
  			protected override void OnTarget( Mobile from, object targeted )
  			{
  				from.RevealingAction();
  
  				if ( targeted is Mobile )
  				{
  					if ( targeted is BaseCreature )
  					{
  						BaseCreature creature = (BaseCreature)targeted;
  
  						if ( !creature.Tamable )
  						{
  							creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1049655, from.NetState ); // That creature cannot be tamed.
  						}
  						else if ( creature.Controlled )
  						{
  							creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502804, from.NetState ); // That animal looks tame already.
  						}
  						else if ( from.Female && !creature.AllowFemaleTamer )
  						{
  							creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1049653, from.NetState ); // That creature can only be tamed by males.
  						}
  						else if ( !from.Female && !creature.AllowMaleTamer )
  						{
  							creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1049652, from.NetState ); // That creature can only be tamed by females.
  						}
  						else if ( creature is CuSidhe && from.Race != Race.Elf )
  						{
  							creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502801, from.NetState ); // You can't tame that!
  						}
  						else if ( from.Followers + creature.ControlSlots > from.FollowersMax )
  						{
  							from.SendLocalizedMessage( 1049611 ); // You have too many followers to tame that creature.
  						}
  						else if ( creature.Owners.Count >= BaseCreature.MaxOwners && !creature.Owners.Contains( from ) )
  						{
  							creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1005615, from.NetState ); // This animal has had too many owners and is too upset for you to tame.
  						}
  						else if ( MustBeSubdued( creature ) )
  						{
  							creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1054025, from.NetState ); // You must subdue this creature before you can tame it!
  						}
  						else if ( CheckMastery( from, creature ) || from.Skills[SkillName.AnimalTaming].Value >= creature.MinTameSkill )
  						{
  							FactionWarHorse warHorse = creature as FactionWarHorse;
  
  							if ( warHorse != null )
  							{
  								Faction faction = Faction.Find( from );
  
  								if ( faction == null || faction != warHorse.Faction )
  								{
  									creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1042590, from.NetState ); // You cannot tame this creature.
  									return;
  								}
  							}
  
  							if ( m_BeingTamed.Contains( targeted ) )
  							{
  								creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502802, from.NetState ); // Someone else is already taming this.
  							}
  							else if ( creature.CanAngerOnTame && 0.95 >= Utility.RandomDouble() )
  							{
  								creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502805, from.NetState ); // You seem to anger the beast!
  								creature.PlaySound( creature.GetAngerSound() );
  								creature.Direction = creature.GetDirectionTo( from );
  								if ( from is PlayerMobile && !(( (PlayerMobile)from ).HonorActive || TransformationSpellHelper.UnderTransformation( from, typeof( EtherealVoyageSpell ))))
  									creature.Combatant = from;
  							}
  							else
  							{
  								m_BeingTamed[targeted] = from;
  
  								from.LocalOverheadMessage( MessageType.Emote, 0x59, 1010597 ); // You start to tame the creature.
  								from.NonlocalOverheadMessage( MessageType.Emote, 0x59, 1010598 ); // *begins taming a creature.*
  
  								new InternalTimer( from, creature, Utility.Random( 3, 2 ) ).Start();
  
  								m_SetSkillTime = false;
  							}
  						}
  						else
  						{
  							creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502806, from.NetState ); // You have no chance of taming this creature.
  						}
  					}
  					else
  					{
  						((Mobile)targeted).PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502469, from.NetState ); // That being cannot be tamed.
  					}
  				}
  				else
  				{
  
gt: 					from.SendLocalizedMessage( 502801 ); // You can't tame that!