diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 2e2ca8031..03eaff932 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "modernuoschemagenerator": { - "version": "2.12.10", + "version": "2.12.13", "commands": [ "ModernUOSchemaGenerator" ] diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index dd2ee185b..8536a2bb2 100644 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -39,7 +39,7 @@ - + diff --git a/Projects/UOContent/Items/Special/Holiday/Christmas/HolidayTree.cs b/Projects/UOContent/Items/Special/Holiday/Christmas/HolidayTree.cs index ed01fed3c..aa7f9358d 100644 --- a/Projects/UOContent/Items/Special/Holiday/Christmas/HolidayTree.cs +++ b/Projects/UOContent/Items/Special/Holiday/Christmas/HolidayTree.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using ModernUO.Serialization; using Server.Multis; @@ -16,7 +17,8 @@ public partial class HolidayTree : Item, IAddon [SerializedCommandProperty(AccessLevel.GameMaster)] private Mobile _placer; - private Item[] _components; + [SerializableField(1, setter: "private")] + private List _components; public HolidayTree(Mobile from, HolidayTreeType type, Point3D loc) : base(1) { @@ -25,75 +27,72 @@ public partial class HolidayTree : Item, IAddon Placer = from; - var index = 0; - switch (type) { case HolidayTreeType.Classic: { ItemID = 0xCD7; - _components = new Item[28]; + _components = new List(28); + AddItem(0, 0, 0, new TreeTrunk(this, 0xCD6)); - AddItem(0, 0, 0, new TreeTrunk(this, 0xCD6), index++); - - AddOrnament(0, 0, 2, 0xF22, index++); - AddOrnament(0, 0, 9, 0xF18, index++); - AddOrnament(0, 0, 15, 0xF20, index++); - AddOrnament(0, 0, 19, 0xF17, index++); - AddOrnament(0, 0, 20, 0xF24, index++); - AddOrnament(0, 0, 20, 0xF1F, index++); - AddOrnament(0, 0, 20, 0xF19, index++); - AddOrnament(0, 0, 21, 0xF1B, index++); - AddOrnament(0, 0, 28, 0xF2F, index++); - AddOrnament(0, 0, 30, 0xF23, index++); - AddOrnament(0, 0, 32, 0xF2A, index++); - AddOrnament(0, 0, 33, 0xF30, index++); - AddOrnament(0, 0, 34, 0xF29, index++); - AddOrnament(0, 1, 7, 0xF16, index++); - AddOrnament(0, 1, 7, 0xF1E, index++); - AddOrnament(0, 1, 12, 0xF0F, index++); - AddOrnament(0, 1, 13, 0xF13, index++); - AddOrnament(0, 1, 18, 0xF12, index++); - AddOrnament(0, 1, 19, 0xF15, index++); - AddOrnament(0, 1, 25, 0xF28, index++); - AddOrnament(0, 1, 29, 0xF1A, index++); - AddOrnament(0, 1, 37, 0xF2B, index++); - AddOrnament(1, 0, 13, 0xF10, index++); - AddOrnament(1, 0, 14, 0xF1C, index++); - AddOrnament(1, 0, 16, 0xF14, index++); - AddOrnament(1, 0, 17, 0xF26, index++); - AddOrnament(1, 0, 22, 0xF27, index); + AddOrnament(0, 0, 2, 0xF22); + AddOrnament(0, 0, 9, 0xF18); + AddOrnament(0, 0, 15, 0xF20); + AddOrnament(0, 0, 19, 0xF17); + AddOrnament(0, 0, 20, 0xF24); + AddOrnament(0, 0, 20, 0xF1F); + AddOrnament(0, 0, 20, 0xF19); + AddOrnament(0, 0, 21, 0xF1B); + AddOrnament(0, 0, 28, 0xF2F); + AddOrnament(0, 0, 30, 0xF23); + AddOrnament(0, 0, 32, 0xF2A); + AddOrnament(0, 0, 33, 0xF30); + AddOrnament(0, 0, 34, 0xF29); + AddOrnament(0, 1, 7, 0xF16); + AddOrnament(0, 1, 7, 0xF1E); + AddOrnament(0, 1, 12, 0xF0F); + AddOrnament(0, 1, 13, 0xF13); + AddOrnament(0, 1, 18, 0xF12); + AddOrnament(0, 1, 19, 0xF15); + AddOrnament(0, 1, 25, 0xF28); + AddOrnament(0, 1, 29, 0xF1A); + AddOrnament(0, 1, 37, 0xF2B); + AddOrnament(1, 0, 13, 0xF10); + AddOrnament(1, 0, 14, 0xF1C); + AddOrnament(1, 0, 16, 0xF14); + AddOrnament(1, 0, 17, 0xF26); + AddOrnament(1, 0, 22, 0xF27); break; } case HolidayTreeType.Modern: { ItemID = 0x1B7E; - _components = new Item[23]; - AddOrnament(0, 0, 2, 0xF2F, index++); - AddOrnament(0, 0, 2, 0xF20, index++); - AddOrnament(0, 0, 2, 0xF22, index++); - AddOrnament(0, 0, 5, 0xF30, index++); - AddOrnament(0, 0, 5, 0xF15, index++); - AddOrnament(0, 0, 5, 0xF1F, index++); - AddOrnament(0, 0, 5, 0xF2B, index++); - AddOrnament(0, 0, 6, 0xF0F, index++); - AddOrnament(0, 0, 7, 0xF1E, index++); - AddOrnament(0, 0, 7, 0xF24, index++); - AddOrnament(0, 0, 8, 0xF29, index++); - AddOrnament(0, 0, 9, 0xF18, index++); - AddOrnament(0, 0, 14, 0xF1C, index++); - AddOrnament(0, 0, 15, 0xF13, index++); - AddOrnament(0, 0, 15, 0xF20, index++); - AddOrnament(0, 0, 16, 0xF26, index++); - AddOrnament(0, 0, 17, 0xF12, index++); - AddOrnament(0, 0, 18, 0xF17, index++); - AddOrnament(0, 0, 20, 0xF1B, index++); - AddOrnament(0, 0, 23, 0xF28, index++); - AddOrnament(0, 0, 25, 0xF18, index++); - AddOrnament(0, 0, 25, 0xF2A, index++); - AddOrnament(0, 1, 7, 0xF16, index); + _components = new List(23); + AddOrnament(0, 0, 2, 0xF2F); + AddOrnament(0, 0, 2, 0xF20); + AddOrnament(0, 0, 2, 0xF22); + AddOrnament(0, 0, 5, 0xF30); + AddOrnament(0, 0, 5, 0xF15); + AddOrnament(0, 0, 5, 0xF1F); + AddOrnament(0, 0, 5, 0xF2B); + AddOrnament(0, 0, 6, 0xF0F); + AddOrnament(0, 0, 7, 0xF1E); + AddOrnament(0, 0, 7, 0xF24); + AddOrnament(0, 0, 8, 0xF29); + AddOrnament(0, 0, 9, 0xF18); + AddOrnament(0, 0, 14, 0xF1C); + AddOrnament(0, 0, 15, 0xF13); + AddOrnament(0, 0, 15, 0xF20); + AddOrnament(0, 0, 16, 0xF26); + AddOrnament(0, 0, 17, 0xF12); + AddOrnament(0, 0, 18, 0xF17); + AddOrnament(0, 0, 20, 0xF1B); + AddOrnament(0, 0, 23, 0xF28); + AddOrnament(0, 0, 25, 0xF18); + AddOrnament(0, 0, 25, 0xF2A); + AddOrnament(0, 1, 7, 0xF16); break; } } @@ -107,24 +106,24 @@ public partial class HolidayTree : Item, IAddon public override void OnAfterDelete() { - for (var i = 0; i < _components.Length; ++i) + foreach (var c in _components) { - _components[i]?.Delete(); + c?.Delete(); } _components = null; } - private void AddOrnament(int x, int y, int z, int itemID, int index) + private void AddOrnament(int x, int y, int z, int itemID) { - AddItem(x + 1, y + 1, z + 11, new Ornament(itemID), index); + AddItem(x + 1, y + 1, z + 11, new Ornament(this, itemID)); } - private void AddItem(int x, int y, int z, Item item, int index) + private void AddItem(int x, int y, int z, Item item) { item.MoveToWorld(new Point3D(Location.X + x, Location.Y + y, Location.Z + z), Map); - _components[index] = item; + _components.Add(item); } private void Deserialize(IGenericReader reader, int version) @@ -133,8 +132,6 @@ public partial class HolidayTree : Item, IAddon var count = reader.ReadInt(); - _components = new Item[count]; - for (var i = 0; i < count; ++i) { var item = reader.ReadEntity(); @@ -149,7 +146,8 @@ public partial class HolidayTree : Item, IAddon [AfterDeserialization(false)] private void AfterDeserialization() { - if (BaseHouse.FindHouseAt(this) == null) + // Bug with older trees, or trees that belong to a house that doesn't exist should be redeeded. + if (_components == null || _components.Count == 0 || BaseHouse.FindHouseAt(this) == null) { var deed = new HolidayTreeDeed(); deed.MoveToWorld(Location, Map); @@ -179,17 +177,43 @@ public partial class HolidayTree : Item, IAddon from.SendLocalizedMessage(503393); // A deed for the tree has been placed in your backpack. } - [SerializationGenerator(0, false)] - private partial class Ornament : Item + [SerializationGenerator(1, false)] + public partial class Ornament : Item { - public Ornament(int itemID) : base(itemID) => Movable = false; + [SerializableField(0)] + private HolidayTree _tree; - public override int LabelNumber => 1041118; // a tree ornament + public Ornament(HolidayTree tree, int itemID) : base(itemID) + { + Movable = false; + _tree = tree; + } + + public override int LabelNumber => 1041118; // a tree ornaments + + [AfterDeserialization] + private void AfterDeserialization() + { + if (_tree == null) + { + Timer.DelayCall(Delete); // There was an issue and old trees will be regenerated + } + else + { + _tree._components.Add(this); + } + } + + private void MigrateFrom(V0Content content) + { + + } } - [SerializationGenerator(0, false)] - private partial class TreeTrunk : Item + [SerializationGenerator(1, false)] + public partial class TreeTrunk : Item { + [SerializableField(0)] private HolidayTree _tree; public TreeTrunk(HolidayTree tree, int itemID) : base(itemID) @@ -208,5 +232,22 @@ public partial class HolidayTree : Item, IAddon _tree.OnDoubleClick(from); } } + + [AfterDeserialization] + private void AfterDeserialization() + { + if (_tree == null) + { + Timer.DelayCall(Delete); // There was an issue and old trees will be regenerated + } + else + { + _tree._components.Add(this); + } + } + + private void MigrateFrom(V0Content content) + { + } } } diff --git a/Projects/UOContent/Migrations/Server.Items.HolidayTree.Ornament.v0.json b/Projects/UOContent/Migrations/Server.Items.HolidayTree.Ornament.v0.json index 7f9be1a65..1f78fe34f 100644 --- a/Projects/UOContent/Migrations/Server.Items.HolidayTree.Ornament.v0.json +++ b/Projects/UOContent/Migrations/Server.Items.HolidayTree.Ornament.v0.json @@ -1,4 +1,11 @@ { "version": 0, - "type": "Server.Items.HolidayTree.Ornament" + "type": "Server.Items.HolidayTree.Ornament", + "properties": [ + { + "name": "Tree", + "type": "Server.Items.HolidayTree", + "rule": "SerializableInterfaceMigrationRule" + } + ] } \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.HolidayTree.Ornament.v1.json b/Projects/UOContent/Migrations/Server.Items.HolidayTree.Ornament.v1.json new file mode 100644 index 000000000..351191026 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.HolidayTree.Ornament.v1.json @@ -0,0 +1,11 @@ +{ + "version": 1, + "type": "Server.Items.HolidayTree.Ornament", + "properties": [ + { + "name": "Tree", + "type": "Server.Items.HolidayTree", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.HolidayTree.TreeTrunk.v0.json b/Projects/UOContent/Migrations/Server.Items.HolidayTree.TreeTrunk.v0.json index 0b62d1eec..93abd2157 100644 --- a/Projects/UOContent/Migrations/Server.Items.HolidayTree.TreeTrunk.v0.json +++ b/Projects/UOContent/Migrations/Server.Items.HolidayTree.TreeTrunk.v0.json @@ -1,4 +1,11 @@ { "version": 0, - "type": "Server.Items.HolidayTree.TreeTrunk" + "type": "Server.Items.HolidayTree.TreeTrunk", + "properties": [ + { + "name": "Tree", + "type": "Server.Items.HolidayTree", + "rule": "SerializableInterfaceMigrationRule" + } + ] } \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.HolidayTree.TreeTrunk.v1.json b/Projects/UOContent/Migrations/Server.Items.HolidayTree.TreeTrunk.v1.json new file mode 100644 index 000000000..9576d6144 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.HolidayTree.TreeTrunk.v1.json @@ -0,0 +1,11 @@ +{ + "version": 1, + "type": "Server.Items.HolidayTree.TreeTrunk", + "properties": [ + { + "name": "Tree", + "type": "Server.Items.HolidayTree", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.HolidayTree.v2.json b/Projects/UOContent/Migrations/Server.Items.HolidayTree.v2.json index d05d3ebbd..cfc27b1af 100644 --- a/Projects/UOContent/Migrations/Server.Items.HolidayTree.v2.json +++ b/Projects/UOContent/Migrations/Server.Items.HolidayTree.v2.json @@ -6,6 +6,15 @@ "name": "Placer", "type": "Server.Mobile", "rule": "SerializableInterfaceMigrationRule" + }, + { + "name": "Components", + "type": "System.Collections.Generic.List\u003CServer.Item\u003E", + "rule": "ListMigrationRule", + "ruleArguments": [ + "Server.Item", + "SerializableInterfaceMigrationRule" + ] } ] } \ No newline at end of file diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj index e2e0bbc88..60e867724 100644 --- a/Projects/UOContent/UOContent.csproj +++ b/Projects/UOContent/UOContent.csproj @@ -47,7 +47,7 @@ - +