From 94040f142ce2cd4bc59bb23928cdec74f68ddcc5 Mon Sep 17 00:00:00 2001 From: Reetus <6239195+Reetus@users.noreply.github.com> Date: Tue, 17 Dec 2024 03:21:09 +0700 Subject: [PATCH 1/7] fix: Fixes overlapping text in TithingGump (#2020) --- Projects/UOContent/Gumps/TithingGump.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/UOContent/Gumps/TithingGump.cs b/Projects/UOContent/Gumps/TithingGump.cs index 6c837bef5..c917ccff2 100644 --- a/Projects/UOContent/Gumps/TithingGump.cs +++ b/Projects/UOContent/Gumps/TithingGump.cs @@ -26,7 +26,7 @@ public class TithingGump : StaticGump // AddLabel(57, 274, 0, "Gold:"); builder.AddLabelPlaceholder(87, 274, 53, "goldOffer"); - builder.AddHtmlLocalized(57, 274, 50, 20, 1079251); // Tithe: + builder.AddHtmlLocalized(137, 274, 50, 20, 1079251); // Tithe: // AddLabel(137, 274, 0, "Tithe:"); builder.AddLabelPlaceholder(172, 274, 53, "titheOffer"); From fefa06d4e0bf5d0db8d9154cdad54bacf05354a9 Mon Sep 17 00:00:00 2001 From: Reetus <6239195+Reetus@users.noreply.github.com> Date: Tue, 17 Dec 2024 03:28:52 +0700 Subject: [PATCH 2/7] fix: Fix Lord/Lady title display in paperdoll when fame >= 10000 (#2022) --- Projects/UOContent/Misc/Titles.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/UOContent/Misc/Titles.cs b/Projects/UOContent/Misc/Titles.cs index 076ae9a05..9595665b5 100644 --- a/Projects/UOContent/Misc/Titles.cs +++ b/Projects/UOContent/Misc/Titles.cs @@ -291,7 +291,7 @@ namespace Server.Misc if (karma <= ke.m_Karma || j == karmaEntries.Length - 1) { - if (karma >= 10000) + if (fame >= 10000) { if (beheld.Female) { From e662b78f5ae177fb6a0b208f6973ff5fb1c35374 Mon Sep 17 00:00:00 2001 From: Reetus <6239195+Reetus@users.noreply.github.com> Date: Tue, 17 Dec 2024 03:32:26 +0700 Subject: [PATCH 3/7] fix: Fix missing LabelNumber on DisguiseKit (#2021) --- Projects/UOContent/Items/Skill Items/Thief/DisguiseKit.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Projects/UOContent/Items/Skill Items/Thief/DisguiseKit.cs b/Projects/UOContent/Items/Skill Items/Thief/DisguiseKit.cs index 1422cc6aa..1de601118 100644 --- a/Projects/UOContent/Items/Skill Items/Thief/DisguiseKit.cs +++ b/Projects/UOContent/Items/Skill Items/Thief/DisguiseKit.cs @@ -14,6 +14,8 @@ namespace Server.Items; [SerializationGenerator(0, false)] public partial class DisguiseKit : Item { + public override int LabelNumber => 1041078; // a disguise kit + [Constructible] public DisguiseKit() : base(0xE05) => Weight = 1.0; From d9e5ec91e1e516f75bdf34bca8b2d2fe4345695d Mon Sep 17 00:00:00 2001 From: Bohica <53943479+Bohicatv@users.noreply.github.com> Date: Tue, 17 Dec 2024 08:59:36 -0800 Subject: [PATCH 4/7] fix: Update Hythloth teleport locations in Felucca and Trammel to new coordinates to prevent looping and stuck. (#2012) --- .../Data/Decoration/Britannia/patches.cfg | 5 +- Distribution/Data/teleporters.json | 54 +++++++++---------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/Distribution/Data/Decoration/Britannia/patches.cfg b/Distribution/Data/Decoration/Britannia/patches.cfg index 76e0baa95..f5fe0df7b 100644 --- a/Distribution/Data/Decoration/Britannia/patches.cfg +++ b/Distribution/Data/Decoration/Britannia/patches.cfg @@ -34,6 +34,9 @@ Blocker 0x21A4 6082 144 -15 6082 145 -15 6082 146 -15 +5920 168 16 +5920 169 16 +5920 170 16 6058 88 29 6058 89 29 6058 90 29 @@ -138,4 +141,4 @@ Static 0x179A 3446 548 -5 3456 538 -5 3472 512 -5 -3488 580 -5 \ No newline at end of file +3488 580 -5 diff --git a/Distribution/Data/teleporters.json b/Distribution/Data/teleporters.json index 91e70eb0b..d92711ece 100644 --- a/Distribution/Data/teleporters.json +++ b/Distribution/Data/teleporters.json @@ -1450,19 +1450,19 @@ "back": false }, { - "src": { "map": "Felucca", "loc": [5905, 97, 0] }, - "dst": { "map": "Felucca", "loc": [5977, 169, 0] }, + "src": { "map": "Felucca", "loc": [5919, 168, 22] }, + "dst": { "map": "Felucca", "loc": [6083, 144, -20] }, "back": false }, { - "src": { "map": "Felucca", "loc": [5906, 96, 0] }, - "dst": { "map": "Felucca", "loc": [5977, 169, 0] }, + "src": { "map": "Felucca", "loc": [5919, 169, 22] }, + "dst": { "map": "Felucca", "loc": [6083, 145, -20] }, "back": false }, { - "src": { "map": "Felucca", "loc": [5906, 4069, 26] }, - "dst": { "map": "Felucca", "loc": [2494, 3576, 5] }, - "back": true + "src": { "map": "Felucca", "loc": [5919, 170, 22] }, + "dst": { "map": "Felucca", "loc": [6083, 146, -20] }, + "back": false }, { "src": { "map": "Felucca", "loc": [5918, 1410, -29] }, @@ -1715,19 +1715,19 @@ "back": false }, { - "src": { "map": "Felucca", "loc": [6039, 204, 22] }, - "dst": { "map": "Felucca", "loc": [6050, 227, 44] }, + "src": { "map": "Felucca", "loc": [6083, 144, -20] }, + "dst": { "map": "Felucca", "loc": [5918, 168, 22] }, "back": false }, { - "src": { "map": "Felucca", "loc": [6040, 192, 12] }, - "dst": { "map": "Felucca", "loc": [6059, 88, 24] }, - "back": true + "src": { "map": "Felucca", "loc": [6083, 145, -20] }, + "dst": { "map": "Felucca", "loc": [5918, 169, 22] }, + "back": false }, { - "src": { "map": "Felucca", "loc": [6040, 193, 12] }, - "dst": { "map": "Felucca", "loc": [6059, 89, 24] }, - "back": true + "src": { "map": "Felucca", "loc": [6083, 146, -20] }, + "dst": { "map": "Felucca", "loc": [5918, 170, 22] }, + "back": false }, { "src": { "map": "Felucca", "loc": [6040, 194, 12] }, @@ -3555,18 +3555,18 @@ "back": false }, { - "src": { "map": "Trammel", "loc": [5882, 243, 0] }, - "dst": { "map": "Trammel", "loc": [1998, 81, 5] }, + "src": { "map": "Trammel", "loc": [5919, 168, 22] }, + "dst": { "map": "Trammel", "loc": [6083, 144, -20] }, "back": false }, { - "src": { "map": "Trammel", "loc": [5899, 1411, 43] }, - "dst": { "map": "Trammel", "loc": [1630, 3320, 0] }, + "src": { "map": "Trammel", "loc": [5919, 169, 22] }, + "dst": { "map": "Trammel", "loc": [6083, 145, -20] }, "back": false }, { - "src": { "map": "Trammel", "loc": [5900, 1411, 42] }, - "dst": { "map": "Trammel", "loc": [1630, 3320, 0] }, + "src": { "map": "Trammel", "loc": [5919, 170, 22] }, + "dst": { "map": "Trammel", "loc": [6083, 146, -20] }, "back": false }, { @@ -3805,18 +3805,18 @@ "back": false }, { - "src": { "map": "Trammel", "loc": [6031, 1499, 42] }, - "dst": { "map": "Trammel", "loc": [1491, 1640, 24] }, + "src": { "map": "Trammel", "loc": [6083, 144, -20] }, + "dst": { "map": "Trammel", "loc": [5918, 168, 22] }, "back": false }, { - "src": { "map": "Trammel", "loc": [6031, 1501, 42] }, - "dst": { "map": "Trammel", "loc": [1491, 1642, 24] }, + "src": { "map": "Trammel", "loc": [6083, 145, -20] }, + "dst": { "map": "Trammel", "loc": [5918, 169, 22] }, "back": false }, { - "src": { "map": "Trammel", "loc": [6039, 204, 22] }, - "dst": { "map": "Trammel", "loc": [6050, 227, 44] }, + "src": { "map": "Trammel", "loc": [6083, 146, -20] }, + "dst": { "map": "Trammel", "loc": [5918, 170, 22] }, "back": false }, { From f33e218c0b39b5ace5d64bca87874fa168c3e62f Mon Sep 17 00:00:00 2001 From: Reetus <6239195+Reetus@users.noreply.github.com> Date: Tue, 17 Dec 2024 23:59:50 +0700 Subject: [PATCH 5/7] fix: Fix HolidayTree not serializing components (#2024) --- .config/dotnet-tools.json | 2 +- Projects/Server/Server.csproj | 2 +- .../Special/Holiday/Christmas/HolidayTree.cs | 185 +++++++++++------- .../Server.Items.HolidayTree.Ornament.v0.json | 9 +- .../Server.Items.HolidayTree.Ornament.v1.json | 11 ++ ...Server.Items.HolidayTree.TreeTrunk.v0.json | 9 +- ...Server.Items.HolidayTree.TreeTrunk.v1.json | 11 ++ .../Server.Items.HolidayTree.v2.json | 9 + Projects/UOContent/UOContent.csproj | 2 +- 9 files changed, 163 insertions(+), 77 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.HolidayTree.Ornament.v1.json create mode 100644 Projects/UOContent/Migrations/Server.Items.HolidayTree.TreeTrunk.v1.json 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 @@ - + From e27773e3d928c9301661c4dc0c2224d55107b78a Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 17 Dec 2024 10:40:02 -0800 Subject: [PATCH 6/7] feat: Adds wall z-offset detection for doorgen (#2025) --- Projects/UOContent/Misc/DoorGenerator.cs | 1013 +++++++++++----------- 1 file changed, 521 insertions(+), 492 deletions(-) diff --git a/Projects/UOContent/Misc/DoorGenerator.cs b/Projects/UOContent/Misc/DoorGenerator.cs index 0ec27c04f..c2d44be2f 100644 --- a/Projects/UOContent/Misc/DoorGenerator.cs +++ b/Projects/UOContent/Misc/DoorGenerator.cs @@ -1,558 +1,587 @@ +using System; using Server.Items; +using Server.Logging; using Server.Network; -namespace Server +namespace Server; + +public static class DoorGenerator { - public static class DoorGenerator + private static readonly ILogger logger = LogFactory.GetLogger(typeof(DoorGenerator)); + + private static readonly Rectangle2D[] _britRegions = { - private static readonly Rectangle2D[] m_BritRegions = - { - new(new Point2D(250, 750), new Point2D(775, 1330)), - new(new Point2D(525, 2095), new Point2D(925, 2430)), - new(new Point2D(1025, 2155), new Point2D(1265, 2310)), - new(new Point2D(1635, 2430), new Point2D(1705, 2508)), - new(new Point2D(1775, 2605), new Point2D(2165, 2975)), - new(new Point2D(1055, 3520), new Point2D(1570, 4075)), - new(new Point2D(2860, 3310), new Point2D(3120, 3630)), - new(new Point2D(2470, 1855), new Point2D(3950, 3045)), - new(new Point2D(3425, 990), new Point2D(3900, 1455)), - new(new Point2D(4175, 735), new Point2D(4840, 1600)), - new(new Point2D(2375, 330), new Point2D(3100, 1045)), - new(new Point2D(2100, 1090), new Point2D(2310, 1450)), - new(new Point2D(1495, 1400), new Point2D(1550, 1475)), - new(new Point2D(1085, 1520), new Point2D(1415, 1910)), - new(new Point2D(1410, 1500), new Point2D(1745, 1795)), - new(new Point2D(5120, 2300), new Point2D(6143, 4095)) - }; + new(new Point2D(250, 750), new Point2D(775, 1330)), + new(new Point2D(525, 2095), new Point2D(925, 2430)), + new(new Point2D(1025, 2155), new Point2D(1265, 2310)), + new(new Point2D(1635, 2430), new Point2D(1705, 2508)), + new(new Point2D(1775, 2605), new Point2D(2165, 2975)), + new(new Point2D(1055, 3520), new Point2D(1570, 4075)), + new(new Point2D(2860, 3310), new Point2D(3120, 3630)), + new(new Point2D(2470, 1855), new Point2D(3950, 3045)), + new(new Point2D(3425, 990), new Point2D(3900, 1455)), + new(new Point2D(4175, 735), new Point2D(4840, 1600)), + new(new Point2D(2375, 330), new Point2D(3100, 1045)), + new(new Point2D(2100, 1090), new Point2D(2310, 1450)), + new(new Point2D(1495, 1400), new Point2D(1550, 1475)), + new(new Point2D(1085, 1520), new Point2D(1415, 1910)), + new(new Point2D(1410, 1500), new Point2D(1745, 1795)), + new(new Point2D(5120, 2300), new Point2D(6143, 4095)) + }; - private static readonly Rectangle2D[] m_IlshRegions = - { - new(new Point2D(0, 0), new Point2D(288 * 8, 200 * 8)) - }; + private static readonly Rectangle2D[] _ilshRegions = + { + new(new Point2D(0, 0), new Point2D(288 * 8, 200 * 8)) + }; - private static readonly Rectangle2D[] m_MalasRegions = - { - new(new Point2D(0, 0), new Point2D(320 * 8, 256 * 8)) - }; + private static readonly Rectangle2D[] _malasRegions = + { + new(new Point2D(0, 0), new Point2D(320 * 8, 256 * 8)) + }; - private static readonly int[] m_SouthFrames = - { - 0x0006, - 0x0008, - 0x000B, - 0x001A, - 0x001B, - 0x001F, - 0x0038, - 0x0057, - 0x0059, - 0x005B, - 0x005D, - 0x0080, - 0x0081, - 0x0082, - 0x0084, - 0x0090, - 0x0091, - 0x0094, - 0x0096, - 0x0099, - 0x00A6, - 0x00A7, - 0x00AA, - 0x00AE, - 0x00B0, - 0x00B3, - 0x00C7, - 0x00C9, - 0x00F8, - 0x00FA, - 0x00FD, - 0x00FE, - 0x0100, - 0x0103, - 0x0104, - 0x0106, - 0x0109, - 0x0127, - 0x0129, - 0x012B, - 0x012D, - 0x012F, - 0x0131, - 0x0132, - 0x0134, - 0x0135, - 0x0137, - 0x0139, - 0x013B, - 0x014C, - 0x014E, - 0x014F, - 0x0151, - 0x0153, - 0x0155, - 0x0157, - 0x0158, - 0x015A, - 0x015D, - 0x015E, - 0x015F, - 0x0162, - 0x01CF, - 0x01D1, - 0x01D4, - 0x01FF, - 0x0204, - 0x0206, - 0x0208, - 0x020A - }; + private static readonly int[] _southFrames = + { + 0x0006, + 0x0008, + 0x000B, + 0x001A, + 0x001B, + 0x001F, + 0x0038, + 0x0057, + 0x0059, + 0x005B, + 0x005D, + 0x0080, + 0x0081, + 0x0082, + 0x0084, + 0x0090, + 0x0091, + 0x0094, + 0x0096, + 0x0099, + 0x00A6, + 0x00A7, + 0x00AA, + 0x00AE, + 0x00B0, + 0x00B3, + 0x00C7, + 0x00C9, + 0x00F8, + 0x00FA, + 0x00FD, + 0x00FE, + 0x0100, + 0x0103, + 0x0104, + 0x0106, + 0x0109, + 0x0127, + 0x0129, + 0x012B, + 0x012D, + 0x012F, + 0x0131, + 0x0132, + 0x0134, + 0x0135, + 0x0137, + 0x0139, + 0x013B, + 0x014C, + 0x014E, + 0x014F, + 0x0151, + 0x0153, + 0x0155, + 0x0157, + 0x0158, + 0x015A, + 0x015D, + 0x015E, + 0x015F, + 0x0162, + 0x01CF, + 0x01D1, + 0x01D4, + 0x01FF, + 0x0204, + 0x0206, + 0x0208, + 0x020A + }; - private static readonly int[] m_NorthFrames = - { - 0x0006, - 0x0008, - 0x000D, - 0x001A, - 0x001B, - 0x0020, - 0x003A, - 0x0057, - 0x0059, - 0x005B, - 0x005D, - 0x0080, - 0x0081, - 0x0082, - 0x0084, - 0x0090, - 0x0091, - 0x0094, - 0x0096, - 0x0099, - 0x00A6, - 0x00A7, - 0x00AC, - 0x00AE, - 0x00B0, - 0x00C7, - 0x00C9, - 0x00F8, - 0x00FA, - 0x00FD, - 0x00FE, - 0x0100, - 0x0103, - 0x0104, - 0x0106, - 0x0109, - 0x0127, - 0x0129, - 0x012B, - 0x012D, - 0x012F, - 0x0131, - 0x0132, - 0x0134, - 0x0135, - 0x0137, - 0x0139, - 0x013B, - 0x014C, - 0x014E, - 0x014F, - 0x0151, - 0x0153, - 0x0155, - 0x0157, - 0x0158, - 0x015A, - 0x015D, - 0x015E, - 0x015F, - 0x0162, - 0x01CF, - 0x01D1, - 0x01D4, - 0x01FF, - 0x0201, - 0x0204, - 0x0208, - 0x020A - }; + private static readonly int[] _northFrames = + { + 0x0006, + 0x0008, + 0x000D, + 0x001A, + 0x001B, + 0x0020, + 0x003A, + 0x0057, + 0x0059, + 0x005B, + 0x005D, + 0x0080, + 0x0081, + 0x0082, + 0x0084, + 0x0090, + 0x0091, + 0x0094, + 0x0096, + 0x0099, + 0x00A6, + 0x00A7, + 0x00AC, + 0x00AE, + 0x00B0, + 0x00C7, + 0x00C9, + 0x00F8, + 0x00FA, + 0x00FD, + 0x00FE, + 0x0100, + 0x0103, + 0x0104, + 0x0106, + 0x0109, + 0x0127, + 0x0129, + 0x012B, + 0x012D, + 0x012F, + 0x0131, + 0x0132, + 0x0134, + 0x0135, + 0x0137, + 0x0139, + 0x013B, + 0x014C, + 0x014E, + 0x014F, + 0x0151, + 0x0153, + 0x0155, + 0x0157, + 0x0158, + 0x015A, + 0x015D, + 0x015E, + 0x015F, + 0x0162, + 0x01CF, + 0x01D1, + 0x01D4, + 0x01FF, + 0x0201, + 0x0204, + 0x0208, + 0x020A + }; - private static readonly int[] m_EastFrames = - { - 0x0007, - 0x000A, - 0x001A, - 0x001C, - 0x001E, - 0x0037, - 0x0058, - 0x0059, - 0x005C, - 0x005E, - 0x0080, - 0x0081, - 0x0082, - 0x0084, - 0x0090, - 0x0092, - 0x0095, - 0x0097, - 0x0098, - 0x00A6, - 0x00A8, - 0x00AB, - 0x00AE, - 0x00AF, - 0x00B2, - 0x00C7, - 0x00C8, - 0x00EA, - 0x00F8, - 0x00F9, - 0x00FC, - 0x00FE, - 0x00FF, - 0x0102, - 0x0104, - 0x0105, - 0x0108, - 0x0127, - 0x0128, - 0x012B, - 0x012C, - 0x012E, - 0x0130, - 0x0132, - 0x0133, - 0x0135, - 0x0136, - 0x0138, - 0x013A, - 0x014C, - 0x014D, - 0x014F, - 0x0150, - 0x0152, - 0x0154, - 0x0156, - 0x0158, - 0x0159, - 0x015C, - 0x015E, - 0x0160, - 0x0163, - 0x01CF, - 0x01D0, - 0x01D3, - 0x01FF, - 0x0203, - 0x0205, - 0x0207, - 0x0209 - }; + private static readonly int[] _eastFrames = + { + 0x0007, + 0x000A, + 0x001A, + 0x001C, + 0x001E, + 0x0037, + 0x0058, + 0x0059, + 0x005C, + 0x005E, + 0x0080, + 0x0081, + 0x0082, + 0x0084, + 0x0090, + 0x0092, + 0x0095, + 0x0097, + 0x0098, + 0x00A6, + 0x00A8, + 0x00AB, + 0x00AE, + 0x00AF, + 0x00B2, + 0x00C7, + 0x00C8, + 0x00EA, + 0x00F8, + 0x00F9, + 0x00FC, + 0x00FE, + 0x00FF, + 0x0102, + 0x0104, + 0x0105, + 0x0108, + 0x0127, + 0x0128, + 0x012B, + 0x012C, + 0x012E, + 0x0130, + 0x0132, + 0x0133, + 0x0135, + 0x0136, + 0x0138, + 0x013A, + 0x014C, + 0x014D, + 0x014F, + 0x0150, + 0x0152, + 0x0154, + 0x0156, + 0x0158, + 0x0159, + 0x015C, + 0x015E, + 0x0160, + 0x0163, + 0x01CF, + 0x01D0, + 0x01D3, + 0x01FF, + 0x0203, + 0x0205, + 0x0207, + 0x0209 + }; - private static readonly int[] m_WestFrames = - { - 0x0007, - 0x000C, - 0x001A, - 0x001C, - 0x0021, - 0x0039, - 0x0058, - 0x0059, - 0x005C, - 0x005E, - 0x0080, - 0x0081, - 0x0082, - 0x0084, - 0x0090, - 0x0092, - 0x0095, - 0x0097, - 0x0098, - 0x00A6, - 0x00A8, - 0x00AD, - 0x00AE, - 0x00AF, - 0x00B5, - 0x00C7, - 0x00C8, - 0x00EA, - 0x00F8, - 0x00F9, - 0x00FC, - 0x00FE, - 0x00FF, - 0x0102, - 0x0104, - 0x0105, - 0x0108, - 0x0127, - 0x0128, - 0x012C, - 0x012E, - 0x0130, - 0x0132, - 0x0133, - 0x0135, - 0x0136, - 0x0138, - 0x013A, - 0x014C, - 0x014D, - 0x014F, - 0x0150, - 0x0152, - 0x0154, - 0x0156, - 0x0158, - 0x0159, - 0x015C, - 0x015E, - 0x0160, - 0x0163, - 0x01CF, - 0x01D0, - 0x01D3, - 0x01FF, - 0x0200, - 0x0203, - 0x0207, - 0x0209 - }; + private static readonly int[] _westFrames = + { + 0x0007, + 0x000C, + 0x001A, + 0x001C, + 0x0021, + 0x0039, + 0x0058, + 0x0059, + 0x005C, + 0x005E, + 0x0080, + 0x0081, + 0x0082, + 0x0084, + 0x0090, + 0x0092, + 0x0095, + 0x0097, + 0x0098, + 0x00A6, + 0x00A8, + 0x00AD, + 0x00AE, + 0x00AF, + 0x00B5, + 0x00C7, + 0x00C8, + 0x00EA, + 0x00F8, + 0x00F9, + 0x00FC, + 0x00FE, + 0x00FF, + 0x0102, + 0x0104, + 0x0105, + 0x0108, + 0x0127, + 0x0128, + 0x012C, + 0x012E, + 0x0130, + 0x0132, + 0x0133, + 0x0135, + 0x0136, + 0x0138, + 0x013A, + 0x014C, + 0x014D, + 0x014F, + 0x0150, + 0x0152, + 0x0154, + 0x0156, + 0x0158, + 0x0159, + 0x015C, + 0x015E, + 0x0160, + 0x0163, + 0x01CF, + 0x01D0, + 0x01D3, + 0x01FF, + 0x0200, + 0x0203, + 0x0207, + 0x0209 + }; - private static Map m_Map; - private static int m_Count; + private static Map m_Map; + private static int m_Count; - public static void Configure() + public static void Configure() + { + CommandSystem.Register("DoorGen", AccessLevel.Developer, DoorGen_OnCommand); + } + + [Usage("DoorGen"), Description("Generates doors by analyzing the map. Slow.")] + public static void DoorGen_OnCommand(CommandEventArgs e) + { + Generate(); + } + + public static void Generate() + { + World.Broadcast(0x35, true, "Generating doors, please wait."); + + NetState.FlushAll(); + + m_Map = Map.Trammel; + m_Count = 0; + + for (var i = 0; i < _britRegions.Length; ++i) { - CommandSystem.Register("DoorGen", AccessLevel.Developer, DoorGen_OnCommand); + Generate(_britRegions[i]); } - [Usage("DoorGen"), Description("Generates doors by analyzing the map. Slow.")] - public static void DoorGen_OnCommand(CommandEventArgs e) + var trammelCount = m_Count; + + m_Map = Map.Felucca; + m_Count = 0; + + for (var i = 0; i < _britRegions.Length; ++i) { - Generate(); + Generate(_britRegions[i]); } - public static void Generate() + var feluccaCount = m_Count; + + m_Map = Map.Ilshenar; + m_Count = 0; + + for (var i = 0; i < _ilshRegions.Length; ++i) { - World.Broadcast(0x35, true, "Generating doors, please wait."); - - NetState.FlushAll(); - - m_Map = Map.Trammel; - m_Count = 0; - - for (var i = 0; i < m_BritRegions.Length; ++i) - { - Generate(m_BritRegions[i]); - } - - var trammelCount = m_Count; - - m_Map = Map.Felucca; - m_Count = 0; - - for (var i = 0; i < m_BritRegions.Length; ++i) - { - Generate(m_BritRegions[i]); - } - - var feluccaCount = m_Count; - - m_Map = Map.Ilshenar; - m_Count = 0; - - for (var i = 0; i < m_IlshRegions.Length; ++i) - { - Generate(m_IlshRegions[i]); - } - - var ilshenarCount = m_Count; - - m_Map = Map.Malas; - m_Count = 0; - - for (var i = 0; i < m_MalasRegions.Length; ++i) - { - Generate(m_MalasRegions[i]); - } - - var malasCount = m_Count; - - World.Broadcast( - 0x35, - true, - $"Door generation complete. Trammel: {trammelCount}; Felucca: {feluccaCount}; Ilshenar: {ilshenarCount}; Malas: {malasCount};" - ); + Generate(_ilshRegions[i]); } - public static bool IsFrame(int id, int[] list) + var ilshenarCount = m_Count; + + m_Map = Map.Malas; + m_Count = 0; + + for (var i = 0; i < _malasRegions.Length; ++i) { - if (id > list[^1]) + Generate(_malasRegions[i]); + } + + var malasCount = m_Count; + + World.Broadcast( + 0x35, + true, + $"Door generation complete. Trammel: {trammelCount}; Felucca: {feluccaCount}; Ilshenar: {ilshenarCount}; Malas: {malasCount};" + ); + } + + public static bool IsFrame(int id, int[] list) + { + if (id > list[^1]) + { + return false; + } + + for (var i = 0; i < list.Length; ++i) + { + var delta = id - list[i]; + + if (delta < 0) { return false; } - for (var i = 0; i < list.Length; ++i) + if (delta == 0) { - var delta = id - list[i]; - - if (delta < 0) - { - return false; - } - - if (delta == 0) - { - return true; - } + return true; } - - return false; } - public static bool IsNorthFrame(int id) => IsFrame(id, m_NorthFrames); + return false; + } - public static bool IsSouthFrame(int id) => IsFrame(id, m_SouthFrames); + public static bool IsNorthFrame(int id) => IsFrame(id, _northFrames); - public static bool IsWestFrame(int id) => IsFrame(id, m_WestFrames); + public static bool IsSouthFrame(int id) => IsFrame(id, _southFrames); - public static bool IsEastFrame(int id) => IsFrame(id, m_EastFrames); + public static bool IsWestFrame(int id) => IsFrame(id, _westFrames); - public static bool IsEastFrame(int x, int y, int z) + public static bool IsEastFrame(int id) => IsFrame(id, _eastFrames); + + public static bool IsEastFrame(int x, int y, int z, out int newZ) + { + foreach (var tile in m_Map.Tiles.GetStaticTiles(x, y)) { - foreach (var tile in m_Map.Tiles.GetStaticTiles(x, y)) + if (!IsEastFrame(tile.ID)) { - if (tile.Z == z && IsEastFrame(tile.ID)) - { - return true; - } + continue; } - return false; + var delta = tile.Z - z; + + if (delta is >= -1 and <= 1) + { + newZ = tile.Z; + return true; + } } - public static bool IsSouthFrame(int x, int y, int z) + newZ = -1; + return false; + } + + public static bool IsSouthFrame(int x, int y, int z, out int newZ) + { + foreach (var tile in m_Map.Tiles.GetStaticTiles(x, y)) { - foreach (var tile in m_Map.Tiles.GetStaticTiles(x, y)) + if (!IsSouthFrame(tile.ID)) { - if (tile.Z == z && IsSouthFrame(tile.ID)) - { - return true; - } + continue; } - return false; + var delta = tile.Z - z; + + if (delta is >= -1 and <= 1) + { + newZ = tile.Z; + return true; + } } - public static BaseDoor AddDoor(int x, int y, int z, DoorFacing facing) + newZ = -1; + return false; + } + + public static BaseDoor AddDoor(int x, int y, int z, int newZ, DoorFacing facing) + { + var minZ = Math.Min(z, newZ); + if (!m_Map.CanFit(x, y, minZ, 16, false, false)) { - var doorZ = z; - var doorTop = doorZ + 20; - - if (!m_Map.CanFit(x, y, z, 16, false, false)) - { - return null; - } - - if (y == 1743 && x >= 1343 && x <= 1344) - { - return null; - } - - if (y == 1679 && x >= 1392 && x <= 1393) - { - return null; - } - - if (x == 1320 && y >= 1618 && y <= 1640) - { - return null; - } - - if (x == 1383 && y >= 1642 && y <= 1643) - { - return null; - } - - BaseDoor door = new DarkWoodDoor(facing); - door.MoveToWorld(new Point3D(x, y, z), m_Map); - - ++m_Count; - - return door; + return null; } - public static void Generate(Rectangle2D region) + if (y == 1743 && x is >= 1343 and <= 1344) { - for (var rx = 0; rx < region.Width; ++rx) - { - for (var ry = 0; ry < region.Height; ++ry) - { - var vx = rx + region.X; - var vy = ry + region.Y; + return null; + } - foreach (var tile in m_Map.Tiles.GetStaticTiles(vx, vy)) + if (y == 1679 && x is >= 1392 and <= 1393) + { + return null; + } + + if (x == 1320 && y is >= 1618 and <= 1640) + { + return null; + } + + if (x == 1383 && y is >= 1642 and <= 1643) + { + return null; + } + + // Ilshenar ruins + if (m_Map == Map.Ilshenar && x is >= 644 and <= 670 && y is >= 925 and <= 941 || x == 985 && y == 994) + { + return null; + } + + if (z != newZ) + { + logger.Warning($"Door at {x}, {y}, {z} ({m_Map}) has mismatched Z levels: {z} != {newZ}"); + } + + BaseDoor door = new DarkWoodDoor(facing); + door.MoveToWorld(new Point3D(x, y, minZ), m_Map); + + ++m_Count; + + return door; + } + + public static void Generate(Rectangle2D region) + { + for (var rx = 0; rx < region.Width; ++rx) + { + for (var ry = 0; ry < region.Height; ++ry) + { + var vx = rx + region.X; + var vy = ry + region.Y; + + foreach (var tile in m_Map.Tiles.GetStaticTiles(vx, vy)) + { + var id = tile.ID; + var z = tile.Z; + int newZ; + + if (IsWestFrame(id)) { - var id = tile.ID; - var z = tile.Z; - - if (IsWestFrame(id)) + if (IsEastFrame(vx + 2, vy, z, out newZ)) { - if (IsEastFrame(vx + 2, vy, z)) + AddDoor(vx + 1, vy, z, newZ, DoorFacing.WestCW); + } + else if (IsEastFrame(vx + 3, vy, z, out newZ)) + { + var first = AddDoor(vx + 1, vy, z, newZ, DoorFacing.WestCW); + var second = AddDoor(vx + 2, vy, z, newZ, DoorFacing.EastCCW); + + if (first != null && second != null) { - AddDoor(vx + 1, vy, z, DoorFacing.WestCW); + first.Link = second; + second.Link = first; } - else if (IsEastFrame(vx + 3, vy, z)) + else { - var first = AddDoor(vx + 1, vy, z, DoorFacing.WestCW); - var second = AddDoor(vx + 2, vy, z, DoorFacing.EastCCW); - - if (first != null && second != null) - { - first.Link = second; - second.Link = first; - } - else - { - first?.Delete(); - - second?.Delete(); - } + first?.Delete(); + second?.Delete(); } } - else if (IsNorthFrame(id)) + } + else if (IsNorthFrame(id)) + { + if (IsSouthFrame(vx, vy + 2, z, out newZ)) { - if (IsSouthFrame(vx, vy + 2, z)) + AddDoor(vx, vy + 1, z, newZ, DoorFacing.SouthCW); + } + else if (IsSouthFrame(vx, vy + 3, z, out newZ)) + { + var first = AddDoor(vx, vy + 1, z, newZ, DoorFacing.NorthCCW); + var second = AddDoor(vx, vy + 2, z, newZ, DoorFacing.SouthCW); + + if (first != null && second != null) { - AddDoor(vx, vy + 1, z, DoorFacing.SouthCW); + first.Link = second; + second.Link = first; } - else if (IsSouthFrame(vx, vy + 3, z)) + else { - var first = AddDoor(vx, vy + 1, z, DoorFacing.NorthCCW); - var second = AddDoor(vx, vy + 2, z, DoorFacing.SouthCW); - - if (first != null && second != null) - { - first.Link = second; - second.Link = first; - } - else - { - first?.Delete(); - - second?.Delete(); - } + first?.Delete(); + second?.Delete(); } } } From 059f008b487dde55320d886b8ffe9c79ed836471 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Wed, 18 Dec 2024 08:41:52 -0800 Subject: [PATCH 7/7] fix: Fixes blood oath duration (#2027) --- .../Spells/Necromancy/BloodOathSpell.cs | 47 +++++++++---------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs b/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs index 5ccf49ea4..bc3903dd3 100644 --- a/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs +++ b/Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs @@ -80,7 +80,7 @@ public class BloodOathSpell : NecromancerSpell, ITargetingSpell m.FixedParticles(0x375A, 1, 17, 9919, 33, 7, EffectLayer.Waist); m.FixedParticles(0x3728, 1, 13, 9502, 33, 7, (EffectLayer)255); - var duration = TimeSpan.FromSeconds((GetDamageSkill(Caster) - GetResistSkill(m)) / 8 + 8); + var duration = TimeSpan.FromSeconds((GetDamageSkill(Caster) - GetResistSkill(m)) / 80 + 8); m.CheckSkill(SkillName.MagicResist, 0.0, 120.0); // Skill check for gain var timer = new ExpireTimer(Caster, m, duration); @@ -101,28 +101,28 @@ public class BloodOathSpell : NecromancerSpell, ITargetingSpell public static bool RemoveCurse(Mobile target) { - if (_table.Remove(target, out var timer)) + if (!_table.Remove(target, out var timer)) { - var caster = timer.Caster; - if (_oathTable.Remove(caster)) - { - caster.SendLocalizedMessage(1061620); // Your Blood Oath has been broken. - } - - if (_oathTable.Remove(target)) - { - target.SendLocalizedMessage(1061620); // Your Blood Oath has been broken. - } - - timer.Stop(); - - BuffInfo.RemoveBuff(caster, BuffIcon.BloodOathCaster); - BuffInfo.RemoveBuff(target, BuffIcon.BloodOathCurse); - - return true; + return false; } - return false; + var caster = timer.Caster; + if (_oathTable.Remove(caster)) + { + caster.SendLocalizedMessage(1061620); // Your Blood Oath has been broken. + } + + if (_oathTable.Remove(target)) + { + target.SendLocalizedMessage(1061620); // Your Blood Oath has been broken. + } + + timer.Stop(); + + BuffInfo.RemoveBuff(caster, BuffIcon.BloodOathCaster); + BuffInfo.RemoveBuff(target, BuffIcon.BloodOathCurse); + + return true; } public static Mobile GetBloodOath(Mobile m) => @@ -130,8 +130,8 @@ public class BloodOathSpell : NecromancerSpell, ITargetingSpell private class ExpireTimer : Timer { - private Mobile _target; - private DateTime _end; + private readonly Mobile _target; + private readonly DateTime _end; public Mobile Caster { get; } @@ -147,8 +147,7 @@ public class BloodOathSpell : NecromancerSpell, ITargetingSpell protected override void OnTick() { - if (Caster.Deleted || _target.Deleted || !Caster.Alive || !_target.Alive || - Core.Now >= _end) + if (Caster.Deleted || _target.Deleted || !Caster.Alive || !_target.Alive || Core.Now >= _end) { RemoveCurse(_target); }