424 lines
15 KiB
C#
424 lines
15 KiB
C#
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// this enables any craftable item where their parent class can be altered, can be altered too.
|
|
/// This is mainly for the ML craftable artifacts.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
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<SlayerSocket>())
|
|
{
|
|
var socket = origItem.GetSocket<SlayerSocket>();
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|