using System; using System.Collections.Generic; using Server; using Server.Engines.Craft; using Server.Network; namespace Server.Items { public enum ClothingQuality { Low, Regular, Exceptional } public interface IArcaneEquip { bool IsArcane{ get; } int CurArcaneCharges{ get; set; } int MaxArcaneCharges{ get; set; } } public abstract class BaseClothing : Item, IDyable, IScissorable, ICraftable { private Mobile m_Crafter; private ClothingQuality m_Quality; private bool m_PlayerConstructed; protected CraftResource m_Resource; private int m_StrBonus = -1, m_DexBonus = -1, m_IntBonus = -1; public virtual int UOStrBonus{ get{ return 0; } } public virtual int UODexBonus{ get{ return 0; } } public virtual int UOIntBonus{ get{ return 0; } } [CommandProperty( AccessLevel.GameMaster )] public int StrBonus { get{ return ( m_StrBonus == -1 ? UOStrBonus : m_StrBonus ); } set{ m_StrBonus = value; InvalidateProperties(); } } [CommandProperty( AccessLevel.GameMaster )] public int DexBonus { get{ return ( m_DexBonus == -1 ? UODexBonus : m_DexBonus ); } set{ m_DexBonus = value; InvalidateProperties(); } } [CommandProperty( AccessLevel.GameMaster )] public int IntBonus { get{ return ( m_IntBonus == -1 ? UOIntBonus : m_IntBonus ); } set{ m_IntBonus = value; InvalidateProperties(); } } [CommandProperty( AccessLevel.GameMaster )] public Mobile Crafter { get{ return m_Crafter; } set{ m_Crafter = value; InvalidateProperties(); } } [CommandProperty( AccessLevel.GameMaster )] public ClothingQuality Quality { get{ return m_Quality; } set{ m_Quality = value; InvalidateProperties(); } } [CommandProperty( AccessLevel.GameMaster )] public bool PlayerConstructed { get{ return m_PlayerConstructed; } set{ m_PlayerConstructed = value; } } public virtual CraftResource DefaultResource{ get{ return CraftResource.None; } } [CommandProperty( AccessLevel.GameMaster )] public CraftResource Resource { get{ return m_Resource; } set{ m_Resource = value; Hue = CraftResources.GetHue( m_Resource ); InvalidateProperties(); } } public override bool CanEquip( Mobile from ) { if( from.AccessLevel < AccessLevel.GameMaster ) { if( !AllowMaleWearer && !from.Female ) { if( AllowFemaleWearer ) from.SendLocalizedMessage( 1010388 ); // Only females can wear this. else from.SendMessage( "You may not wear this." ); return false; } else if( !AllowFemaleWearer && from.Female ) { if( AllowMaleWearer ) from.SendLocalizedMessage( 1063343 ); // Only males can wear this. else from.SendMessage( "You may not wear this." ); return false; } } return base.CanEquip( from ); } public virtual bool AllowMaleWearer{ get{ return true; } } public virtual bool AllowFemaleWearer{ get{ return true; } } public virtual bool CanBeBlessed{ get{ return true; } } public int ComputeStatBonus( StatType type ) { if ( type == StatType.Str ) return StrBonus; else if ( type == StatType.Dex ) return DexBonus; else return IntBonus; } public virtual void AddStatBonuses( Mobile parent ) { if ( parent == null ) return; int strBonus = ComputeStatBonus( StatType.Str ); int dexBonus = ComputeStatBonus( StatType.Dex ); int intBonus = ComputeStatBonus( StatType.Int ); if ( strBonus == 0 && dexBonus == 0 && intBonus == 0 ) return; string modName = this.Serial.ToString(); if ( strBonus != 0 ) parent.AddStatMod( new StatMod( StatType.Str, modName + "Str", strBonus, TimeSpan.Zero ) ); if ( dexBonus != 0 ) parent.AddStatMod( new StatMod( StatType.Dex, modName + "Dex", dexBonus, TimeSpan.Zero ) ); if ( intBonus != 0 ) parent.AddStatMod( new StatMod( StatType.Int, modName + "Int", intBonus, TimeSpan.Zero ) ); } public static void ValidateMobile( Mobile m ) { for ( int i = m.Items.Count - 1; i >= 0; --i ) { if ( i >= m.Items.Count ) continue; Item item = m.Items[i]; if ( item is BaseClothing ) { BaseClothing clothing = (BaseClothing)item; if ( !clothing.AllowMaleWearer && !m.Female && m.AccessLevel < AccessLevel.GameMaster ) { if ( clothing.AllowFemaleWearer ) m.SendLocalizedMessage( 1010388 ); // Only females can wear this. else m.SendMessage( "You may not wear this." ); m.AddToBackpack( clothing ); } else if ( !clothing.AllowFemaleWearer && m.Female && m.AccessLevel < AccessLevel.GameMaster ) { if ( clothing.AllowMaleWearer ) m.SendLocalizedMessage( 1063343 ); // Only males can wear this. else m.SendMessage( "You may not wear this." ); m.AddToBackpack( clothing ); } } } } public BaseClothing( int itemID, Layer layer ) : this( itemID, layer, 0 ) { } public BaseClothing( int itemID, Layer layer, int hue ) : base( itemID ) { Layer = layer; Hue = hue; m_Resource = DefaultResource; m_Quality = ClothingQuality.Regular; } public override void OnAfterDuped( Item newItem ) { BaseClothing clothing = newItem as BaseClothing; if ( clothing == null ) return; } public BaseClothing( Serial serial ) : base( serial ) { } public override bool AllowEquipedCast( Mobile from ) { return true; } public override bool CheckPropertyConfliction( Mobile m ) { if ( base.CheckPropertyConfliction( m ) ) return true; if ( Layer == Layer.Pants ) return ( m.FindItemOnLayer( Layer.InnerLegs ) != null ); if ( Layer == Layer.Shirt ) return ( m.FindItemOnLayer( Layer.InnerTorso ) != null ); return false; } public override bool OnEquip( Mobile from ) { from.CheckStatTimers(); int strBonus = ComputeStatBonus( StatType.Str ); int dexBonus = ComputeStatBonus( StatType.Dex ); int intBonus = ComputeStatBonus( StatType.Int ); if ( strBonus != 0 || dexBonus != 0 || intBonus != 0 ) { string modName = this.Serial.ToString(); if ( strBonus != 0 ) from.AddStatMod( new StatMod( StatType.Str, modName + "Str", strBonus, TimeSpan.Zero ) ); if ( dexBonus != 0 ) from.AddStatMod( new StatMod( StatType.Dex, modName + "Dex", dexBonus, TimeSpan.Zero ) ); if ( intBonus != 0 ) from.AddStatMod( new StatMod( StatType.Int, modName + "Int", intBonus, TimeSpan.Zero ) ); } return base.OnEquip( from ); } public override void OnAdded( object parent ) { Mobile mob = parent as Mobile; if ( mob != null ) { AddStatBonuses( mob ); mob.CheckStatTimers(); } base.OnAdded( parent ); } public override void OnRemoved( object parent ) { if ( parent is Mobile ) { Mobile m = (Mobile)parent; string modName = this.Serial.ToString(); m.RemoveStatMod( modName + "Str" ); m.RemoveStatMod( modName + "Dex" ); m.RemoveStatMod( modName + "Int" ); m.CheckStatTimers(); } base.OnRemoved( parent ); } private string GetNameString() { string name = this.Name; if ( name == null ) name = String.Format( "#{0}", LabelNumber ); return name; } public override void GetProperties( ObjectPropertyList list ) { base.GetProperties( list ); if ( m_Crafter != null ) list.Add( 1050043, m_Crafter.Name ); // crafted by ~1_NAME~ if ( m_Quality == ClothingQuality.Exceptional ) list.Add( 1060636 ); // exceptional if ( m_StrBonus > 0 && m_StrBonus < 3 ) list.Add( 1038027 ); // Great Strength else if ( m_StrBonus > 2 && m_StrBonus < 5 ) list.Add( 1038028 ); // Greater Strength else if ( m_StrBonus > 4 ) list.Add( 1038029 ); // Ultimate Strength if ( m_DexBonus > 0 && m_DexBonus < 3 ) list.Add( 1038033 ); // Great Agility else if ( m_DexBonus > 2 && m_DexBonus < 5 ) list.Add( 1038034 ); // Greater Agility else if ( m_DexBonus > 4 ) list.Add( 1038035 ); // Ultimate Agility if ( m_IntBonus > 0 && m_IntBonus < 3 ) list.Add( 1038030 ); // Great Intellect else if ( m_IntBonus > 2 && m_IntBonus < 5 ) list.Add( 1038031 ); // Greater Intellect else if ( m_IntBonus > 4 ) list.Add( 1038032 ); // Ultimate Intellect if ( Magical > 0 && Uses > 0 ) { list.Add( 1062520, "\t#{0}", Magical ); } if ( Uses > 0 && Server.Misc.Settings.DisplayInfo() ) { if ( Uses > 1 ) list.Add( 1062516, "{0}", Uses ); else list.Add( 1062517, "{0}", Uses ); } else if ( Uses > 0 ) { double usage = (double)Uses / (double)UsesMax; if ( usage > 0.95 ) list.Add( 1063269 ); // Fully Charged else if ( usage > 0.75 ) list.Add( 1063270 ); // Mostly Charged else if ( usage > 0.50 ) list.Add( 1063271 ); // Partially Charged else if ( usage > 0.25 ) list.Add( 1063272 ); // Somewhat Charged else if ( usage > 0.05 ) list.Add( 1063273 ); // Barely Charged else list.Add( 1063274 ); // Almost Drained } } #region Serialization private static void SetSaveFlag( ref SaveFlag flags, SaveFlag toSet, bool setIf ) { if ( setIf ) flags |= toSet; } private static bool GetSaveFlag( SaveFlag flags, SaveFlag toGet ) { return ( (flags & toGet) != 0 ); } [Flags] private enum SaveFlag { None = 0x00000000, Resource = 0x00000001, PlayerConstructed = 0x00000002, Crafter = 0x00000004, Quality = 0x00000008, StrBonus = 0x00000010, DexBonus = 0x00000020, IntBonus = 0x00000040 } public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); writer.Write( (int) 0 ); // version SaveFlag flags = SaveFlag.None; SetSaveFlag( ref flags, SaveFlag.Resource, m_Resource != DefaultResource ); SetSaveFlag( ref flags, SaveFlag.PlayerConstructed, m_PlayerConstructed != false ); SetSaveFlag( ref flags, SaveFlag.Crafter, m_Crafter != null ); SetSaveFlag( ref flags, SaveFlag.Quality, m_Quality != ClothingQuality.Regular ); SetSaveFlag( ref flags, SaveFlag.StrBonus, m_StrBonus != -1 ); SetSaveFlag( ref flags, SaveFlag.DexBonus, m_DexBonus != -1 ); SetSaveFlag( ref flags, SaveFlag.IntBonus, m_IntBonus != -1 ); writer.WriteEncodedInt( (int) flags ); if ( GetSaveFlag( flags, SaveFlag.Resource ) ) writer.WriteEncodedInt( (int) m_Resource ); if ( GetSaveFlag( flags, SaveFlag.PlayerConstructed ) ) writer.Write( (bool) m_PlayerConstructed ); if ( GetSaveFlag( flags, SaveFlag.Crafter ) ) writer.Write( (Mobile) m_Crafter ); if ( GetSaveFlag( flags, SaveFlag.Quality ) ) writer.WriteEncodedInt( (int) m_Quality ); if ( GetSaveFlag( flags, SaveFlag.StrBonus ) ) writer.WriteEncodedInt( (int) m_StrBonus ); if ( GetSaveFlag( flags, SaveFlag.DexBonus ) ) writer.WriteEncodedInt( (int) m_DexBonus ); if ( GetSaveFlag( flags, SaveFlag.IntBonus ) ) writer.WriteEncodedInt( (int) m_IntBonus ); } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); SaveFlag flags = (SaveFlag)reader.ReadEncodedInt(); if ( GetSaveFlag( flags, SaveFlag.Resource ) ) m_Resource = (CraftResource)reader.ReadEncodedInt(); else m_Resource = DefaultResource; if ( GetSaveFlag( flags, SaveFlag.PlayerConstructed ) ) m_PlayerConstructed = true; if ( GetSaveFlag( flags, SaveFlag.Crafter ) ) m_Crafter = reader.ReadMobile(); if ( GetSaveFlag( flags, SaveFlag.Quality ) ) m_Quality = (ClothingQuality)reader.ReadEncodedInt(); else m_Quality = ClothingQuality.Regular; if ( GetSaveFlag( flags, SaveFlag.StrBonus ) ) m_StrBonus = reader.ReadEncodedInt(); else m_StrBonus = -1; if ( GetSaveFlag( flags, SaveFlag.DexBonus ) ) m_DexBonus = reader.ReadEncodedInt(); else m_DexBonus = -1; if ( GetSaveFlag( flags, SaveFlag.IntBonus ) ) m_IntBonus = reader.ReadEncodedInt(); else m_IntBonus = -1; Mobile parent = Parent as Mobile; if ( parent != null ) { AddStatBonuses( parent ); parent.CheckStatTimers(); } } #endregion public virtual bool Dye( Mobile from, DyeTub sender ) { if ( Deleted ) return false; else if ( RootParent is Mobile && from != RootParent ) return false; Hue = sender.DyedHue; return true; } public virtual bool Scissor( Mobile from, Scissors scissors ) { if ( !IsChildOf( from.Backpack ) ) { from.SendLocalizedMessage( 502437 ); // Items you wish to cut must be in your backpack. return false; } CraftSystem system = DefTailoring.CraftSystem; CraftItem item = system.CraftItems.SearchFor( GetType() ); if ( item != null && item.Resources.Count == 1 && item.Resources.GetAt( 0 ).Amount >= 2 ) { try { Type resourceType = null; CraftResourceInfo info = CraftResources.GetInfo( m_Resource ); if ( info != null && info.ResourceTypes.Length > 0 ) resourceType = info.ResourceTypes[0]; if ( resourceType == null ) resourceType = item.Resources.GetAt( 0 ).ItemType; Item res = (Item)Activator.CreateInstance( resourceType ); ScissorHelper( from, res, m_PlayerConstructed ? (item.Resources.GetAt( 0 ).Amount / 2) : 1 ); res.LootType = LootType.Regular; return true; } catch { } } from.SendLocalizedMessage( 502440 ); // Scissors can not be used on that to produce anything. return false; } #region ICraftable Members public virtual int OnCraft( int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, CraftItem craftItem, int resHue ) { Quality = (ClothingQuality)quality; if ( makersMark ) Crafter = from; if ( DefaultResource != CraftResource.None ) { Type resourceType = typeRes; if ( resourceType == null ) resourceType = craftItem.Resources.GetAt( 0 ).ItemType; Resource = CraftResources.GetFromType( resourceType ); } else { Hue = resHue; } PlayerConstructed = true; CraftContext context = craftSystem.GetContext( from ); if ( context != null && context.DoNotColor ) Hue = 0; return quality; } #endregion } }