diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs b/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs index 65cd08d66..9f63e9722 100644 --- a/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs +++ b/Projects/UOContent/Engines/Treasures of Tokuno/BasePigmentsOfTokuno.cs @@ -1,289 +1,231 @@ using System; +using ModernUO.Serialization; using Server.Engines.Stealables; using Server.Misc; using Server.Mobiles; using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public abstract partial class BasePigmentsOfTokuno : Item, IUsesRemaining { - public abstract class BasePigmentsOfTokuno : Item, IUsesRemaining + private static readonly Type[] m_Glasses = { - private static readonly Type[] m_Glasses = + typeof(MaritimeGlasses), + typeof(WizardsGlasses), + typeof(TradeGlasses), + typeof(LyricalGlasses), + typeof(NecromanticGlasses), + typeof(LightOfWayGlasses), + typeof(FoldedSteelGlasses), + typeof(PoisonedGlasses), + typeof(TreasureTrinketGlasses), + typeof(MaceShieldGlasses), + typeof(ArtsGlasses), + typeof(AnthropomorphistGlasses) + }; + + private static readonly Type[] m_Replicas = + { + typeof(ANecromancerShroud), + typeof(BraveKnightOfTheBritannia), + typeof(CaptainJohnsHat), + typeof(DetectiveBoots), + typeof(DjinnisRing), + typeof(EmbroideredOakLeafCloak), + typeof(GuantletsOfAnger), + typeof(LieutenantOfTheBritannianRoyalGuard), + typeof(OblivionsNeedle), + typeof(RoyalGuardSurvivalKnife), + typeof(SamaritanRobe), + typeof(TheMostKnowledgePerson), + typeof(TheRobeOfBritanniaAri), + typeof(AcidProofRobe), + typeof(Calm), + typeof(CrownOfTalKeesh), + typeof(FangOfRactus), + typeof(GladiatorsCollar), + typeof(OrcChieftainHelm), + typeof(Pacify), + typeof(Quell), + typeof(ShroudOfDeciet), + typeof(Subdue) + }; + + private static readonly Type[] m_DyableHeritageItems = + { + typeof(ChargerOfTheFallen), + typeof(SamuraiHelm), + typeof(HolySword), + typeof(LeggingsOfEmbers), + typeof(ShaminoCrossbow) + }; + + private TextDefinition m_Label; + + [EncodedInt] + [InvalidateProperties] + [SerializableField(0)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private int _usesRemaining; + + public BasePigmentsOfTokuno() : base(0xEFF) + { + Weight = 1.0; + _usesRemaining = 1; + } + + public BasePigmentsOfTokuno(int uses) : base(0xEFF) + { + Weight = 1.0; + _usesRemaining = uses; + } + + public BasePigmentsOfTokuno(Serial serial) : base(serial) + { + } + + public override int LabelNumber => 1070933; // Pigments of Tokuno + + protected TextDefinition Label + { + get => m_Label; + set { - typeof(MaritimeGlasses), - typeof(WizardsGlasses), - typeof(TradeGlasses), - typeof(LyricalGlasses), - typeof(NecromanticGlasses), - typeof(LightOfWayGlasses), - typeof(FoldedSteelGlasses), - typeof(PoisonedGlasses), - typeof(TreasureTrinketGlasses), - typeof(MaceShieldGlasses), - typeof(ArtsGlasses), - typeof(AnthropomorphistGlasses) - }; - - private static readonly Type[] m_Replicas = - { - typeof(ANecromancerShroud), - typeof(BraveKnightOfTheBritannia), - typeof(CaptainJohnsHat), - typeof(DetectiveBoots), - typeof(DjinnisRing), - typeof(EmbroideredOakLeafCloak), - typeof(GuantletsOfAnger), - typeof(LieutenantOfTheBritannianRoyalGuard), - typeof(OblivionsNeedle), - typeof(RoyalGuardSurvivalKnife), - typeof(SamaritanRobe), - typeof(TheMostKnowledgePerson), - typeof(TheRobeOfBritanniaAri), - typeof(AcidProofRobe), - typeof(Calm), - typeof(CrownOfTalKeesh), - typeof(FangOfRactus), - typeof(GladiatorsCollar), - typeof(OrcChieftainHelm), - typeof(Pacify), - typeof(Quell), - typeof(ShroudOfDeciet), - typeof(Subdue) - }; - - private static readonly Type[] m_DyableHeritageItems = - { - typeof(ChargerOfTheFallen), - typeof(SamuraiHelm), - typeof(HolySword), - typeof(LeggingsOfEmbers), - typeof(ShaminoCrossbow) - }; - - private TextDefinition m_Label; - - private int m_UsesRemaining; - - public BasePigmentsOfTokuno() : base(0xEFF) - { - Weight = 1.0; - m_UsesRemaining = 1; - } - - public BasePigmentsOfTokuno(int uses) : base(0xEFF) - { - Weight = 1.0; - m_UsesRemaining = uses; - } - - public BasePigmentsOfTokuno(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070933; // Pigments of Tokuno - - protected TextDefinition Label - { - get => m_Label; - set - { - m_Label = value; - InvalidateProperties(); - } - } - - /* DO NOT USE! Only used in serialization of pigments that originally derived from Item */ - - protected bool InheritsItem { get; private set; } - - [CommandProperty(AccessLevel.GameMaster)] - public int UsesRemaining - { - get => m_UsesRemaining; - set - { - m_UsesRemaining = value; - InvalidateProperties(); - } - } - - bool IUsesRemaining.ShowUsesRemaining - { - get => true; - set { } - } - - public override void GetProperties(IPropertyList list) - { - base.GetProperties(list); - - m_Label.AddTo(list); - list.Add(1060584, m_UsesRemaining); // uses remaining: ~1_val~ - } - - public override void OnDoubleClick(Mobile from) - { - if (IsAccessibleTo(from) && from.InRange(GetWorldLocation(), 3)) - { - from.SendLocalizedMessage(1070929); // Select the artifact or enhanced magic item to dye. - from.BeginTarget(3, false, TargetFlags.None, InternalCallback); - } - else - { - from.SendLocalizedMessage(502436); // That is not accessible. - } - } - - private void InternalCallback(Mobile from, object targeted) - { - if (Deleted || UsesRemaining <= 0 || !from.InRange(GetWorldLocation(), 3) || - !IsAccessibleTo(from)) - { - return; - } - - if (targeted is not Item i) - { - from.SendLocalizedMessage(1070931); // You can only dye artifacts and enhanced magic items with this tub. - } - else if (!from.InRange(i.GetWorldLocation(), 3) || !IsAccessibleTo(from)) - { - from.SendLocalizedMessage(502436); // That is not accessible. - } - else if (from.Items.Contains(i)) - { - from.SendLocalizedMessage(1070930); // Can't dye artifacts or enhanced magic items that are being worn. - } - else if (i.IsLockedDown) - { - from.SendLocalizedMessage( - 1070932 - ); // You may not dye artifacts and enhanced magic items which are locked down. - } - else if (i.QuestItem) - { - from.SendLocalizedMessage(1151836); // You may not dye toggled quest items. - } - else if (i is MetalPigmentsOfTokuno) - { - from.SendLocalizedMessage(1042417); // You cannot dye that. - } - else if (i is LesserPigmentsOfTokuno) - { - from.SendLocalizedMessage(1042417); // You cannot dye that. - } - else if (i is PigmentsOfTokuno) - { - from.SendLocalizedMessage(1042417); // You cannot dye that. - } - else if (!IsValidItem(i)) - { - from.SendLocalizedMessage( - 1070931 - ); // You can only dye artifacts and enhanced magic items with this tub. //Yes, it says tub on OSI. Don't ask me why ;p - } - else - { - // Notes: on OSI there IS no hue check to see if it's already hued. and no messages on successful hue either - i.Hue = Hue; - - if (--UsesRemaining <= 0) - { - Delete(); - } - - from.PlaySound(0x23E); // As per OSI TC1 - } - } - - public static bool IsValidItem(Item i) - { - if (i is BasePigmentsOfTokuno) - { - return false; - } - - var t = i.GetType(); - - var resource = CraftResource.None; - - if (i is BaseWeapon weapon) - { - resource = weapon.Resource; - } - else if (i is BaseArmor armor) - { - resource = armor.Resource; - } - else if (i is BaseClothing clothing) - { - resource = clothing.Resource; - } - - if (!CraftResources.IsStandard(resource)) - { - return true; - } - - return t.InTypeList(TreasuresOfTokuno.TokunoDyable) - || t.InTypeList(TreasuresOfTokuno.LesserArtifactsTotal) - || t.InTypeList(TreasuresOfTokuno.GreaterArtifacts) - || t.InTypeList(DemonKnight.ArtifactRarity10) - || t.InTypeList(DemonKnight.ArtifactRarity11) - || t.InTypeList(MondainsLegacy.Artifacts) - || t.InTypeList(StealableArtifacts.TypesOfEntries) - || t.InTypeList(Paragon.Artifacts) - || t.InTypeList(Leviathan.Artifacts) - || t.InTypeList(TreasureMapChest.Artifacts) - || t.InTypeList(m_Replicas) - || t.InTypeList(m_DyableHeritageItems) - || t.InTypeList(m_Glasses); - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); - - writer.WriteEncodedInt(m_UsesRemaining); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 1: - { - m_UsesRemaining = reader.ReadEncodedInt(); - break; - } - case 0: // Old pigments that inherited from item - { - InheritsItem = true; - - if (this is LesserPigmentsOfTokuno) - { - ((LesserPigmentsOfTokuno)this).Type = (LesserPigmentType)reader.ReadEncodedInt(); - } - else if (this is PigmentsOfTokuno) - { - ((PigmentsOfTokuno)this).Type = (PigmentType)reader.ReadEncodedInt(); - } - else if (this is MetalPigmentsOfTokuno) - { - reader.ReadEncodedInt(); - } - - m_UsesRemaining = reader.ReadEncodedInt(); - - break; - } - } + m_Label = value; + InvalidateProperties(); } } + + bool IUsesRemaining.ShowUsesRemaining + { + get => true; + set { } + } + + public override void GetProperties(IPropertyList list) + { + base.GetProperties(list); + + m_Label.AddTo(list); + list.Add(1060584, _usesRemaining); // uses remaining: ~1_val~ + } + + public override void OnDoubleClick(Mobile from) + { + if (IsAccessibleTo(from) && from.InRange(GetWorldLocation(), 3)) + { + from.SendLocalizedMessage(1070929); // Select the artifact or enhanced magic item to dye. + from.BeginTarget(3, false, TargetFlags.None, InternalCallback); + } + else + { + from.SendLocalizedMessage(502436); // That is not accessible. + } + } + + private void InternalCallback(Mobile from, object targeted) + { + if (Deleted || UsesRemaining <= 0 || !from.InRange(GetWorldLocation(), 3) || + !IsAccessibleTo(from)) + { + return; + } + + if (targeted is not Item i) + { + from.SendLocalizedMessage(1070931); // You can only dye artifacts and enhanced magic items with this tub. + } + else if (!from.InRange(i.GetWorldLocation(), 3) || !IsAccessibleTo(from)) + { + from.SendLocalizedMessage(502436); // That is not accessible. + } + else if (from.Items.Contains(i)) + { + from.SendLocalizedMessage(1070930); // Can't dye artifacts or enhanced magic items that are being worn. + } + else if (i.IsLockedDown) + { + // You may not dye artifacts and enhanced magic items which are locked down. + from.SendLocalizedMessage(1070932); + } + else if (i.QuestItem) + { + from.SendLocalizedMessage(1151836); // You may not dye toggled quest items. + } + else if (i is MetalPigmentsOfTokuno) + { + from.SendLocalizedMessage(1042417); // You cannot dye that. + } + else if (i is LesserPigmentsOfTokuno) + { + from.SendLocalizedMessage(1042417); // You cannot dye that. + } + else if (i is PigmentsOfTokuno) + { + from.SendLocalizedMessage(1042417); // You cannot dye that. + } + else if (!IsValidItem(i)) + { + // You can only dye artifacts and enhanced magic items with this tub. //Yes, it says tub on OSI. Don't ask me why ;p + from.SendLocalizedMessage(1070931); + } + else + { + // Notes: on OSI there IS no hue check to see if it's already hued. and no messages on successful hue either + i.Hue = Hue; + + if (--UsesRemaining <= 0) + { + Delete(); + } + + from.PlaySound(0x23E); // As per OSI TC1 + } + } + + public static bool IsValidItem(Item i) + { + if (i is BasePigmentsOfTokuno) + { + return false; + } + + var t = i.GetType(); + + var resource = CraftResource.None; + + if (i is BaseWeapon weapon) + { + resource = weapon.Resource; + } + else if (i is BaseArmor armor) + { + resource = armor.Resource; + } + else if (i is BaseClothing clothing) + { + resource = clothing.Resource; + } + + if (!CraftResources.IsStandard(resource)) + { + return true; + } + + return t.InTypeList(TreasuresOfTokuno.TokunoDyable) + || t.InTypeList(TreasuresOfTokuno.LesserArtifactsTotal) + || t.InTypeList(TreasuresOfTokuno.GreaterArtifacts) + || t.InTypeList(DemonKnight.ArtifactRarity10) + || t.InTypeList(DemonKnight.ArtifactRarity11) + || t.InTypeList(MondainsLegacy.Artifacts) + || t.InTypeList(StealableArtifacts.TypesOfEntries) + || t.InTypeList(Paragon.Artifacts) + || t.InTypeList(Leviathan.Artifacts) + || t.InTypeList(TreasureMapChest.Artifacts) + || t.InTypeList(m_Replicas) + || t.InTypeList(m_DyableHeritageItems) + || t.InTypeList(m_Glasses); + } } diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/GreaterArtifacts.cs b/Projects/UOContent/Engines/Treasures of Tokuno/GreaterArtifacts.cs index 7603968e8..a9fa2d7ca 100644 --- a/Projects/UOContent/Engines/Treasures of Tokuno/GreaterArtifacts.cs +++ b/Projects/UOContent/Engines/Treasures of Tokuno/GreaterArtifacts.cs @@ -1,567 +1,376 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class DarkenedSky : Kama { - public class DarkenedSky : Kama + [Constructible] + public DarkenedSky() { - [Constructible] - public DarkenedSky() - { - WeaponAttributes.HitLightning = 60; - Attributes.WeaponSpeed = 25; - Attributes.WeaponDamage = 50; - } - - public DarkenedSky(Serial serial) : base(serial) - { - } - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override int LabelNumber => 1070966; // Darkened Sky - - public override void GetDamageTypes( - Mobile wielder, out int phys, out int fire, out int cold, out int pois, - out int nrgy, out int chaos, out int direct - ) - { - phys = fire = pois = chaos = direct = 0; - cold = nrgy = 50; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } + WeaponAttributes.HitLightning = 60; + Attributes.WeaponSpeed = 25; + Attributes.WeaponDamage = 50; } - public class KasaOfTheRajin : Kasa + public override int InitMinHits => 255; + public override int InitMaxHits => 255; + + public override int LabelNumber => 1070966; // Darkened Sky + + public override void GetDamageTypes( + Mobile wielder, out int phys, out int fire, out int cold, out int pois, + out int nrgy, out int chaos, out int direct + ) { - [Constructible] - public KasaOfTheRajin() => Attributes.SpellDamage = 12; - - public KasaOfTheRajin(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070969; // Kasa of the Raj-in - - public override int BasePhysicalResistance => 12; - public override int BaseFireResistance => 17; - public override int BaseColdResistance => 21; - public override int BasePoisonResistance => 17; - public override int BaseEnergyResistance => 17; - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(2); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version <= 1) - { - MaxHitPoints = 255; - HitPoints = 255; - } - - if (version == 0) - { - LootType = LootType.Regular; - } - } - } - - public class RuneBeetleCarapace : PlateDo - { - [Constructible] - public RuneBeetleCarapace() - { - Attributes.BonusMana = 10; - Attributes.RegenMana = 3; - Attributes.LowerManaCost = 15; - ArmorAttributes.LowerStatReq = 100; - ArmorAttributes.MageArmor = 1; - } - - public RuneBeetleCarapace(Serial serial) : base(serial) - { - } - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override int LabelNumber => 1070968; // Rune Beetle Carapace - - public override int BaseColdResistance => 14; - public override int BaseEnergyResistance => 14; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class Stormgrip : LeatherNinjaMitts - { - [Constructible] - public Stormgrip() - { - Attributes.BonusInt = 8; - Attributes.Luck = 125; - Attributes.WeaponDamage = 25; - } - - public Stormgrip(Serial serial) : base(serial) - { - } - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override int LabelNumber => 1070970; // Stormgrip - - public override int BasePhysicalResistance => 10; - public override int BaseColdResistance => 18; - public override int BaseEnergyResistance => 18; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class SwordOfTheStampede : NoDachi - { - [Constructible] - public SwordOfTheStampede() - { - WeaponAttributes.HitHarm = 100; - Attributes.AttackChance = 10; - Attributes.WeaponDamage = 60; - } - - public SwordOfTheStampede(Serial serial) : base(serial) - { - } - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override int LabelNumber => 1070964; // Sword of the Stampede - - public override void GetDamageTypes( - Mobile wielder, out int phys, out int fire, out int cold, out int pois, - out int nrgy, out int chaos, out int direct - ) - { - phys = fire = pois = nrgy = chaos = direct = 0; - cold = 100; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class SwordsOfProsperity : Daisho - { - [Constructible] - public SwordsOfProsperity() - { - WeaponAttributes.MageWeapon = 30; - Attributes.SpellChanneling = 1; - Attributes.CastSpeed = 1; - Attributes.Luck = 200; - } - - public SwordsOfProsperity(Serial serial) : base(serial) - { - } - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override int LabelNumber => 1070963; // Swords of Prosperity - - public override void GetDamageTypes( - Mobile wielder, out int phys, out int fire, out int cold, out int pois, - out int nrgy, out int chaos, out int direct - ) - { - phys = cold = pois = nrgy = chaos = direct = 0; - fire = 100; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class TheHorselord : Yumi - { - [Constructible] - public TheHorselord() - { - Attributes.BonusDex = 5; - Attributes.RegenMana = 1; - Attributes.Luck = 125; - Attributes.WeaponDamage = 50; - - Slayer = SlayerName.ElementalBan; - Slayer2 = SlayerName.ReptilianDeath; - } - - public TheHorselord(Serial serial) : base(serial) - { - } - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override int LabelNumber => 1070967; // The Horselord - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class TomeOfLostKnowledge : Spellbook - { - [Constructible] - public TomeOfLostKnowledge() - { - LootType = LootType.Regular; - Hue = 0x530; - - SkillBonuses.SetValues(0, SkillName.Magery, 15.0); - Attributes.BonusInt = 8; - Attributes.LowerManaCost = 15; - Attributes.SpellDamage = 15; - } - - public TomeOfLostKnowledge(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070971; // Tome of Lost Knowledge - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class WindsEdge : Tessen - { - [Constructible] - public WindsEdge() - { - WeaponAttributes.HitLeechMana = 40; - - Attributes.WeaponDamage = 50; - Attributes.WeaponSpeed = 50; - Attributes.DefendChance = 10; - } - - public WindsEdge(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070965; // Wind's Edge - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void GetDamageTypes( - Mobile wielder, out int phys, out int fire, out int cold, out int pois, - out int nrgy, out int chaos, out int direct - ) - { - phys = fire = cold = pois = chaos = direct = 0; - nrgy = 100; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public enum PigmentType - { - None, - ParagonGold, - VioletCouragePurple, - InvulnerabilityBlue, - LunaWhite, - DryadGreen, - ShadowDancerBlack, - BerserkerRed, - NoxGreen, - RumRed, - FireOrange, - FadedCoal, - Coal, - FadedGold, - StormBronze, - Rose, - MidnightCoal, - FadedBronze, - FadedRose, - DeepRose - } - - public class PigmentsOfTokuno : BasePigmentsOfTokuno - { - private static readonly int[][] m_Table = - { - // Hue, Label - new[] - { - /*PigmentType.None,*/ 0, -1 - }, - new[] - { - /*PigmentType.ParagonGold,*/ 0x501, 1070987 - }, - new[] - { - /*PigmentType.VioletCouragePurple,*/ 0x486, 1070988 - }, - new[] - { - /*PigmentType.InvulnerabilityBlue,*/ 0x4F2, 1070989 - }, - new[] - { - /*PigmentType.LunaWhite,*/ 0x47E, 1070990 - }, - new[] - { - /*PigmentType.DryadGreen,*/ 0x48F, 1070991 - }, - new[] - { - /*PigmentType.ShadowDancerBlack,*/ 0x455, 1070992 - }, - new[] - { - /*PigmentType.BerserkerRed,*/ 0x21, 1070993 - }, - new[] - { - /*PigmentType.NoxGreen,*/ 0x58C, 1070994 - }, - new[] - { - /*PigmentType.RumRed,*/ 0x66C, 1070995 - }, - new[] - { - /*PigmentType.FireOrange,*/ 0x54F, 1070996 - }, - new[] - { - /*PigmentType.Fadedcoal,*/ 0x96A, 1079579 - }, - new[] - { - /*PigmentType.Coal,*/ 0x96B, 1079580 - }, - new[] - { - /*PigmentType.FadedGold,*/ 0x972, 1079581 - }, - new[] - { - /*PigmentType.StormBronze,*/ 0x977, 1079582 - }, - new[] - { - /*PigmentType.Rose,*/ 0x97C, 1079583 - }, - new[] - { - /*PigmentType.MidnightCoal,*/ 0x96C, 1079584 - }, - new[] - { - /*PigmentType.FadedBronze,*/ 0x975, 1079585 - }, - new[] - { - /*PigmentType.FadedRose,*/ 0x97B, 1079586 - }, - new[] - { - /*PigmentType.DeepRose,*/ 0x97E, 1079587 - } - }; - - private PigmentType m_Type; - - [Constructible] - public PigmentsOfTokuno(PigmentType type = PigmentType.None) : this( - type, - type is PigmentType.None or >= PigmentType.FadedCoal ? 10 : 50 - ) - { - } - - [Constructible] - public PigmentsOfTokuno(PigmentType type, int uses) : base(uses) - { - Weight = 1.0; - Type = type; - } - - public PigmentsOfTokuno(Serial serial) : base(serial) - { - } - - [CommandProperty(AccessLevel.GameMaster)] - public PigmentType Type - { - get => m_Type; - set - { - m_Type = value; - - var v = (int)m_Type; - - if (v >= 0 && v < m_Table.Length) - { - Hue = m_Table[v][0]; - Label = m_Table[v][1]; - } - else - { - Hue = 0; - Label = -1; - } - } - } - - public override int LabelNumber => 1070933; // Pigments of Tokuno - - public static int[] GetInfo(PigmentType type) - { - var v = (int)type; - - if (v < 0 || v >= m_Table.Length) - { - v = 0; - } - - return m_Table[v]; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); - - writer.WriteEncodedInt((int)m_Type); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = InheritsItem ? 0 : reader.ReadInt(); // Required for BasePigmentsOfTokuno insertion - - switch (version) - { - case 1: - Type = (PigmentType)reader.ReadEncodedInt(); - break; - case 0: break; - } - } + phys = fire = pois = chaos = direct = 0; + cold = nrgy = 50; + } +} + +[SerializationGenerator(0, false)] +public partial class KasaOfTheRajin : Kasa +{ + [Constructible] + public KasaOfTheRajin() => Attributes.SpellDamage = 12; + + public override int LabelNumber => 1070969; // Kasa of the Raj-in + + public override int BasePhysicalResistance => 12; + public override int BaseFireResistance => 17; + public override int BaseColdResistance => 21; + public override int BasePoisonResistance => 17; + public override int BaseEnergyResistance => 17; + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +[SerializationGenerator(0, false)] +public partial class RuneBeetleCarapace : PlateDo +{ + [Constructible] + public RuneBeetleCarapace() + { + Attributes.BonusMana = 10; + Attributes.RegenMana = 3; + Attributes.LowerManaCost = 15; + ArmorAttributes.LowerStatReq = 100; + ArmorAttributes.MageArmor = 1; + } + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; + + public override int LabelNumber => 1070968; // Rune Beetle Carapace + + public override int BaseColdResistance => 14; + public override int BaseEnergyResistance => 14; +} + +[SerializationGenerator(0, false)] +public partial class Stormgrip : LeatherNinjaMitts +{ + [Constructible] + public Stormgrip() + { + Attributes.BonusInt = 8; + Attributes.Luck = 125; + Attributes.WeaponDamage = 25; + } + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; + + public override int LabelNumber => 1070970; // Stormgrip + + public override int BasePhysicalResistance => 10; + public override int BaseColdResistance => 18; + public override int BaseEnergyResistance => 18; +} + +[SerializationGenerator(0, false)] +public partial class SwordOfTheStampede : NoDachi +{ + [Constructible] + public SwordOfTheStampede() + { + WeaponAttributes.HitHarm = 100; + Attributes.AttackChance = 10; + Attributes.WeaponDamage = 60; + } + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; + + public override int LabelNumber => 1070964; // Sword of the Stampede + + public override void GetDamageTypes( + Mobile wielder, out int phys, out int fire, out int cold, out int pois, + out int nrgy, out int chaos, out int direct + ) + { + phys = fire = pois = nrgy = chaos = direct = 0; + cold = 100; + } +} + +[SerializationGenerator(0, false)] +public partial class SwordsOfProsperity : Daisho +{ + [Constructible] + public SwordsOfProsperity() + { + WeaponAttributes.MageWeapon = 30; + Attributes.SpellChanneling = 1; + Attributes.CastSpeed = 1; + Attributes.Luck = 200; + } + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; + + public override int LabelNumber => 1070963; // Swords of Prosperity + + public override void GetDamageTypes( + Mobile wielder, out int phys, out int fire, out int cold, out int pois, + out int nrgy, out int chaos, out int direct + ) + { + phys = cold = pois = nrgy = chaos = direct = 0; + fire = 100; + } +} + +[SerializationGenerator(0, false)] +public partial class TheHorselord : Yumi +{ + [Constructible] + public TheHorselord() + { + Attributes.BonusDex = 5; + Attributes.RegenMana = 1; + Attributes.Luck = 125; + Attributes.WeaponDamage = 50; + + Slayer = SlayerName.ElementalBan; + Slayer2 = SlayerName.ReptilianDeath; + } + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; + + public override int LabelNumber => 1070967; // The Horselord +} + +[SerializationGenerator(0, false)] +public partial class TomeOfLostKnowledge : Spellbook +{ + [Constructible] + public TomeOfLostKnowledge() + { + LootType = LootType.Regular; + Hue = 0x530; + + SkillBonuses.SetValues(0, SkillName.Magery, 15.0); + Attributes.BonusInt = 8; + Attributes.LowerManaCost = 15; + Attributes.SpellDamage = 15; + } + + public override int LabelNumber => 1070971; // Tome of Lost Knowledge +} + +[SerializationGenerator(0, false)] +public partial class WindsEdge : Tessen +{ + [Constructible] + public WindsEdge() + { + WeaponAttributes.HitLeechMana = 40; + + Attributes.WeaponDamage = 50; + Attributes.WeaponSpeed = 50; + Attributes.DefendChance = 10; + } + + public override int LabelNumber => 1070965; // Wind's Edge + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; + + public override void GetDamageTypes( + Mobile wielder, out int phys, out int fire, out int cold, out int pois, + out int nrgy, out int chaos, out int direct + ) + { + phys = fire = cold = pois = chaos = direct = 0; + nrgy = 100; + } +} + +public enum PigmentType +{ + None, + ParagonGold, + VioletCouragePurple, + InvulnerabilityBlue, + LunaWhite, + DryadGreen, + ShadowDancerBlack, + BerserkerRed, + NoxGreen, + RumRed, + FireOrange, + FadedCoal, + Coal, + FadedGold, + StormBronze, + Rose, + MidnightCoal, + FadedBronze, + FadedRose, + DeepRose +} + +[SerializationGenerator(0, false)] +public partial class PigmentsOfTokuno : BasePigmentsOfTokuno +{ + private static readonly int[][] _table = + { + // Hue, Label + new[] + { + /*PigmentType.None,*/ 0, -1 + }, + new[] + { + /*PigmentType.ParagonGold,*/ 0x501, 1070987 + }, + new[] + { + /*PigmentType.VioletCouragePurple,*/ 0x486, 1070988 + }, + new[] + { + /*PigmentType.InvulnerabilityBlue,*/ 0x4F2, 1070989 + }, + new[] + { + /*PigmentType.LunaWhite,*/ 0x47E, 1070990 + }, + new[] + { + /*PigmentType.DryadGreen,*/ 0x48F, 1070991 + }, + new[] + { + /*PigmentType.ShadowDancerBlack,*/ 0x455, 1070992 + }, + new[] + { + /*PigmentType.BerserkerRed,*/ 0x21, 1070993 + }, + new[] + { + /*PigmentType.NoxGreen,*/ 0x58C, 1070994 + }, + new[] + { + /*PigmentType.RumRed,*/ 0x66C, 1070995 + }, + new[] + { + /*PigmentType.FireOrange,*/ 0x54F, 1070996 + }, + new[] + { + /*PigmentType.Fadedcoal,*/ 0x96A, 1079579 + }, + new[] + { + /*PigmentType.Coal,*/ 0x96B, 1079580 + }, + new[] + { + /*PigmentType.FadedGold,*/ 0x972, 1079581 + }, + new[] + { + /*PigmentType.StormBronze,*/ 0x977, 1079582 + }, + new[] + { + /*PigmentType.Rose,*/ 0x97C, 1079583 + }, + new[] + { + /*PigmentType.MidnightCoal,*/ 0x96C, 1079584 + }, + new[] + { + /*PigmentType.FadedBronze,*/ 0x975, 1079585 + }, + new[] + { + /*PigmentType.FadedRose,*/ 0x97B, 1079586 + }, + new[] + { + /*PigmentType.DeepRose,*/ 0x97E, 1079587 + } + }; + + [Constructible] + public PigmentsOfTokuno(PigmentType type = PigmentType.None) : this( + type, + type is PigmentType.None or >= PigmentType.FadedCoal ? 10 : 50 + ) + { + } + + [Constructible] + public PigmentsOfTokuno(PigmentType type, int uses) : base(uses) + { + Weight = 1.0; + Type = type; + } + + [SerializableProperty(0)] + [CommandProperty(AccessLevel.GameMaster)] + public PigmentType Type + { + get => _type; + set + { + _type = value; + + var v = (int)_type; + + if (v >= 0 && v < _table.Length) + { + Hue = _table[v][0]; + Label = _table[v][1]; + } + else + { + Hue = 0; + Label = -1; + } + } + } + + public override int LabelNumber => 1070933; // Pigments of Tokuno + + public static int[] GetInfo(PigmentType type) + { + var v = (int)type; + + if (v < 0 || v >= _table.Length) + { + v = 0; + } + + return _table[v]; } } diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/LesserArtifacts.cs b/Projects/UOContent/Engines/Treasures of Tokuno/LesserArtifacts.cs index 9289fa0e7..8b230040e 100644 --- a/Projects/UOContent/Engines/Treasures of Tokuno/LesserArtifacts.cs +++ b/Projects/UOContent/Engines/Treasures of Tokuno/LesserArtifacts.cs @@ -1,1099 +1,688 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class AncientFarmersKasa : Kasa { - public class AncientFarmersKasa : Kasa + [Constructible] + public AncientFarmersKasa() { - [Constructible] - public AncientFarmersKasa() + Attributes.BonusStr = 5; + Attributes.BonusStam = 5; + Attributes.RegenStam = 5; + + SkillBonuses.SetValues(0, SkillName.AnimalLore, 5.0); + } + + public override int LabelNumber => 1070922; // Ancient Farmer's Kasa + public override int BaseColdResistance => 19; + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +[SerializationGenerator(0, false)] +public partial class AncientSamuraiDo : PlateDo +{ + [Constructible] + public AncientSamuraiDo() + { + ArmorAttributes.LowerStatReq = 100; + ArmorAttributes.MageArmor = 1; + SkillBonuses.SetValues(0, SkillName.Parry, 10.0); + } + + public override int LabelNumber => 1070926; // Ancient Samurai Do + + public override int BasePhysicalResistance => 15; + public override int BaseFireResistance => 12; + public override int BaseColdResistance => 10; + public override int BasePoisonResistance => 11; + public override int BaseEnergyResistance => 8; + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +[SerializationGenerator(0, false)] +public partial class ArmsOfTacticalExcellence : LeatherHiroSode +{ + [Constructible] + public ArmsOfTacticalExcellence() + { + Attributes.BonusDex = 5; + SkillBonuses.SetValues(0, SkillName.Tactics, 12.0); + } + + public override int LabelNumber => 1070921; // Arms of Tactical Excellence + + public override int BaseFireResistance => 9; + public override int BaseColdResistance => 13; + public override int BasePoisonResistance => 8; + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +[SerializationGenerator(0, false)] +public partial class BlackLotusHood : ClothNinjaHood +{ + [Constructible] + public BlackLotusHood() + { + Attributes.LowerManaCost = 6; + Attributes.AttackChance = 6; + ClothingAttributes.SelfRepair = 5; + } + + public override int LabelNumber => 1070919; // Black Lotus Hood + + public override int BasePhysicalResistance => 0; + public override int BaseFireResistance => 11; + public override int BaseColdResistance => 15; + public override int BasePoisonResistance => 11; + public override int BaseEnergyResistance => 11; + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +[SerializationGenerator(0, false)] +public partial class DaimyosHelm : PlateBattleKabuto +{ + [Constructible] + public DaimyosHelm() + { + ArmorAttributes.LowerStatReq = 100; + ArmorAttributes.MageArmor = 1; + ArmorAttributes.SelfRepair = 3; + Attributes.WeaponSpeed = 10; + } + + public override int LabelNumber => 1070920; // Daimyo's Helm + + public override int BaseColdResistance => 10; + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +[SerializationGenerator(0, false)] +public partial class DemonForks : Sai +{ + [Constructible] + public DemonForks() + { + WeaponAttributes.ResistFireBonus = 10; + WeaponAttributes.ResistPoisonBonus = 10; + + Attributes.ReflectPhysical = 10; + Attributes.WeaponDamage = 35; + Attributes.DefendChance = 10; + } + + public override int LabelNumber => 1070917; // Demon Forks + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +[SerializationGenerator(0, false)] +public partial class DragonNunchaku : Nunchaku +{ + [Constructible] + public DragonNunchaku() + { + WeaponAttributes.ResistFireBonus = 5; + WeaponAttributes.SelfRepair = 3; + WeaponAttributes.HitFireball = 50; + + Attributes.WeaponDamage = 40; + Attributes.WeaponSpeed = 20; + } + + public override int LabelNumber => 1070914; // Dragon Nunchaku + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +[SerializationGenerator(0, false)] +public partial class Exiler : Tetsubo +{ + [Constructible] + public Exiler() + { + WeaponAttributes.HitDispel = 33; + Slayer = SlayerName.Exorcism; + + Attributes.WeaponDamage = 40; + Attributes.WeaponSpeed = 20; + } + + public override int LabelNumber => 1070913; // Exiler + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; + + public override void GetDamageTypes( + Mobile wielder, out int phys, out int fire, out int cold, out int pois, + out int nrgy, out int chaos, out int direct + ) + { + phys = fire = cold = pois = chaos = direct = 0; + + nrgy = 100; + } +} + +[SerializationGenerator(0, false)] +public partial class GlovesOfTheSun : LeatherNinjaMitts +{ + [Constructible] + public GlovesOfTheSun() + { + Attributes.RegenHits = 2; + Attributes.NightSight = 1; + Attributes.LowerManaCost = 5; + Attributes.LowerRegCost = 18; + } + + public override int LabelNumber => 1070924; // Gloves of the Sun + + public override int BaseFireResistance => 24; + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +[SerializationGenerator(0, false)] +public partial class HanzosBow : Yumi +{ + [Constructible] + public HanzosBow() + { + WeaponAttributes.HitLeechHits = 40; + WeaponAttributes.SelfRepair = 3; + + Attributes.WeaponDamage = 50; + + SkillBonuses.SetValues(0, SkillName.Ninjitsu, 10); + } + + public override int LabelNumber => 1070918; // Hanzo's Bow + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +[SerializationGenerator(0, false)] +public partial class LegsOfStability : PlateSuneate +{ + [Constructible] + public LegsOfStability() + { + Attributes.BonusStam = 5; + + ArmorAttributes.SelfRepair = 3; + ArmorAttributes.LowerStatReq = 100; + ArmorAttributes.MageArmor = 1; + } + + public override int LabelNumber => 1070925; // Legs of Stability + + public override int BasePhysicalResistance => 20; + public override int BasePoisonResistance => 18; + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +[SerializationGenerator(0, false)] +public partial class PeasantsBokuto : Bokuto +{ + [Constructible] + public PeasantsBokuto() + { + WeaponAttributes.SelfRepair = 3; + WeaponAttributes.HitLowerDefend = 30; + + Attributes.WeaponDamage = 35; + Attributes.WeaponSpeed = 10; + Slayer = SlayerName.SnakesBane; + } + + public override int LabelNumber => 1070912; // Peasant's Bokuto + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +[SerializationGenerator(0, false)] +public partial class PilferedDancerFans : Tessen +{ + [Constructible] + public PilferedDancerFans() + { + Attributes.WeaponDamage = 20; + Attributes.WeaponSpeed = 20; + Attributes.CastRecovery = 2; + Attributes.DefendChance = 5; + Attributes.SpellChanneling = 1; + } + + public override int LabelNumber => 1070916; // Pilfered Dancer Fans + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +[SerializationGenerator(0, false)] +public partial class TheDestroyer : NoDachi +{ + [Constructible] + public TheDestroyer() + { + WeaponAttributes.HitLeechStam = 40; + + Attributes.BonusStr = 6; + Attributes.AttackChance = 10; + Attributes.WeaponDamage = 50; + } + + public override int LabelNumber => 1070915; // The Destroyer + + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +[SerializationGenerator(0, false)] +public partial class TomeOfEnlightenment : Spellbook +{ + [Constructible] + public TomeOfEnlightenment() + { + LootType = LootType.Regular; + Hue = 0x455; + + Attributes.BonusInt = 5; + Attributes.SpellDamage = 10; + Attributes.CastSpeed = 1; + } + + public override int LabelNumber => 1070934; // Tome of Enlightenment +} + +[SerializationGenerator(0, false)] +public partial class LeurociansMempoOfFortune : LeatherMempo +{ + [Constructible] + public LeurociansMempoOfFortune() + { + LootType = LootType.Regular; + Hue = 0x501; + + Attributes.Luck = 300; + Attributes.RegenMana = 1; + } + + public override int LabelNumber => 1071460; // Leurocian's mempo of fortune + + public override int BasePhysicalResistance => 15; + public override int BaseFireResistance => 10; + public override int BaseColdResistance => 10; + public override int BasePoisonResistance => 10; + public override int BaseEnergyResistance => 15; + public override int InitMinHits => 255; + public override int InitMaxHits => 255; +} + +// Non weapon/armor ones: + +[SerializationGenerator(0, false)] +public partial class AncientUrn : Item +{ + [InvalidateProperties] + [SerializableField(0)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private string _urnName; + + [Constructible] + public AncientUrn() : this(Names.RandomElement()) + { + } + + [Constructible] + public AncientUrn(string urnName) : base(0x241D) + { + _urnName = urnName; + Weight = 1.0; + } + + public static string[] Names { get; } = + { + "Akira", + "Avaniaga", + "Aya", + "Chie", + "Emiko", + "Fumiyo", + "Gennai", + "Gennosuke", + "Genjo", + "Hamato", + "Harumi", + "Ikuyo", + "Juri", + "Kaori", + "Kaoru", + "Kiyomori", + "Mayako", + "Motoki", + "Musashi", + "Nami", + "Nobukazu", + "Roku", + "Romi", + "Ryo", + "Sanzo", + "Sakamae", + "Satoshi", + "Takamori", + "Takuro", + "Teruyo", + "Toshiro", + "Yago", + "Yeijiro", + "Yoshi", + "Zeshin" + }; + + public override int LabelNumber => 1071014; // Ancient Urn + + [AfterDeserialization] + private void AfterDeserialization() + { + Utility.Intern(ref _urnName); + } + + public override void AddNameProperty(IPropertyList list) + { + list.Add(1070935, _urnName); // Ancient Urn of ~1_name~ + } + + public override void OnSingleClick(Mobile from) + { + LabelTo(from, 1070935, _urnName); // Ancient Urn of ~1_name~ + } +} + +[SerializationGenerator(0, false)] +public partial class HonorableSwords : Item +{ + [InvalidateProperties] + [SerializableField(0)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private string _swordsName; + + [Constructible] + public HonorableSwords() : this(AncientUrn.Names.RandomElement()) + { + } + + [Constructible] + public HonorableSwords(string swordsName) : base(0x2853) + { + _swordsName = swordsName; + + Weight = 5.0; + } + + public override int LabelNumber => 1071015; // Honorable Swords + + public override void AddNameProperty(IPropertyList list) + { + list.Add(1070936, _swordsName); // Honorable Swords of ~1_name~ + } + + public override void OnSingleClick(Mobile from) + { + LabelTo(from, 1070936, _swordsName); // Honorable Swords of ~1_name~ + } + + [AfterDeserialization] + private void AfterDeserialization() + { + Utility.Intern(ref _swordsName); + } +} + +[Furniture] +[Flippable(0x2811, 0x2812)] +[SerializationGenerator(0, false)] +public partial class ChestOfHeirlooms : LockableContainer +{ + [Constructible] + public ChestOfHeirlooms() : base(0x2811) + { + Locked = true; + LockLevel = 95; + MaxLockLevel = 140; + RequiredSkill = 95; + + TrapType = TrapType.ExplosionTrap; + TrapLevel = 10; + TrapPower = 100; + + GumpID = 0x10B; + + for (var i = 0; i < 10; ++i) { - Attributes.BonusStr = 5; - Attributes.BonusStam = 5; - Attributes.RegenStam = 5; + var item = Loot.ChestOfHeirloomsContains(); - SkillBonuses.SetValues(0, SkillName.AnimalLore, 5.0); - } + var attributeCount = Utility.RandomMinMax(1, 5); + var min = 20; + var max = 80; - public AncientFarmersKasa(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070922; // Ancient Farmer's Kasa - public override int BaseColdResistance => 19; - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(2); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version <= 1) + if (item is BaseWeapon weapon) { - MaxHitPoints = 255; - HitPoints = 255; - } - - if (version == 0) - { - SkillBonuses.SetValues(0, SkillName.AnimalLore, 5.0); - } - } - } - - public class AncientSamuraiDo : PlateDo - { - [Constructible] - public AncientSamuraiDo() - { - ArmorAttributes.LowerStatReq = 100; - ArmorAttributes.MageArmor = 1; - SkillBonuses.SetValues(0, SkillName.Parry, 10.0); - } - - public AncientSamuraiDo(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070926; // Ancient Samurai Do - - public override int BasePhysicalResistance => 15; - public override int BaseFireResistance => 12; - public override int BaseColdResistance => 10; - public override int BasePoisonResistance => 11; - public override int BaseEnergyResistance => 8; - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class ArmsOfTacticalExcellence : LeatherHiroSode - { - [Constructible] - public ArmsOfTacticalExcellence() - { - Attributes.BonusDex = 5; - SkillBonuses.SetValues(0, SkillName.Tactics, 12.0); - } - - public ArmsOfTacticalExcellence(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070921; // Arms of Tactical Excellence - - public override int BaseFireResistance => 9; - public override int BaseColdResistance => 13; - public override int BasePoisonResistance => 8; - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class BlackLotusHood : ClothNinjaHood - { - [Constructible] - public BlackLotusHood() - { - Attributes.LowerManaCost = 6; - Attributes.AttackChance = 6; - ClothingAttributes.SelfRepair = 5; - } - - public BlackLotusHood(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070919; // Black Lotus Hood - - public override int BasePhysicalResistance => 0; - public override int BaseFireResistance => 11; - public override int BaseColdResistance => 15; - public override int BasePoisonResistance => 11; - public override int BaseEnergyResistance => 11; - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0) - { - MaxHitPoints = 255; - HitPoints = 255; - } - } - } - - public class DaimyosHelm : PlateBattleKabuto - { - [Constructible] - public DaimyosHelm() - { - ArmorAttributes.LowerStatReq = 100; - ArmorAttributes.MageArmor = 1; - ArmorAttributes.SelfRepair = 3; - Attributes.WeaponSpeed = 10; - } - - public DaimyosHelm(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070920; // Daimyo's Helm - - public override int BaseColdResistance => 10; - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class DemonForks : Sai - { - [Constructible] - public DemonForks() - { - WeaponAttributes.ResistFireBonus = 10; - WeaponAttributes.ResistPoisonBonus = 10; - - Attributes.ReflectPhysical = 10; - Attributes.WeaponDamage = 35; - Attributes.DefendChance = 10; - } - - public DemonForks(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070917; // Demon Forks - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class DragonNunchaku : Nunchaku - { - [Constructible] - public DragonNunchaku() - { - WeaponAttributes.ResistFireBonus = 5; - WeaponAttributes.SelfRepair = 3; - WeaponAttributes.HitFireball = 50; - - Attributes.WeaponDamage = 40; - Attributes.WeaponSpeed = 20; - } - - public DragonNunchaku(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070914; // Dragon Nunchaku - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class Exiler : Tetsubo - { - [Constructible] - public Exiler() - { - WeaponAttributes.HitDispel = 33; - Slayer = SlayerName.Exorcism; - - Attributes.WeaponDamage = 40; - Attributes.WeaponSpeed = 20; - } - - public Exiler(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070913; // Exiler - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void GetDamageTypes( - Mobile wielder, out int phys, out int fire, out int cold, out int pois, - out int nrgy, out int chaos, out int direct - ) - { - phys = fire = cold = pois = chaos = direct = 0; - - nrgy = 100; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class GlovesOfTheSun : LeatherNinjaMitts - { - [Constructible] - public GlovesOfTheSun() - { - Attributes.RegenHits = 2; - Attributes.NightSight = 1; - Attributes.LowerManaCost = 5; - Attributes.LowerRegCost = 18; - } - - public GlovesOfTheSun(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070924; // Gloves of the Sun - - public override int BaseFireResistance => 24; - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class HanzosBow : Yumi - { - [Constructible] - public HanzosBow() - { - WeaponAttributes.HitLeechHits = 40; - WeaponAttributes.SelfRepair = 3; - - Attributes.WeaponDamage = 50; - - SkillBonuses.SetValues(0, SkillName.Ninjitsu, 10); - } - - public HanzosBow(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070918; // Hanzo's Bow - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class LegsOfStability : PlateSuneate - { - [Constructible] - public LegsOfStability() - { - Attributes.BonusStam = 5; - - ArmorAttributes.SelfRepair = 3; - ArmorAttributes.LowerStatReq = 100; - ArmorAttributes.MageArmor = 1; - } - - public LegsOfStability(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070925; // Legs of Stability - - public override int BasePhysicalResistance => 20; - public override int BasePoisonResistance => 18; - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class PeasantsBokuto : Bokuto - { - [Constructible] - public PeasantsBokuto() - { - WeaponAttributes.SelfRepair = 3; - WeaponAttributes.HitLowerDefend = 30; - - Attributes.WeaponDamage = 35; - Attributes.WeaponSpeed = 10; - Slayer = SlayerName.SnakesBane; - } - - public PeasantsBokuto(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070912; // Peasant's Bokuto - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class PilferedDancerFans : Tessen - { - [Constructible] - public PilferedDancerFans() - { - Attributes.WeaponDamage = 20; - Attributes.WeaponSpeed = 20; - Attributes.CastRecovery = 2; - Attributes.DefendChance = 5; - Attributes.SpellChanneling = 1; - } - - public PilferedDancerFans(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070916; // Pilfered Dancer Fans - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class TheDestroyer : NoDachi - { - [Constructible] - public TheDestroyer() - { - WeaponAttributes.HitLeechStam = 40; - - Attributes.BonusStr = 6; - Attributes.AttackChance = 10; - Attributes.WeaponDamage = 50; - } - - public TheDestroyer(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070915; // The Destroyer - - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class TomeOfEnlightenment : Spellbook - { - [Constructible] - public TomeOfEnlightenment() - { - LootType = LootType.Regular; - Hue = 0x455; - - Attributes.BonusInt = 5; - Attributes.SpellDamage = 10; - Attributes.CastSpeed = 1; - } - - public TomeOfEnlightenment(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070934; // Tome of Enlightenment - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class LeurociansMempoOfFortune : LeatherMempo - { - [Constructible] - public LeurociansMempoOfFortune() - { - LootType = LootType.Regular; - Hue = 0x501; - - Attributes.Luck = 300; - Attributes.RegenMana = 1; - } - - public LeurociansMempoOfFortune(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1071460; // Leurocian's mempo of fortune - - public override int BasePhysicalResistance => 15; - public override int BaseFireResistance => 10; - public override int BaseColdResistance => 10; - public override int BasePoisonResistance => 10; - public override int BaseEnergyResistance => 15; - public override int InitMinHits => 255; - public override int InitMaxHits => 255; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - // Non weapon/armor ones: - - public class AncientUrn : Item - { - private string m_UrnName; - - [Constructible] - public AncientUrn() : this(Names.RandomElement()) - { - } - - [Constructible] - public AncientUrn(string urnName) : base(0x241D) - { - m_UrnName = urnName; - Weight = 1.0; - } - - public AncientUrn(Serial serial) : base(serial) - { - } - - public static string[] Names { get; } = - { - "Akira", - "Avaniaga", - "Aya", - "Chie", - "Emiko", - "Fumiyo", - "Gennai", - "Gennosuke", - "Genjo", - "Hamato", - "Harumi", - "Ikuyo", - "Juri", - "Kaori", - "Kaoru", - "Kiyomori", - "Mayako", - "Motoki", - "Musashi", - "Nami", - "Nobukazu", - "Roku", - "Romi", - "Ryo", - "Sanzo", - "Sakamae", - "Satoshi", - "Takamori", - "Takuro", - "Teruyo", - "Toshiro", - "Yago", - "Yeijiro", - "Yoshi", - "Zeshin" - }; - - [CommandProperty(AccessLevel.GameMaster)] - public string UrnName - { - get => m_UrnName; - set => m_UrnName = value; - } - - public override int LabelNumber => 1071014; // Ancient Urn - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - writer.Write(m_UrnName); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - m_UrnName = reader.ReadString(); - - Utility.Intern(ref m_UrnName); - } - - public override void AddNameProperty(IPropertyList list) - { - list.Add(1070935, m_UrnName); // Ancient Urn of ~1_name~ - } - - public override void OnSingleClick(Mobile from) - { - LabelTo(from, 1070935, m_UrnName); // Ancient Urn of ~1_name~ - } - } - - public class HonorableSwords : Item - { - private string m_SwordsName; - - [Constructible] - public HonorableSwords() : this(AncientUrn.Names.RandomElement()) - { - } - - [Constructible] - public HonorableSwords(string swordsName) : base(0x2853) - { - m_SwordsName = swordsName; - - Weight = 5.0; - } - - public HonorableSwords(Serial serial) : base(serial) - { - } - - [CommandProperty(AccessLevel.GameMaster)] - public string SwordsName - { - get => m_SwordsName; - set => m_SwordsName = value; - } - - public override int LabelNumber => 1071015; // Honorable Swords - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - writer.Write(m_SwordsName); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - m_SwordsName = reader.ReadString(); - - Utility.Intern(ref m_SwordsName); - } - - public override void AddNameProperty(IPropertyList list) - { - list.Add(1070936, m_SwordsName); // Honorable Swords of ~1_name~ - } - - public override void OnSingleClick(Mobile from) - { - LabelTo(from, 1070936, m_SwordsName); // Honorable Swords of ~1_name~ - } - } - - [Furniture] - [Flippable(0x2811, 0x2812)] - public class ChestOfHeirlooms : LockableContainer - { - [Constructible] - public ChestOfHeirlooms() : base(0x2811) - { - Locked = true; - LockLevel = 95; - MaxLockLevel = 140; - RequiredSkill = 95; - - TrapType = TrapType.ExplosionTrap; - TrapLevel = 10; - TrapPower = 100; - - GumpID = 0x10B; - - for (var i = 0; i < 10; ++i) - { - var item = Loot.ChestOfHeirloomsContains(); - - var attributeCount = Utility.RandomMinMax(1, 5); - var min = 20; - var max = 80; - - if (item is BaseWeapon weapon) + if (Core.AOS) { - if (Core.AOS) - { - BaseRunicTool.ApplyAttributesTo(weapon, attributeCount, min, max); - } - else - { - weapon.DamageLevel = (WeaponDamageLevel)Utility.Random(6); - weapon.AccuracyLevel = (WeaponAccuracyLevel)Utility.Random(6); - weapon.DurabilityLevel = (WeaponDurabilityLevel)Utility.Random(6); - } - } - else if (item is BaseArmor armor) - { - if (Core.AOS) - { - BaseRunicTool.ApplyAttributesTo(armor, attributeCount, min, max); - } - else - { - armor.ProtectionLevel = (ArmorProtectionLevel)Utility.Random(6); - armor.Durability = (ArmorDurabilityLevel)Utility.Random(6); - } - } - else if (Core.AOS) - { - if (item is BaseHat hat) - { - BaseRunicTool.ApplyAttributesTo(hat, attributeCount, min, max); - } - else if (item is BaseJewel jewel) - { - BaseRunicTool.ApplyAttributesTo(jewel, attributeCount, min, max); - } - } - - DropItem(item); - } - } - - public ChestOfHeirlooms(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070937; // Chest of heirlooms - - 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(); - } - } - - public class FluteOfRenewal : BambooFlute - { - [Constructible] - public FluteOfRenewal() - { - Slayer = SlayerGroup.Groups[Utility.Random(SlayerGroup.Groups.Length - 1)] - .Super - .Name; // -1 to exclude Fey slayer. Try to confirm no fey slayer on this on OSI - - ReplenishesCharges = true; - } - - public FluteOfRenewal(Serial serial) : base(serial) - { - } - - public override int LabelNumber => 1070927; // Flute of Renewal - - public override int InitMinUses => 300; - public override int InitMaxUses => 300; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - if (version == 0 && Slayer == SlayerName.Fey) - { - Slayer = SlayerGroup.Groups[Utility.Random(SlayerGroup.Groups.Length - 1)].Super.Name; - } - } - } - - public enum LesserPigmentType - { - None, - PaleOrange, - FreshRose, - ChaosBlue, - Silver, - NobleGold, - LightGreen, - PaleBlue, - FreshPlum, - DeepBrown, - BurntBrown - } - - public class LesserPigmentsOfTokuno : BasePigmentsOfTokuno - { - private static readonly int[][] m_Table = - { - // Hue, Label - new[] - { - /*PigmentType.None,*/ 0, -1 - }, - new[] - { - /*PigmentType.PaleOrange,*/ 0x02E, 1071458 - }, - new[] - { - /*PigmentType.FreshRose,*/ 0x4B9, 1071455 - }, - new[] - { - /*PigmentType.ChaosBlue,*/ 0x005, 1071459 - }, - new[] - { - /*PigmentType.Silver,*/ 0x3E9, 1071451 - }, - new[] - { - /*PigmentType.NobleGold,*/ 0x227, 1071457 - }, - new[] - { - /*PigmentType.LightGreen,*/ 0x1C8, 1071454 - }, - new[] - { - /*PigmentType.PaleBlue,*/ 0x24F, 1071456 - }, - new[] - { - /*PigmentType.FreshPlum,*/ 0x145, 1071450 - }, - new[] - { - /*PigmentType.DeepBrown,*/ 0x3F0, 1071452 - }, - new[] - { - /*PigmentType.BurntBrown,*/ 0x41A, 1071453 - } - }; - - private LesserPigmentType m_Type; - - [Constructible] - public LesserPigmentsOfTokuno() : this((LesserPigmentType)Utility.Random(0, 11)) - { - } - - [Constructible] - public LesserPigmentsOfTokuno(LesserPigmentType type) : base(1) - { - Weight = 1.0; - Type = type; - } - - public LesserPigmentsOfTokuno(Serial serial) : base(serial) - { - } - - [CommandProperty(AccessLevel.GameMaster)] - public LesserPigmentType Type - { - get => m_Type; - set - { - m_Type = value; - - var v = (int)m_Type; - - if (v >= 0 && v < m_Table.Length) - { - Hue = m_Table[v][0]; - Label = m_Table[v][1]; + BaseRunicTool.ApplyAttributesTo(weapon, attributeCount, min, max); } else { - Hue = 0; - Label = -1; + weapon.DamageLevel = (WeaponDamageLevel)Utility.Random(6); + weapon.AccuracyLevel = (WeaponAccuracyLevel)Utility.Random(6); + weapon.DurabilityLevel = (WeaponDurabilityLevel)Utility.Random(6); } } - } - - public static int[] GetInfo(LesserPigmentType type) - { - var v = (int)type; - - if (v < 0 || v >= m_Table.Length) + else if (item is BaseArmor armor) { - v = 0; + if (Core.AOS) + { + BaseRunicTool.ApplyAttributesTo(armor, attributeCount, min, max); + } + else + { + armor.ProtectionLevel = (ArmorProtectionLevel)Utility.Random(6); + armor.Durability = (ArmorDurabilityLevel)Utility.Random(6); + } + } + else if (Core.AOS) + { + if (item is BaseHat hat) + { + BaseRunicTool.ApplyAttributesTo(hat, attributeCount, min, max); + } + else if (item is BaseJewel jewel) + { + BaseRunicTool.ApplyAttributesTo(jewel, attributeCount, min, max); + } } - return m_Table[v]; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); - - writer.WriteEncodedInt((int)m_Type); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = InheritsItem ? 0 : reader.ReadInt(); // Required for BasePigmentsOfTokuno insertion - - switch (version) - { - case 1: - Type = (LesserPigmentType)reader.ReadEncodedInt(); - break; - case 0: break; - } + DropItem(item); } } - public class MetalPigmentsOfTokuno : BasePigmentsOfTokuno + public override int LabelNumber => 1070937; // Chest of heirlooms +} + +[SerializationGenerator(0, false)] +public partial class FluteOfRenewal : BambooFlute +{ + [Constructible] + public FluteOfRenewal() { - [Constructible] - public MetalPigmentsOfTokuno() : base(1) - { - RandomHue(); - Label = -1; - } + // -1 to exclude Fey slayer. Try to confirm no fey slayer on this on OSI + Slayer = SlayerGroup.Groups[Utility.Random(SlayerGroup.Groups.Length - 1)].Super.Name; - public MetalPigmentsOfTokuno(Serial serial) : base(serial) - { - } + ReplenishesCharges = true; + } - public void RandomHue() + public override int LabelNumber => 1070927; // Flute of Renewal + + public override int InitMinUses => 300; + public override int InitMaxUses => 300; +} + +public enum LesserPigmentType +{ + None, + PaleOrange, + FreshRose, + ChaosBlue, + Silver, + NobleGold, + LightGreen, + PaleBlue, + FreshPlum, + DeepBrown, + BurntBrown +} + +[SerializationGenerator(0, false)] +public partial class LesserPigmentsOfTokuno : BasePigmentsOfTokuno +{ + private static readonly int[][] _table = + { + // Hue, Label + new[] { - var a = Utility.Random(0, 30); - if (a != 0) + /*PigmentType.None,*/ 0, -1 + }, + new[] + { + /*PigmentType.PaleOrange,*/ 0x02E, 1071458 + }, + new[] + { + /*PigmentType.FreshRose,*/ 0x4B9, 1071455 + }, + new[] + { + /*PigmentType.ChaosBlue,*/ 0x005, 1071459 + }, + new[] + { + /*PigmentType.Silver,*/ 0x3E9, 1071451 + }, + new[] + { + /*PigmentType.NobleGold,*/ 0x227, 1071457 + }, + new[] + { + /*PigmentType.LightGreen,*/ 0x1C8, 1071454 + }, + new[] + { + /*PigmentType.PaleBlue,*/ 0x24F, 1071456 + }, + new[] + { + /*PigmentType.FreshPlum,*/ 0x145, 1071450 + }, + new[] + { + /*PigmentType.DeepBrown,*/ 0x3F0, 1071452 + }, + new[] + { + /*PigmentType.BurntBrown,*/ 0x41A, 1071453 + } + }; + + [Constructible] + public LesserPigmentsOfTokuno() : this((LesserPigmentType)Utility.Random(0, 11)) + { + } + + [Constructible] + public LesserPigmentsOfTokuno(LesserPigmentType type) : base(1) + { + Weight = 1.0; + Type = type; + } + + [SerializableProperty(0)] + [CommandProperty(AccessLevel.GameMaster)] + public LesserPigmentType Type + { + get => _type; + set + { + _type = value; + + var v = (int)_type; + + if (v >= 0 && v < _table.Length) { - Hue = a + 0x960; + Hue = _table[v][0]; + Label = _table[v][1]; } else { Hue = 0; + Label = -1; } } + } - public override void Serialize(IGenericWriter writer) + public static int[] GetInfo(LesserPigmentType type) + { + var v = (int)type; + + if (v < 0 || v >= _table.Length) { - base.Serialize(writer); - - writer.Write(0); + v = 0; } - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); + return _table[v]; + } +} - var version = InheritsItem ? 0 : reader.ReadInt(); // Required for BasePigmentsOfTokuno insertion +[SerializationGenerator(0, false)] +public partial class MetalPigmentsOfTokuno : BasePigmentsOfTokuno +{ + [Constructible] + public MetalPigmentsOfTokuno() : base(1) + { + RandomHue(); + Label = -1; + } + + public void RandomHue() + { + var a = Utility.Random(0, 30); + if (a != 0) + { + Hue = a + 0x960; + } + else + { + Hue = 0; } } } diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs b/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs index f6c158d34..2425f94b9 100644 --- a/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs +++ b/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokuno.cs @@ -1,8 +1,11 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using ModernUO.Serialization; using Server.Gumps; using Server.Items; +using Server.Json; using Server.Misc; using Server.Mobiles; using Server.Multis; @@ -20,8 +23,15 @@ namespace Server.Misc ToTThree } + public class ToTConfig + { + public TreasuresOfTokunoEra DropEra { get; set; } + public TreasuresOfTokunoEra RewardEra { get; set; } + } + public static class TreasuresOfTokuno { + public const string ToTConfigurationPath = "Configuration/tot.json"; public const int ItemsPerReward = 10; private static readonly Type[][] m_LesserArtifacts = @@ -86,9 +96,45 @@ namespace Server.Misc typeof(BaseFormTalisman), typeof(BaseWand), typeof(JesterHatofChuckles) }; - public static TreasuresOfTokunoEra DropEra { get; set; } = TreasuresOfTokunoEra.None; + public static void Configure() + { + var pathToTFile = Path.Combine(Core.BaseDirectory, ToTConfigurationPath); + _totConfig = File.Exists(pathToTFile) + ? JsonConfig.Deserialize(pathToTFile) + : new ToTConfig + { + DropEra = TreasuresOfTokunoEra.None, + RewardEra = TreasuresOfTokunoEra.ToTOne, + }; + } - public static TreasuresOfTokunoEra RewardEra { get; set; } = TreasuresOfTokunoEra.ToTOne; + private static ToTConfig _totConfig; + + public static TreasuresOfTokunoEra DropEra + { + get => _totConfig.DropEra; + set + { + _totConfig.DropEra = value; + SaveConfiguration(); + } + } + + public static TreasuresOfTokunoEra RewardEra + { + get => _totConfig.RewardEra; + set + { + _totConfig.RewardEra = value; + SaveConfiguration(); + } + } + + private static void SaveConfiguration() + { + var pathToTFile = Path.Combine(Core.BaseDirectory, ToTConfigurationPath); + JsonConfig.Serialize(pathToTFile, _totConfig); + } public static Type[] LesserArtifacts => m_LesserArtifacts[(int)RewardEra - 1]; @@ -203,7 +249,8 @@ namespace Server.Misc namespace Server.Mobiles { - public class IharaSoko : BaseVendor + [SerializationGenerator(0, false)] + public partial class IharaSoko : BaseVendor { protected List m_SBInfos = new(); @@ -215,10 +262,6 @@ namespace Server.Mobiles Hue = 0x8403; } - public IharaSoko(Serial serial) : base(serial) - { - } - public override bool IsActiveVendor => false; public override bool IsInvulnerable => true; public override bool DisallowAllMoves => true; @@ -243,20 +286,6 @@ namespace Server.Mobiles AddItem(item); } - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - public override bool CanBeDamaged() => false; public override void OnMovement(Mobile m, Point3D oldLocation) @@ -302,7 +331,7 @@ namespace Server.Mobiles } } - var leaveRange = 7; + const int leaveRange = 7; if (!InRange(m, leaveRange) && InRange(oldLocation, leaveRange)) { diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokunoPersistance.cs b/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokunoPersistance.cs deleted file mode 100644 index 0f7fbafc5..000000000 --- a/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokunoPersistance.cs +++ /dev/null @@ -1,65 +0,0 @@ -namespace Server.Misc -{ - public class TreasuresOfTokunoPersistance : Item - { - public TreasuresOfTokunoPersistance() : base(1) - { - Movable = false; - - if (Instance?.Deleted != false) - { - Instance = this; - } - else - { - base.Delete(); - } - } - - public TreasuresOfTokunoPersistance(Serial serial) : base(serial) => Instance = this; - - public static TreasuresOfTokunoPersistance Instance { get; private set; } - - public override string DefaultName => "TreasuresOfTokuno Persistance - Internal"; - - public static void Initialize() - { - if (Instance == null) - { - new TreasuresOfTokunoPersistance(); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - - writer.WriteEncodedInt((int)TreasuresOfTokuno.RewardEra); - writer.WriteEncodedInt((int)TreasuresOfTokuno.DropEra); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 0: - { - TreasuresOfTokuno.RewardEra = (TreasuresOfTokunoEra)reader.ReadEncodedInt(); - TreasuresOfTokuno.DropEra = (TreasuresOfTokunoEra)reader.ReadEncodedInt(); - - break; - } - } - } - - public override void Delete() - { - } - } -} diff --git a/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokunoPersistence.cs b/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokunoPersistence.cs new file mode 100644 index 000000000..7e9a981a5 --- /dev/null +++ b/Projects/UOContent/Engines/Treasures of Tokuno/TreasuresOfTokunoPersistence.cs @@ -0,0 +1,32 @@ +using System; + +namespace Server.Misc; + +[ManualDirtyChecking] +[TypeAlias("Server.Misc.TreasuresOfTokunoPersistance")] +[Obsolete("Deprecated in favor of a configuration file. Only used for legacy deserialization")] +public class TreasuresOfTokunoPersistence : Item +{ + public TreasuresOfTokunoPersistence() : base(1) => Movable = false; + + public TreasuresOfTokunoPersistence(Serial serial) : base(serial) + { + } + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadInt(); + + TreasuresOfTokuno.RewardEra = (TreasuresOfTokunoEra)reader.ReadEncodedInt(); + TreasuresOfTokuno.DropEra = (TreasuresOfTokunoEra)reader.ReadEncodedInt(); + + Timer.DelayCall(Delete); + } +} diff --git a/Projects/UOContent/Migrations/Server.Items.AncientFarmersKasa.v0.json b/Projects/UOContent/Migrations/Server.Items.AncientFarmersKasa.v0.json new file mode 100644 index 000000000..61ab32296 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.AncientFarmersKasa.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.AncientFarmersKasa" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.AncientSamuraiDo.v0.json b/Projects/UOContent/Migrations/Server.Items.AncientSamuraiDo.v0.json new file mode 100644 index 000000000..5cdb3d54e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.AncientSamuraiDo.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.AncientSamuraiDo" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.AncientUrn.v0.json b/Projects/UOContent/Migrations/Server.Items.AncientUrn.v0.json new file mode 100644 index 000000000..3c3f40e98 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.AncientUrn.v0.json @@ -0,0 +1,14 @@ +{ + "version": 0, + "type": "Server.Items.AncientUrn", + "properties": [ + { + "name": "UrnName", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ArmsOfTacticalExcellence.v0.json b/Projects/UOContent/Migrations/Server.Items.ArmsOfTacticalExcellence.v0.json new file mode 100644 index 000000000..f4d39c07a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ArmsOfTacticalExcellence.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ArmsOfTacticalExcellence" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BasePigmentsOfTokuno.v0.json b/Projects/UOContent/Migrations/Server.Items.BasePigmentsOfTokuno.v0.json new file mode 100644 index 000000000..65b095437 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BasePigmentsOfTokuno.v0.json @@ -0,0 +1,14 @@ +{ + "version": 0, + "type": "Server.Items.BasePigmentsOfTokuno", + "properties": [ + { + "name": "UsesRemaining", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BlackLotusHood.v0.json b/Projects/UOContent/Migrations/Server.Items.BlackLotusHood.v0.json new file mode 100644 index 000000000..72709b1ec --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BlackLotusHood.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BlackLotusHood" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.ChestOfHeirlooms.v0.json b/Projects/UOContent/Migrations/Server.Items.ChestOfHeirlooms.v0.json new file mode 100644 index 000000000..519ea6633 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.ChestOfHeirlooms.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.ChestOfHeirlooms" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DaimyosHelm.v0.json b/Projects/UOContent/Migrations/Server.Items.DaimyosHelm.v0.json new file mode 100644 index 000000000..b13dadb7f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DaimyosHelm.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.DaimyosHelm" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DarkenedSky.v0.json b/Projects/UOContent/Migrations/Server.Items.DarkenedSky.v0.json new file mode 100644 index 000000000..005459438 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DarkenedSky.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.DarkenedSky" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DemonForks.v0.json b/Projects/UOContent/Migrations/Server.Items.DemonForks.v0.json new file mode 100644 index 000000000..484d32d6f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DemonForks.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.DemonForks" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DragonNunchaku.v0.json b/Projects/UOContent/Migrations/Server.Items.DragonNunchaku.v0.json new file mode 100644 index 000000000..bc8b902a2 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DragonNunchaku.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.DragonNunchaku" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Exiler.v0.json b/Projects/UOContent/Migrations/Server.Items.Exiler.v0.json new file mode 100644 index 000000000..ddbbcd136 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Exiler.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Exiler" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.FluteOfRenewal.v0.json b/Projects/UOContent/Migrations/Server.Items.FluteOfRenewal.v0.json new file mode 100644 index 000000000..db6a97786 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.FluteOfRenewal.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.FluteOfRenewal" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GlovesOfTheSun.v0.json b/Projects/UOContent/Migrations/Server.Items.GlovesOfTheSun.v0.json new file mode 100644 index 000000000..e7bd8413b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GlovesOfTheSun.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GlovesOfTheSun" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.HanzosBow.v0.json b/Projects/UOContent/Migrations/Server.Items.HanzosBow.v0.json new file mode 100644 index 000000000..d21fde169 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.HanzosBow.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.HanzosBow" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.HonorableSwords.v0.json b/Projects/UOContent/Migrations/Server.Items.HonorableSwords.v0.json new file mode 100644 index 000000000..1c6697685 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.HonorableSwords.v0.json @@ -0,0 +1,14 @@ +{ + "version": 0, + "type": "Server.Items.HonorableSwords", + "properties": [ + { + "name": "SwordsName", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.KasaOfTheRajin.v0.json b/Projects/UOContent/Migrations/Server.Items.KasaOfTheRajin.v0.json new file mode 100644 index 000000000..d05f2f44c --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.KasaOfTheRajin.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.KasaOfTheRajin" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LegsOfStability.v0.json b/Projects/UOContent/Migrations/Server.Items.LegsOfStability.v0.json new file mode 100644 index 000000000..42f273051 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LegsOfStability.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LegsOfStability" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LesserPigmentsOfTokuno.v0.json b/Projects/UOContent/Migrations/Server.Items.LesserPigmentsOfTokuno.v0.json new file mode 100644 index 000000000..c30b93790 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LesserPigmentsOfTokuno.v0.json @@ -0,0 +1,11 @@ +{ + "version": 0, + "type": "Server.Items.LesserPigmentsOfTokuno", + "properties": [ + { + "name": "Type", + "type": "Server.Items.LesserPigmentType", + "rule": "EnumMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LeurociansMempoOfFortune.v0.json b/Projects/UOContent/Migrations/Server.Items.LeurociansMempoOfFortune.v0.json new file mode 100644 index 000000000..3b58ebe52 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LeurociansMempoOfFortune.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LeurociansMempoOfFortune" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.MetalPigmentsOfTokuno.v0.json b/Projects/UOContent/Migrations/Server.Items.MetalPigmentsOfTokuno.v0.json new file mode 100644 index 000000000..de3d5d052 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MetalPigmentsOfTokuno.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MetalPigmentsOfTokuno" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PeasantsBokuto.v0.json b/Projects/UOContent/Migrations/Server.Items.PeasantsBokuto.v0.json new file mode 100644 index 000000000..ebd383a9a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PeasantsBokuto.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PeasantsBokuto" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PigmentsOfTokuno.v0.json b/Projects/UOContent/Migrations/Server.Items.PigmentsOfTokuno.v0.json new file mode 100644 index 000000000..04f2a6a4e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PigmentsOfTokuno.v0.json @@ -0,0 +1,11 @@ +{ + "version": 0, + "type": "Server.Items.PigmentsOfTokuno", + "properties": [ + { + "name": "Type", + "type": "Server.Items.PigmentType", + "rule": "EnumMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PilferedDancerFans.v0.json b/Projects/UOContent/Migrations/Server.Items.PilferedDancerFans.v0.json new file mode 100644 index 000000000..adab70bc4 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PilferedDancerFans.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PilferedDancerFans" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RuneBeetleCarapace.v0.json b/Projects/UOContent/Migrations/Server.Items.RuneBeetleCarapace.v0.json new file mode 100644 index 000000000..8954805ea --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RuneBeetleCarapace.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RuneBeetleCarapace" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.Stormgrip.v0.json b/Projects/UOContent/Migrations/Server.Items.Stormgrip.v0.json new file mode 100644 index 000000000..2ada26337 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.Stormgrip.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.Stormgrip" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SwordOfTheStampede.v0.json b/Projects/UOContent/Migrations/Server.Items.SwordOfTheStampede.v0.json new file mode 100644 index 000000000..c65c340a5 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SwordOfTheStampede.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SwordOfTheStampede" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SwordsOfProsperity.v0.json b/Projects/UOContent/Migrations/Server.Items.SwordsOfProsperity.v0.json new file mode 100644 index 000000000..459afe990 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SwordsOfProsperity.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SwordsOfProsperity" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TheDestroyer.v0.json b/Projects/UOContent/Migrations/Server.Items.TheDestroyer.v0.json new file mode 100644 index 000000000..d59adac4a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TheDestroyer.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TheDestroyer" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TheHorselord.v0.json b/Projects/UOContent/Migrations/Server.Items.TheHorselord.v0.json new file mode 100644 index 000000000..d422453da --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TheHorselord.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TheHorselord" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TomeOfEnlightenment.v0.json b/Projects/UOContent/Migrations/Server.Items.TomeOfEnlightenment.v0.json new file mode 100644 index 000000000..6673ad91b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TomeOfEnlightenment.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TomeOfEnlightenment" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TomeOfLostKnowledge.v0.json b/Projects/UOContent/Migrations/Server.Items.TomeOfLostKnowledge.v0.json new file mode 100644 index 000000000..47a71af0e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TomeOfLostKnowledge.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.TomeOfLostKnowledge" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.WindsEdge.v0.json b/Projects/UOContent/Migrations/Server.Items.WindsEdge.v0.json new file mode 100644 index 000000000..0eb66d459 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.WindsEdge.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.WindsEdge" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Mobiles.IharaSoko.v0.json b/Projects/UOContent/Migrations/Server.Mobiles.IharaSoko.v0.json new file mode 100644 index 000000000..0bd681463 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Mobiles.IharaSoko.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Mobiles.IharaSoko" +} \ No newline at end of file