diff --git a/Projects/UOContent/Items/Armor/BaseArmor.Migrations.cs b/Projects/UOContent/Items/Armor/BaseArmor.Migrations.cs index 2e4906f52..de8904f0c 100644 --- a/Projects/UOContent/Items/Armor/BaseArmor.Migrations.cs +++ b/Projects/UOContent/Items/Armor/BaseArmor.Migrations.cs @@ -16,7 +16,8 @@ public partial class BaseArmor _identified = content.Identified; _maxHitPoints = content.MaxHitPoints ?? 0; _hitPoints = content.HitPoints ?? 0; - _crafter = content.Crafter?.RawName; // Convert from Mobile -> String via RawName + var crafter = content.Crafter; + Timer.StartTimer(() => _crafter = crafter?.RawName); _quality = content.Quality ?? ArmorQuality.Regular; _durability = content.Durability ?? ArmorDurabilityLevel.Regular; _rawResource = content.RawResource ?? DefaultResource; @@ -90,7 +91,8 @@ public partial class BaseArmor if (GetSaveFlag(flags, OldSaveFlag.Crafter)) { - _crafter = reader.ReadEntity()?.RawName; + var crafter = reader.ReadEntity(); + Timer.StartTimer(() => _crafter = crafter?.RawName); } if (GetSaveFlag(flags, OldSaveFlag.Quality)) diff --git a/Projects/UOContent/Items/Armor/BaseArmor.cs b/Projects/UOContent/Items/Armor/BaseArmor.cs index faba5062c..c306494b3 100644 --- a/Projects/UOContent/Items/Armor/BaseArmor.cs +++ b/Projects/UOContent/Items/Armor/BaseArmor.cs @@ -589,8 +589,8 @@ namespace Server.Items if (Quality == ArmorQuality.Exceptional) { - if (!(Core.ML && this is BaseShield) - ) // Guessed Core.ML removed exceptional resist bonuses from crafted shields + // Guessed Core.ML removed exceptional resist bonuses from crafted shields + if (!(Core.ML && this is BaseShield)) { DistributeBonuses( tool is BaseRunicTool ? 6 : diff --git a/Projects/UOContent/Items/Clothing/BaseClothing.Migrations.cs b/Projects/UOContent/Items/Clothing/BaseClothing.Migrations.cs index 1278b0db2..fe0902747 100644 --- a/Projects/UOContent/Items/Clothing/BaseClothing.Migrations.cs +++ b/Projects/UOContent/Items/Clothing/BaseClothing.Migrations.cs @@ -11,7 +11,8 @@ public partial class BaseClothing _resistances = content.Resistances ?? ResistancesDefaultValue(); _maxHitPoints = content.MaxHitPoints ?? 0; _playerConstructed = content.PlayerConstructed; - _crafter = content.Crafter?.RawName; // Convert from Mobile -> String via RawName + var crafter = content.Crafter; + Timer.StartTimer(() => _crafter = crafter?.RawName); _quality = content.Quality ?? ClothingQuality.Regular; _strReq = content.StrRequirement ?? -1; } @@ -70,7 +71,8 @@ public partial class BaseClothing if (GetSaveFlag(flags, OldSaveFlag.Crafter)) { - _crafter = reader.ReadEntity()?.RawName; + var crafter = reader.ReadEntity(); + Timer.StartTimer(() => _crafter = crafter?.RawName); } if (GetSaveFlag(flags, OldSaveFlag.Quality)) diff --git a/Projects/UOContent/Items/Deeds/BarkeepContract.cs b/Projects/UOContent/Items/Deeds/BarkeepContract.cs index 086088722..c1fa4b22c 100644 --- a/Projects/UOContent/Items/Deeds/BarkeepContract.cs +++ b/Projects/UOContent/Items/Deeds/BarkeepContract.cs @@ -2,96 +2,78 @@ using Server.Mobiles; using Server.Multis; using Server.Network; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class BarkeepContract : Item { - public class BarkeepContract : Item + [Constructible] + public BarkeepContract() : base(0x14F0) { - [Constructible] - public BarkeepContract() : base(0x14F0) + Weight = 1.0; + LootType = LootType.Blessed; + } + + public override string DefaultName => "a barkeep contract"; + + public override void OnDoubleClick(Mobile from) + { + if (!IsChildOf(from.Backpack)) { - Weight = 1.0; - LootType = LootType.Blessed; + from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. } - - public BarkeepContract(Serial serial) : base(serial) + else if (from.AccessLevel >= AccessLevel.GameMaster) { + from.SendLocalizedMessage(503248); // Your godly powers allow you to place this vendor whereever you wish. + + Mobile v = new PlayerBarkeeper(from, BaseHouse.FindHouseAt(from)); + + v.Direction = from.Direction & Direction.Mask; + v.MoveToWorld(from.Location, from.Map); + + Delete(); } - - public override string DefaultName => "a barkeep contract"; - - public override void Serialize(IGenericWriter writer) + else { - base.Serialize(writer); + var house = BaseHouse.FindHouseAt(from); - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - - public override void OnDoubleClick(Mobile from) - { - if (!IsChildOf(from.Backpack)) + if (house?.IsOwner(from) != true) { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. + from.LocalOverheadMessage( + MessageType.Regular, + 0x3B2, + false, + "You are not the full owner of this house." + ); } - else if (from.AccessLevel >= AccessLevel.GameMaster) + else if (!house.CanPlaceNewBarkeep()) { - from.SendLocalizedMessage(503248); // Your godly powers allow you to place this vendor whereever you wish. - - Mobile v = new PlayerBarkeeper(from, BaseHouse.FindHouseAt(from)); - - v.Direction = from.Direction & Direction.Mask; - v.MoveToWorld(from.Location, from.Map); - - Delete(); + from.SendLocalizedMessage( + 1062490 + ); // That action would exceed the maximum number of barkeeps for this house. } else { - var house = BaseHouse.FindHouseAt(from); + BaseHouse.IsThereVendor(from.Location, from.Map, out var vendor, out var contract); - if (house?.IsOwner(from) != true) + if (vendor) { - from.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - false, - "You are not the full owner of this house." - ); + from.SendLocalizedMessage(1062677); // You cannot place a vendor or barkeep at this location. } - else if (!house.CanPlaceNewBarkeep()) + else if (contract) { from.SendLocalizedMessage( - 1062490 - ); // That action would exceed the maximum number of barkeeps for this house. + 1062678 + ); // You cannot place a vendor or barkeep on top of a rental contract! } else { - BaseHouse.IsThereVendor(from.Location, from.Map, out var vendor, out var contract); + Mobile v = new PlayerBarkeeper(from, house); - if (vendor) - { - from.SendLocalizedMessage(1062677); // You cannot place a vendor or barkeep at this location. - } - else if (contract) - { - from.SendLocalizedMessage( - 1062678 - ); // You cannot place a vendor or barkeep on top of a rental contract! - } - else - { - Mobile v = new PlayerBarkeeper(from, house); + v.Direction = from.Direction & Direction.Mask; + v.MoveToWorld(from.Location, from.Map); - v.Direction = from.Direction & Direction.Mask; - v.MoveToWorld(from.Location, from.Map); - - Delete(); - } + Delete(); } } } diff --git a/Projects/UOContent/Items/Deeds/ClothingBlessDeed.cs b/Projects/UOContent/Items/Deeds/ClothingBlessDeed.cs index 598c17bab..cb6186600 100644 --- a/Projects/UOContent/Items/Deeds/ClothingBlessDeed.cs +++ b/Projects/UOContent/Items/Deeds/ClothingBlessDeed.cs @@ -1,99 +1,80 @@ using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +public class ClothingBlessTarget : Target // Create our targeting class (which we derive from the base target class) { - public class ClothingBlessTarget : Target // Create our targeting class (which we derive from the base target class) + private readonly ClothingBlessDeed m_Deed; + + public ClothingBlessTarget(ClothingBlessDeed deed) : base(1, false, TargetFlags.None) => m_Deed = deed; + + protected override void OnTarget(Mobile from, object target) // Override the protected OnTarget() for our feature { - private readonly ClothingBlessDeed m_Deed; - - public ClothingBlessTarget(ClothingBlessDeed deed) : base(1, false, TargetFlags.None) => m_Deed = deed; - - protected override void OnTarget(Mobile from, object target) // Override the protected OnTarget() for our feature + if (m_Deed.Deleted || m_Deed.RootParent != from) { - if (m_Deed.Deleted || m_Deed.RootParent != from) + return; + } + + if (target is BaseClothing item) + { + if ((item as IArcaneEquip)?.IsArcane == true) { + from.SendLocalizedMessage(1005019); // This bless deed is for Clothes only. return; } - if (target is BaseClothing item) + // Check if its already newbied (blessed) + if (item.LootType == LootType.Blessed || item.BlessedFor == from || Mobile.InsuranceEnabled && item.Insured) { - if ((item as IArcaneEquip)?.IsArcane == true) - { - from.SendLocalizedMessage(1005019); // This bless deed is for Clothes only. - return; - } - - if (item.LootType == LootType.Blessed || item.BlessedFor == from || Mobile.InsuranceEnabled && item.Insured - ) // Check if its already newbied (blessed) - { - from.SendLocalizedMessage(1045113); // That item is already blessed - } - else if (item.LootType != LootType.Regular) - { - from.SendLocalizedMessage(1045114); // You can not bless that item - } - else if (!item.CanBeBlessed || item.RootParent != from) - { - from.SendLocalizedMessage(500509); // You cannot bless that object - } - else - { - item.LootType = LootType.Blessed; - from.SendLocalizedMessage(1010026); // You bless the item.... - - m_Deed.Delete(); // Delete the bless deed - } + from.SendLocalizedMessage(1045113); // That item is already blessed } - else + else if (item.LootType != LootType.Regular) + { + from.SendLocalizedMessage(1045114); // You can not bless that item + } + else if (!item.CanBeBlessed || item.RootParent != from) { from.SendLocalizedMessage(500509); // You cannot bless that object } - } - } - - public class ClothingBlessDeed : Item // Create the item class which is derived from the base item class - { - [Constructible] - public ClothingBlessDeed() : base(0x14F0) - { - Weight = 1.0; - LootType = LootType.Blessed; - } - - public ClothingBlessDeed(Serial serial) : base(serial) - { - } - - public override string DefaultName => "a clothing bless deed"; - - public override bool DisplayLootType => false; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - LootType = LootType.Blessed; - - var version = reader.ReadInt(); - } - - public override void OnDoubleClick(Mobile from) // Override double click of the deed to call our target - { - if (!IsChildOf(from.Backpack)) // Make sure its in their pack - { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } else { - from.SendLocalizedMessage(1005018); // What would you like to bless? (Clothes Only) - from.Target = new ClothingBlessTarget(this); // Call our target + item.LootType = LootType.Blessed; + from.SendLocalizedMessage(1010026); // You bless the item.... + + m_Deed.Delete(); // Delete the bless deed } } + else + { + from.SendLocalizedMessage(500509); // You cannot bless that object + } + } +} + +[Serializable(0, false)] +public partial class ClothingBlessDeed : Item // Create the item class which is derived from the base item class +{ + [Constructible] + public ClothingBlessDeed() : base(0x14F0) + { + Weight = 1.0; + LootType = LootType.Blessed; + } + + public override string DefaultName => "a clothing bless deed"; + + public override bool DisplayLootType => false; + + public override void OnDoubleClick(Mobile from) // Override double click of the deed to call our target + { + if (!IsChildOf(from.Backpack)) // Make sure its in their pack + { + from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. + } + else + { + from.SendLocalizedMessage(1005018); // What would you like to bless? (Clothes Only) + from.Target = new ClothingBlessTarget(this); // Call our target + } } } diff --git a/Projects/UOContent/Items/Deeds/CommodityDeed.cs b/Projects/UOContent/Items/Deeds/CommodityDeed.cs index 5133f2b3c..3aa141533 100644 --- a/Projects/UOContent/Items/Deeds/CommodityDeed.cs +++ b/Projects/UOContent/Items/Deeds/CommodityDeed.cs @@ -1,183 +1,209 @@ using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +public interface ICommodity /* added IsDeedable prop so expansion-based deedables can determine true/false */ { - public interface ICommodity /* added IsDeedable prop so expansion-based deedables can determine true/false */ + int DescriptionNumber { get; } + bool IsDeedable { get; } +} + +[Serializable(1, false)] +public partial class CommodityDeed : Item +{ + [SerializableField(0, setter: "private")] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + public Item _commodity; + + [Constructible] + public CommodityDeed(Item commodity = null) : base(0x14F0) { - int DescriptionNumber { get; } - bool IsDeedable { get; } + Weight = 1.0; + Hue = 0x47; + + Commodity = commodity; + + LootType = LootType.Blessed; } - public class CommodityDeed : Item + public override int LabelNumber => Commodity == null ? 1047016 : 1047017; + + public bool SetCommodity(Item item) { - [Constructible] - public CommodityDeed(Item commodity = null) : base(0x14F0) - { - Weight = 1.0; - Hue = 0x47; - - Commodity = commodity; - - LootType = LootType.Blessed; - } - - public CommodityDeed(Serial serial) : base(serial) - { - } - - [CommandProperty(AccessLevel.GameMaster)] - public Item Commodity { get; private set; } - - public override int LabelNumber => Commodity == null ? 1047016 : 1047017; - - public bool SetCommodity(Item item) + InvalidateProperties(); + + if (Commodity == null && (item as ICommodity)?.IsDeedable == true) { + Commodity = item; + Commodity.Internalize(); InvalidateProperties(); - if (Commodity == null && (item as ICommodity)?.IsDeedable == true) - { - Commodity = item; - Commodity.Internalize(); - InvalidateProperties(); + return true; + } - return true; + return false; + } + + private void Deserialize(IGenericReader reader, int version) + { + Commodity = reader.ReadEntity(); + + if (Commodity != null) + { + Hue = 0x592; + } + } + + public override void OnDelete() + { + Commodity?.Delete(); + + base.OnDelete(); + } + + public override void GetProperties(ObjectPropertyList list) + { + base.GetProperties(list); + + if (Commodity != null) + { + var args = Commodity.Name == null + ? $"#{(Commodity as ICommodity)?.DescriptionNumber ?? Commodity.LabelNumber}\t{Commodity.Amount}" + : $"{Commodity.Name}\t{Commodity.Amount}"; + + list.Add(1060658, args); // ~1_val~: ~2_val~ + } + else + { + list.Add(1060748); // unfilled + } + } + + public override void OnSingleClick(Mobile from) + { + base.OnSingleClick(from); + + if (Commodity != null) + { + var args = Commodity.Name == null + ? $"#{(Commodity as ICommodity)?.DescriptionNumber ?? Commodity.LabelNumber}\t{Commodity.Amount}" + : $"{Commodity.Name}\t{Commodity.Amount}"; + + LabelTo(from, 1060658, args); // ~1_val~: ~2_val~ + } + } + + public override void OnDoubleClick(Mobile from) + { + int number; + + var box = from.FindBankNoCreate(); + var cox = CommodityDeedBox.Find(this); + + // Veteran Rewards mods + if (Commodity != null) + { + if (box != null && IsChildOf(box)) + { + number = 1047031; // The commodity has been redeemed. + + box.DropItem(Commodity); + + Commodity = null; + Delete(); } - - return false; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - - writer.Write(Commodity); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - Commodity = reader.ReadEntity(); - - switch (version) + else if (cox != null) { - case 0: - { - if (Commodity != null) - { - Hue = 0x592; - } - - break; - } - } - } - - public override void OnDelete() - { - Commodity?.Delete(); - - base.OnDelete(); - } - - public override void GetProperties(ObjectPropertyList list) - { - base.GetProperties(list); - - if (Commodity != null) - { - var args = Commodity.Name == null - ? $"#{(Commodity is ICommodity commodity ? commodity.DescriptionNumber : Commodity.LabelNumber)}\t{Commodity.Amount}" - : $"{Commodity.Name}\t{Commodity.Amount}"; - - list.Add(1060658, args); // ~1_val~: ~2_val~ - } - else - { - list.Add(1060748); // unfilled - } - } - - public override void OnSingleClick(Mobile from) - { - base.OnSingleClick(from); - - if (Commodity != null) - { - string args; - - if (Commodity.Name == null) - { - args = - $"#{(Commodity is ICommodity commodity ? commodity.DescriptionNumber : Commodity.LabelNumber)}\t{Commodity.Amount}"; - } - else - { - args = $"{Commodity.Name}\t{Commodity.Amount}"; - } - - LabelTo(from, 1060658, args); // ~1_val~: ~2_val~ - } - } - - public override void OnDoubleClick(Mobile from) - { - int number; - - var box = from.FindBankNoCreate(); - var cox = CommodityDeedBox.Find(this); - - // Veteran Rewards mods - if (Commodity != null) - { - if (box != null && IsChildOf(box)) + if (cox.IsSecure) { number = 1047031; // The commodity has been redeemed. - box.DropItem(Commodity); + cox.DropItem(Commodity); Commodity = null; Delete(); } - else if (cox != null) + else { - if (cox.IsSecure) - { - number = 1047031; // The commodity has been redeemed. - - cox.DropItem(Commodity); - - Commodity = null; - Delete(); - } - else - { - number = 1080525; // The commodity deed box must be secured before you can use it. - } + number = 1080525; // The commodity deed box must be secured before you can use it. + } + } + else + { + if (Core.ML) + { + number = 1080526; // That must be in your bank box or commodity deed box to use it. } else { - if (Core.ML) + number = 1047024; // To claim the resources .... + } + } + } + else if (cox?.IsSecure == false) + { + number = 1080525; // The commodity deed box must be secured before you can use it. + } + else if ((box == null || !IsChildOf(box)) && cox == null) + { + if (Core.ML) + { + number = 1080526; // That must be in your bank box or commodity deed box to use it. + } + else + { + number = 1047026; // That must be in your bank box to use it. + } + } + else + { + number = 1047029; // Target the commodity to fill this deed with. + + from.Target = new InternalTarget(this); + } + + from.SendLocalizedMessage(number); + } + + private class InternalTarget : Target + { + private readonly CommodityDeed m_Deed; + + public InternalTarget(CommodityDeed deed) : base(3, false, TargetFlags.None) => m_Deed = deed; + + protected override void OnTarget(Mobile from, object targeted) + { + if (m_Deed.Deleted) + { + return; + } + + int number; + + if (m_Deed.Commodity != null) + { + number = 1047028; // The commodity deed has already been filled. + } + else if (targeted is Item item) + { + var box = from.FindBankNoCreate(); + var cox = CommodityDeedBox.Find(m_Deed); + + // Veteran Rewards mods + if (box != null && m_Deed.IsChildOf(box) && item.IsChildOf(box) || + cox?.IsSecure != true && item.IsChildOf(cox)) + { + if (m_Deed.SetCommodity(item)) { - number = 1080526; // That must be in your bank box or commodity deed box to use it. + m_Deed.Hue = 0x592; + number = 1047030; // The commodity deed has been filled. } else { - number = 1047024; // To claim the resources .... + number = 1047027; // That is not a commodity the bankers will fill a commodity deed with. } } - } - else if (cox?.IsSecure == false) - { - number = 1080525; // The commodity deed box must be secured before you can use it. - } - else if ((box == null || !IsChildOf(box)) && cox == null) - { - if (Core.ML) + else if (Core.ML) { number = 1080526; // That must be in your bank box or commodity deed box to use it. } @@ -188,68 +214,10 @@ namespace Server.Items } else { - number = 1047029; // Target the commodity to fill this deed with. - - from.Target = new InternalTarget(this); + number = 1047027; // That is not a commodity the bankers will fill a commodity deed with. } from.SendLocalizedMessage(number); } - - private class InternalTarget : Target - { - private readonly CommodityDeed m_Deed; - - public InternalTarget(CommodityDeed deed) : base(3, false, TargetFlags.None) => m_Deed = deed; - - protected override void OnTarget(Mobile from, object targeted) - { - if (m_Deed.Deleted) - { - return; - } - - int number; - - if (m_Deed.Commodity != null) - { - number = 1047028; // The commodity deed has already been filled. - } - else if (targeted is Item item) - { - var box = from.FindBankNoCreate(); - var cox = CommodityDeedBox.Find(m_Deed); - - // Veteran Rewards mods - if (box != null && m_Deed.IsChildOf(box) && item.IsChildOf(box) || - cox?.IsSecure != true && item.IsChildOf(cox)) - { - if (m_Deed.SetCommodity(item)) - { - m_Deed.Hue = 0x592; - number = 1047030; // The commodity deed has been filled. - } - else - { - number = 1047027; // That is not a commodity the bankers will fill a commodity deed with. - } - } - else if (Core.ML) - { - number = 1080526; // That must be in your bank box or commodity deed box to use it. - } - else - { - number = 1047026; // That must be in your bank box to use it. - } - } - else - { - number = 1047027; // That is not a commodity the bankers will fill a commodity deed with. - } - - from.SendLocalizedMessage(number); - } - } } } diff --git a/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs b/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs index cf3e814a4..75840190b 100644 --- a/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs +++ b/Projects/UOContent/Items/Deeds/DragonBardingDeed.cs @@ -3,176 +3,136 @@ using Server.Engines.Craft; using Server.Mobiles; using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +[TypeAlias("Server.Items.DragonBarding")] +[Serializable(2, false)] +public partial class DragonBardingDeed : Item, ICraftable { - [TypeAlias("Server.Items.DragonBarding")] - public class DragonBardingDeed : Item, ICraftable + [InvalidateProperties] + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private string _craftedBy; + + [InvalidateProperties] + [SerializableField(1)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private bool _exceptional; + + [SerializableField(2, "private", "private")] + private CraftResource _rawResource; + + public DragonBardingDeed() : base(0x14F0) => Weight = 1.0; + + public override int LabelNumber => _exceptional ? 1053181 : 1053012; // dragon barding deed + + [CommandProperty(AccessLevel.GameMaster)] + public CraftResource Resource { - private Mobile m_Crafter; - private bool m_Exceptional; - private CraftResource m_Resource; - - public DragonBardingDeed() : base(0x14F0) => Weight = 1.0; - - public DragonBardingDeed(Serial serial) : base(serial) + get => _rawResource; + set { - } - - public override int LabelNumber => m_Exceptional ? 1053181 : 1053012; // dragon barding deed - - [CommandProperty(AccessLevel.GameMaster)] - public Mobile Crafter - { - get => m_Crafter; - set - { - m_Crafter = value; - InvalidateProperties(); - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public bool Exceptional - { - get => m_Exceptional; - set - { - m_Exceptional = value; - InvalidateProperties(); - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public CraftResource Resource - { - get => m_Resource; - set - { - m_Resource = value; - Hue = CraftResources.GetHue(value); - InvalidateProperties(); - } - } - - public int OnCraft( - int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, - CraftItem craftItem, int resHue - ) - { - Exceptional = quality >= 2; - - if (makersMark) - { - Crafter = from; - } - - var resourceType = typeRes ?? craftItem.Resources[0].ItemType; - - Resource = CraftResources.GetFromType(resourceType); - - var context = craftSystem.GetContext(from); - - if (context?.DoNotColor == true) - { - Hue = 0; - } - - return quality; - } - - public override void GetProperties(ObjectPropertyList list) - { - base.GetProperties(list); - - if (m_Exceptional && m_Crafter != null) - { - list.Add(1050043, m_Crafter.Name); // crafted by ~1_NAME~ - } - } - - public override void OnDoubleClick(Mobile from) - { - if (IsChildOf(from.Backpack)) - { - from.BeginTarget(6, false, TargetFlags.None, OnTarget); - from.SendLocalizedMessage(1053024); // Select the swamp dragon you wish to place the barding on. - } - else - { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } - } - - public virtual void OnTarget(Mobile from, object obj) - { - if (Deleted) - { - return; - } - - if (obj is not SwampDragon pet || pet.HasBarding) - { - from.SendLocalizedMessage(1053025); // That is not an unarmored swamp dragon. - } - else if (!pet.Controlled || pet.ControlMaster != from) - { - from.SendLocalizedMessage(1053026); // You can only put barding on a tamed swamp dragon that you own. - } - else if (!IsChildOf(from.Backpack)) - { - from.SendLocalizedMessage(1060640); // The item must be in your backpack to use it. - } - else - { - pet.BardingExceptional = Exceptional; - pet.BardingCrafter = Crafter; - pet.BardingHP = pet.BardingMaxHP; - pet.BardingResource = Resource; - pet.HasBarding = true; - pet.Hue = Hue; - - Delete(); - - from.SendLocalizedMessage( - 1053027 - ); // You place the barding on your swamp dragon. Use a bladed item on your dragon to remove the armor. - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - - writer.Write(m_Exceptional); - writer.Write(m_Crafter); - writer.Write((int)m_Resource); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 1: - case 0: - { - m_Exceptional = reader.ReadBool(); - m_Crafter = reader.ReadEntity(); - - if (version < 1) - { - reader.ReadInt(); - } - - m_Resource = (CraftResource)reader.ReadInt(); - break; - } - } + _rawResource = value; + Hue = CraftResources.GetHue(value); + InvalidateProperties(); } } + + public int OnCraft( + int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, + CraftItem craftItem, int resHue + ) + { + Exceptional = quality >= 2; + + if (makersMark) + { + CraftedBy = from?.RawName; + } + + var resourceType = typeRes ?? craftItem.Resources[0].ItemType; + + Resource = CraftResources.GetFromType(resourceType); + + var context = craftSystem.GetContext(from); + + if (context?.DoNotColor == true) + { + Hue = 0; + } + + return quality; + } + + public override void GetProperties(ObjectPropertyList list) + { + base.GetProperties(list); + + if (_exceptional && _craftedBy != null) + { + list.Add(1050043, _craftedBy); // crafted by ~1_NAME~ + } + } + + public override void OnDoubleClick(Mobile from) + { + if (IsChildOf(from.Backpack)) + { + from.BeginTarget(6, false, TargetFlags.None, OnTarget); + from.SendLocalizedMessage(1053024); // Select the swamp dragon you wish to place the barding on. + } + else + { + from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. + } + } + + public virtual void OnTarget(Mobile from, object obj) + { + if (Deleted) + { + return; + } + + if (obj is not SwampDragon pet || pet.HasBarding) + { + from.SendLocalizedMessage(1053025); // That is not an unarmored swamp dragon. + } + else if (!pet.Controlled || pet.ControlMaster != from) + { + from.SendLocalizedMessage(1053026); // You can only put barding on a tamed swamp dragon that you own. + } + else if (!IsChildOf(from.Backpack)) + { + from.SendLocalizedMessage(1060640); // The item must be in your backpack to use it. + } + else + { + pet.BardingExceptional = Exceptional; + pet.BardingCraftedBy = _craftedBy; + pet.BardingHP = pet.BardingMaxHP; + pet.BardingResource = Resource; + pet.HasBarding = true; + pet.Hue = Hue; + + Delete(); + + // You place the barding on your swamp dragon. Use a bladed item on your dragon to remove the armor. + from.SendLocalizedMessage(1053027); + } + } + + private void Deserialize(IGenericReader reader, int version) + { + _exceptional = reader.ReadBool(); + var crafter = reader.ReadEntity(); + Timer.StartTimer(() => _craftedBy = crafter?.RawName); + + if (version < 1) + { + reader.ReadInt(); + } + + _rawResource = (CraftResource)reader.ReadInt(); + } } diff --git a/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs b/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs index 847536294..e87eb7d1d 100644 --- a/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs +++ b/Projects/UOContent/Items/Deeds/HairRestylingDeed.cs @@ -2,163 +2,146 @@ using Server.Gumps; using Server.Mobiles; using Server.Network; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class HairRestylingDeed : Item { - public class HairRestylingDeed : Item + [Constructible] + public HairRestylingDeed() : base(0x14F0) { - [Constructible] - public HairRestylingDeed() : base(0x14F0) + Weight = 1.0; + LootType = LootType.Blessed; + } + + public override int LabelNumber => 1041061; // a coupon for a free hair restyling + + public override void OnDoubleClick(Mobile from) + { + if (!IsChildOf(from.Backpack)) { - Weight = 1.0; - LootType = LootType.Blessed; + from.SendLocalizedMessage(1042001); // That must be in your pack... } - - public HairRestylingDeed(Serial serial) : base(serial) + else { + from.SendGump(new InternalGump(from, this)); } + } - public override int LabelNumber => 1041061; // a coupon for a free hair restyling - - public override void Serialize(IGenericWriter writer) + private class InternalGump : Gump + { + private static readonly int[][] ElvenArray = { - base.Serialize(writer); + new[] { 0 }, + new[] { 1011064, 1011064, 0, 0, 0, 0 }, // bald + new[] { 1074386, 1074386, 0x2fc0, 0x2fc0, 0xedf5, 0xc6e5 }, // long feather + new[] { 1074387, 1074387, 0x2fc1, 0x2fc1, 0xedf6, 0xc6e6 }, // short + new[] { 1074388, 1074388, 0x2fc2, 0x2fc2, 0xedf7, 0xc6e7 }, // mullet + new[] { 1074391, 1074391, 0x2fce, 0x2fce, 0xeddc, 0xc6cc }, // knob + new[] { 1074392, 1074392, 0x2fcf, 0x2fcf, 0xeddd, 0xc6cd }, // braided + new[] { 1074394, 1074394, 0x2fd1, 0x2fd1, 0xeddf, 0xc6cf }, // spiked + new[] { 1074389, 1074385, 0x2fcc, 0x2fbf, 0xedda, 0xc6e4 }, // flower, mid-long + new[] { 1074393, 1074390, 0x2fd0, 0x2fcd, 0xedde, 0xc6cb } // buns, long + }; - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) + /* + racial arrays are: cliloc_F, cliloc_M, ItemID_F, ItemID_M, gump_img_F, gump_img_M + */ + private static readonly int[][] HumanArray = /* why on earth cant these utilities be consistent with hex/dec */ { - base.Deserialize(reader); - var version = reader.ReadInt(); - } + new[] { 0 }, + new[] { 1011064, 1011064, 0, 0, 0, 0 }, // bald + new[] { 1011052, 1011052, 0x203B, 0x203B, 0xed1c, 0xC60C }, // Short + new[] { 1011053, 1011053, 0x203C, 0x203C, 0xed1d, 0xc60d }, // Long + new[] { 1011054, 1011054, 0x203D, 0x203D, 0xed1e, 0xc60e }, // Ponytail + new[] { 1011055, 1011055, 0x2044, 0x2044, 0xed27, 0xC60F }, // Mohawk + new[] { 1011047, 1011047, 0x2045, 0x2045, 0xED26, 0xED26 }, // Pageboy + new[] { 1074393, 1011048, 0x2046, 0x2048, 0xed28, 0xEDE5 }, // Buns, Receding + new[] { 1011049, 1011049, 0x2049, 0x2049, 0xede6, 0xede6 }, // 2-tails + new[] { 1011050, 1011050, 0x204A, 0x204A, 0xED29, 0xED29 }, // Topknot + new[] { 1011396, 1011396, 0x2047, 0x2047, 0xed25, 0xc618 } // Curly + }; - public override void OnDoubleClick(Mobile from) + /* + gump data: bgX, bgY, htmlX, htmlY, imgX, imgY, butX, butY + */ + private static readonly int[][] LayoutArray = { - if (!IsChildOf(from.Backpack)) + new[] { 0 }, /* padding: its more efficient than code to ++ the index/buttonid */ + new[] { 425, 280, 342, 295, 000, 000, 310, 292 }, + new[] { 235, 060, 150, 075, 168, 020, 118, 073 }, + new[] { 235, 115, 150, 130, 168, 070, 118, 128 }, + new[] { 235, 170, 150, 185, 168, 130, 118, 183 }, + new[] { 235, 225, 150, 240, 168, 185, 118, 238 }, + new[] { 425, 060, 342, 075, 358, 018, 310, 073 }, + new[] { 425, 115, 342, 130, 358, 075, 310, 128 }, + new[] { 425, 170, 342, 185, 358, 125, 310, 183 }, + new[] { 425, 225, 342, 240, 358, 185, 310, 238 }, + new[] { 235, 280, 150, 295, 168, 245, 118, 292 } // slot 10, Curly - N/A for elfs. + }; + + private readonly HairRestylingDeed m_Deed; + private readonly Mobile m_From; + + public InternalGump(Mobile from, HairRestylingDeed deed) : base(50, 50) + { + m_From = from; + m_Deed = deed; + + from.CloseGump(); + + AddBackground(100, 10, 400, 385, 0xA28); + + AddHtmlLocalized(100, 25, 400, 35, 1013008); + AddButton(175, 340, 0xFA5, 0xFA7, 0x0); // CANCEL + + AddHtmlLocalized(210, 342, 90, 35, 1011012); //
HAIRSTYLE SELECTION MENU
+ + var RacialData = from.Race == Race.Human ? HumanArray : ElvenArray; + + for (var i = 1; i < RacialData.Length; i++) { - from.SendLocalizedMessage(1042001); // That must be in your pack... - } - else - { - from.SendGump(new InternalGump(from, this)); + AddHtmlLocalized( + LayoutArray[i][2], + LayoutArray[i][3], + i == 1 ? 125 : 80, + i == 1 ? 70 : 35, + m_From.Female ? RacialData[i][0] : RacialData[i][1] + ); + if (LayoutArray[i][4] != 0) + { + AddBackground(LayoutArray[i][0], LayoutArray[i][1], 50, 50, 0xA3C); + AddImage(LayoutArray[i][4], LayoutArray[i][5], m_From.Female ? RacialData[i][4] : RacialData[i][5]); + } + + AddButton(LayoutArray[i][6], LayoutArray[i][7], 0xFA5, 0xFA7, i); } } - private class InternalGump : Gump + public override void OnResponse(NetState sender, RelayInfo info) { - private static readonly int[][] ElvenArray = + if (m_From?.Alive != true) { - new[] { 0 }, - new[] { 1011064, 1011064, 0, 0, 0, 0 }, // bald - new[] { 1074386, 1074386, 0x2fc0, 0x2fc0, 0xedf5, 0xc6e5 }, // long feather - new[] { 1074387, 1074387, 0x2fc1, 0x2fc1, 0xedf6, 0xc6e6 }, // short - new[] { 1074388, 1074388, 0x2fc2, 0x2fc2, 0xedf7, 0xc6e7 }, // mullet - new[] { 1074391, 1074391, 0x2fce, 0x2fce, 0xeddc, 0xc6cc }, // knob - new[] { 1074392, 1074392, 0x2fcf, 0x2fcf, 0xeddd, 0xc6cd }, // braided - new[] { 1074394, 1074394, 0x2fd1, 0x2fd1, 0xeddf, 0xc6cf }, // spiked - new[] { 1074389, 1074385, 0x2fcc, 0x2fbf, 0xedda, 0xc6e4 }, // flower, mid-long - new[] { 1074393, 1074390, 0x2fd0, 0x2fcd, 0xedde, 0xc6cb } // buns, long - }; - - /* - racial arrays are: cliloc_F, cliloc_M, ItemID_F, ItemID_M, gump_img_F, gump_img_M - */ - private static readonly int[][] HumanArray = /* why on earth cant these utilities be consistent with hex/dec */ - { - new[] { 0 }, - new[] { 1011064, 1011064, 0, 0, 0, 0 }, // bald - new[] { 1011052, 1011052, 0x203B, 0x203B, 0xed1c, 0xC60C }, // Short - new[] { 1011053, 1011053, 0x203C, 0x203C, 0xed1d, 0xc60d }, // Long - new[] { 1011054, 1011054, 0x203D, 0x203D, 0xed1e, 0xc60e }, // Ponytail - new[] { 1011055, 1011055, 0x2044, 0x2044, 0xed27, 0xC60F }, // Mohawk - new[] { 1011047, 1011047, 0x2045, 0x2045, 0xED26, 0xED26 }, // Pageboy - new[] { 1074393, 1011048, 0x2046, 0x2048, 0xed28, 0xEDE5 }, // Buns, Receding - new[] { 1011049, 1011049, 0x2049, 0x2049, 0xede6, 0xede6 }, // 2-tails - new[] { 1011050, 1011050, 0x204A, 0x204A, 0xED29, 0xED29 }, // Topknot - new[] { 1011396, 1011396, 0x2047, 0x2047, 0xed25, 0xc618 } // Curly - }; - - /* - gump data: bgX, bgY, htmlX, htmlY, imgX, imgY, butX, butY - */ - private static readonly int[][] LayoutArray = - { - new[] { 0 }, /* padding: its more efficient than code to ++ the index/buttonid */ - new[] { 425, 280, 342, 295, 000, 000, 310, 292 }, - new[] { 235, 060, 150, 075, 168, 020, 118, 073 }, - new[] { 235, 115, 150, 130, 168, 070, 118, 128 }, - new[] { 235, 170, 150, 185, 168, 130, 118, 183 }, - new[] { 235, 225, 150, 240, 168, 185, 118, 238 }, - new[] { 425, 060, 342, 075, 358, 018, 310, 073 }, - new[] { 425, 115, 342, 130, 358, 075, 310, 128 }, - new[] { 425, 170, 342, 185, 358, 125, 310, 183 }, - new[] { 425, 225, 342, 240, 358, 185, 310, 238 }, - new[] { 235, 280, 150, 295, 168, 245, 118, 292 } // slot 10, Curly - N/A for elfs. - }; - - private readonly HairRestylingDeed m_Deed; - private readonly Mobile m_From; - - public InternalGump(Mobile from, HairRestylingDeed deed) : base(50, 50) - { - m_From = from; - m_Deed = deed; - - from.CloseGump(); - - AddBackground(100, 10, 400, 385, 0xA28); - - AddHtmlLocalized(100, 25, 400, 35, 1013008); - AddButton(175, 340, 0xFA5, 0xFA7, 0x0); // CANCEL - - AddHtmlLocalized(210, 342, 90, 35, 1011012); //
HAIRSTYLE SELECTION MENU
- - var RacialData = from.Race == Race.Human ? HumanArray : ElvenArray; - - for (var i = 1; i < RacialData.Length; i++) - { - AddHtmlLocalized( - LayoutArray[i][2], - LayoutArray[i][3], - i == 1 ? 125 : 80, - i == 1 ? 70 : 35, - m_From.Female ? RacialData[i][0] : RacialData[i][1] - ); - if (LayoutArray[i][4] != 0) - { - AddBackground(LayoutArray[i][0], LayoutArray[i][1], 50, 50, 0xA3C); - AddImage(LayoutArray[i][4], LayoutArray[i][5], m_From.Female ? RacialData[i][4] : RacialData[i][5]); - } - - AddButton(LayoutArray[i][6], LayoutArray[i][7], 0xFA5, 0xFA7, i); - } + return; } - public override void OnResponse(NetState sender, RelayInfo info) + if (m_Deed.Deleted) { - if (m_From?.Alive != true) - { - return; - } + return; + } - if (m_Deed.Deleted) - { - return; - } + if (info.ButtonID is < 1 or > 10) + { + return; + } - if (info.ButtonID is < 1 or > 10) - { - return; - } + var RacialData = m_From.Race == Race.Human ? HumanArray : ElvenArray; - var RacialData = m_From.Race == Race.Human ? HumanArray : ElvenArray; - - if (m_From is PlayerMobile pm) - { - pm.SetHairMods(-1, -1); // clear any hairmods (disguise kit, incognito) - pm.HairItemID = pm.Female ? RacialData[info.ButtonID][2] : RacialData[info.ButtonID][3]; - m_Deed.Delete(); - } + if (m_From is PlayerMobile pm) + { + pm.SetHairMods(-1, -1); // clear any hairmods (disguise kit, incognito) + pm.HairItemID = pm.Female ? RacialData[info.ButtonID][2] : RacialData[info.ButtonID][3]; + m_Deed.Delete(); } } } diff --git a/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs b/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs index 9f3eb7962..da5ca4a71 100644 --- a/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs +++ b/Projects/UOContent/Items/Deeds/HolidayTreeDeed.cs @@ -3,171 +3,151 @@ using Server.Multis; using Server.Network; using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class HolidayTreeDeed : Item { - public class HolidayTreeDeed : Item + [Constructible] + public HolidayTreeDeed() : base(0x14F0) { - [Constructible] - public HolidayTreeDeed() : base(0x14F0) + Hue = 0x488; + Weight = 1.0; + LootType = LootType.Blessed; + } + + public override int LabelNumber => 1041116; // a deed for a holiday tree + + public bool ValidatePlacement(Mobile from, Point3D loc) + { + if (from.AccessLevel >= AccessLevel.GameMaster) { - Hue = 0x488; - Weight = 1.0; - LootType = LootType.Blessed; - } - - public HolidayTreeDeed(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1041116; // a deed for a holiday tree - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - LootType = LootType.Blessed; - } - - public bool ValidatePlacement(Mobile from, Point3D loc) - { - if (from.AccessLevel >= AccessLevel.GameMaster) - { - return true; - } - - if (!from.InRange(GetWorldLocation(), 1)) - { - from.SendLocalizedMessage(500446); // That is too far away. - return false; - } - - if (Core.Now.Month != 12) - { - from.SendLocalizedMessage( - 1005700 - ); // You will have to wait till next December to put your tree back up for display. - return false; - } - - var map = from.Map; - - if (map == null) - { - return false; - } - - var house = BaseHouse.FindHouseAt(loc, map, 20); - - if (house?.IsFriend(from) != true) - { - from.SendLocalizedMessage(1005701); // The holiday tree can only be placed in your house. - return false; - } - - if (!map.CanFit(loc, 20)) - { - from.SendLocalizedMessage(500269); // You cannot build that there. - return false; - } - return true; } - public void BeginPlace(Mobile from, HolidayTreeType type) + if (!from.InRange(GetWorldLocation(), 1)) { - from.BeginTarget(-1, true, TargetFlags.None, Placement_OnTarget, type); + from.SendLocalizedMessage(500446); // That is too far away. + return false; } - public void Placement_OnTarget(Mobile from, object targeted, HolidayTreeType type) + if (Core.Now.Month != 12) { - if (targeted is not IPoint3D p) - { - return; - } - - var loc = new Point3D(p); - - if (p is StaticTarget target) - /* NOTE: OSI does not properly normalize Z positioning here. - * A side affect is that you can only place on floors (due to the CanFit call). - * That functionality may be desired. And so, it's included in this script. - */ - { - loc.Z -= TileData.ItemTable[target.ItemID] - .CalcHeight; - } - - if (ValidatePlacement(from, loc)) - { - EndPlace(from, type, loc); - } + from.SendLocalizedMessage( + 1005700 + ); // You will have to wait till next December to put your tree back up for display. + return false; } - public void EndPlace(Mobile from, HolidayTreeType type, Point3D loc) + var map = from.Map; + + if (map == null) { - Delete(); - var tree = new HolidayTree(from, type, loc); - BaseHouse.FindHouseAt(tree)?.Addons.Add(tree); + return false; } - public override void OnDoubleClick(Mobile from) + var house = BaseHouse.FindHouseAt(loc, map, 20); + + if (house?.IsFriend(from) != true) { - from.CloseGump(); - from.SendGump(new HolidayTreeChoiceGump(from, this)); + from.SendLocalizedMessage(1005701); // The holiday tree can only be placed in your house. + return false; + } + + if (!map.CanFit(loc, 20)) + { + from.SendLocalizedMessage(500269); // You cannot build that there. + return false; + } + + return true; + } + + public void BeginPlace(Mobile from, HolidayTreeType type) + { + from.BeginTarget(-1, true, TargetFlags.None, Placement_OnTarget, type); + } + + public void Placement_OnTarget(Mobile from, object targeted, HolidayTreeType type) + { + if (targeted is not IPoint3D p) + { + return; + } + + var loc = new Point3D(p); + + if (p is StaticTarget target) + /* NOTE: OSI does not properly normalize Z positioning here. + * A side affect is that you can only place on floors (due to the CanFit call). + * That functionality may be desired. And so, it's included in this script. + */ + { + loc.Z -= TileData.ItemTable[target.ItemID] + .CalcHeight; + } + + if (ValidatePlacement(from, loc)) + { + EndPlace(from, type, loc); } } - public class HolidayTreeChoiceGump : Gump + public void EndPlace(Mobile from, HolidayTreeType type, Point3D loc) { - private readonly HolidayTreeDeed m_Deed; - private readonly Mobile m_From; + Delete(); + var tree = new HolidayTree(from, type, loc); + BaseHouse.FindHouseAt(tree)?.Addons.Add(tree); + } - public HolidayTreeChoiceGump(Mobile from, HolidayTreeDeed deed) : base(200, 200) + public override void OnDoubleClick(Mobile from) + { + from.CloseGump(); + from.SendGump(new HolidayTreeChoiceGump(from, this)); + } +} + +public class HolidayTreeChoiceGump : Gump +{ + private readonly HolidayTreeDeed m_Deed; + private readonly Mobile m_From; + + public HolidayTreeChoiceGump(Mobile from, HolidayTreeDeed deed) : base(200, 200) + { + m_From = from; + m_Deed = deed; + + AddPage(0); + + AddBackground(0, 0, 220, 120, 5054); + AddBackground(10, 10, 200, 100, 3000); + + AddButton(20, 35, 4005, 4007, 1); + AddHtmlLocalized(55, 35, 145, 25, 1018322); // Classic + + AddButton(20, 65, 4005, 4007, 2); + AddHtmlLocalized(55, 65, 145, 25, 1018321); // Modern + } + + public override void OnResponse(NetState sender, RelayInfo info) + { + if (m_Deed.Deleted) { - m_From = from; - m_Deed = deed; - - AddPage(0); - - AddBackground(0, 0, 220, 120, 5054); - AddBackground(10, 10, 200, 100, 3000); - - AddButton(20, 35, 4005, 4007, 1); - AddHtmlLocalized(55, 35, 145, 25, 1018322); // Classic - - AddButton(20, 65, 4005, 4007, 2); - AddHtmlLocalized(55, 65, 145, 25, 1018321); // Modern + return; } - public override void OnResponse(NetState sender, RelayInfo info) + switch (info.ButtonID) { - if (m_Deed.Deleted) - { - return; - } - - switch (info.ButtonID) - { - case 1: - { - m_Deed.BeginPlace(m_From, HolidayTreeType.Classic); - break; - } - case 2: - { - m_Deed.BeginPlace(m_From, HolidayTreeType.Modern); - break; - } - } + case 1: + { + m_Deed.BeginPlace(m_From, HolidayTreeType.Classic); + break; + } + case 2: + { + m_Deed.BeginPlace(m_From, HolidayTreeType.Modern); + break; + } } } } diff --git a/Projects/UOContent/Items/Deeds/NameChangeDeed.cs b/Projects/UOContent/Items/Deeds/NameChangeDeed.cs index 05a7d3628..45fd6e080 100644 --- a/Projects/UOContent/Items/Deeds/NameChangeDeed.cs +++ b/Projects/UOContent/Items/Deeds/NameChangeDeed.cs @@ -2,115 +2,97 @@ using Server.Gumps; using Server.Misc; using Server.Network; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class NameChangeDeed : Item { - public class NameChangeDeed : Item + [Constructible] + public NameChangeDeed() : base(0x14F0) => LootType = LootType.Blessed; + + public override string DefaultName => "a name change deed"; + + public override void OnDoubleClick(Mobile from) { - [Constructible] - public NameChangeDeed() : base(0x14F0) => LootType = LootType.Blessed; - - public NameChangeDeed(Serial serial) : base(serial) + if (RootParent == from) { + from.CloseGump(); + from.SendGump(new NameChangeDeedGump(this)); } - - public override string DefaultName => "a name change deed"; - - public override void Serialize(IGenericWriter writer) + else { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - - public override void OnDoubleClick(Mobile from) - { - if (RootParent == from) - { - from.CloseGump(); - from.SendGump(new NameChangeDeedGump(this)); - } - else - { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } - } - } - - public class NameChangeDeedGump : Gump - { - private readonly Item m_Sender; - - public NameChangeDeedGump(Item sender) : base(50, 50) - { - m_Sender = sender; - - Closable = true; - Draggable = true; - Resizable = false; - - AddPage(0); - - AddBlackAlpha(10, 120, 250, 85); - AddHtml(10, 125, 250, 20, Color(Center("Name Change Deed"), 0xFFFFFF)); - - AddLabel(73, 15, 1152, ""); - AddLabel(20, 150, 0x480, "New Name:"); - AddTextField(100, 150, 150, 20, 0); - - AddButtonLabeled(75, 180, 1, "Submit"); - } - - public void AddBlackAlpha(int x, int y, int width, int height) - { - AddImageTiled(x, y, width, height, 2624); - AddAlphaRegion(x, y, width, height); - } - - public void AddTextField(int x, int y, int width, int height, int index) - { - AddBackground(x - 2, y - 2, width + 4, height + 4, 0x2486); - AddTextEntry(x + 2, y + 2, width - 4, height - 4, 0, index, ""); - } - - public string Center(string text) => $"
{text}
"; - - public string Color(string text, int color) => $"{text}"; - - public void AddButtonLabeled(int x, int y, int buttonID, string text) - { - AddButton(x, y - 1, 4005, 4007, buttonID); - AddHtml(x + 35, y, 240, 20, Color(text, 0xFFFFFF)); - } - - public override void OnResponse(NetState sender, RelayInfo info) - { - if (m_Sender?.Deleted != false || info.ButtonID != 1 || m_Sender.RootParent != sender.Mobile) - { - return; - } - - var m = sender.Mobile; - var nameEntry = info.GetTextEntry(0); - - var newName = nameEntry?.Text.Trim(); - - if (!NameVerification.Validate(newName, 2, 16, true, false, true, 1, NameVerification.SpaceDashPeriodQuote)) - { - m.SendMessage("That name is unacceptable."); - return; - } - - m.RawName = newName; - m.SendMessage("Your name has been changed!"); - m.SendMessage($"You are now known as {newName}"); - m_Sender.Delete(); + from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. } } } + +public class NameChangeDeedGump : Gump +{ + private readonly Item m_Sender; + + public NameChangeDeedGump(Item sender) : base(50, 50) + { + m_Sender = sender; + + Closable = true; + Draggable = true; + Resizable = false; + + AddPage(0); + + AddBlackAlpha(10, 120, 250, 85); + AddHtml(10, 125, 250, 20, Color(Center("Name Change Deed"), 0xFFFFFF)); + + AddLabel(73, 15, 1152, ""); + AddLabel(20, 150, 0x480, "New Name:"); + AddTextField(100, 150, 150, 20, 0); + + AddButtonLabeled(75, 180, 1, "Submit"); + } + + public void AddBlackAlpha(int x, int y, int width, int height) + { + AddImageTiled(x, y, width, height, 2624); + AddAlphaRegion(x, y, width, height); + } + + public void AddTextField(int x, int y, int width, int height, int index) + { + AddBackground(x - 2, y - 2, width + 4, height + 4, 0x2486); + AddTextEntry(x + 2, y + 2, width - 4, height - 4, 0, index, ""); + } + + public string Center(string text) => $"
{text}
"; + + public string Color(string text, int color) => $"{text}"; + + public void AddButtonLabeled(int x, int y, int buttonID, string text) + { + AddButton(x, y - 1, 4005, 4007, buttonID); + AddHtml(x + 35, y, 240, 20, Color(text, 0xFFFFFF)); + } + + public override void OnResponse(NetState sender, RelayInfo info) + { + if (m_Sender?.Deleted != false || info.ButtonID != 1 || m_Sender.RootParent != sender.Mobile) + { + return; + } + + var m = sender.Mobile; + var nameEntry = info.GetTextEntry(0); + + var newName = nameEntry?.Text.Trim(); + + if (!NameVerification.Validate(newName, 2, 16, true, false, true, 1, NameVerification.SpaceDashPeriodQuote)) + { + m.SendMessage("That name is unacceptable."); + return; + } + + m.RawName = newName; + m.SendMessage("Your name has been changed!"); + m.SendMessage($"You are now known as {newName}"); + m_Sender.Delete(); + } +} diff --git a/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs b/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs index 5db09f6ef..1b75e9eaf 100644 --- a/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs +++ b/Projects/UOContent/Items/Deeds/NewPlayerTicket.cs @@ -2,217 +2,188 @@ using Server.Gumps; using Server.Network; using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +[Serializable(0, false)] +public partial class NewPlayerTicket : Item { - public class NewPlayerTicket : Item + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.Owner)]")] + private Mobile _owner; + + [Constructible] + public NewPlayerTicket() : base(0x14EF) { - [Constructible] - public NewPlayerTicket() : base(0x14EF) + Weight = 1.0; + LootType = LootType.Blessed; + } + + public override int LabelNumber => 1062094; // a young player ticket + + public override bool DisplayLootType => false; + + public override void GetProperties(ObjectPropertyList list) + { + base.GetProperties(list); + + // This is half a prize ticket! Double-click this ticket and target any other ticket marked NEW PLAYER and get a prize! This ticket will only work for YOU, so don't give it away! + list.Add(1041492); + } + + public override void OnDoubleClick(Mobile from) + { + if (from != Owner) { - Weight = 1.0; - LootType = LootType.Blessed; + from.SendLocalizedMessage(501926); // This isn't your ticket! Shame on you! You have to use YOUR ticket. } - - public NewPlayerTicket(Serial serial) : base(serial) + else if (!IsChildOf(from.Backpack)) { + from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. } - - [CommandProperty(AccessLevel.GameMaster)] - public Mobile Owner { get; set; } - - public override int LabelNumber => 1062094; // a young player ticket - - public override bool DisplayLootType => false; - - public override void GetProperties(ObjectPropertyList list) + else { - base.GetProperties(list); - - list.Add( - 1041492 - ); // This is half a prize ticket! Double-click this ticket and target any other ticket marked NEW PLAYER and get a prize! This ticket will only work for YOU, so don't give it away! + from.SendLocalizedMessage(501927); // Target any other ticket marked NEW PLAYER to win a prize. + from.Target = new InternalTarget(this); } + } - public override void Serialize(IGenericWriter writer) + private class InternalTarget : Target + { + private readonly NewPlayerTicket m_Ticket; + + public InternalTarget(NewPlayerTicket ticket) : base(2, false, TargetFlags.None) => m_Ticket = ticket; + + protected override void OnTarget(Mobile from, object targeted) { - base.Serialize(writer); - - writer.Write(0); // version - - writer.Write(Owner); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) + if (targeted == m_Ticket) { - case 0: - { - Owner = reader.ReadEntity(); - break; - } + from.SendLocalizedMessage(501928); // You can't target the same ticket! } - - if (Name == "a young player ticket") + else if (targeted is NewPlayerTicket theirTicket) { - Name = null; - } - } + var them = theirTicket.Owner; - public override void OnDoubleClick(Mobile from) - { - if (from != Owner) - { - from.SendLocalizedMessage(501926); // This isn't your ticket! Shame on you! You have to use YOUR ticket. - } - else if (!IsChildOf(from.Backpack)) - { - from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } - else - { - from.SendLocalizedMessage(501927); // Target any other ticket marked NEW PLAYER to win a prize. - from.Target = new InternalTarget(this); - } - } - - private class InternalTarget : Target - { - private readonly NewPlayerTicket m_Ticket; - - public InternalTarget(NewPlayerTicket ticket) : base(2, false, TargetFlags.None) => m_Ticket = ticket; - - protected override void OnTarget(Mobile from, object targeted) - { - if (targeted == m_Ticket) + if (them?.Deleted != false) { - from.SendLocalizedMessage(501928); // You can't target the same ticket! - } - else if (targeted is NewPlayerTicket theirTicket) - { - var them = theirTicket.Owner; - - if (them?.Deleted != false) - { - from.SendLocalizedMessage(501930); // That is not a valid ticket. - } - else - { - from.SendGump(new InternalGump(from, m_Ticket)); - them.SendGump(new InternalGump(them, theirTicket)); - } - } - else if ((targeted as Item)?.ItemID == 0x14F0) - { - from.SendLocalizedMessage(501931); // You need to find another ticket marked NEW PLAYER. + from.SendLocalizedMessage(501930); // That is not a valid ticket. } else { - from.SendLocalizedMessage(501929); // You will need to select a ticket. + from.SendGump(new InternalGump(from, m_Ticket)); + them.SendGump(new InternalGump(them, theirTicket)); } } + else if ((targeted as Item)?.ItemID == 0x14F0) + { + from.SendLocalizedMessage(501931); // You need to find another ticket marked NEW PLAYER. + } + else + { + from.SendLocalizedMessage(501929); // You will need to select a ticket. + } } + } - private class InternalGump : Gump + private class InternalGump : Gump + { + private readonly Mobile m_From; + private readonly NewPlayerTicket m_Ticket; + + public InternalGump(Mobile from, NewPlayerTicket ticket) : base(50, 50) { - private readonly Mobile m_From; - private readonly NewPlayerTicket m_Ticket; + m_From = from; + m_Ticket = ticket; - public InternalGump(Mobile from, NewPlayerTicket ticket) : base(50, 50) + AddBackground(0, 0, 400, 385, 0xA28); + + // Choose the gift you prefer. WARNING: if you cancel, and your partner does not, you will need to find another matching ticket! + AddHtmlLocalized(30, 45, 340, 70, 1013011, true, true); + + AddButton(46, 128, 0xFA5, 0xFA7, 1); + AddHtmlLocalized(80, 130, 320, 35, 1013012); // A sextant + + AddButton(46, 163, 0xFA5, 0xFA7, 2); + AddHtmlLocalized(80, 165, 320, 35, 1013013); // A coupon for a single hair restyling + + AddButton(46, 198, 0xFA5, 0xFA7, 3); + AddHtmlLocalized(80, 200, 320, 35, 1013014); // A spellbook with all 1st - 4th spells. + + AddButton(46, 233, 0xFA5, 0xFA7, 4); + AddHtmlLocalized(80, 235, 320, 35, 1013015); // A wand of fireworks + + AddButton(46, 268, 0xFA5, 0xFA7, 5); + AddHtmlLocalized(80, 270, 320, 35, 1013016); // A spyglass + + AddButton(46, 303, 0xFA5, 0xFA7, 6); + AddHtmlLocalized(80, 305, 320, 35, 1013017); // Dyes and a dye tub + + AddButton(120, 340, 0xFA5, 0xFA7, 0); + AddHtmlLocalized(154, 342, 100, 35, 1011012); // CANCEL + } + + public override void OnResponse(NetState sender, RelayInfo info) + { + if (m_Ticket.Deleted) { - m_From = from; - m_Ticket = ticket; - - AddBackground(0, 0, 400, 385, 0xA28); - - AddHtmlLocalized( - 30, - 45, - 340, - 70, - 1013011, - true, - true - ); // Choose the gift you prefer. WARNING: if you cancel, and your partner does not, you will need to find another matching ticket! - - AddButton(46, 128, 0xFA5, 0xFA7, 1); - AddHtmlLocalized(80, 130, 320, 35, 1013012); // A sextant - - AddButton(46, 163, 0xFA5, 0xFA7, 2); - AddHtmlLocalized(80, 165, 320, 35, 1013013); // A coupon for a single hair restyling - - AddButton(46, 198, 0xFA5, 0xFA7, 3); - AddHtmlLocalized(80, 200, 320, 35, 1013014); // A spellbook with all 1st - 4th spells. - - AddButton(46, 233, 0xFA5, 0xFA7, 4); - AddHtmlLocalized(80, 235, 320, 35, 1013015); // A wand of fireworks - - AddButton(46, 268, 0xFA5, 0xFA7, 5); - AddHtmlLocalized(80, 270, 320, 35, 1013016); // A spyglass - - AddButton(46, 303, 0xFA5, 0xFA7, 6); - AddHtmlLocalized(80, 305, 320, 35, 1013017); // Dyes and a dye tub - - AddButton(120, 340, 0xFA5, 0xFA7, 0); - AddHtmlLocalized(154, 342, 100, 35, 1011012); // CANCEL + return; } - public override void OnResponse(NetState sender, RelayInfo info) + var number = 0; + + Item item = null; + Item item2 = null; + + switch (info.ButtonID) { - if (m_Ticket.Deleted) - { - return; - } - - var number = 0; - - Item item = null; - Item item2 = null; - - switch (info.ButtonID) - { - case 1: + case 1: + { item = new Sextant(); number = 1010494; break; // A sextant has been placed in your backpack. - case 2: + } + case 2: + { item = new HairRestylingDeed(); number = 501933; break; // A coupon for a free hair restyling has been placed in your backpack. - case 3: + } + case 3: + { item = new Spellbook(0xFFFFFFFF); number = 1010495; break; // A spellbook with all 1st to 4th circle spells has been placed in your backpack. - case 4: + } + case 4: + { item = new FireworksWand(); number = 501935; break; // A wand of fireworks has been placed in your backpack. - case 5: + } + case 5: + { item = new Spyglass(); number = 501936; break; // A spyglass has been placed in your backpack. - case 6: + } + case 6: + { item = new DyeTub(); item2 = new Dyes(); number = 501937; break; // The dyes and dye tub have been placed in your backpack. - } - - if (item != null) - { - m_Ticket.Delete(); - - m_From.SendLocalizedMessage(number); - m_From.AddToBackpack(item); - - if (item2 != null) - { - m_From.AddToBackpack(item2); } + } + + if (item != null) + { + m_Ticket.Delete(); + + m_From.SendLocalizedMessage(number); + m_From.AddToBackpack(item); + + if (item2 != null) + { + m_From.AddToBackpack(item2); } } } diff --git a/Projects/UOContent/Migrations/Server.Items.BarkeepContract.v0.json b/Projects/UOContent/Migrations/Server.Items.BarkeepContract.v0.json new file mode 100644 index 000000000..76a2853cc --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BarkeepContract.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BarkeepContract" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ClothingBlessDeed.v0.json b/Projects/UOContent/Migrations/Server.Items.ClothingBlessDeed.v0.json new file mode 100644 index 000000000..4e081598a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ClothingBlessDeed.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ClothingBlessDeed" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.CommodityDeed.v1.json b/Projects/UOContent/Migrations/Server.Items.CommodityDeed.v1.json new file mode 100644 index 000000000..57487eb5d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.CommodityDeed.v1.json @@ -0,0 +1,11 @@ +{ + "version": 1, + "type": "Server.Items.CommodityDeed", + "properties": [ + { + "name": "Commodity", + "type": "Server.Item", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DragonBardingDeed.v2.json b/Projects/UOContent/Migrations/Server.Items.DragonBardingDeed.v2.json new file mode 100644 index 000000000..a6a26d015 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DragonBardingDeed.v2.json @@ -0,0 +1,27 @@ +{ + "version": 2, + "type": "Server.Items.DragonBardingDeed", + "properties": [ + { + "name": "CraftedBy", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Exceptional", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "RawResource", + "type": "Server.Items.CraftResource", + "rule": "EnumMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.HairRestylingDeed.v0.json b/Projects/UOContent/Migrations/Server.Items.HairRestylingDeed.v0.json new file mode 100644 index 000000000..8db04fb3d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.HairRestylingDeed.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.HairRestylingDeed" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.HolidayTreeDeed.v0.json b/Projects/UOContent/Migrations/Server.Items.HolidayTreeDeed.v0.json new file mode 100644 index 000000000..8263aa14e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.HolidayTreeDeed.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.HolidayTreeDeed" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.NameChangeDeed.v0.json b/Projects/UOContent/Migrations/Server.Items.NameChangeDeed.v0.json new file mode 100644 index 000000000..265569945 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.NameChangeDeed.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.NameChangeDeed" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.NewPlayerTicket.v0.json b/Projects/UOContent/Migrations/Server.Items.NewPlayerTicket.v0.json new file mode 100644 index 000000000..b73d06bb7 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.NewPlayerTicket.v0.json @@ -0,0 +1,11 @@ +{ + "version": 0, + "type": "Server.Items.NewPlayerTicket", + "properties": [ + { + "name": "Owner", + "type": "Server.Mobile", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs b/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs index 3e08164d1..64671c8d5 100644 --- a/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs +++ b/Projects/UOContent/Mobiles/Animals/Mounts/SwampDragon.cs @@ -4,7 +4,7 @@ namespace Server.Mobiles { public class SwampDragon : BaseMount { - private Mobile m_BardingCrafter; + private string _bardingCraftedBy; private bool m_BardingExceptional; private int m_BardingHP; private CraftResource m_BardingResource; @@ -54,12 +54,12 @@ namespace Server.Mobiles public override string CorpseName => "a swamp dragon corpse"; [CommandProperty(AccessLevel.GameMaster)] - public Mobile BardingCrafter + public string BardingCraftedBy { - get => m_BardingCrafter; + get => _bardingCraftedBy; set { - m_BardingCrafter = value; + _bardingCraftedBy = value; InvalidateProperties(); } } @@ -156,9 +156,9 @@ namespace Server.Mobiles { base.GetProperties(list); - if (m_HasBarding && m_BardingExceptional && m_BardingCrafter != null) + if (m_HasBarding && m_BardingExceptional && _bardingCraftedBy != null) { - list.Add(1060853, m_BardingCrafter.Name); // armor exceptionally crafted by ~1_val~ + list.Add(1060853, _bardingCraftedBy); // armor exceptionally crafted by ~1_val~ } } @@ -166,10 +166,10 @@ namespace Server.Mobiles { base.Serialize(writer); - writer.Write(1); // version + writer.Write(2); // version writer.Write(m_BardingExceptional); - writer.Write(m_BardingCrafter); + writer.Write(_bardingCraftedBy); writer.Write(m_HasBarding); writer.Write(m_BardingHP); writer.Write((int)m_BardingResource); @@ -183,10 +183,21 @@ namespace Server.Mobiles switch (version) { + case 2: + { + m_BardingExceptional = reader.ReadBool(); + _bardingCraftedBy = reader.ReadString(); + m_HasBarding = reader.ReadBool(); + m_BardingHP = reader.ReadInt(); + m_BardingResource = (CraftResource)reader.ReadInt(); + break; + } case 1: { m_BardingExceptional = reader.ReadBool(); - m_BardingCrafter = reader.ReadEntity(); + var crafter = reader.ReadEntity(); + // Name might not be set during this deserialization + Timer.StartTimer(() => _bardingCraftedBy = crafter?.RawName); m_HasBarding = reader.ReadBool(); m_BardingHP = reader.ReadInt(); m_BardingResource = (CraftResource)reader.ReadInt();