using System.Collections.Generic; using System.Linq; using System; using Server.Engines.Craft; using Server.Items; using Server.Targeting; using Server.Engines.VeteranRewards; using Server.SkillHandlers; namespace Server.Engines.Craft { [AttributeUsage(AttributeTargets.Class)] public class AlterableAttribute : Attribute { public Type CraftSystem { get; private set; } public Type AlteredType { get; private set; } public bool Inherit { get; private set; } public AlterableAttribute(Type craftSystem, Type alteredType, bool inherit = false) { CraftSystem = craftSystem; AlteredType = alteredType; Inherit = inherit; } /// /// this enables any craftable item where their parent class can be altered, can be altered too. /// This is mainly for the ML craftable artifacts. /// /// public bool CheckInherit(Type original) { if (Inherit) return true; var system = CraftContext.Systems.FirstOrDefault(sys => sys.GetType() == CraftSystem); if (system != null) { return system.CraftItems.SearchFor(original) != null; } return false; } } public class AlterItem { public static void BeginTarget(Mobile from, CraftSystem system, ITool tool) { from.Target = new AlterItemTarget(system, tool); from.SendLocalizedMessage(1094730); //Target the item to altar } public static void BeginTarget(Mobile from, CraftSystem system, Item contract) { from.Target = new AlterItemTarget(system, contract); from.SendLocalizedMessage(1094730); //Target the item to altar } } public class AlterItemTarget : Target { private readonly CraftSystem m_System; private readonly ITool m_Tool; private Item m_Contract; public AlterItemTarget(CraftSystem system, Item contract) : base(2, false, TargetFlags.None) { m_System = system; m_Contract = contract; } public AlterItemTarget(CraftSystem system, ITool tool) : base(1, false, TargetFlags.None) { this.m_System = system; this.m_Tool = tool; } private static AlterableAttribute GetAlterableAttribute(object o, bool inherit) { Type t = o.GetType(); object[] attrs = t.GetCustomAttributes(typeof(AlterableAttribute), inherit); if (attrs != null && attrs.Length > 0) { AlterableAttribute attr = attrs[0] as AlterableAttribute; if (attr != null && (!inherit || attr.CheckInherit(t))) return attr; } return null; } protected override void OnTarget(Mobile from, object o) { int number = -1; Item origItem = o as Item; SkillName skill = m_System.MainSkill; double value = from.Skills[skill].Value; var alterInfo = GetAlterableAttribute(o, false); if (alterInfo == null) { alterInfo = GetAlterableAttribute(o, true); } if (origItem == null || !origItem.IsChildOf(from.Backpack)) { number = 1094729; // The item must be in your backpack for you to alter it. } else if (origItem is BlankScroll) { if (m_Contract == null) { if (value >= 100.0) { Item contract = null; if (skill == SkillName.Blacksmith) contract = new AlterContract(RepairSkillType.Smithing, from); else if (skill == SkillName.Carpentry) contract = new AlterContract(RepairSkillType.Carpentry, from); else if (skill == SkillName.Tailoring) contract = new AlterContract(RepairSkillType.Tailoring, from); else if (skill == SkillName.Tinkering) contract = new AlterContract(RepairSkillType.Tinkering, from); if (contract != null) { from.AddToBackpack(contract); number = 1044154; // You create the item. // Consume a blank scroll origItem.Consume(); } } else { number = 1111869; // You must be at least grandmaster level to create an alter service contract. } } else { number = 1094728; // You may not alter that item. } } else if (alterInfo == null) { number = 1094728; // You may not alter that item. } else if (!IsAlterable(origItem)) { number = 1094728; // You may not alter that item. } else if (alterInfo.CraftSystem != m_System.GetType()) { if (m_Tool != null) { // You may not alter that item. number = 1094728; } else { // You cannot alter that item with this type of alter contract. number = 1094793; } } else if (!Server.SkillHandlers.Imbuing.CheckSoulForge(from, 2, false, false)) { number = 1111867; // You must be near a soulforge to alter an item. } else if (m_Contract == null && value < 100.0) { number = 1111870; // You must be at least grandmaster level to alter an item. } else if (origItem is BaseWeapon && ((BaseWeapon)origItem).EnchantedWeilder != null) { number = 1111849; // You cannot alter an item that is currently enchanted. } else if (origItem.HasSocket()) { var socket = origItem.GetSocket(); if (socket.Slayer == SlayerName.Silver) { number = 1155681; // You cannot alter an item that has been treated with Tincture of Silver. } else { number = 1111849; // You cannot alter an item that is currently enchanted. } } else { Item newitem = Activator.CreateInstance(alterInfo.AlteredType) as Item; if (newitem == null) return; if (origItem is BaseWeapon && newitem is BaseWeapon) { BaseWeapon oldweapon = (BaseWeapon)origItem; BaseWeapon newweapon = (BaseWeapon)newitem; newweapon.Slayer = oldweapon.Slayer; newweapon.Slayer2 = oldweapon.Slayer2; newweapon.Slayer3 = oldweapon.Slayer3; newweapon.Resource = oldweapon.Resource; if (oldweapon.PlayerConstructed) { newweapon.PlayerConstructed = true; newweapon.Crafter = oldweapon.Crafter; newweapon.Quality = oldweapon.Quality; } newweapon.Altered = true; } else if (origItem is BaseArmor && newitem is BaseArmor) { BaseArmor oldarmor = (BaseArmor)origItem; BaseArmor newarmor = (BaseArmor)newitem; if (oldarmor.PlayerConstructed) { newarmor.PlayerConstructed = true; newarmor.Crafter = oldarmor.Crafter; newarmor.Quality = oldarmor.Quality; } newarmor.Resource = oldarmor.Resource; newarmor.PhysicalBonus = oldarmor.PhysicalBonus; newarmor.FireBonus = oldarmor.FireBonus; newarmor.ColdBonus = oldarmor.ColdBonus; newarmor.PoisonBonus = oldarmor.PoisonBonus; newarmor.EnergyBonus = oldarmor.EnergyBonus; newarmor.Altered = true; } else if (origItem is BaseClothing && newitem is BaseClothing) { BaseClothing oldcloth = (BaseClothing)origItem; BaseClothing newcloth = (BaseClothing)newitem; if (oldcloth.PlayerConstructed) { newcloth.PlayerConstructed = true; newcloth.Crafter = oldcloth.Crafter; newcloth.Quality = oldcloth.Quality; } newcloth.Altered = true; } else if (origItem is BaseClothing && newitem is BaseArmor) { BaseClothing oldcloth = (BaseClothing)origItem; BaseArmor newarmor = (BaseArmor)newitem; if (oldcloth.PlayerConstructed) { int qual = (int)oldcloth.Quality; newarmor.PlayerConstructed = true; newarmor.Crafter = oldcloth.Crafter; newarmor.Quality = (ItemQuality)qual; } newarmor.Altered = true; } else if (origItem is BaseQuiver && newitem is BaseArmor) { /*BaseQuiver oldquiver = (BaseQuiver)origItem; BaseArmor newarmor = (BaseArmor)newitem;*/ ((BaseArmor)newitem).Altered = true; } else { return; } if (origItem.Name != null) { newitem.Name = origItem.Name; } else if (Server.Engines.VendorSearching.VendorSearch.StringList != null) { if (origItem.LabelNumber > 0 && RetainsName(origItem)) newitem.Name = Server.Engines.VendorSearching.VendorSearch.StringList.GetString(origItem.LabelNumber); } AlterResists(newitem, origItem); newitem.Hue = origItem.Hue; newitem.LootType = origItem.LootType; newitem.Insured = origItem.Insured; origItem.OnAfterDuped(newitem); newitem.Parent = null; if (origItem is IDurability && newitem is IDurability) { ((IDurability)newitem).MaxHitPoints = ((IDurability)origItem).MaxHitPoints; ((IDurability)newitem).HitPoints = ((IDurability)origItem).HitPoints; } if (from.Backpack == null) newitem.MoveToWorld(from.Location, from.Map); else from.Backpack.DropItem(newitem); newitem.InvalidateProperties(); if (m_Contract != null) m_Contract.Delete(); origItem.Delete(); EventSink.InvokeAlterItem(new AlterItemEventArgs(from, m_Tool is Item ? (Item)m_Tool : m_Contract, origItem, newitem)); number = 1094727; // You have altered the item. } if (m_Tool != null) from.SendGump(new CraftGump(from, m_System, m_Tool, number)); else from.SendLocalizedMessage(number); } private void AlterResists(Item newItem, Item oldItem) { if (newItem is BaseArmor || newItem is BaseClothing) { var newResists = Imbuing.GetBaseResists(newItem); var oldResists = Imbuing.GetBaseResists(oldItem); for (int i = 0; i < newResists.Length; i++) { if (oldResists[i] > newResists[i]) { Imbuing.SetProperty(newItem, 51 + i, oldResists[i] - newResists[i]); } } } } private bool RetainsName(Item item) { if (item is Glasses || item is ElvenGlasses || item.IsArtifact) return true; if (item is IArtifact && ((IArtifact)item).ArtifactRarity > 0) return true; return (item.LabelNumber >= 1073505 && item.LabelNumber <= 1073552) || (item.LabelNumber >= 1073111 && item.LabelNumber <= 1075040); } private static bool IsAlterable(Item item) { if (item is BaseWeapon) { BaseWeapon weapon = (BaseWeapon)item; if (weapon.SetID != SetItem.None || !weapon.CanAlter || weapon.NegativeAttributes.Antique != 0) return false; if ((weapon.RequiredRace != null && weapon.RequiredRace == Race.Gargoyle && !weapon.IsArtifact)) return false; } if (item is BaseArmor) { BaseArmor armor = (BaseArmor)item; if (armor.SetID != SetItem.None || !armor.CanAlter || armor.NegativeAttributes.Antique != 0) return false; if ((armor.RequiredRace != null && armor.RequiredRace == Race.Gargoyle && !armor.IsArtifact)) return false; if (armor is RingmailGlovesOfMining && armor.Resource > CraftResource.Iron) return false; } if (item is BaseClothing) { BaseClothing cloth = (BaseClothing)item; if (cloth.SetID != SetItem.None || !cloth.CanAlter || cloth.NegativeAttributes.Antique != 0) return false; if ((cloth.RequiredRace != null && cloth.RequiredRace == Race.Gargoyle && !cloth.IsArtifact)) return false; } if (item is BaseQuiver) { BaseQuiver quiver = (BaseQuiver) item; if (quiver.SetID != SetItem.None || !quiver.CanAlter) return false; } if (item is IVvVItem && ((IVvVItem)item).IsVvVItem) return false; if (item is IRewardItem) return false; return true; } } }