From 79c6f0375c8a02fcda8695510817e9b85971496f Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 18 Apr 2023 19:28:54 -0700 Subject: [PATCH] fix: Fixes doors as decorations & optimizes them (#1392) --- .../Data/Decoration/Britannia/jhelom.cfg | 2 +- Projects/Server/Utilities/Utility.cs | 4 + .../Commands/Object Creation/Decorate.cs | 55 +- .../Commands/Object Creation/DecorateMag.cs | 54 +- .../UOContent/Engines/Doom/GauntletSpawner.cs | 2 +- .../UOContent/Engines/Doom/GenGauntlet.cs | 2 +- .../Items/Construction/Doors/BaseDoor.cs | 1033 ++++++++--------- .../Items/Construction/Doors/Doors.cs | 644 ++++------ .../Items/Construction/Doors/HouseDoors.cs | 382 +++--- .../Items/Construction/Doors/Portcullis.cs | 71 +- .../Items/Construction/Doors/SecretDoors.cs | 279 ++--- .../Server.Items.BarredMetalDoor.v0.json | 4 + .../Server.Items.BarredMetalDoor2.v0.json | 4 + .../Migrations/Server.Items.BaseDoor.v0.json | 75 ++ .../Server.Items.BaseHouseDoor.v2.json | 16 + .../Server.Items.DarkWoodDoor.v0.json | 4 + .../Server.Items.DarkWoodGate.v0.json | 4 + .../Server.Items.DarkWoodHouseDoor.v0.json | 4 + .../Server.Items.GenericHouseDoor.v0.json | 4 + .../Migrations/Server.Items.IronGate.v0.json | 4 + .../Server.Items.IronGateShort.v0.json | 4 + .../Server.Items.LightWoodDoor.v0.json | 4 + .../Server.Items.LightWoodGate.v0.json | 4 + .../Server.Items.MediumWoodDoor.v0.json | 4 + .../Migrations/Server.Items.MetalDoor.v0.json | 4 + .../Server.Items.MetalDoor2.v0.json | 4 + .../Server.Items.MetalHouseDoor.v0.json | 4 + .../Server.Items.PortcullisEW.v0.json | 4 + .../Server.Items.PortcullisNS.v0.json | 4 + .../Server.Items.RattanDoor.v0.json | 4 + .../Server.Items.SecretDungeonDoor.v0.json | 4 + .../Server.Items.SecretLightWoodDoor.v0.json | 4 + .../Server.Items.SecretStoneDoor1.v0.json | 4 + .../Server.Items.SecretStoneDoor2.v0.json | 4 + .../Server.Items.SecretStoneDoor3.v0.json | 4 + .../Server.Items.SecretWoodenDoor.v0.json | 4 + .../Server.Items.StrongWoodDoor.v0.json | 4 + .../Multis/Houses/HouseFoundation.cs | 232 ++-- 38 files changed, 1369 insertions(+), 1578 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.BarredMetalDoor.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BarredMetalDoor2.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseDoor.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseHouseDoor.v2.json create mode 100644 Projects/UOContent/Migrations/Server.Items.DarkWoodDoor.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.DarkWoodGate.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.DarkWoodHouseDoor.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.GenericHouseDoor.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.IronGate.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.IronGateShort.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.LightWoodDoor.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.LightWoodGate.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.MediumWoodDoor.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.MetalDoor.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.MetalDoor2.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.MetalHouseDoor.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PortcullisEW.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.PortcullisNS.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.RattanDoor.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SecretDungeonDoor.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SecretLightWoodDoor.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SecretStoneDoor1.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SecretStoneDoor2.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SecretStoneDoor3.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.SecretWoodenDoor.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.StrongWoodDoor.v0.json diff --git a/Distribution/Data/Decoration/Britannia/jhelom.cfg b/Distribution/Data/Decoration/Britannia/jhelom.cfg index 4e68ca897..b5aea3dc2 100644 --- a/Distribution/Data/Decoration/Britannia/jhelom.cfg +++ b/Distribution/Data/Decoration/Britannia/jhelom.cfg @@ -2766,4 +2766,4 @@ Static 0x1BD7 # bulletin board BulletinBoard 0x1E5E -1452 3768 0 \ No newline at end of file +1452 3768 0 diff --git a/Projects/Server/Utilities/Utility.cs b/Projects/Server/Utilities/Utility.cs index 525e9422e..c1e5151f3 100644 --- a/Projects/Server/Utilities/Utility.cs +++ b/Projects/Server/Utilities/Utility.cs @@ -1736,4 +1736,8 @@ public static class Utility TypeCode.UInt64 => 64, _ => 64 }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNullOrWhiteSpace(this ReadOnlySpan span) => + span == default || span.IsEmpty || span.IsWhiteSpace(); } diff --git a/Projects/UOContent/Commands/Object Creation/Decorate.cs b/Projects/UOContent/Commands/Object Creation/Decorate.cs index 1bc5607db..07c87fe7d 100644 --- a/Projects/UOContent/Commands/Object Creation/Decorate.cs +++ b/Projects/UOContent/Commands/Object Creation/Decorate.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using Microsoft.Toolkit.HighPerformance; using Server.Engines.Quests.Haven; using Server.Engines.Quests.Necro; using Server.Engines.Spawners; @@ -414,7 +415,7 @@ namespace Server.Commands item = m_Type.CreateInstance(); } } - else if (m_Type.IsSubclassOf(typeofBaseDoor)) + else if (m_Type.IsSubclassOf(typeofBaseDoor) && m_Params.Length > 0) { var facing = DoorFacing.WestCW; @@ -1059,7 +1060,7 @@ namespace Server.Commands if (bd.Open) { p = new Point3D(bd.X - bd.Offset.X, bd.Y - bd.Offset.Y, bd.Z - bd.Offset.Z); - bdItemID = bd.ClosedID; + bdItemID = bd.ClosedId; } else { @@ -1272,51 +1273,59 @@ namespace Server.Commands var indexOf = line.IndexOfOrdinal(' '); - list.m_Type = AssemblyHandler.FindTypeByName(line[..indexOf++]); + list.m_Type = AssemblyHandler.FindTypeByName(indexOf > -1 ? line[..indexOf] : line); + indexOf++; if (list.m_Type == null) { throw new ArgumentException($"Type not found for header: '{line}'"); } - line = line[indexOf..]; - indexOf = line.IndexOfOrdinal('('); - if (indexOf >= 0) + var span = line.AsSpan(indexOf, line.Length - indexOf); + + var argsStart = span.IndexOfOrdinal('('); + + if (argsStart > -1) { - list.m_ItemID = Utility.ToInt32(line.AsSpan()[..(indexOf - 1)]); - - var parms = line[++indexOf..^(line.EndsWithOrdinal(")") ? 1 : 0)]; - - list.m_Params = parms.Split(';'); - - for (var i = 0; i < list.m_Params.Length; ++i) + var parms = span[(argsStart + 1)..^(line.EndsWithOrdinal(")") ? 1 : 0)]; + if (parms.Length == 0) { - list.m_Params[i] = list.m_Params[i].Trim(); + list.m_Params = Array.Empty(); + } + else + { + list.m_Params = new string[parms.Count(';') + 1]; + + indexOf = 0; + foreach (var part in parms.Tokenize(';')) + { + list.m_Params[indexOf++] = part.Trim().ToString(); + } } } else { - list.m_ItemID = Utility.ToInt32(line); list.m_Params = m_EmptyParams; } + list.m_ItemID = Utility.ToInt32(argsStart > -1 ? span[..argsStart] : span); list.m_Entries = new List(); while ((line = ip.ReadLine()) != null) { - line = line.Trim(); + span = line.AsSpan().Trim(); - if (line.Length == 0) + if (span.Length == 0) { break; } - if (line.StartsWithOrdinal("#")) + if (span.StartsWithOrdinal("#")) { continue; } - list.m_Entries.Add(new DecorationEntry(line)); + list.m_Entries.Add(new DecorationEntry(span)); } return list; @@ -1325,21 +1334,21 @@ namespace Server.Commands public class DecorationEntry { - public DecorationEntry(string line) + public DecorationEntry(ReadOnlySpan line) { Pop(out var x, ref line); Pop(out var y, ref line); Pop(out var z, ref line); Location = new Point3D(Utility.ToInt32(x), Utility.ToInt32(y), Utility.ToInt32(z)); - Extra = line; + Extra = line.ToString(); } public Point3D Location { get; } public string Extra { get; } - public static void Pop(out string v, ref string line) + public static void Pop(out ReadOnlySpan v, ref ReadOnlySpan line) { var space = line.IndexOfOrdinal(' '); @@ -1351,7 +1360,7 @@ namespace Server.Commands else { v = line; - line = ""; + line = default; } } } diff --git a/Projects/UOContent/Commands/Object Creation/DecorateMag.cs b/Projects/UOContent/Commands/Object Creation/DecorateMag.cs index 75fdb61e4..2e73c02ed 100644 --- a/Projects/UOContent/Commands/Object Creation/DecorateMag.cs +++ b/Projects/UOContent/Commands/Object Creation/DecorateMag.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using Microsoft.Toolkit.HighPerformance; using Server.Engines.Quests.Haven; using Server.Engines.Quests.Necro; using Server.Engines.Spawners; @@ -410,7 +411,7 @@ namespace Server.Commands item = m_Type.CreateInstance(); } } - else if (m_Type.IsSubclassOf(typeofBaseDoor)) + else if (m_Type.IsSubclassOf(typeofBaseDoor) && m_Params.Length > 0) { var facing = DoorFacing.WestCW; @@ -1055,7 +1056,7 @@ namespace Server.Commands if (bd.Open) { p = new Point3D(bd.X - bd.Offset.X, bd.Y - bd.Offset.Y, bd.Z - bd.Offset.Z); - bdItemID = bd.ClosedID; + bdItemID = bd.ClosedId; } else { @@ -1258,51 +1259,60 @@ namespace Server.Commands var indexOf = line.IndexOfOrdinal(' '); - list.m_Type = AssemblyHandler.FindTypeByName(line[..indexOf++]); + list.m_Type = AssemblyHandler.FindTypeByName(indexOf > -1 ? line[..indexOf] : line); + indexOf++; if (list.m_Type == null) { throw new ArgumentException($"Type not found for header: '{line}'"); } - line = line[indexOf..]; - indexOf = line.IndexOfOrdinal('('); - if (indexOf >= 0) + var span = line.AsSpan(indexOf, line.Length - indexOf); + + var argsStart = span.IndexOfOrdinal('('); + + if (argsStart > -1) { - list.m_ItemID = Utility.ToInt32(line.AsSpan()[..(indexOf - 1)]); - - var parms = line[++indexOf..^(line.EndsWithOrdinal(")") ? 1 : 0)]; - - list.m_Params = parms.Split(';'); - - for (var i = 0; i < list.m_Params.Length; ++i) + var parms = span[(argsStart + 1)..^(line.EndsWithOrdinal(")") ? 1 : 0)]; + if (parms.Length == 0) { - list.m_Params[i] = list.m_Params[i].Trim(); + list.m_Params = Array.Empty(); + } + else + { + list.m_Params = new string[parms.Count(';') + 1]; + + indexOf = 0; + foreach (var part in parms.Tokenize(';')) + { + list.m_Params[indexOf++] = part.Trim().ToString(); + } } } else { - list.m_ItemID = Utility.ToInt32(line); list.m_Params = m_EmptyParams; } + list.m_ItemID = Utility.ToInt32(argsStart > -1 ? span[..argsStart] : span); + list.m_Entries = new List(); while ((line = ip.ReadLine()) != null) { - line = line.Trim(); + span = line.AsSpan().Trim(); - if (line.Length == 0) + if (span.Length == 0) { break; } - if (line.StartsWithOrdinal("#")) + if (span.StartsWithOrdinal("#")) { continue; } - list.m_Entries.Add(new DecorationEntryMag(line)); + list.m_Entries.Add(new DecorationEntryMag(span)); } return list; @@ -1311,21 +1321,21 @@ namespace Server.Commands public class DecorationEntryMag { - public DecorationEntryMag(string line) + public DecorationEntryMag(ReadOnlySpan line) { Pop(out var x, ref line); Pop(out var y, ref line); Pop(out var z, ref line); Location = new Point3D(Utility.ToInt32(x), Utility.ToInt32(y), Utility.ToInt32(z)); - Extra = line; + Extra = line.ToString(); } public Point3D Location { get; } public string Extra { get; } - public void Pop(out string v, ref string line) + public void Pop(out ReadOnlySpan v, ref ReadOnlySpan line) { var space = line.IndexOfOrdinal(' '); diff --git a/Projects/UOContent/Engines/Doom/GauntletSpawner.cs b/Projects/UOContent/Engines/Doom/GauntletSpawner.cs index 2d99f424d..51abc207c 100644 --- a/Projects/UOContent/Engines/Doom/GauntletSpawner.cs +++ b/Projects/UOContent/Engines/Doom/GauntletSpawner.cs @@ -121,7 +121,7 @@ namespace Server.Engines.Doom Door.Open = false; } - if (Door.Link != null) + if (Door.Link?.Deleted == false) { Door.Link.Hue = hue; Door.Link.Locked = lockDoors; diff --git a/Projects/UOContent/Engines/Doom/GenGauntlet.cs b/Projects/UOContent/Engines/Doom/GenGauntlet.cs index 881546cb6..04f0baebd 100644 --- a/Projects/UOContent/Engines/Doom/GenGauntlet.cs +++ b/Projects/UOContent/Engines/Doom/GenGauntlet.cs @@ -58,7 +58,7 @@ namespace Server.Engines.Doom healerDoor.Locked = true; healerDoor.KeyValue = Key.RandomValue(); - if (healerDoor.Link != null) + if (healerDoor.Link?.Deleted == false) { healerDoor.Link.Locked = true; healerDoor.Link.KeyValue = Key.RandomValue(); diff --git a/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs b/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs index d00574aa6..c444838fe 100644 --- a/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs +++ b/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs @@ -1,577 +1,546 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Targeting; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public abstract partial class BaseDoor : Item, ILockable, ITelekinesisable { - public abstract class BaseDoor : Item, ILockable, ITelekinesisable + private static readonly Point3D[] m_Offsets = { - private static readonly Point3D[] m_Offsets = + new(-1, 1, 0), + new(1, 1, 0), + new(-1, 0, 0), + new(1, -1, 0), + new(1, 1, 0), + new(1, -1, 0), + new(0, 0, 0), + new(0, -1, 0), + + new(0, 0, 0), + new(0, 0, 0), + new(0, 0, 0), + new(0, 0, 0) + }; + + private Timer _timer; + + [SerializableField(0)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private uint _keyValue; + + [SerializableField(2)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private bool _locked; + + [SerializableField(3)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private int _openedId; + + [SerializableField(4)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private int _closedId; + + [SerializableField(5)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private int _openedSound; + + [SerializableField(6)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private int _closedSound; + + [SerializableField(7)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private Point3D _offset; + + [SerializableField(8)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private BaseDoor _link; + + public BaseDoor(int closedID, int openedID, int openedSound, int closedSound, Point3D offset) : base(closedID) + { + _openedId = openedID; + _closedId = closedID; + _openedSound = openedSound; + _closedSound = closedSound; + _offset = offset; + + _timer = new InternalTimer(this); + + Movable = false; + } + + [SerializableProperty(1)] + [CommandProperty(AccessLevel.GameMaster)] + public bool Open + { + get => _open; + set { - new(-1, 1, 0), - new(1, 1, 0), - new(-1, 0, 0), - new(1, -1, 0), - new(1, 1, 0), - new(1, -1, 0), - new(0, 0, 0), - new(0, -1, 0), - - new(0, 0, 0), - new(0, 0, 0), - new(0, 0, 0), - new(0, 0, 0) - }; - - private BaseDoor m_Link; - private bool m_Open; - - private Timer m_Timer; - - public BaseDoor(int closedID, int openedID, int openedSound, int closedSound, Point3D offset) : base(closedID) - { - OpenedID = openedID; - ClosedID = closedID; - OpenedSound = openedSound; - ClosedSound = closedSound; - Offset = offset; - - m_Timer = new InternalTimer(this); - - Movable = false; - } - - public BaseDoor(Serial serial) : base(serial) - { - } - - [CommandProperty(AccessLevel.GameMaster)] - public bool Open - { - get => m_Open; - set + if (_open != value) { - if (m_Open != value) + _open = value; + + ItemID = _open ? _openedId : _closedId; + + if (_open) { - m_Open = value; - - ItemID = m_Open ? OpenedID : ClosedID; - - if (m_Open) - { - Location = new Point3D(X + Offset.X, Y + Offset.Y, Z + Offset.Z); - } - else - { - Location = new Point3D(X - Offset.X, Y - Offset.Y, Z - Offset.Z); - } - - Effects.PlaySound(this, m_Open ? OpenedSound : ClosedSound); - - if (m_Open) - { - m_Timer.Start(); - } - else - { - m_Timer.Stop(); - } + Location = new Point3D(X + _offset.X, Y + _offset.Y, Z + _offset.Z); } - } - } - - [CommandProperty(AccessLevel.GameMaster)] - public int OpenedID { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public int ClosedID { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public int OpenedSound { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public int ClosedSound { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public Point3D Offset { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public BaseDoor Link - { - get - { - if (m_Link?.Deleted == true) + else { - m_Link = null; + Location = new Point3D(X - _offset.X, Y - _offset.Y, Z - _offset.Z); } - return m_Link; + Effects.PlaySound(this, _open ? OpenedSound : ClosedSound); + + if (_open) + { + _timer ??= new InternalTimer(this); + _timer.Start(); + } + else + { + _timer.Stop(); + _timer = null; + } + + this.MarkDirty(); } - set => m_Link = value; } + } - public virtual bool UseChainedFunctionality => false; + public virtual bool UseChainedFunctionality => false; - [CommandProperty(AccessLevel.GameMaster)] - public bool Locked { get; set; } + public void OnTelekinesis(Mobile from) + { + Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x376A, 9, 32, 5022); + Effects.PlaySound(Location, Map, 0x1F5); - [CommandProperty(AccessLevel.GameMaster)] - public uint KeyValue { get; set; } + Use(from); + } - public void OnTelekinesis(Mobile from) + public static void Initialize() + { + EventSink.OpenDoorMacroUsed += EventSink_OpenDoorMacroUsed; + + CommandSystem.Register("Link", AccessLevel.GameMaster, Link_OnCommand); + CommandSystem.Register("ChainLink", AccessLevel.GameMaster, ChainLink_OnCommand); + } + + [Usage("Link"), Description("Links two targeted doors together.")] + private static void Link_OnCommand(CommandEventArgs e) + { + e.Mobile.BeginTarget(-1, false, TargetFlags.None, Link_OnFirstTarget); + e.Mobile.SendMessage("Target the first door to link."); + } + + private static void Link_OnFirstTarget(Mobile from, object targeted) + { + if (targeted is not BaseDoor door) { - Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x376A, 9, 32, 5022); - Effects.PlaySound(Location, Map, 0x1F5); - - Use(from); + from.BeginTarget(-1, false, TargetFlags.None, Link_OnFirstTarget); + from.SendMessage("That is not a door. Try again."); } - - public static void Initialize() + else { - EventSink.OpenDoorMacroUsed += EventSink_OpenDoorMacroUsed; - - CommandSystem.Register("Link", AccessLevel.GameMaster, Link_OnCommand); - CommandSystem.Register("ChainLink", AccessLevel.GameMaster, ChainLink_OnCommand); + from.BeginTarget(-1, false, TargetFlags.None, Link_OnSecondTarget, door); + from.SendMessage("Target the second door to link."); } + } - [Usage("Link"), Description("Links two targeted doors together.")] - private static void Link_OnCommand(CommandEventArgs e) + private static void Link_OnSecondTarget(Mobile from, object targeted, BaseDoor first) + { + if (targeted is not BaseDoor second) { - e.Mobile.BeginTarget(-1, false, TargetFlags.None, Link_OnFirstTarget); - e.Mobile.SendMessage("Target the first door to link."); + from.BeginTarget(-1, false, TargetFlags.None, Link_OnSecondTarget, first); + from.SendMessage("That is not a door. Try again."); } - - private static void Link_OnFirstTarget(Mobile from, object targeted) + else { - if (targeted is not BaseDoor door) + first.Link = second; + second.Link = first; + from.SendMessage("The doors have been linked."); + } + } + + [Usage("ChainLink"), Description("Chain-links two or more targeted doors together.")] + private static void ChainLink_OnCommand(CommandEventArgs e) + { + e.Mobile.BeginTarget(-1, false, TargetFlags.None, ChainLink_OnTarget, new List()); + e.Mobile.SendMessage("Target the first of a sequence of doors to link."); + } + + private static void ChainLink_OnTarget(Mobile from, object targeted, List list) + { + if (targeted is not BaseDoor door) + { + from.BeginTarget(-1, false, TargetFlags.None, ChainLink_OnTarget, list); + from.SendMessage("That is not a door. Try again."); + } + else + { + if (list.Count > 0 && list[0] == door) { - from.BeginTarget(-1, false, TargetFlags.None, Link_OnFirstTarget); - from.SendMessage("That is not a door. Try again."); - } - else - { - from.BeginTarget(-1, false, TargetFlags.None, Link_OnSecondTarget, door); - from.SendMessage("Target the second door to link."); - } - } + if (list.Count >= 2) + { + for (var i = 0; i < list.Count; ++i) + { + list[i].Link = list[(i + 1) % list.Count]; + } - private static void Link_OnSecondTarget(Mobile from, object targeted, BaseDoor first) - { - if (targeted is not BaseDoor second) - { - from.BeginTarget(-1, false, TargetFlags.None, Link_OnSecondTarget, first); - from.SendMessage("That is not a door. Try again."); + from.SendMessage("The chain of doors have been linked."); + } + else + { + from.BeginTarget(-1, false, TargetFlags.None, ChainLink_OnTarget, list); + from.SendMessage("You have not yet targeted two unique doors. Target the second door to link."); + } } - else - { - first.Link = second; - second.Link = first; - from.SendMessage("The doors have been linked."); - } - } - - [Usage("ChainLink"), Description("Chain-links two or more targeted doors together.")] - private static void ChainLink_OnCommand(CommandEventArgs e) - { - e.Mobile.BeginTarget(-1, false, TargetFlags.None, ChainLink_OnTarget, new List()); - e.Mobile.SendMessage("Target the first of a sequence of doors to link."); - } - - private static void ChainLink_OnTarget(Mobile from, object targeted, List list) - { - if (targeted is not BaseDoor door) + else if (list.Contains(door)) { from.BeginTarget(-1, false, TargetFlags.None, ChainLink_OnTarget, list); - from.SendMessage("That is not a door. Try again."); + from.SendMessage( + "You have already targeted that door. Target another door, or retarget the first door to complete the chain." + ); } else { - if (list.Count > 0 && list[0] == door) - { - if (list.Count >= 2) - { - for (var i = 0; i < list.Count; ++i) - { - list[i].Link = list[(i + 1) % list.Count]; - } + list.Add(door); - from.SendMessage("The chain of doors have been linked."); - } - else - { - from.BeginTarget(-1, false, TargetFlags.None, ChainLink_OnTarget, list); - from.SendMessage("You have not yet targeted two unique doors. Target the second door to link."); - } - } - else if (list.Contains(door)) + from.BeginTarget(-1, false, TargetFlags.None, ChainLink_OnTarget, list); + + if (list.Count == 1) { - from.BeginTarget(-1, false, TargetFlags.None, ChainLink_OnTarget, list); - from.SendMessage( - "You have already targeted that door. Target another door, or retarget the first door to complete the chain." - ); + from.SendMessage("Target the second door to link."); } else { - list.Add(door); - - from.BeginTarget(-1, false, TargetFlags.None, ChainLink_OnTarget, list); - - if (list.Count == 1) - { - from.SendMessage("Target the second door to link."); - } - else - { - from.SendMessage("Target another door to link. To complete the chain, retarget the first door."); - } - } - } - } - - private static void EventSink_OpenDoorMacroUsed(Mobile m) - { - if (m.Map == null) - { - return; - } - - int x = m.X, y = m.Y; - - switch (m.Direction & Direction.Mask) - { - case Direction.North: - --y; - break; - case Direction.Right: - ++x; - --y; - break; - case Direction.East: - ++x; - break; - case Direction.Down: - ++x; - ++y; - break; - case Direction.South: - ++y; - break; - case Direction.Left: - --x; - ++y; - break; - case Direction.West: - --x; - break; - case Direction.Up: - --x; - --y; - break; - } - - var sector = m.Map.GetSector(x, y); - - foreach (var item in sector.Items) - { - if (item.Location.X == x && item.Location.Y == y && item.Z + item.ItemData.Height > m.Z && - m.Z + 16 > item.Z && item is BaseDoor && m.CanSee(item) && m.InLOS(item)) - { - if (m.CheckAlive()) - { - m.SendLocalizedMessage(500024); // Opening door... - item.OnDoubleClick(m); - } - - break; - } - } - } - - public static Point3D GetOffset(DoorFacing facing) => m_Offsets[(int)facing]; - - public bool CanClose() - { - if (!m_Open) - { - return true; - } - - var map = Map; - - if (map == null) - { - return false; - } - - var p = new Point3D(X - Offset.X, Y - Offset.Y, Z - Offset.Z); - - return CheckFit(map, p, 16); - } - - private bool CheckFit(Map map, Point3D p, int height) - { - if (map == Map.Internal) - { - return false; - } - - var x = p.X; - var y = p.Y; - var z = p.Z; - - var sector = map.GetSector(x, y); - var items = sector.Items; - var mobs = sector.Mobiles; - - for (var i = 0; i < items.Count; ++i) - { - var item = items[i]; - - if (item is not BaseMulti && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint(x, y) && - item is not BaseDoor) - { - var id = item.ItemData; - var surface = id.Surface; - var impassable = id.Impassable; - - if ((surface || impassable) && item.Z + id.CalcHeight > z && z + height > item.Z) - { - return false; - } - } - } - - for (var i = 0; i < mobs.Count; ++i) - { - var m = mobs[i]; - - if (m.Location.X == x && m.Location.Y == y) - { - if (m.Hidden && m.AccessLevel > AccessLevel.Player) - { - continue; - } - - if (!m.Alive) - { - continue; - } - - if (m.Z + 16 > z && z + height > m.Z) - { - return false; - } - } - } - - return true; - } - - public List GetChain() - { - var list = new List(); - var c = this; - - do - { - list.Add(c); - c = c.Link; - } while (c != null && !list.Contains(c)); - - return list; - } - - public bool IsFreeToClose() - { - if (!UseChainedFunctionality) - { - return CanClose(); - } - - var list = GetChain(); - - var freeToClose = true; - - for (var i = 0; freeToClose && i < list.Count; ++i) - { - freeToClose = list[i].CanClose(); - } - - return freeToClose; - } - - public virtual bool IsInside(Mobile from) => false; - - public virtual bool UseLocks() => true; - - public virtual void Use(Mobile from) - { - if (Locked && !m_Open && UseLocks()) - { - if (from.AccessLevel >= AccessLevel.GameMaster) - { - from.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - 502502 - ); // That is locked, but you open it with your godly powers. - // from.Send( new MessageLocalized( Serial, ItemID, MessageType.Regular, 0x3B2, 3, 502502, "", "" ) ); // That is locked, but you open it with your godly powers. - } - else if (Key.ContainsKey(from.Backpack, KeyValue)) - { - from.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - 501282 - ); // You quickly unlock, open, and relock the door - } - else if (IsInside(from)) - { - from.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - 501280 - ); // That is locked, but is usable from the inside. - } - else - { - if (Hue == 0x44E && Map == Map.Malas) // doom door into healer room in doom - { - SendLocalizedMessageTo(from, 1060014); // Only the dead may pass. - } - else - { - from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 502503); // That is locked. - } - - return; - } - } - - if (m_Open && !IsFreeToClose()) - { - return; - } - - if (m_Open) - { - OnClosed(from); - } - else - { - OnOpened(from); - } - - if (UseChainedFunctionality) - { - var open = !m_Open; - - var list = GetChain(); - - for (var i = 0; i < list.Count; ++i) - { - list[i].Open = open; - } - } - else - { - Open = !m_Open; - - var link = Link; - - if (m_Open && link?.Open == false) - { - link.Open = true; - } - } - } - - public virtual void OnOpened(Mobile from) - { - } - - public virtual void OnClosed(Mobile from) - { - } - - public override void OnDoubleClick(Mobile from) - { - if (from.AccessLevel == AccessLevel.Player && !from.InRange(GetWorldLocation(), 2)) - { - from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. - } - else - { - Use(from); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - - writer.Write(KeyValue); - - writer.Write(m_Open); - writer.Write(Locked); - writer.Write(OpenedID); - writer.Write(ClosedID); - writer.Write(OpenedSound); - writer.Write(ClosedSound); - writer.Write(Offset); - writer.Write(m_Link); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 0: - { - KeyValue = reader.ReadUInt(); - m_Open = reader.ReadBool(); - Locked = reader.ReadBool(); - OpenedID = reader.ReadInt(); - ClosedID = reader.ReadInt(); - OpenedSound = reader.ReadInt(); - ClosedSound = reader.ReadInt(); - Offset = reader.ReadPoint3D(); - m_Link = reader.ReadEntity(); - - m_Timer = new InternalTimer(this); - - if (m_Open) - { - m_Timer.Start(); - } - - break; - } - } - } - - private class InternalTimer : Timer - { - private readonly BaseDoor m_Door; - - public InternalTimer(BaseDoor door) : base(TimeSpan.FromSeconds(20.0), TimeSpan.FromSeconds(10.0)) - { - m_Door = door; - } - - protected override void OnTick() - { - if (m_Door.Open && m_Door.IsFreeToClose()) - { - m_Door.Open = false; + from.SendMessage("Target another door to link. To complete the chain, retarget the first door."); } } } } + + private static void EventSink_OpenDoorMacroUsed(Mobile m) + { + if (m.Map == null) + { + return; + } + + int x = m.X, y = m.Y; + + switch (m.Direction & Direction.Mask) + { + case Direction.North: + { + --y; + break; + } + case Direction.Right: + { + ++x; + --y; + break; + } + case Direction.East: + { + ++x; + break; + } + case Direction.Down: + { + ++x; + ++y; + break; + } + case Direction.South: + { + ++y; + break; + } + case Direction.Left: + { + --x; + ++y; + break; + } + case Direction.West: + { + --x; + break; + } + case Direction.Up: + { + --x; + --y; + break; + } + } + + var sector = m.Map.GetSector(x, y); + + foreach (var item in sector.Items) + { + if (item.Location.X == x && item.Location.Y == y && item.Z + item.ItemData.Height > m.Z && + m.Z + 16 > item.Z && item is BaseDoor && m.CanSee(item) && m.InLOS(item)) + { + if (m.CheckAlive()) + { + m.SendLocalizedMessage(500024); // Opening door... + item.OnDoubleClick(m); + } + + break; + } + } + } + + public static Point3D GetOffset(DoorFacing facing) => m_Offsets[(int)facing]; + + public bool CanClose() + { + if (!_open) + { + return true; + } + + var map = Map; + + if (map == null) + { + return false; + } + + var p = new Point3D(X - Offset.X, Y - Offset.Y, Z - Offset.Z); + + return CheckFit(map, p, 16); + } + + private bool CheckFit(Map map, Point3D p, int height) + { + if (map == Map.Internal) + { + return false; + } + + var x = p.X; + var y = p.Y; + var z = p.Z; + + var sector = map.GetSector(x, y); + var items = sector.Items; + var mobs = sector.Mobiles; + + for (var i = 0; i < items.Count; ++i) + { + var item = items[i]; + + if (item is not BaseMulti && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint(x, y) && + item is not BaseDoor) + { + var id = item.ItemData; + var surface = id.Surface; + var impassable = id.Impassable; + + if ((surface || impassable) && item.Z + id.CalcHeight > z && z + height > item.Z) + { + return false; + } + } + } + + for (var i = 0; i < mobs.Count; ++i) + { + var m = mobs[i]; + + if (m.Location.X == x && m.Location.Y == y) + { + if (m.Hidden && m.AccessLevel > AccessLevel.Player) + { + continue; + } + + if (!m.Alive) + { + continue; + } + + if (m.Z + 16 > z && z + height > m.Z) + { + return false; + } + } + } + + return true; + } + + public List GetChain() + { + var list = new List(); + var c = this; + + do + { + list.Add(c); + c = c.Link; + } while (c?.Deleted == false && !list.Contains(c)); + + return list; + } + + public bool IsFreeToClose() + { + if (!UseChainedFunctionality) + { + return CanClose(); + } + + var list = GetChain(); + + var freeToClose = true; + + for (var i = 0; freeToClose && i < list.Count; ++i) + { + freeToClose = list[i].CanClose(); + } + + return freeToClose; + } + + public virtual bool IsInside(Mobile from) => false; + + public virtual bool UseLocks() => true; + + public virtual void Use(Mobile from) + { + if (Locked && !_open && UseLocks()) + { + if (from.AccessLevel >= AccessLevel.GameMaster) + { + from.LocalOverheadMessage( + MessageType.Regular, + 0x3B2, + 502502 + ); // That is locked, but you open it with your godly powers. + // from.Send( new MessageLocalized( Serial, ItemID, MessageType.Regular, 0x3B2, 3, 502502, "", "" ) ); // That is locked, but you open it with your godly powers. + } + else if (Key.ContainsKey(from.Backpack, KeyValue)) + { + from.LocalOverheadMessage( + MessageType.Regular, + 0x3B2, + 501282 + ); // You quickly unlock, open, and relock the door + } + else if (IsInside(from)) + { + from.LocalOverheadMessage( + MessageType.Regular, + 0x3B2, + 501280 + ); // That is locked, but is usable from the inside. + } + else + { + if (Hue == 0x44E && Map == Map.Malas) // doom door into healer room in doom + { + SendLocalizedMessageTo(from, 1060014); // Only the dead may pass. + } + else + { + from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 502503); // That is locked. + } + + return; + } + } + + if (_open && !IsFreeToClose()) + { + return; + } + + if (_open) + { + OnClosed(from); + } + else + { + OnOpened(from); + } + + if (UseChainedFunctionality) + { + var open = !_open; + + var list = GetChain(); + + for (var i = 0; i < list.Count; ++i) + { + list[i].Open = open; + } + } + else + { + Open = !_open; + + var link = Link; + + if (_open && link is { Deleted: false, Open: false }) + { + link.Open = true; + } + } + } + + public virtual void OnOpened(Mobile from) + { + } + + public virtual void OnClosed(Mobile from) + { + } + + public override void OnDoubleClick(Mobile from) + { + if (from.AccessLevel == AccessLevel.Player && !from.InRange(GetWorldLocation(), 2)) + { + from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. + } + else + { + Use(from); + } + } + + [AfterDeserialization] + private void AfterDeserialization() + { + if (_open) + { + _timer = new InternalTimer(this); + _timer.Start(); + } + } + + private class InternalTimer : Timer + { + private readonly BaseDoor _door; + + public InternalTimer(BaseDoor door) : base(TimeSpan.FromSeconds(20.0), TimeSpan.FromSeconds(10.0)) => + _door = door; + + protected override void OnTick() + { + if (_door.Open && _door.IsFreeToClose()) + { + _door.Open = false; + } + } + } } diff --git a/Projects/UOContent/Items/Construction/Doors/Doors.cs b/Projects/UOContent/Items/Construction/Doors/Doors.cs index 1990fbb83..1f6cded82 100644 --- a/Projects/UOContent/Items/Construction/Doors/Doors.cs +++ b/Projects/UOContent/Items/Construction/Doors/Doors.cs @@ -1,436 +1,216 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +public enum DoorFacing { - public enum DoorFacing + WestCW, + EastCCW, + WestCCW, + EastCW, + SouthCW, + NorthCCW, + SouthCCW, + NorthCW, + + // Sliding Doors + SouthSW, + SouthSE, + WestSS, + WestSN +} + +[SerializationGenerator(0, false)] +public partial class IronGateShort : BaseDoor +{ + [Constructible] + public IronGateShort(DoorFacing facing) : base( + 0x84c + 2 * (int)facing, + 0x84d + 2 * (int)facing, + 0xEC, + 0xF3, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class IronGate : BaseDoor +{ + [Constructible] + public IronGate(DoorFacing facing) : base( + 0x824 + 2 * (int)facing, + 0x825 + 2 * (int)facing, + 0xEC, + 0xF3, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class LightWoodGate : BaseDoor +{ + [Constructible] + public LightWoodGate(DoorFacing facing) : base( + 0x839 + 2 * (int)facing, + 0x83A + 2 * (int)facing, + 0xEB, + 0xF2, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class DarkWoodGate : BaseDoor +{ + [Constructible] + public DarkWoodGate(DoorFacing facing) : base( + 0x866 + 2 * (int)facing, + 0x867 + 2 * (int)facing, + 0xEB, + 0xF2, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class MetalDoor : BaseDoor +{ + [Constructible] + public MetalDoor(DoorFacing facing) : base( + 0x675 + 2 * (int)facing, + 0x676 + 2 * (int)facing, + 0xEC, + 0xF3, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class BarredMetalDoor : BaseDoor +{ + [Constructible] + public BarredMetalDoor(DoorFacing facing) : base( + 0x685 + 2 * (int)facing, + 0x686 + 2 * (int)facing, + 0xEC, + 0xF3, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class BarredMetalDoor2 : BaseDoor +{ + [Constructible] + public BarredMetalDoor2(DoorFacing facing) : base( + 0x1FED + 2 * (int)facing, + 0x1FEE + 2 * (int)facing, + 0xEC, + 0xF3, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class RattanDoor : BaseDoor +{ + [Constructible] + public RattanDoor(DoorFacing facing) : base( + 0x695 + 2 * (int)facing, + 0x696 + 2 * (int)facing, + 0xEB, + 0xF2, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class DarkWoodDoor : BaseDoor +{ + [Constructible] + public DarkWoodDoor(DoorFacing facing) : base( + 0x6A5 + 2 * (int)facing, + 0x6A6 + 2 * (int)facing, + 0xEA, + 0xF1, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class MediumWoodDoor : BaseDoor +{ + [Constructible] + public MediumWoodDoor(DoorFacing facing) : base( + 0x6B5 + 2 * (int)facing, + 0x6B6 + 2 * (int)facing, + 0xEA, + 0xF1, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class MetalDoor2 : BaseDoor +{ + [Constructible] + public MetalDoor2(DoorFacing facing) : base( + 0x6C5 + 2 * (int)facing, + 0x6C6 + 2 * (int)facing, + 0xEC, + 0xF3, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class LightWoodDoor : BaseDoor +{ + [Constructible] + public LightWoodDoor(DoorFacing facing) : base( + 0x6D5 + 2 * (int)facing, + 0x6D6 + 2 * (int)facing, + 0xEA, + 0xF1, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class StrongWoodDoor : BaseDoor +{ + [Constructible] + public StrongWoodDoor(DoorFacing facing) : base( + 0x6E5 + 2 * (int)facing, + 0x6E6 + 2 * (int)facing, + 0xEA, + 0xF1, + GetOffset(facing) + ) { - WestCW, - EastCCW, - WestCCW, - EastCW, - SouthCW, - NorthCCW, - SouthCCW, - NorthCW, - - // Sliding Doors - SouthSW, - SouthSE, - WestSS, - WestSN - } - - public class IronGateShort : BaseDoor - { - [Constructible] - public IronGateShort(DoorFacing facing) : base( - 0x84c + 2 * (int)facing, - 0x84d + 2 * (int)facing, - 0xEC, - 0xF3, - GetOffset(facing) - ) - { - } - - public IronGateShort(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class IronGate : BaseDoor - { - [Constructible] - public IronGate(DoorFacing facing) : base( - 0x824 + 2 * (int)facing, - 0x825 + 2 * (int)facing, - 0xEC, - 0xF3, - GetOffset(facing) - ) - { - } - - public IronGate(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class LightWoodGate : BaseDoor - { - [Constructible] - public LightWoodGate(DoorFacing facing) : base( - 0x839 + 2 * (int)facing, - 0x83A + 2 * (int)facing, - 0xEB, - 0xF2, - GetOffset(facing) - ) - { - } - - public LightWoodGate(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class DarkWoodGate : BaseDoor - { - [Constructible] - public DarkWoodGate(DoorFacing facing) : base( - 0x866 + 2 * (int)facing, - 0x867 + 2 * (int)facing, - 0xEB, - 0xF2, - GetOffset(facing) - ) - { - } - - public DarkWoodGate(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class MetalDoor : BaseDoor - { - [Constructible] - public MetalDoor(DoorFacing facing) : base( - 0x675 + 2 * (int)facing, - 0x676 + 2 * (int)facing, - 0xEC, - 0xF3, - GetOffset(facing) - ) - { - } - - public MetalDoor(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class BarredMetalDoor : BaseDoor - { - [Constructible] - public BarredMetalDoor(DoorFacing facing) : base( - 0x685 + 2 * (int)facing, - 0x686 + 2 * (int)facing, - 0xEC, - 0xF3, - GetOffset(facing) - ) - { - } - - public BarredMetalDoor(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class BarredMetalDoor2 : BaseDoor - { - [Constructible] - public BarredMetalDoor2(DoorFacing facing) : base( - 0x1FED + 2 * (int)facing, - 0x1FEE + 2 * (int)facing, - 0xEC, - 0xF3, - GetOffset(facing) - ) - { - } - - public BarredMetalDoor2(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class RattanDoor : BaseDoor - { - [Constructible] - public RattanDoor(DoorFacing facing) : base( - 0x695 + 2 * (int)facing, - 0x696 + 2 * (int)facing, - 0xEB, - 0xF2, - GetOffset(facing) - ) - { - } - - public RattanDoor(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class DarkWoodDoor : BaseDoor - { - [Constructible] - public DarkWoodDoor(DoorFacing facing) : base( - 0x6A5 + 2 * (int)facing, - 0x6A6 + 2 * (int)facing, - 0xEA, - 0xF1, - GetOffset(facing) - ) - { - } - - public DarkWoodDoor(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class MediumWoodDoor : BaseDoor - { - [Constructible] - public MediumWoodDoor(DoorFacing facing) : base( - 0x6B5 + 2 * (int)facing, - 0x6B6 + 2 * (int)facing, - 0xEA, - 0xF1, - GetOffset(facing) - ) - { - } - - public MediumWoodDoor(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class MetalDoor2 : BaseDoor - { - [Constructible] - public MetalDoor2(DoorFacing facing) : base( - 0x6C5 + 2 * (int)facing, - 0x6C6 + 2 * (int)facing, - 0xEC, - 0xF3, - GetOffset(facing) - ) - { - } - - public MetalDoor2(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class LightWoodDoor : BaseDoor - { - [Constructible] - public LightWoodDoor(DoorFacing facing) : base( - 0x6D5 + 2 * (int)facing, - 0x6D6 + 2 * (int)facing, - 0xEA, - 0xF1, - GetOffset(facing) - ) - { - } - - public LightWoodDoor(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class StrongWoodDoor : BaseDoor - { - [Constructible] - public StrongWoodDoor(DoorFacing facing) : base( - 0x6E5 + 2 * (int)facing, - 0x6E6 + 2 * (int)facing, - 0xEA, - 0xF1, - GetOffset(facing) - ) - { - } - - public StrongWoodDoor(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } } } diff --git a/Projects/UOContent/Items/Construction/Doors/HouseDoors.cs b/Projects/UOContent/Items/Construction/Doors/HouseDoors.cs index 43a46e7ce..a111d28fc 100644 --- a/Projects/UOContent/Items/Construction/Doors/HouseDoors.cs +++ b/Projects/UOContent/Items/Construction/Doors/HouseDoors.cs @@ -1,291 +1,219 @@ using System.Collections.Generic; +using ModernUO.Serialization; using Server.ContextMenus; using Server.Gumps; using Server.Multis; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class MetalHouseDoor : BaseHouseDoor { - public class MetalHouseDoor : BaseHouseDoor + [Constructible] + public MetalHouseDoor(DoorFacing facing) : base( + facing, + 0x675 + 2 * (int)facing, + 0x676 + 2 * (int)facing, + 0xEC, + 0xF3, + GetOffset(facing) + ) { - [Constructible] - public MetalHouseDoor(DoorFacing facing) : base( + } +} + +[SerializationGenerator(0, false)] +public partial class DarkWoodHouseDoor : BaseHouseDoor +{ + [Constructible] + public DarkWoodHouseDoor(DoorFacing facing) : base( + facing, + 0x6A5 + 2 * (int)facing, + 0x6A6 + 2 * (int)facing, + 0xEA, + 0xF1, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class GenericHouseDoor : BaseHouseDoor +{ + [Constructible] + public GenericHouseDoor(DoorFacing facing, int baseItemID, int openedSound, int closedSound, bool autoAdjust = true) + : base( facing, - 0x675 + 2 * (int)facing, - 0x676 + 2 * (int)facing, - 0xEC, - 0xF3, + baseItemID + (autoAdjust ? 2 * (int)facing : 0), + baseItemID + 1 + (autoAdjust ? 2 * (int)facing : 0), + openedSound, + closedSound, GetOffset(facing) ) + { + } +} + +[SerializationGenerator(2, false)] +public abstract partial class BaseHouseDoor : BaseDoor, ISecurable +{ + [SerializableField(0)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private SecureLevel _level; + + [SerializableField(1)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private DoorFacing _facing; + + public BaseHouseDoor(DoorFacing facing, int closedID, int openedID, int openedSound, int closedSound, Point3D offset) + : base(closedID, openedID, openedSound, closedSound, offset) + { + _facing = facing; + _level = SecureLevel.Anyone; + } + + public override void GetContextMenuEntries(Mobile from, List list) + { + base.GetContextMenuEntries(from, list); + SetSecureLevelEntry.AddTo(from, this, list); + } + + public BaseHouse FindHouse() + { + Point3D loc; + + if (Open) { + loc = new Point3D(X - Offset.X, Y - Offset.Y, Z - Offset.Z); + } + else + { + loc = Location; } - public MetalHouseDoor(Serial serial) : base(serial) + return BaseHouse.FindHouseAt(loc, Map, 20); + } + + public bool CheckAccess(Mobile m) + { + var house = FindHouse(); + + if (house == null) { + return false; } - public override void Serialize(IGenericWriter writer) // Default Serialize method + if (!house.IsAosRules) { - base.Serialize(writer); - - writer.Write(0); // version + return true; } - public override void Deserialize(IGenericReader reader) // Default Deserialize method + if (house.Public ? house.IsBanned(m) : !house.HasAccess(m)) { - base.Deserialize(reader); + return false; + } - var version = reader.ReadInt(); + return house.HasSecureAccess(m, Level); + } + + public override void OnOpened(Mobile from) + { + var house = FindHouse(); + + if (house?.IsFriend(from) == true && from.AccessLevel == AccessLevel.Player && house.RefreshDecay()) + { + from.SendLocalizedMessage(1043293); // Your house's age and contents have been refreshed. + } + + if (house?.Public == true && !house.IsFriend(from)) + { + house.Visits++; } } - public class DarkWoodHouseDoor : BaseHouseDoor + public override bool UseLocks() => FindHouse()?.IsAosRules != true; + + public override void Use(Mobile from) { - [Constructible] - public DarkWoodHouseDoor(DoorFacing facing) : base( - facing, - 0x6A5 + 2 * (int)facing, - 0x6A6 + 2 * (int)facing, - 0xEA, - 0xF1, - GetOffset(facing) - ) + if (!CheckAccess(from)) { + from.SendLocalizedMessage(1061637); // You are not allowed to access this. } - - public DarkWoodHouseDoor(Serial serial) : base(serial) + else { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); + base.Use(from); } } - public class GenericHouseDoor : BaseHouseDoor + private void Deserialize(IGenericReader reader, int version) { - [Constructible] - public GenericHouseDoor(DoorFacing facing, int baseItemID, int openedSound, int closedSound, bool autoAdjust = true) - : base( - facing, - baseItemID + (autoAdjust ? 2 * (int)facing : 0), - baseItemID + 1 + (autoAdjust ? 2 * (int)facing : 0), - openedSound, - closedSound, - GetOffset(facing) - ) - { - } - - public GenericHouseDoor(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } + _level = (SecureLevel)reader.ReadInt(); + _facing = (DoorFacing)reader.ReadInt(); } - public abstract class BaseHouseDoor : BaseDoor, ISecurable + public override bool IsInside(Mobile from) { - public BaseHouseDoor(DoorFacing facing, int closedID, int openedID, int openedSound, int closedSound, Point3D offset) - : base(closedID, openedID, openedSound, closedSound, offset) + int x, y, w, h; + + const int r = 2; + const int bs = r * 2 + 1; + const int ss = r + 1; + + switch (Facing) { - Facing = facing; - Level = SecureLevel.Anyone; - } - - public BaseHouseDoor(Serial serial) : base(serial) - { - } - - [CommandProperty(AccessLevel.GameMaster)] - public DoorFacing Facing { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public SecureLevel Level { get; set; } - - public override void GetContextMenuEntries(Mobile from, List list) - { - base.GetContextMenuEntries(from, list); - SetSecureLevelEntry.AddTo(from, this, list); - } - - public BaseHouse FindHouse() - { - Point3D loc; - - if (Open) - { - loc = new Point3D(X - Offset.X, Y - Offset.Y, Z - Offset.Z); - } - else - { - loc = Location; - } - - return BaseHouse.FindHouseAt(loc, Map, 20); - } - - public bool CheckAccess(Mobile m) - { - var house = FindHouse(); - - if (house == null) - { - return false; - } - - if (!house.IsAosRules) - { - return true; - } - - if (house.Public ? house.IsBanned(m) : !house.HasAccess(m)) - { - return false; - } - - return house.HasSecureAccess(m, Level); - } - - public override void OnOpened(Mobile from) - { - var house = FindHouse(); - - if (house?.IsFriend(from) == true && from.AccessLevel == AccessLevel.Player && house.RefreshDecay()) - { - from.SendLocalizedMessage(1043293); // Your house's age and contents have been refreshed. - } - - if (house?.Public == true && !house.IsFriend(from)) - { - house.Visits++; - } - } - - public override bool UseLocks() => FindHouse()?.IsAosRules != true; - - public override void Use(Mobile from) - { - if (!CheckAccess(from)) - { - from.SendLocalizedMessage(1061637); // You are not allowed to access this. - } - else - { - base.Use(from); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - - writer.Write((int)Level); - - writer.Write((int)Facing); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 1: - { - Level = (SecureLevel)reader.ReadInt(); - goto case 0; - } - case 0: - { - if (version < 1) - { - Level = SecureLevel.Anyone; - } - - Facing = (DoorFacing)reader.ReadInt(); - break; - } - } - } - - public override bool IsInside(Mobile from) - { - int x, y, w, h; - - const int r = 2; - const int bs = r * 2 + 1; - const int ss = r + 1; - - switch (Facing) - { - case DoorFacing.WestCW: - case DoorFacing.EastCCW: + case DoorFacing.WestCW: + case DoorFacing.EastCCW: + { x = -r; y = -r; w = bs; h = ss; break; + } - case DoorFacing.EastCW: - case DoorFacing.WestCCW: + case DoorFacing.EastCW: + case DoorFacing.WestCCW: + { x = -r; y = 0; w = bs; h = ss; break; + } - case DoorFacing.SouthCW: - case DoorFacing.NorthCCW: + case DoorFacing.SouthCW: + case DoorFacing.NorthCCW: + { x = -r; y = -r; w = ss; h = bs; break; + } - case DoorFacing.NorthCW: - case DoorFacing.SouthCCW: + case DoorFacing.NorthCW: + case DoorFacing.SouthCCW: + { x = 0; y = -r; w = ss; h = bs; break; + } - // No way to test the 'insideness' of SE Sliding doors on OSI, so leaving them default to false until further information gained + // No way to test the 'insideness' of SE Sliding doors on OSI, so leaving them default to false until further information gained - default: return false; - } - - var rx = from.X - X; - var ry = from.Y - Y; - var az = (from.Z - Z).Abs(); - - return rx >= x && rx < x + w && ry >= y && ry < y + h && az <= 4; + default: + { + return false; + } } + + var rx = from.X - X; + var ry = from.Y - Y; + var az = (from.Z - Z).Abs(); + + return rx >= x && rx < x + w && ry >= y && ry < y + h && az <= 4; } } diff --git a/Projects/UOContent/Items/Construction/Doors/Portcullis.cs b/Projects/UOContent/Items/Construction/Doors/Portcullis.cs index fc7bf3cdb..3fccb70cd 100644 --- a/Projects/UOContent/Items/Construction/Doors/Portcullis.cs +++ b/Projects/UOContent/Items/Construction/Doors/Portcullis.cs @@ -1,58 +1,21 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class PortcullisNS : BaseDoor { - public class PortcullisNS : BaseDoor + [Constructible] + public PortcullisNS() : base(0x6F5, 0x6F5, 0xF0, 0xEF, new Point3D(0, 0, 20)) + { + } +} + +[SerializationGenerator(0, false)] +public partial class PortcullisEW : BaseDoor +{ + [Constructible] + public PortcullisEW() : base(0x6F6, 0x6F6, 0xF0, 0xEF, new Point3D(0, 0, 20)) { - [Constructible] - public PortcullisNS() : base(0x6F5, 0x6F5, 0xF0, 0xEF, new Point3D(0, 0, 20)) - { - } - - public PortcullisNS(Serial serial) : base(serial) - { - } - - public override bool UseChainedFunctionality => true; - - 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 PortcullisEW : BaseDoor - { - [Constructible] - public PortcullisEW() : base(0x6F6, 0x6F6, 0xF0, 0xEF, new Point3D(0, 0, 20)) - { - } - - public PortcullisEW(Serial serial) : base(serial) - { - } - - public override bool UseChainedFunctionality => true; - - 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(); - } } } diff --git a/Projects/UOContent/Items/Construction/Doors/SecretDoors.cs b/Projects/UOContent/Items/Construction/Doors/SecretDoors.cs index 074b60d7c..86ddc88cc 100644 --- a/Projects/UOContent/Items/Construction/Doors/SecretDoors.cs +++ b/Projects/UOContent/Items/Construction/Doors/SecretDoors.cs @@ -1,194 +1,93 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class SecretStoneDoor1 : BaseDoor { - public class SecretStoneDoor1 : BaseDoor + [Constructible] + public SecretStoneDoor1(DoorFacing facing) : base( + 0xE8 + 2 * (int)facing, + 0xE9 + 2 * (int)facing, + 0xED, + 0xF4, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class SecretDungeonDoor : BaseDoor +{ + [Constructible] + public SecretDungeonDoor(DoorFacing facing) : base( + 0x314 + 2 * (int)facing, + 0x315 + 2 * (int)facing, + 0xED, + 0xF4, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class SecretStoneDoor2 : BaseDoor +{ + [Constructible] + public SecretStoneDoor2(DoorFacing facing) : base( + 0x324 + 2 * (int)facing, + 0x325 + 2 * (int)facing, + 0xED, + 0xF4, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class SecretWoodenDoor : BaseDoor +{ + [Constructible] + public SecretWoodenDoor(DoorFacing facing) : base( + 0x334 + 2 * (int)facing, + 0x335 + 2 * (int)facing, + 0xED, + 0xF4, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class SecretLightWoodDoor : BaseDoor +{ + [Constructible] + public SecretLightWoodDoor(DoorFacing facing) : base( + 0x344 + 2 * (int)facing, + 0x345 + 2 * (int)facing, + 0xED, + 0xF4, + GetOffset(facing) + ) + { + } +} + +[SerializationGenerator(0, false)] +public partial class SecretStoneDoor3 : BaseDoor +{ + [Constructible] + public SecretStoneDoor3(DoorFacing facing) : base( + 0x354 + 2 * (int)facing, + 0x355 + 2 * (int)facing, + 0xED, + 0xF4, + GetOffset(facing) + ) { - [Constructible] - public SecretStoneDoor1(DoorFacing facing) : base( - 0xE8 + 2 * (int)facing, - 0xE9 + 2 * (int)facing, - 0xED, - 0xF4, - GetOffset(facing) - ) - { - } - - public SecretStoneDoor1(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class SecretDungeonDoor : BaseDoor - { - [Constructible] - public SecretDungeonDoor(DoorFacing facing) : base( - 0x314 + 2 * (int)facing, - 0x315 + 2 * (int)facing, - 0xED, - 0xF4, - GetOffset(facing) - ) - { - } - - public SecretDungeonDoor(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class SecretStoneDoor2 : BaseDoor - { - [Constructible] - public SecretStoneDoor2(DoorFacing facing) : base( - 0x324 + 2 * (int)facing, - 0x325 + 2 * (int)facing, - 0xED, - 0xF4, - GetOffset(facing) - ) - { - } - - public SecretStoneDoor2(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class SecretWoodenDoor : BaseDoor - { - [Constructible] - public SecretWoodenDoor(DoorFacing facing) : base( - 0x334 + 2 * (int)facing, - 0x335 + 2 * (int)facing, - 0xED, - 0xF4, - GetOffset(facing) - ) - { - } - - public SecretWoodenDoor(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class SecretLightWoodDoor : BaseDoor - { - [Constructible] - public SecretLightWoodDoor(DoorFacing facing) : base( - 0x344 + 2 * (int)facing, - 0x345 + 2 * (int)facing, - 0xED, - 0xF4, - GetOffset(facing) - ) - { - } - - public SecretLightWoodDoor(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } - } - - public class SecretStoneDoor3 : BaseDoor - { - [Constructible] - public SecretStoneDoor3(DoorFacing facing) : base( - 0x354 + 2 * (int)facing, - 0x355 + 2 * (int)facing, - 0xED, - 0xF4, - GetOffset(facing) - ) - { - } - - public SecretStoneDoor3(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) // Default Serialize method - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) // Default Deserialize method - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } } } diff --git a/Projects/UOContent/Migrations/Server.Items.BarredMetalDoor.v0.json b/Projects/UOContent/Migrations/Server.Items.BarredMetalDoor.v0.json new file mode 100644 index 000000000..f173276a9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BarredMetalDoor.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BarredMetalDoor" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BarredMetalDoor2.v0.json b/Projects/UOContent/Migrations/Server.Items.BarredMetalDoor2.v0.json new file mode 100644 index 000000000..f456b15db --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BarredMetalDoor2.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BarredMetalDoor2" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BaseDoor.v0.json b/Projects/UOContent/Migrations/Server.Items.BaseDoor.v0.json new file mode 100644 index 000000000..6bbb2c244 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseDoor.v0.json @@ -0,0 +1,75 @@ +{ + "version": 0, + "type": "Server.Items.BaseDoor", + "properties": [ + { + "name": "KeyValue", + "type": "uint", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Open", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Locked", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "OpenedId", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "ClosedId", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "OpenedSound", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "ClosedSound", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Offset", + "type": "Server.Point3D", + "rule": "PrimitiveUOTypeMigrationRule", + "ruleArguments": [ + "Point3D" + ] + }, + { + "name": "Link", + "type": "Server.Items.BaseDoor", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BaseHouseDoor.v2.json b/Projects/UOContent/Migrations/Server.Items.BaseHouseDoor.v2.json new file mode 100644 index 000000000..d0ab93e45 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseHouseDoor.v2.json @@ -0,0 +1,16 @@ +{ + "version": 2, + "type": "Server.Items.BaseHouseDoor", + "properties": [ + { + "name": "Level", + "type": "Server.Multis.SecureLevel", + "rule": "EnumMigrationRule" + }, + { + "name": "Facing", + "type": "Server.Items.DoorFacing", + "rule": "EnumMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DarkWoodDoor.v0.json b/Projects/UOContent/Migrations/Server.Items.DarkWoodDoor.v0.json new file mode 100644 index 000000000..280d506af --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DarkWoodDoor.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.DarkWoodDoor" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DarkWoodGate.v0.json b/Projects/UOContent/Migrations/Server.Items.DarkWoodGate.v0.json new file mode 100644 index 000000000..9e1e651ca --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DarkWoodGate.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.DarkWoodGate" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.DarkWoodHouseDoor.v0.json b/Projects/UOContent/Migrations/Server.Items.DarkWoodHouseDoor.v0.json new file mode 100644 index 000000000..08fd1826b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.DarkWoodHouseDoor.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.DarkWoodHouseDoor" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GenericHouseDoor.v0.json b/Projects/UOContent/Migrations/Server.Items.GenericHouseDoor.v0.json new file mode 100644 index 000000000..39b518d97 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GenericHouseDoor.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GenericHouseDoor" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.IronGate.v0.json b/Projects/UOContent/Migrations/Server.Items.IronGate.v0.json new file mode 100644 index 000000000..6dd4089f1 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.IronGate.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.IronGate" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.IronGateShort.v0.json b/Projects/UOContent/Migrations/Server.Items.IronGateShort.v0.json new file mode 100644 index 000000000..b46a350dc --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.IronGateShort.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.IronGateShort" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LightWoodDoor.v0.json b/Projects/UOContent/Migrations/Server.Items.LightWoodDoor.v0.json new file mode 100644 index 000000000..57c186ffa --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LightWoodDoor.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LightWoodDoor" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.LightWoodGate.v0.json b/Projects/UOContent/Migrations/Server.Items.LightWoodGate.v0.json new file mode 100644 index 000000000..cadc16129 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.LightWoodGate.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.LightWoodGate" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.MediumWoodDoor.v0.json b/Projects/UOContent/Migrations/Server.Items.MediumWoodDoor.v0.json new file mode 100644 index 000000000..3ae0beccd --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MediumWoodDoor.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MediumWoodDoor" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.MetalDoor.v0.json b/Projects/UOContent/Migrations/Server.Items.MetalDoor.v0.json new file mode 100644 index 000000000..db1c8c5cf --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MetalDoor.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MetalDoor" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.MetalDoor2.v0.json b/Projects/UOContent/Migrations/Server.Items.MetalDoor2.v0.json new file mode 100644 index 000000000..8cb41fbb7 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MetalDoor2.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MetalDoor2" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.MetalHouseDoor.v0.json b/Projects/UOContent/Migrations/Server.Items.MetalHouseDoor.v0.json new file mode 100644 index 000000000..7acba8e94 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.MetalHouseDoor.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.MetalHouseDoor" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PortcullisEW.v0.json b/Projects/UOContent/Migrations/Server.Items.PortcullisEW.v0.json new file mode 100644 index 000000000..1ab479810 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PortcullisEW.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PortcullisEW" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.PortcullisNS.v0.json b/Projects/UOContent/Migrations/Server.Items.PortcullisNS.v0.json new file mode 100644 index 000000000..2b6fe95e2 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.PortcullisNS.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.PortcullisNS" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RattanDoor.v0.json b/Projects/UOContent/Migrations/Server.Items.RattanDoor.v0.json new file mode 100644 index 000000000..4fa37d45d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RattanDoor.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.RattanDoor" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SecretDungeonDoor.v0.json b/Projects/UOContent/Migrations/Server.Items.SecretDungeonDoor.v0.json new file mode 100644 index 000000000..885e25c52 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SecretDungeonDoor.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SecretDungeonDoor" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SecretLightWoodDoor.v0.json b/Projects/UOContent/Migrations/Server.Items.SecretLightWoodDoor.v0.json new file mode 100644 index 000000000..0e81c6340 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SecretLightWoodDoor.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SecretLightWoodDoor" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SecretStoneDoor1.v0.json b/Projects/UOContent/Migrations/Server.Items.SecretStoneDoor1.v0.json new file mode 100644 index 000000000..4bff594a1 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SecretStoneDoor1.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SecretStoneDoor1" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SecretStoneDoor2.v0.json b/Projects/UOContent/Migrations/Server.Items.SecretStoneDoor2.v0.json new file mode 100644 index 000000000..012340b39 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SecretStoneDoor2.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SecretStoneDoor2" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SecretStoneDoor3.v0.json b/Projects/UOContent/Migrations/Server.Items.SecretStoneDoor3.v0.json new file mode 100644 index 000000000..38b1cda20 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SecretStoneDoor3.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SecretStoneDoor3" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.SecretWoodenDoor.v0.json b/Projects/UOContent/Migrations/Server.Items.SecretWoodenDoor.v0.json new file mode 100644 index 000000000..fea79d639 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.SecretWoodenDoor.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.SecretWoodenDoor" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.StrongWoodDoor.v0.json b/Projects/UOContent/Migrations/Server.Items.StrongWoodDoor.v0.json new file mode 100644 index 000000000..31e44d0d3 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.StrongWoodDoor.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.StrongWoodDoor" +} \ No newline at end of file diff --git a/Projects/UOContent/Multis/Houses/HouseFoundation.cs b/Projects/UOContent/Multis/Houses/HouseFoundation.cs index d8d9f2a89..717ec87d9 100644 --- a/Projects/UOContent/Multis/Houses/HouseFoundation.cs +++ b/Projects/UOContent/Multis/Houses/HouseFoundation.cs @@ -561,7 +561,7 @@ namespace Server.Multis } else if (fixture is BaseHouseDoor door) { - if (door.Link != null) + if (door.Link?.Deleted == false) { continue; } @@ -572,70 +572,94 @@ namespace Server.Multis switch (door.Facing) { default: - linkFacing = DoorFacing.EastCCW; - xOffset = 1; - yOffset = 0; - break; + { + linkFacing = DoorFacing.EastCCW; + xOffset = 1; + yOffset = 0; + break; + } case DoorFacing.EastCCW: - linkFacing = DoorFacing.WestCW; - xOffset = -1; - yOffset = 0; - break; + { + linkFacing = DoorFacing.WestCW; + xOffset = -1; + yOffset = 0; + break; + } case DoorFacing.WestCCW: - linkFacing = DoorFacing.EastCW; - xOffset = 1; - yOffset = 0; - break; + { + linkFacing = DoorFacing.EastCW; + xOffset = 1; + yOffset = 0; + break; + } case DoorFacing.EastCW: - linkFacing = DoorFacing.WestCCW; - xOffset = -1; - yOffset = 0; - break; + { + linkFacing = DoorFacing.WestCCW; + xOffset = -1; + yOffset = 0; + break; + } case DoorFacing.SouthCW: - linkFacing = DoorFacing.NorthCCW; - xOffset = 0; - yOffset = -1; - break; + { + linkFacing = DoorFacing.NorthCCW; + xOffset = 0; + yOffset = -1; + break; + } case DoorFacing.NorthCCW: - linkFacing = DoorFacing.SouthCW; - xOffset = 0; - yOffset = 1; - break; + { + linkFacing = DoorFacing.SouthCW; + xOffset = 0; + yOffset = 1; + break; + } case DoorFacing.SouthCCW: - linkFacing = DoorFacing.NorthCW; - xOffset = 0; - yOffset = -1; - break; + { + linkFacing = DoorFacing.NorthCW; + xOffset = 0; + yOffset = -1; + break; + } case DoorFacing.NorthCW: - linkFacing = DoorFacing.SouthCCW; - xOffset = 0; - yOffset = 1; - break; + { + linkFacing = DoorFacing.SouthCCW; + xOffset = 0; + yOffset = 1; + break; + } case DoorFacing.SouthSW: - linkFacing = DoorFacing.SouthSE; - xOffset = 1; - yOffset = 0; - break; + { + linkFacing = DoorFacing.SouthSE; + xOffset = 1; + yOffset = 0; + break; + } case DoorFacing.SouthSE: - linkFacing = DoorFacing.SouthSW; - xOffset = -1; - yOffset = 0; - break; + { + linkFacing = DoorFacing.SouthSW; + xOffset = -1; + yOffset = 0; + break; + } case DoorFacing.WestSN: - linkFacing = DoorFacing.WestSS; - xOffset = 0; - yOffset = 1; - break; + { + linkFacing = DoorFacing.WestSS; + xOffset = 0; + yOffset = 1; + break; + } case DoorFacing.WestSS: - linkFacing = DoorFacing.WestSN; - xOffset = 0; - yOffset = -1; - break; + { + linkFacing = DoorFacing.WestSN; + xOffset = 0; + yOffset = -1; + break; + } } for (var j = i + 1; j < Fixtures.Count; ++j) { - if (Fixtures[j] is BaseHouseDoor check && check.Link == null && check.Facing == linkFacing && + if (Fixtures[j] is BaseHouseDoor check && check.Link?.Deleted == false && check.Facing == linkFacing && check.X - door.X == xOffset && check.Y - door.Y == yOffset && check.Z == door.Z) { check.Link = door; @@ -663,61 +687,79 @@ namespace Server.Multis switch (type) { default: - corner = 0x0014; - east = 0x0015; - south = 0x0016; - post = 0x0017; - break; + { + corner = 0x0014; + east = 0x0015; + south = 0x0016; + post = 0x0017; + break; + } case FoundationType.LightWood: - corner = 0x00BD; - east = 0x00BE; - south = 0x00BF; - post = 0x00C0; - break; + { + corner = 0x00BD; + east = 0x00BE; + south = 0x00BF; + post = 0x00C0; + break; + } case FoundationType.Dungeon: - corner = 0x02FD; - east = 0x02FF; - south = 0x02FE; - post = 0x0300; - break; + { + corner = 0x02FD; + east = 0x02FF; + south = 0x02FE; + post = 0x0300; + break; + } case FoundationType.Brick: - corner = 0x0041; - east = 0x0043; - south = 0x0042; - post = 0x0044; - break; + { + corner = 0x0041; + east = 0x0043; + south = 0x0042; + post = 0x0044; + break; + } case FoundationType.Stone: - corner = 0x0065; - east = 0x0064; - south = 0x0063; - post = 0x0066; - break; + { + corner = 0x0065; + east = 0x0064; + south = 0x0063; + post = 0x0066; + break; + } case FoundationType.ElvenGrey: - corner = 0x2DF7; - east = 0x2DF9; - south = 0x2DFA; - post = 0x2DF8; - break; + { + corner = 0x2DF7; + east = 0x2DF9; + south = 0x2DFA; + post = 0x2DF8; + break; + } case FoundationType.ElvenNatural: - corner = 0x2DFB; - east = 0x2DFD; - south = 0x2DFE; - post = 0x2DFC; - break; + { + corner = 0x2DFB; + east = 0x2DFD; + south = 0x2DFE; + post = 0x2DFC; + break; + } case FoundationType.Crystal: - corner = 0x3672; - east = 0x3671; - south = 0x3670; - post = 0x3673; - break; + { + corner = 0x3672; + east = 0x3671; + south = 0x3670; + post = 0x3673; + break; + } case FoundationType.Shadow: - corner = 0x3676; - east = 0x3675; - south = 0x3674; - post = 0x3677; - break; + { + corner = 0x3676; + east = 0x3675; + south = 0x3674; + post = 0x3677; + break; + } } }