using System; using Server; using Server.Targeting; using Server.Mobiles; using Server.Network; using Server.Items; using Server.Gumps; using System.Collections; using System.Collections.Generic; using Server.ContextMenus; using Server.Commands; using Server.Factions; using Server.Engines.Craft; using System.Linq; namespace Server.SkillHandlers { public class Imbuing { public static void Initialize() { SkillInfo.Table[(int)SkillName.Imbuing].Callback = new SkillUseCallback(OnUse); CommandSystem.Register("GetTotalWeight", AccessLevel.GameMaster, new CommandEventHandler(GetTotalWeight_OnCommand)); CommandSystem.Register("GetTotalMods", AccessLevel.GameMaster, new CommandEventHandler(GetTotalMods_OnCommand)); } private static void OnLogin(LoginEventArgs e) { if (!e.Mobile.CanBeginAction(typeof(Imbuing))) e.Mobile.EndAction(typeof(Imbuing)); } private static Dictionary m_ContextTable = new Dictionary(); public static Dictionary ContextTable { get { return m_ContextTable; } } public static TimeSpan OnUse(Mobile from) { if (!from.Alive) { from.SendLocalizedMessage(500949); //You can't do that when you're dead. } else if (from is PlayerMobile) { from.CloseGump(typeof(ImbuingGump)); BaseGump.SendGump(new ImbuingGump((PlayerMobile)from)); from.BeginAction(typeof(Imbuing)); } return TimeSpan.FromSeconds(1.0); } public static ImbuingContext GetContext(Mobile m) { if (!m_ContextTable.ContainsKey(m)) { ImbuingContext context = new ImbuingContext(m); m_ContextTable[m] = context; return context; } return m_ContextTable[m]; } public static void AddContext(Mobile from, ImbuingContext context) { m_ContextTable[from] = context; } public static bool CanImbueItem(Mobile from, Item item) { if (!CheckSoulForge(from, 2)) { return false; } if (item == null || !item.IsChildOf(from.Backpack)) { from.SendLocalizedMessage(1079575); // The item must be in your backpack to imbue it. } else if (item.LootType == LootType.Blessed || item.LootType == LootType.Newbied) { from.SendLocalizedMessage(1080438); // You cannot imbue a blessed item. } else if (item is BaseWeapon && Spells.Mysticism.EnchantSpell.IsUnderSpellEffects(from, (BaseWeapon)item)) { from.SendLocalizedMessage(1080130); // You cannot imbue an item that is currently enchanted. } else if (item is BaseWeapon && ((BaseWeapon)item).FocusWeilder != null) { from.SendLocalizedMessage(1080444); //You cannot imbue an item that is under the effects of the ninjitsu focus attack ability. } else if (IsSpecialItem(item)) { from.SendLocalizedMessage(1079576); // You cannot imbue this item. } else if (item is IFactionItem && ((IFactionItem)item).FactionItemState != null) { from.SendLocalizedMessage(1114312); // You cannot imbue faction items. } else if (item is BaseJewel && !(item is BaseRing) && !(item is BaseBracelet)) { from.SendLocalizedMessage(1079576); // You cannot imbue this item. } else if (IsInNonImbueList(item.GetType())) { from.SendLocalizedMessage(1079576); // You cannot imbue this item. } else { return true; } return false; } public static bool OnBeforeImbue(Mobile from, Item item, int id, int value) { return OnBeforeImbue(from, item, id, value, GetTotalMods(item, id), GetMaxProps(item), GetTotalWeight(item, id, false, true), Imbuing.GetMaxWeight(item)); } public static bool OnBeforeImbue(Mobile from, Item item, int id, int value, int totalprops, int maxprops, int totalitemweight, int maxweight) { if (totalprops >= maxprops || totalitemweight > maxweight) { from.SendLocalizedMessage(1079772); // You cannot imbue this item with any more item properties. from.CloseGump(typeof(ImbueGump)); from.EndAction(typeof(Imbuing)); return false; } return true; } public static bool CanUnravelItem(Mobile from, Item item, bool message = true) { if (!CheckSoulForge(from, 2, false, false)) { from.SendLocalizedMessage(1080433); // You must be near a soulforge to magically unravel an item. } else if (!item.IsChildOf(from.Backpack)) { if (message) from.SendLocalizedMessage(1080424); // The item must be in your backpack to magically unravel it. } else if (item.LootType == LootType.Blessed || item.LootType == LootType.Newbied) { if (message) from.SendLocalizedMessage(1080421); // You cannot unravel the magic of a blessed item. } else if (!(item is BaseWeapon || item is BaseArmor || item is BaseJewel || item is BaseHat)) { if (message) from.SendLocalizedMessage(1080425); // You cannot magically unravel this item. } else if (item is BaseWeapon && Spells.Mysticism.EnchantSpell.IsUnderSpellEffects(from, (BaseWeapon)item)) { if (message) from.SendLocalizedMessage(1080427); // You cannot magically unravel an item that is currently enchanted. } else if (item is BaseWeapon && ((BaseWeapon)item).FocusWeilder != null) { if (message) from.SendLocalizedMessage(1080445); //You cannot magically unravel an item that is under the effects of the ninjitsu focus attack ability. } else if (item is IFactionItem && ((IFactionItem)item).FactionItemState != null) { if (message) from.SendLocalizedMessage(1112408); // You cannot magically unravel a faction reward item. } else { return true; } return false; } public static bool IsSpecialItem(Item item) { if (item == null) return true; if (IsSpecialImbuable(item)) return false; if (item.IsArtifact) return true; if (RunicReforging.GetArtifactRarity(item) > 0) return true; if (NonCraftableImbuable(item)) return false; foreach (CraftSystem system in CraftSystem.Systems) { CraftItem crItem = null; if(system != null && system.CraftItems != null) crItem = system.CraftItems.SearchFor(item.GetType()); if (crItem != null) return false; } return true; } private static bool IsSpecialImbuable(Item item) { return IsSpecialImbuable(item.GetType()); } private static bool IsSpecialImbuable(Type type) { if (_SpecialImbuable.Any(i => i == type)) return true; if (type.IsSubclassOf(typeof(BaseGlovesOfMining)) || typeof(IFishingAttire).IsAssignableFrom(type)) return true; return false; } private static Type[] _SpecialImbuable = { typeof(ClockworkLeggings), typeof(GargishClockworkLeggings), typeof(OrcishKinMask), typeof(SavageMask), typeof(VirtuososArmbands), typeof(VirtuososCap), typeof(VirtuososCollar), typeof(VirtuososEarpieces), typeof(VirtuososKidGloves), typeof(VirtuososKilt), typeof(VirtuososNecklace), typeof(VirtuososTunic), typeof(BestialArms), typeof(BestialEarrings), typeof(BestialGloves), typeof(BestialGorget), typeof(BestialHelm), typeof(BestialKilt), typeof(BestialLegs), typeof(BestialNecklace), typeof(BarbedWhip), typeof(BladedWhip), typeof(SpikedWhip), typeof(SkullGnarledStaff), typeof(GargishSkullGnarledStaff), typeof(SkullLongsword), typeof(GargishSkullLongsword) }; private static Type[] _NonCraftables = { typeof(SilverRing), typeof(SilverBracelet) }; public static bool NonCraftableImbuable(Item item) { if (item is BaseWand) return true; Type type = item.GetType(); foreach (var t in _NonCraftables) { if (t == type) return true; } return false; } public static double GetSuccessChance(Mobile from, Item item, int totalItemIntensity, int propintensity, double bonus) { double skill = from.Skills[SkillName.Imbuing].Value; double resultWeight = totalItemIntensity + propintensity; double e = Math.E; double a, b, c, w; double i = item is BaseJewel ? 0.9162 : 1.0; // - Racial Bonus - SA ONLY - if (from.Race == Race.Gargoyle) { a = 1362.281555; b = 66.32801518; c = 235.2223147; w = -1481.037561; } else { a = 1554.96118; b = 53.81743328; c = 230.0038452; w = -1664.857794; } // Royal City Bonus, Fluctuation - Removed as EA doesn't seem to fluctuate despite stratics posts /*if (bonus == 0.02) { if (totalItemIntensity < 295) { bonus = (double)Utility.RandomMinMax(190, 210) / 100.0; } }*/ return Math.Max(0, Math.Round(Math.Floor(20 * skill + 10 * a * Math.Pow(e, (b / (resultWeight + c))) + 10 * w - 2400) / 1000 * (i) + bonus, 3) * 100); } public static int GetQualityBonus(Item item) { IQuality quality = item as IQuality; if (quality != null) { if (quality.Quality == ItemQuality.Exceptional) return 20; if (quality.PlayerConstructed) return 10; } return 0; } /// /// Imbues Item with selected id /// /// Player Imbuing /// Item to be imbued /// id to be imbued, see m_Table /// value for id public static void TryImbueItem(Mobile from, Item i, int id, int value) { double bonus = 0.0; if (!CheckSoulForge(from, 2, out bonus)) return; ImbuingContext context = Imbuing.GetContext(from); context.LastImbued = i; context.Imbue_Mod = id; context.Imbue_ModInt = value; var def = ItemPropertyInfo.GetInfo(id); if (def == null) return; var gem = def.GemRes; var primary = def.PrimaryRes; var special = def.SpecialRes; context.Imbue_ModVal = def.Weight; var gemAmount = GetGemAmount(i, id, value); var primResAmount = GetPrimaryAmount(i, id, value); var specResAmount = GetSpecialAmount(i, id, value); if (from.AccessLevel == AccessLevel.Player && (from.Backpack == null || from.Backpack.GetAmount(gem) < gemAmount || from.Backpack.GetAmount(primary) < primResAmount || from.Backpack.GetAmount(special) < specResAmount)) from.SendLocalizedMessage(1079773); //You do not have enough resources to imbue this item. else { var maxWeight = GetMaxWeight(i); context.Imbue_IWmax = maxWeight; var trueWeight = GetTotalWeight(i, id, true, true); var imbuingWeight = GetTotalWeight(i, id, false, true); var totalItemMods = GetTotalMods(i, id); var maxint = ItemPropertyInfo.GetMaxIntensity(i, id, true); var propImbuingweight = (int)(((double)def.Weight / (double)maxint) * value); var propTrueWeight = (int)(((double)propImbuingweight / (double)def.Weight) * 100); if ((imbuingWeight + propImbuingweight) > maxWeight) { from.SendLocalizedMessage(1079772); // You cannot imbue this item with any more item properties. from.CloseGump(typeof(ImbueGump)); return; } double skill = from.Skills[SkillName.Imbuing].Value; double success = GetSuccessChance(from, i, trueWeight, propTrueWeight, bonus); if (TimesImbued(i) < 20 && skill < from.Skills[SkillName.Imbuing].Cap) { double s = Math.Min(100, success); double mins = 120 - (s * 1.2); double maxs = Math.Max(120 / (s / 100), skill); from.CheckSkill(SkillName.Imbuing, mins, maxs); } success /= 100; Effects.SendPacket(from, from.Map, new GraphicalEffect(EffectType.FixedFrom, from.Serial, Server.Serial.Zero, 0x375A, from.Location, from.Location, 1, 17, true, false)); Effects.SendTargetParticles(from, 0, 1, 0, 0x1593, EffectLayer.Waist); if (success >= Utility.RandomDouble() || id < 0 || id > 180) { if (from.AccessLevel == AccessLevel.Player) { from.Backpack.ConsumeTotal(gem, gemAmount); from.Backpack.ConsumeTotal(primary, primResAmount); if (specResAmount > 0) from.Backpack.ConsumeTotal(special, specResAmount); } ImbueItem(from, i, id, value); } else { // This is consumed regardless of success/fail if (from.AccessLevel == AccessLevel.Player) { from.Backpack.ConsumeTotal(primary, primResAmount); } from.SendLocalizedMessage(1079774); // You attempt to imbue the item, but fail. from.PlaySound(0x1E4); } } from.EndAction(typeof(Imbuing)); } public static void ImbueItem(Mobile from, Item item, int id, int value) { from.SendLocalizedMessage(1079775); // You successfully imbue the item! from.PlaySound(0x1EB); if (item is BaseWeapon) { var wep = (BaseWeapon)item; // New property replaces the old one, so lets set them all to 0 if (id >= 30 && id <= 34) { wep.WeaponAttributes.HitPhysicalArea = 0; wep.WeaponAttributes.HitFireArea = 0; wep.WeaponAttributes.HitColdArea = 0; wep.WeaponAttributes.HitPoisonArea = 0; wep.WeaponAttributes.HitEnergyArea = 0; } else if (id >= 35 && id <= 39) { wep.WeaponAttributes.HitMagicArrow = 0; wep.WeaponAttributes.HitHarm = 0; wep.WeaponAttributes.HitFireball = 0; wep.WeaponAttributes.HitLightning = 0; wep.WeaponAttributes.HitDispel = 0; } } if (item is BaseJewel && id >= 151 && id <= 183) { var jewel = (BaseJewel)item; var group = GetSkillGroup((SkillName)ItemPropertyInfo.GetAttribute(id)); //Removes skill bonus if that group already exists on the item for (int j = 0; j < 5; j++) { if (jewel.SkillBonuses.GetBonus(j) > 0 && group.Any(sk => sk == jewel.SkillBonuses.GetSkill(j))) { jewel.SkillBonuses.SetBonus(j, 0.0); jewel.SkillBonuses.SetSkill(j, SkillName.Alchemy); } } } SetProperty(item, id, value); // Sets DImodded, which is used in BaseWeapon if (item is BaseWeapon && id == 12 && !((BaseWeapon)item).DImodded) { ((BaseWeapon)item).DImodded = true; } // removes nom-imbued Imbuing value, which changes the way the items total weight is calculated if (id >= 51 && id <= 55) { if (item is BaseArmor) { var arm = (BaseArmor)item; switch (id) { case 51: arm.PhysNonImbuing = 0; break; case 52: arm.FireNonImbuing = 0; break; case 53: arm.ColdNonImbuing = 0; break; case 54: arm.PoisonNonImbuing = 0; break; case 55: arm.EnergyNonImbuing = 0; break; } } else if (item is BaseClothing) { var hat = (BaseClothing)item; switch (id) { case 51: hat.PhysNonImbuing = 0; break; case 52: hat.FireNonImbuing = 0; break; case 53: hat.ColdNonImbuing = 0; break; case 54: hat.PoisonNonImbuing = 0; break; case 55: hat.EnergyNonImbuing = 0; break; } } } if (item is IImbuableEquipement) { var imbuable = (IImbuableEquipement)item; imbuable.OnAfterImbued(from, id, value); imbuable.TimesImbued++; } // jewels get hits set to 255 if (item is BaseJewel && ((BaseJewel)item).MaxHitPoints <= 0) { ((BaseJewel)item).MaxHitPoints = 255; ((BaseJewel)item).HitPoints = 255; } // Removes self repair var armorAttrs = RunicReforging.GetAosArmorAttributes(item); if (armorAttrs != null) { armorAttrs.SelfRepair = 0; } else { var wepAttrs = RunicReforging.GetAosWeaponAttributes(item); if (wepAttrs != null) { wepAttrs.SelfRepair = 0; } } } public static void SetProperty(Item item, int id, int value) { object prop = ItemPropertyInfo.GetAttribute(id); if (item is BaseWeapon) { BaseWeapon wep = item as BaseWeapon; if (prop is AosAttribute) { AosAttribute attr = (AosAttribute)prop; if (attr == AosAttribute.SpellChanneling) { wep.Attributes.SpellChanneling = value; if (value > 0 && wep.Attributes.CastSpeed >= 0) wep.Attributes.CastSpeed -= 1; } else if (attr == AosAttribute.CastSpeed) { wep.Attributes.CastSpeed += value; } else { wep.Attributes[attr] = value; } } else if (prop is AosWeaponAttribute) { wep.WeaponAttributes[(AosWeaponAttribute)prop] = value; } else if (prop is SlayerName) { wep.Slayer = (SlayerName)prop; } else if (prop is SAAbsorptionAttribute) { wep.AbsorptionAttributes[(SAAbsorptionAttribute)prop] = value; } else if (prop is AosElementAttribute) { int fire, phys, cold, nrgy, pois, chaos, direct; wep.GetDamageTypes(null, out phys, out fire, out cold, out pois, out nrgy, out chaos, out direct); value = Math.Min(phys, value); wep.AosElementDamages[(AosElementAttribute)prop] = value; wep.Hue = wep.GetElementalDamageHue(); } else if (prop is string && wep is BaseRanged && (string)prop == "WeaponVelocity") { ((BaseRanged)wep).Velocity = value; } } else if (item is BaseShield) { BaseShield shield = item as BaseShield; if (prop is AosWeaponAttribute && (AosWeaponAttribute)prop == AosWeaponAttribute.DurabilityBonus) { prop = AosArmorAttribute.DurabilityBonus; } if (prop is AosAttribute) { AosAttribute attr = (AosAttribute)prop; if (attr == AosAttribute.SpellChanneling) { shield.Attributes.SpellChanneling = value; if (value > 0 && shield.Attributes.CastSpeed >= 0) shield.Attributes.CastSpeed -= 1; } else if (attr == AosAttribute.CastSpeed) { shield.Attributes.CastSpeed += value; } else { shield.Attributes[attr] = value; } } else if (prop is AosElementAttribute) { AosElementAttribute attr = (AosElementAttribute)prop; switch (attr) { case AosElementAttribute.Physical: shield.PhysicalBonus = value; break; case AosElementAttribute.Fire: shield.FireBonus = value; break; case AosElementAttribute.Cold: shield.ColdBonus = value; break; case AosElementAttribute.Poison: shield.PoisonBonus = value; break; case AosElementAttribute.Energy: shield.EnergyBonus = value; break; } } else if (prop is SAAbsorptionAttribute) { shield.AbsorptionAttributes[(SAAbsorptionAttribute)prop] = value; } else if (prop is AosArmorAttribute) { shield.ArmorAttributes[(AosArmorAttribute)prop] = value; } } else if (item is BaseArmor) { BaseArmor arm = item as BaseArmor; if (prop is AosWeaponAttribute && (AosWeaponAttribute)prop == AosWeaponAttribute.DurabilityBonus) { prop = AosArmorAttribute.DurabilityBonus; } if (prop is AosAttribute) { arm.Attributes[(AosAttribute)prop] = value; } else if (prop is AosElementAttribute) { AosElementAttribute attr = (AosElementAttribute)prop; switch (attr) { case AosElementAttribute.Physical: arm.PhysicalBonus = value; break; case AosElementAttribute.Fire: arm.FireBonus = value; break; case AosElementAttribute.Cold: arm.ColdBonus = value; break; case AosElementAttribute.Poison: arm.PoisonBonus = value; break; case AosElementAttribute.Energy: arm.EnergyBonus = value; break; } } else if (prop is SAAbsorptionAttribute) { arm.AbsorptionAttributes[(SAAbsorptionAttribute)prop] = value; } else if (prop is AosArmorAttribute) { arm.ArmorAttributes[(AosArmorAttribute)prop] = value; } } else if (item is BaseClothing) { BaseClothing clothing = item as BaseClothing; if (prop is AosAttribute) { clothing.Attributes[(AosAttribute)prop] = value; } else if (prop is SAAbsorptionAttribute) { clothing.SAAbsorptionAttributes[(SAAbsorptionAttribute)prop] = value; } else if (prop is AosElementAttribute) { AosElementAttribute attr = (AosElementAttribute)prop; switch (attr) { case AosElementAttribute.Physical: clothing.Resistances.Physical = value; break; case AosElementAttribute.Fire: clothing.Resistances.Fire = value; break; case AosElementAttribute.Cold: clothing.Resistances.Cold = value; break; case AosElementAttribute.Poison: clothing.Resistances.Poison = value; break; case AosElementAttribute.Energy: clothing.Resistances.Energy = value; break; } } } else if (item is BaseJewel) { BaseJewel jewel = item as BaseJewel; if (prop is AosAttribute) { jewel.Attributes[(AosAttribute)prop] = value; } else if (prop is SAAbsorptionAttribute) { jewel.AbsorptionAttributes[(SAAbsorptionAttribute)prop] = value; } else if (prop is AosElementAttribute) { AosElementAttribute attr = (AosElementAttribute)prop; switch (attr) { case AosElementAttribute.Physical: jewel.Resistances.Physical = value; break; case AosElementAttribute.Fire: jewel.Resistances.Fire = value; break; case AosElementAttribute.Cold: jewel.Resistances.Cold = value; break; case AosElementAttribute.Poison: jewel.Resistances.Poison = value; break; case AosElementAttribute.Energy: jewel.Resistances.Energy = value; break; } } else if (prop is SkillName) { SkillName skill = (SkillName)prop; var bonuses = jewel.SkillBonuses; var index = GetAvailableSkillIndex(bonuses); if (index >= 0 && index <= 4) { bonuses.SetValues(index, skill, value); } } } item.InvalidateProperties(); } public static bool UnravelItem(Mobile from, Item item, bool message = true) { double bonus = 0.0; if (!CheckSoulForge(from, 2, out bonus)) return false; int weight = GetTotalWeight(item, -1, false, true); if (weight <= 0) { if (message) { // You cannot magically unravel this item. It appears to possess little or no magic. from.SendLocalizedMessage(1080437); } return false; } ImbuingContext context = GetContext(from); Type resType = null; var resAmount = Math.Max(1, weight / 100); var success = false; if (weight >= 480 - bonus) { if (from.Skills[SkillName.Imbuing].Value < 95.0) { if (message) { // Your Imbuing skill is not high enough to magically unravel this item. from.SendLocalizedMessage(1080434); } return false; } if (from.CheckSkill(SkillName.Imbuing, 90.1, 120.0)) { success = true; resType = typeof(RelicFragment); resAmount = 1; } else if (from.CheckSkill(SkillName.Imbuing, 45.0, 95.0)) { success = true; resType = typeof(EnchantedEssence); resAmount = Math.Max(1, resAmount - Utility.Random(3)); } } else if (weight > 200 - bonus && weight < 480 - bonus) { if (from.Skills[SkillName.Imbuing].Value < 45.0) { if (message) { // Your Imbuing skill is not high enough to magically unravel this item. from.SendLocalizedMessage(1080434); } return false; } if (from.CheckSkill(SkillName.Imbuing, 45.0, 95.0)) { success = true; resType = typeof(EnchantedEssence); resAmount = Math.Max(1, resAmount); } else if (from.CheckSkill(SkillName.Imbuing, 0.0, 45.0)) { success = true; resType = typeof(MagicalResidue); resAmount = Math.Max(1, resAmount + Utility.Random(2)); } } else if (weight <= 200 - bonus) { if (from.CheckSkill(SkillName.Imbuing, 0.0, 45.0)) { success = true; resType = typeof(MagicalResidue); resAmount = Math.Max(1, resAmount + Utility.Random(2)); } } else { if (message) { // You cannot magically unravel this item. It appears to possess little or no magic. from.SendLocalizedMessage(1080437); } return false; } if (!success) { return false; } Item res; while (resAmount > 0) { res = Activator.CreateInstance(resType) as Item; if (res == null) { break; } if (res.Stackable) { res.Amount = Math.Max(1, Math.Min(60000, resAmount)); } resAmount -= res.Amount; from.AddToBackpack(res); } item.Delete(); return true; } public static int GetMaxWeight(object item) { int maxWeight = 450; IQuality quality = item as IQuality; if (quality != null && quality.Quality == ItemQuality.Exceptional) maxWeight += 50; if (item is BaseWeapon) { BaseWeapon itemToImbue = item as BaseWeapon; if (itemToImbue is BaseThrown) maxWeight += 0; else if (itemToImbue is BaseRanged) maxWeight += 50; else if (itemToImbue.Layer == Layer.TwoHanded) maxWeight += 100; } else if (item is BaseJewel) { maxWeight = 500; } return maxWeight; } public static int GetMaxProps(Item item) { return 5; } public static int GetGemAmount(Item item, int id, int value) { int max = ItemPropertyInfo.GetMaxIntensity(item, id, true); int inc = ItemPropertyInfo.GetScale(item, id); if (max == 1 && inc == 0) return 10; double v = Math.Floor(value / ((double)max / 10)); if (v > 10) v = 10; if (v < 1) v = 1; return (int)v; } public static int GetPrimaryAmount(Item item, int id, int value) { int max = ItemPropertyInfo.GetMaxIntensity(item, id, true); int inc = ItemPropertyInfo.GetScale(item, id); //if (item is BaseJewel && id == 12) // max /= 2; if (max == 1 && inc == 0) return 5; double v = Math.Floor(value / ((double)max / 5.0)); if (v > 5) v = 5; if (v < 1) v = 1; return (int)v; } public static int GetSpecialAmount(Item item, int id, int value) { int max = ItemPropertyInfo.GetMaxIntensity(item, id, true); int intensity = (int)(((double)value / (double)max) * 100); if (intensity >= 100) { return 10; } else if (intensity >= 1 && intensity > 90) { return intensity - 90; } return 0; } [Usage("GetTotalMods")] [Description("Displays the total mods, ie AOS attributes for the targeted item.")] public static void GetTotalMods_OnCommand(CommandEventArgs e) { e.Mobile.BeginTarget(12, false, TargetFlags.None, new TargetCallback(GetTotalMods_OnTarget)); e.Mobile.SendMessage("Target the item to get total AOS Attributes."); } public static void GetTotalMods_OnTarget(Mobile from, object targeted) { if (targeted is Item) { int ids = GetTotalMods((Item)targeted); ((Item)targeted).LabelTo(from, String.Format("Total Mods: {0}", ids.ToString())); } else from.SendMessage("That is not an item!"); } public static int GetTotalMods(Item item, int id = -1) { int total = 0; object prop = ItemPropertyInfo.GetAttribute(id); if (item is BaseWeapon) { BaseWeapon wep = item as BaseWeapon; foreach (int i in Enum.GetValues(typeof(AosAttribute))) { AosAttribute attr = (AosAttribute)i; if(!ItemPropertyInfo.ValidateProperty(attr)) continue; if (wep.Attributes[attr] > 0) { if (!(prop is AosAttribute) || ((AosAttribute)prop) != attr) total++; } else if (wep.Attributes[attr] == 0 && attr == AosAttribute.CastSpeed && wep.Attributes[AosAttribute.SpellChanneling] > 0) { if(!(prop is AosAttribute) || (AosAttribute)prop != attr) total++; } } total += GetSkillBonuses(wep.SkillBonuses, prop); foreach (long i in Enum.GetValues(typeof(AosWeaponAttribute))) { AosWeaponAttribute attr = (AosWeaponAttribute)i; if (!ItemPropertyInfo.ValidateProperty(attr)) continue; if (wep.WeaponAttributes[attr] > 0) { if (IsHitAreaOrSpell(attr, id)) continue; if (!(prop is AosWeaponAttribute) || ((AosWeaponAttribute)prop) != attr) total++; } } foreach (int i in Enum.GetValues(typeof(ExtendedWeaponAttribute))) { ExtendedWeaponAttribute attr = (ExtendedWeaponAttribute)i; if (!ItemPropertyInfo.ValidateProperty(attr)) continue; if (wep.ExtendedWeaponAttributes[attr] > 0) { if (!(prop is ExtendedWeaponAttribute) || ((ExtendedWeaponAttribute)prop) != attr) total++; } } if (wep.Slayer != SlayerName.None && (!(prop is SlayerName) || ((SlayerName)prop) != wep.Slayer)) total++; if (wep.Slayer2 != SlayerName.None) total++; if (wep.Slayer3 != TalismanSlayerName.None) total++; foreach (int i in Enum.GetValues(typeof(SAAbsorptionAttribute))) { SAAbsorptionAttribute attr = (SAAbsorptionAttribute)i; if (!ItemPropertyInfo.ValidateProperty(attr)) continue; if (wep.AbsorptionAttributes[attr] > 0) { if (!(prop is SAAbsorptionAttribute) || ((SAAbsorptionAttribute)prop) != attr) total++; } } if (wep is BaseRanged && !(prop is string)) { BaseRanged ranged = wep as BaseRanged; if (ranged.Velocity > 0 && id != 60) total++; } if (wep.SearingWeapon) total++; } else if (item is BaseArmor) { BaseArmor armor = item as BaseArmor; foreach (int i in Enum.GetValues(typeof(AosAttribute))) { AosAttribute attr = (AosAttribute)i; if (!ItemPropertyInfo.ValidateProperty(attr)) continue; if (armor.Attributes[attr] > 0) { if (!(prop is AosAttribute) || ((AosAttribute)prop) != attr) total++; } else if (armor.Attributes[attr] == 0 && attr == AosAttribute.CastSpeed && armor.Attributes[AosAttribute.SpellChanneling] > 0) { if (!(prop is AosAttribute) || (AosAttribute)prop == attr) total++; } } total += GetSkillBonuses(armor.SkillBonuses, prop); if (armor.PhysicalBonus > armor.PhysNonImbuing && id != 51) { total++; } if (armor.FireBonus > armor.FireNonImbuing && id != 52) { total++; } if (armor.ColdBonus > armor.ColdNonImbuing && id != 53) { total++; } if (armor.PoisonBonus > armor.PoisonNonImbuing && id != 54) { total++; } if (armor.EnergyBonus > armor.EnergyNonImbuing && id != 55) { total++; } foreach (int i in Enum.GetValues(typeof(AosArmorAttribute))) { AosArmorAttribute attr = (AosArmorAttribute)i; if (!ItemPropertyInfo.ValidateProperty(attr)) continue; if (armor.ArmorAttributes[attr] > 0) { if (!(prop is AosArmorAttribute) || ((AosArmorAttribute)prop) != attr) total++; } } foreach (int i in Enum.GetValues(typeof(SAAbsorptionAttribute))) { SAAbsorptionAttribute attr = (SAAbsorptionAttribute)i; if (!ItemPropertyInfo.ValidateProperty(attr)) continue; if (armor.AbsorptionAttributes[attr] > 0) { if (!(prop is SAAbsorptionAttribute) || ((SAAbsorptionAttribute)prop) != attr) total++; } } } else if (item is BaseJewel) { BaseJewel j = item as BaseJewel; foreach (int i in Enum.GetValues(typeof(AosAttribute))) { AosAttribute attr = (AosAttribute)i; if (!ItemPropertyInfo.ValidateProperty(attr)) continue; if (j.Attributes[attr] > 0) { if (!(prop is AosAttribute) || ((AosAttribute)prop) != attr) total++; } } foreach (int i in Enum.GetValues(typeof(SAAbsorptionAttribute))) { SAAbsorptionAttribute attr = (SAAbsorptionAttribute)i; if (!ItemPropertyInfo.ValidateProperty(attr)) continue; if (j.AbsorptionAttributes[attr] > 0) { if (!(prop is SAAbsorptionAttribute) || ((SAAbsorptionAttribute)prop) != attr) total++; } } total += GetSkillBonuses(j.SkillBonuses, prop); if (j.Resistances.Physical > 0 && id != 51) { total++; } if (j.Resistances.Fire > 0 && id != 52) { total++; } if (j.Resistances.Cold > 0 && id != 53) { total++; } if (j.Resistances.Poison > 0 && id != 54) { total++; } if (j.Resistances.Energy > 0 && id != 55) { total++; } } else if (item is BaseClothing) { BaseClothing clothing = item as BaseClothing; foreach (int i in Enum.GetValues(typeof(AosAttribute))) { AosAttribute attr = (AosAttribute)i; if (!ItemPropertyInfo.ValidateProperty(attr)) continue; if (clothing.Attributes[attr] > 0) { if (!(prop is AosAttribute) || ((AosAttribute)prop) != attr) total++; } } foreach (int i in Enum.GetValues(typeof(SAAbsorptionAttribute))) { SAAbsorptionAttribute attr = (SAAbsorptionAttribute)i; if (!ItemPropertyInfo.ValidateProperty(attr)) continue; if (clothing.SAAbsorptionAttributes[attr] > 0) { if (!(prop is SAAbsorptionAttribute) || ((SAAbsorptionAttribute)prop) != attr) total++; } } total += GetSkillBonuses(clothing.SkillBonuses, prop); if (clothing.Resistances.Physical > clothing.PhysNonImbuing && id != 51) { total++; } if (clothing.Resistances.Fire > clothing.FireNonImbuing && id != 52) { total++; } if (clothing.Resistances.Cold > clothing.ColdNonImbuing && id != 53) { total++; } if (clothing.Resistances.Poison > clothing.PoisonNonImbuing && id != 54) { total++; } if (clothing.Resistances.Energy > clothing.EnergyNonImbuing && id != 55) { total++; } } var type = item.GetType(); if (IsDerivedArmorOrClothing(type)) { int[] resists = null; if (ResistBuffer != null && ResistBuffer.ContainsKey(type)) { resists = ResistBuffer[type]; } else { var baseType = type.BaseType; if (IsDerivedArmorOrClothing(baseType)) { var temp = Loot.Construct(baseType); if (temp != null) { resists = new int[5]; resists[0] = GetBaseResistBonus(item, AosElementAttribute.Physical) - GetBaseResistBonus(temp, AosElementAttribute.Physical); resists[1] = GetBaseResistBonus(item, AosElementAttribute.Fire) - GetBaseResistBonus(temp, AosElementAttribute.Fire); resists[2] = GetBaseResistBonus(item, AosElementAttribute.Cold) - GetBaseResistBonus(temp, AosElementAttribute.Cold); resists[3] = GetBaseResistBonus(item, AosElementAttribute.Poison) - GetBaseResistBonus(temp, AosElementAttribute.Poison); resists[4] = GetBaseResistBonus(item, AosElementAttribute.Energy) - GetBaseResistBonus(temp, AosElementAttribute.Energy); if (ResistBuffer == null) ResistBuffer = new Dictionary(); ResistBuffer[type] = resists; temp.Delete(); } } } if (resists != null) { for (int i = 0; i < resists.Length; i++) { if (id != 51 + i && resists[i] > 0) { total++; } } } } return total; } private static bool IsHitAreaOrSpell(AosWeaponAttribute attr, int id) { if (attr >= AosWeaponAttribute.HitMagicArrow && attr <= AosWeaponAttribute.HitDispel) return id >= 35 && id <= 39; else if (attr >= AosWeaponAttribute.HitColdArea && attr <= AosWeaponAttribute.HitPhysicalArea) return id >= 30 && id <= 34; return false; } private static bool IsInSkillGroup(SkillName skill, int index) { if (index < 0 || index >= m_SkillGroups.Length) return false; foreach (SkillName name in m_SkillGroups[index]) { if (name == skill) return true; } return false; } private static int GetSkillBonuses(AosSkillBonuses bonus, object prop) { int id = 0; for (int j = 0; j < 5; j++) { if (bonus.GetBonus(j) > 0) { if (!(prop is SkillName) || !IsInSkillGroup((SkillName)prop, j)) id += 1; } } return id; } [Usage("GetTotalWeight")] [Description("Displays the total imbuing weight of the targeted item.")] public static void GetTotalWeight_OnCommand(CommandEventArgs e) { e.Mobile.BeginTarget(12, false, TargetFlags.None, new TargetCallback(GetTotalWeight_OnTarget)); e.Mobile.SendMessage("Target the item to get total imbuing weight."); } public static void GetTotalWeight_OnTarget(Mobile from, object targeted) { if (targeted is Item) { int w = GetTotalWeight((Item)targeted, -1, false, true); ((Item)targeted).LabelTo(from, String.Format("Imbuing Weight: {0}", w.ToString())); w = GetTotalWeight((Item)targeted, -1, false, false); ((Item)targeted).LabelTo(from, String.Format("Loot Weight: {0}", w.ToString())); w = GetTotalWeight((Item)targeted, -1, true, true); ((Item)targeted).LabelTo(from, String.Format("True Weight: {0}", w.ToString())); } else from.SendMessage("That is not an item!"); } public static Dictionary ResistBuffer { get; private set; } public static int GetTotalWeight(Item item, int id, bool trueWeight, bool imbuing) { double weight = 0; AosAttributes aosAttrs = RunicReforging.GetAosAttributes(item); AosWeaponAttributes wepAttrs = RunicReforging.GetAosWeaponAttributes(item); SAAbsorptionAttributes saAttrs = RunicReforging.GetSAAbsorptionAttributes(item); AosArmorAttributes armorAttrs = RunicReforging.GetAosArmorAttributes(item); AosElementAttributes resistAttrs = RunicReforging.GetElementalAttributes(item); ExtendedWeaponAttributes extattrs = RunicReforging.GetExtendedWeaponAttributes(item); if (item is BaseWeapon) { if(((BaseWeapon)item).Slayer != SlayerName.None) weight += GetIntensityForAttribute(item, ((BaseWeapon)item).Slayer, id, 1, trueWeight, imbuing); if (((BaseWeapon)item).Slayer2 != SlayerName.None) weight += GetIntensityForAttribute(item, ((BaseWeapon)item).Slayer2, id, 1, trueWeight, imbuing); if (((BaseWeapon)item).Slayer3 != TalismanSlayerName.None) weight += GetIntensityForAttribute(item, ((BaseWeapon)item).Slayer3, id, 1, trueWeight, imbuing); if(((BaseWeapon)item).SearingWeapon) weight += GetIntensityForAttribute(item, "SearingWeapon", id, 1, trueWeight, imbuing); if (item is BaseRanged) { BaseRanged ranged = item as BaseRanged; if(ranged.Velocity > 0) weight += GetIntensityForAttribute(item, "WeaponVelocity", id, ranged.Velocity, trueWeight, imbuing); } } else if (item is BaseArmor) { var arm = (BaseArmor)item; if (arm.PhysicalBonus > arm.PhysNonImbuing) { if (id != 51) { weight += ((double)(100.0 / 15) * (double)(arm.PhysicalBonus - arm.PhysNonImbuing)); } } if (arm.FireBonus > arm.FireNonImbuing) { if (id != 52) { weight += ((double)(100.0 / 15) * (double)(arm.FireBonus - arm.FireNonImbuing)); } } if (arm.ColdBonus > arm.ColdNonImbuing) { if (id != 53) { weight += ((double)(100.0 / 15) * (double)(arm.ColdBonus - arm.ColdNonImbuing)); } } if (arm.PoisonBonus > arm.PoisonNonImbuing) { if (id != 54) { weight += ((double)(100.0 / 15) * (double)(arm.PoisonBonus - arm.PoisonNonImbuing)); } } if (arm.EnergyBonus > arm.EnergyNonImbuing) { if (id != 55) { weight += ((double)(100.0 / 15) * (double)(arm.EnergyBonus - arm.EnergyNonImbuing)); } } } var type = item.GetType(); if (IsDerivedArmorOrClothing(type)) { int[] resists = null; if (ResistBuffer != null && ResistBuffer.ContainsKey(type)) { resists = ResistBuffer[type]; } else { var baseType = type.BaseType; if (IsDerivedArmorOrClothing(baseType)) { var temp = Loot.Construct(baseType); if (temp != null) { resists = new int[5]; resists[0] = GetBaseResistBonus(item, AosElementAttribute.Physical) - GetBaseResistBonus(temp, AosElementAttribute.Physical); resists[1] = GetBaseResistBonus(item, AosElementAttribute.Fire) - GetBaseResistBonus(temp, AosElementAttribute.Fire); resists[2] = GetBaseResistBonus(item, AosElementAttribute.Cold) - GetBaseResistBonus(temp, AosElementAttribute.Cold); resists[3] = GetBaseResistBonus(item, AosElementAttribute.Poison) - GetBaseResistBonus(temp, AosElementAttribute.Poison); resists[4] = GetBaseResistBonus(item, AosElementAttribute.Energy) - GetBaseResistBonus(temp, AosElementAttribute.Energy); if (ResistBuffer == null) ResistBuffer = new Dictionary(); ResistBuffer[type] = resists; temp.Delete(); } } } if (resists != null) { for (int i = 0; i < resists.Length; i++) { if(id != 51 + i && resists[i] > 0) { weight += ((double)(100.0 / 15) * (double)resists[i]); } } } } if (aosAttrs != null) foreach (int i in Enum.GetValues(typeof(AosAttribute))) weight += GetIntensityForAttribute(item, (AosAttribute)i, id, aosAttrs[(AosAttribute)i], trueWeight, imbuing); if (wepAttrs != null) foreach (long i in Enum.GetValues(typeof(AosWeaponAttribute))) weight += GetIntensityForAttribute(item, (AosWeaponAttribute)i, id, wepAttrs[(AosWeaponAttribute)i], trueWeight, imbuing); if (saAttrs != null) foreach (int i in Enum.GetValues(typeof(SAAbsorptionAttribute))) weight += GetIntensityForAttribute(item, (SAAbsorptionAttribute)i, id, saAttrs[(SAAbsorptionAttribute)i], trueWeight, imbuing); if (armorAttrs != null) foreach (int i in Enum.GetValues(typeof(AosArmorAttribute))) weight += GetIntensityForAttribute(item, (AosArmorAttribute)i, id, armorAttrs[(AosArmorAttribute)i], trueWeight, imbuing); if (resistAttrs != null && !(item is BaseWeapon)) foreach (int i in Enum.GetValues(typeof(AosElementAttribute))) weight += GetIntensityForAttribute(item, (AosElementAttribute)i, id, resistAttrs[(AosElementAttribute)i], trueWeight, imbuing); if(extattrs != null) foreach (int i in Enum.GetValues(typeof(ExtendedWeaponAttribute))) weight += GetIntensityForAttribute(item, (ExtendedWeaponAttribute)i, id, extattrs[(ExtendedWeaponAttribute)i], trueWeight, imbuing); weight += CheckSkillBonuses(item, id, trueWeight, imbuing); return (int)weight; } public static int[] GetBaseResists(Item item) { int[] resists; // Special items base resist don't count as a property or weight. Once that resist is imbued, // it then uses the base class resistance as the base resistance. EA is stupid. if (item is IImbuableEquipement && IsSpecialImbuable(item)) { resists = ((IImbuableEquipement)item).BaseResists; } else { resists = new int[5]; resists[0] = GetBaseResistBonus(item, AosElementAttribute.Physical); resists[1] = GetBaseResistBonus(item, AosElementAttribute.Fire); resists[2] = GetBaseResistBonus(item, AosElementAttribute.Cold); resists[3] = GetBaseResistBonus(item, AosElementAttribute.Poison); resists[4] = GetBaseResistBonus(item, AosElementAttribute.Energy); } return resists; } private static int GetBaseResistBonus(Item item, AosElementAttribute resist) { switch (resist) { case AosElementAttribute.Physical: { if (item is BaseArmor) return ((BaseArmor)item).BasePhysicalResistance; if (item is BaseClothing) return ((BaseClothing)item).BasePhysicalResistance; break; } case AosElementAttribute.Fire: { if (item is BaseArmor) return ((BaseArmor)item).BaseFireResistance; if (item is BaseClothing) return ((BaseClothing)item).BaseFireResistance; break; } case AosElementAttribute.Cold: { if (item is BaseArmor) return ((BaseArmor)item).BaseColdResistance; if (item is BaseClothing) return ((BaseClothing)item).BaseColdResistance; break; } case AosElementAttribute.Poison: { if (item is BaseArmor) return ((BaseArmor)item).BasePoisonResistance; if (item is BaseClothing) return ((BaseClothing)item).BasePoisonResistance; break; } case AosElementAttribute.Energy: { if (item is BaseArmor) return ((BaseArmor)item).BaseEnergyResistance; if (item is BaseClothing) return ((BaseClothing)item).BaseEnergyResistance; break; } } return 0; } /// /// This is for special items such as artifacts, if you ever so chose to imbue them on your server. Without /// massive edits, this should never come back as true. /// /// /// private static bool IsDerivedArmorOrClothing(Type type) { if (IsSpecialImbuable(type)) { return false; } return (type.IsSubclassOf(typeof(BaseClothing)) || type.IsSubclassOf(typeof(BaseArmor))) && type != typeof(BaseHat) && type != typeof(BaseShield) && type != typeof(Item) && type != typeof(BaseOuterTorso) && type != typeof(BaseMiddleTorso) && type != typeof(BaseOuterLegs) && type != typeof(BasePants) && type != typeof(BaseShirt) && type != typeof(BaseWaist) && type != typeof(BaseShoes) && type != typeof(BaseCloak); } private static int CheckSkillBonuses(Item item, int check, bool trueWeight, bool imbuing) { double weight = 0; int id = -1; AosSkillBonuses skills = RunicReforging.GetAosSkillBonuses(item); if (item is BaseJewel) { id = check; } // Place Holder. THis is in case the skill weight/max intensity every changes int totalWeight = trueWeight ? 100 : ItemPropertyInfo.GetWeight(151); int maxInt = ItemPropertyInfo.GetMaxIntensity(item, 151, imbuing); if (skills != null) { if (skills.GetBonus(0) > 0) { if (id < 151 || id > 155) { weight += ((double)(totalWeight / maxInt) * (double)skills.GetBonus(0)); } } if (skills.GetBonus(1) > 0) { if (id < 156 || id > 160) { weight += ((double)(totalWeight / maxInt) * (double)skills.GetBonus(1)); } } if (skills.GetBonus(2) > 0) { if (id < 161 || id > 166) { weight += ((double)(totalWeight / maxInt) * (double)skills.GetBonus(2)); } } if (skills.GetBonus(3) > 0) { if (id < 167 || id > 173) { weight += ((double)(totalWeight / maxInt) * (double)skills.GetBonus(3)); } } if (skills.GetBonus(4) > 0) { if (id < 174 || id > 180) { weight += ((double)(totalWeight / maxInt) * (double)skills.GetBonus(4)); } } } return (int)weight; } public static SkillName[] PossibleSkills { get { return m_PossibleSkills; } } private static SkillName[] m_PossibleSkills = new SkillName[] { SkillName.Swords, SkillName.Fencing, SkillName.Macing, SkillName.Archery, SkillName.Wrestling, SkillName.Parry, SkillName.Tactics, SkillName.Anatomy, SkillName.Healing, SkillName.Magery, SkillName.Meditation, SkillName.EvalInt, SkillName.MagicResist, SkillName.AnimalTaming, SkillName.AnimalLore, SkillName.Veterinary, SkillName.Musicianship, SkillName.Provocation, SkillName.Discordance, SkillName.Peacemaking, SkillName.Chivalry, SkillName.Focus, SkillName.Necromancy, SkillName.Stealing, SkillName.Stealth, SkillName.SpiritSpeak, SkillName.Bushido, SkillName.Ninjitsu, SkillName.Throwing, SkillName.Mysticism }; private static SkillName[][] m_SkillGroups = new SkillName[][] { new SkillName[] { SkillName.Fencing, SkillName.Macing, SkillName.Swords, SkillName.Musicianship, SkillName.Magery }, new SkillName[] { SkillName.Wrestling, SkillName.AnimalTaming, SkillName.SpiritSpeak, SkillName.Tactics, SkillName.Provocation }, new SkillName[] { SkillName.Focus, SkillName.Parry, SkillName.Stealth, SkillName.Meditation, SkillName.AnimalLore, SkillName.Discordance }, new SkillName[] { SkillName.Mysticism, SkillName.Bushido, SkillName.Necromancy, SkillName.Veterinary, SkillName.Stealing, SkillName.EvalInt, SkillName.Anatomy }, new SkillName[] { SkillName.Peacemaking, SkillName.Ninjitsu, SkillName.Chivalry, SkillName.Archery, SkillName.MagicResist, SkillName.Healing, SkillName.Throwing } }; public static SkillName[] GetSkillGroup(SkillName skill) { return m_SkillGroups.FirstOrDefault(list => list.Any(sk => sk == skill)); } public static int GetAvailableSkillIndex(AosSkillBonuses skills) { for (int i = 0; i < 5; i++) { if (skills.GetBonus(i) == 0) { return i; } } return 01; } public static bool CheckSoulForge(Mobile from, int range) { return CheckSoulForge(from, range, true, true); } public static bool CheckSoulForge(Mobile from, int range, out double bonus) { return CheckSoulForge(from, range, true, true, out bonus); } public static bool CheckSoulForge(Mobile from, int range, bool message) { double bonus; return CheckSoulForge(from, range, message, false, out bonus); } public static bool CheckSoulForge(Mobile from, int range, bool message, bool checkqueen) { double bonus; return CheckSoulForge(from, range, message, checkqueen, out bonus); } public static bool CheckSoulForge(Mobile from, int range, bool message, bool checkqueen, out double bonus) { PlayerMobile m = from as PlayerMobile; bonus = 0.0; ImbuingContext context = Imbuing.GetContext(m); Map map = from.Map; if (map == null) return false; bool isForge = false; IPooledEnumerable eable = map.GetItemsInRange(from.Location, range); foreach (Item item in eable) { if ((item.ItemID >= 0x4277 && item.ItemID <= 0x4286) || (item.ItemID >= 0x4263 && item.ItemID <= 0x4272) || (item.ItemID >= 17607 && item.ItemID <= 17610)) { isForge = true; break; } } eable.Free(); if (!isForge) { if (message) from.SendLocalizedMessage(1079787); // You must be near a soulforge to imbue an item. return false; } if (checkqueen) { if (from.Region != null && from.Region.IsPartOf("Queen's Palace")) { if (!Server.Engines.Points.PointsSystem.QueensLoyalty.IsNoble(from)) { if (message) { from.SendLocalizedMessage(1113736); // You must rise to the rank of noble in the eyes of the Gargoyle Queen before her majesty will allow you to use this soulforge. } return false; } else { bonus = 0.06; } } else if (from.Region != null && from.Region.IsPartOf("Royal City")) { bonus = 0.02; } } return true; } public static Type[] IngredTypes { get { return m_IngredTypes; } } private static Type[] m_IngredTypes = new Type[] { typeof(MagicalResidue), typeof(EnchantedEssence), typeof(RelicFragment), typeof(SeedOfRenewal), typeof(ChagaMushroom), typeof(CrystalShards), typeof(BottleIchor), typeof(ReflectiveWolfEye), typeof(FaeryDust), typeof(BouraPelt), typeof(SilverSnakeSkin), typeof(ArcanicRuneStone), typeof(SlithTongue), typeof(VoidOrb), typeof(RaptorTeeth), typeof(SpiderCarapace), typeof(DaemonClaw), typeof(VialOfVitriol), typeof(GoblinBlood), typeof(LavaSerpentCrust), typeof(UndyingFlesh), typeof(CrushedGlass), typeof(CrystallineBlackrock), typeof(PowderedIron), typeof(ElvenFletching), typeof(DelicateScales), typeof(EssenceSingularity), typeof(EssenceBalance), typeof(EssencePassion), typeof(EssenceDirection), typeof(EssencePrecision), typeof(EssenceControl), typeof(EssenceDiligence), typeof(EssenceAchievement), typeof(EssenceFeeling), typeof(EssenceOrder), typeof(ParasiticPlant), typeof(LuminescentFungi), typeof(FireRuby), typeof(WhitePearl), typeof(BlueDiamond), typeof(Turquoise) }; public static bool IsInNonImbueList(Type itemType) { foreach (Type type in m_CannotImbue) { if (type == itemType) return true; } return false; } private static Type[] m_CannotImbue = new Type[] { typeof(GargishLeatherWingArmor), typeof(GargishClothWingArmor) }; public static int GetValueForID(Item item, int id) { object attr = ItemPropertyInfo.GetAttribute(id); if (item is BaseWeapon) { BaseWeapon w = (BaseWeapon)item; if (id == 16 && w.Attributes.SpellChanneling > 0) return w.Attributes[AosAttribute.CastSpeed] + 1; if (attr is AosAttribute) return w.Attributes[(AosAttribute)attr]; else if (attr is AosWeaponAttribute) return w.WeaponAttributes[(AosWeaponAttribute)attr]; else if (attr is ExtendedWeaponAttribute) return w.ExtendedWeaponAttributes[(ExtendedWeaponAttribute)attr]; else if (attr is SAAbsorptionAttribute) return w.AbsorptionAttributes[(SAAbsorptionAttribute)attr]; else if (attr is SlayerName && w.Slayer == (SlayerName)attr) return 1; else if (id == 60 && item is BaseRanged) return ((BaseRanged)item).Velocity; else if (id == 62) return w.SearingWeapon ? 1 : 0; else if (attr is AosElementAttribute) { AosElementAttribute ele = (AosElementAttribute)attr; switch (ele) { case AosElementAttribute.Physical: return w.WeaponAttributes.ResistPhysicalBonus; case AosElementAttribute.Fire: return w.WeaponAttributes.ResistFireBonus; case AosElementAttribute.Cold: return w.WeaponAttributes.ResistColdBonus; case AosElementAttribute.Poison: return w.WeaponAttributes.ResistPoisonBonus; case AosElementAttribute.Energy: return w.WeaponAttributes.ResistEnergyBonus; } } } else if (item is BaseArmor) { BaseArmor a = (BaseArmor)item; if (a is BaseShield && id == 16 && a.Attributes.SpellChanneling > 0) return a.Attributes[AosAttribute.CastSpeed] + 1; if (attr is AosAttribute) return a.Attributes[(AosAttribute)attr]; else if (attr is AosArmorAttribute) return a.ArmorAttributes[(AosArmorAttribute)attr]; else if (attr is SAAbsorptionAttribute) return a.AbsorptionAttributes[(SAAbsorptionAttribute)attr]; else if (attr is AosElementAttribute) { AosElementAttribute ele = (AosElementAttribute)attr; var value = 0; switch (ele) { case AosElementAttribute.Physical: value = a.PhysicalBonus; break; case AosElementAttribute.Fire: value = a.FireBonus; break; case AosElementAttribute.Cold: value = a.ColdBonus; break; case AosElementAttribute.Poison: value = a.PoisonBonus; break; case AosElementAttribute.Energy: value = a.EnergyBonus; break; } if (value > 0) { return value; } } } else if (item is BaseClothing) { BaseClothing c = (BaseClothing)item; if (attr is AosAttribute) return c.Attributes[(AosAttribute)attr]; else if (attr is AosElementAttribute) { var value = c.Resistances[(AosElementAttribute)attr]; if (value > 0) { return value; } } else if (attr is AosArmorAttribute) return c.ClothingAttributes[(AosArmorAttribute)attr]; else if (attr is SAAbsorptionAttribute) return c.SAAbsorptionAttributes[(SAAbsorptionAttribute)attr]; } else if (item is BaseJewel) { BaseJewel j = (BaseJewel)item; if (attr is AosAttribute) return j.Attributes[(AosAttribute)attr]; else if (attr is AosElementAttribute) return j.Resistances[(AosElementAttribute)attr]; else if (attr is SAAbsorptionAttribute) return j.AbsorptionAttributes[(SAAbsorptionAttribute)attr]; else if (attr is SkillName) { SkillName sk = (SkillName)attr; if (j.SkillBonuses.Skill_1_Name == sk) return (int)j.SkillBonuses.Skill_1_Value; if (j.SkillBonuses.Skill_2_Name == sk) return (int)j.SkillBonuses.Skill_2_Value; if (j.SkillBonuses.Skill_3_Name == sk) return (int)j.SkillBonuses.Skill_3_Value; if (j.SkillBonuses.Skill_4_Name == sk) return (int)j.SkillBonuses.Skill_4_Value; if (j.SkillBonuses.Skill_5_Name == sk) return (int)j.SkillBonuses.Skill_5_Value; } } var type = item.GetType(); if (id >= 51 && id <= 55 && IsDerivedArmorOrClothing(type)) { int[] resists = null; if (ResistBuffer != null && ResistBuffer.ContainsKey(type)) { resists = ResistBuffer[type]; } else { var baseType = type.BaseType; if (IsDerivedArmorOrClothing(baseType)) { var temp = Loot.Construct(baseType); if (temp != null) { resists = new int[5]; resists[0] = GetBaseResistBonus(item, AosElementAttribute.Physical) - GetBaseResistBonus(temp, AosElementAttribute.Physical); resists[1] = GetBaseResistBonus(item, AosElementAttribute.Fire) - GetBaseResistBonus(temp, AosElementAttribute.Fire); resists[2] = GetBaseResistBonus(item, AosElementAttribute.Cold) - GetBaseResistBonus(temp, AosElementAttribute.Cold); resists[3] = GetBaseResistBonus(item, AosElementAttribute.Poison) - GetBaseResistBonus(temp, AosElementAttribute.Poison); resists[4] = GetBaseResistBonus(item, AosElementAttribute.Energy) - GetBaseResistBonus(temp, AosElementAttribute.Energy); if (ResistBuffer == null) ResistBuffer = new Dictionary(); ResistBuffer[type] = resists; temp.Delete(); } } } if (resists != null && resists.Length == 5) { return resists[id - 51]; } } return 0; } public static int GetIntensityForAttribute(Item item, object attr, int checkID, int value) { return GetIntensityForAttribute(item, attr, checkID, value, false); } public static int GetIntensityForAttribute(Item item, object attr, int checkID, int value, bool trueWeight) { return GetIntensityForID(item, ItemPropertyInfo.GetID(attr), checkID, value, trueWeight, true); } public static int GetIntensityForAttribute(Item item, object attr, int checkID, int value, bool trueWeight, bool imbuing) { return GetIntensityForID(item, ItemPropertyInfo.GetID(attr), checkID, value, trueWeight, imbuing); } public static int GetIntensityForID(Item item, int id, int checkID, int value) { return GetIntensityForID(item, id, checkID, value, false); } public static int GetIntensityForID(Item item, int id, int checkID, int value, bool trueWeight) { return GetIntensityForID(item, id, checkID, value, trueWeight, true); } public static int GetIntensityForID(Item item, int id, int checkID, int value, bool trueWeight, bool imbuing) { // This is terribly clunky, however we're accomidating 1 out of 50+ attributes that acts differently if (value <= 0 && id != 16) { return 0; } if ((item is BaseWeapon || item is BaseShield) && id == 16) { AosAttributes attrs = RunicReforging.GetAosAttributes(item); if (attrs != null && attrs.SpellChanneling > 0) value++; } if (value <= 0) return 0; if (id != checkID) { var weight = trueWeight ? 100 : ItemPropertyInfo.GetWeight(id); if (weight == 0) { return 0; } int max = ItemPropertyInfo.GetMaxIntensity(item, id, imbuing); return (int)(((double)weight / max) * (double)value); } return 0; } public static bool CanImbueProperty(Mobile from, Item item, int id) { ItemPropertyInfo info = ItemPropertyInfo.GetInfo(id); bool canImbue = false; if (info != null) { if (item is BaseWeapon) { if (item is BaseRanged && info.CanImbue(ItemType.Ranged)) { canImbue = true; } else if (info.CanImbue(ItemType.Melee)) { canImbue = true; } } else if (item is BaseArmor) { if (item is BaseShield && info.CanImbue(ItemType.Shield)) { canImbue = true; } else if (info.CanImbue(ItemType.Armor)) { canImbue = true; } } else if (item is BaseJewel && info.CanImbue(ItemType.Jewel)) { canImbue = true; } } if (!canImbue) { from.CloseGump(typeof(ImbueGump)); from.SendLocalizedMessage(1114291); // You cannot imbue the last property on that item. } return canImbue; } public static int TimesImbued(Item item) { if (item is IImbuableEquipement) { return ((IImbuableEquipement)item).TimesImbued; } return 0; } } }